最近一直忙著實(shí)習(xí)面試,在準(zhǔn)備面試的過(guò)程確實(shí)也補(bǔ)充了很多自己以前的知識(shí)盲區(qū),雖然有點(diǎn)考前惡補(bǔ)的意思,但能學(xué)到知識(shí)總歸是好的。當(dāng)然,面試的結(jié)果也還算滿意,雖然還沒(méi)有拿到自己心中T0的大廠offer,但也獲得了很多其他乙方包括某個(gè)大廠甲方的實(shí)習(xí)offer。師哥們也陸續(xù)去實(shí)習(xí)了,老師這邊壓著比較多的項(xiàng)目正在推進(jìn),大都是滲透方向的,包括這個(gè)月的業(yè)務(wù),所以趁著實(shí)習(xí)面試的尾聲,好好的干一波嘿嘿。
一、Result
這個(gè)月的業(yè)務(wù)挖洞成果對(duì)自己來(lái)說(shuō)還是很滿意的,除了漏洞數(shù)量外,漏洞質(zhì)量也比較高。具體就不多說(shuō)了,言歸正傳,在本月的業(yè)務(wù)滲透測(cè)試?yán)锇l(fā)現(xiàn)一個(gè)很有趣的sql注入,也是自己之前的一個(gè)盲區(qū)——order by排序注入,一直想著在實(shí)戰(zhàn)中接觸這種類(lèi)型的注入場(chǎng)景,還真就來(lái)了。
二、Process
話不多說(shuō),上接口:
https://xxxx.com/xxx/xxx/xxx/getAreaSpotPageList?&pageindex=1&pagesize=20&passAreaId=2&orderby=pass_area_spot_id+desc&userId=1181163&hotelId=5&brandId=5
這是一個(gè)比較正常的get類(lèi)型的獲取數(shù)據(jù)接口,但orderby參數(shù)比較惹眼,因?yàn)閰?shù)的值為pass_area_spot_id+desc,desc表示的是sql中的降序排序,卻以orderby參數(shù)值的方式輸入,所以就對(duì)該參數(shù)進(jìn)行了測(cè)試:
Step 1:
令orderby=pass_area_spot_id+desc,返回?cái)?shù)據(jù)如下:

Step 2:
令orderby=pass_area_spot_id+asc,返回?cái)?shù)據(jù)如下:

(解釋一下,兩種情況下返回內(nèi)容不一致)
Step 3:
這里其實(shí)大致可以判斷存在排序注入的可能,但還是有歧義,需要進(jìn)一步進(jìn)行判斷,這里采用基于時(shí)間的盲注輔助判斷:
Payload1:pass_area_spot_id+desc,(select*from(select+sleep(3)union/**/select+1)a)
返回如下:

該請(qǐng)求在5s多時(shí)得到響應(yīng)。
Payload2:pass_area_spot_id+desc,(select*from(select+sleep(6)union/**/select+1)a)
返回如下:

該請(qǐng)求在8s多時(shí)得到響應(yīng)。
在不考慮測(cè)試環(huán)境本身的網(wǎng)絡(luò)狀況,上述測(cè)試過(guò)程可以證明漏洞的存在。
Step 4:
Time-based還是不太方便,并且時(shí)間較長(zhǎng)。所以更換注入手法,直觀輸出注入結(jié)果:
Payload:pass_area_spot_id+desc,if(ascii(substr(database(),? ,1))=?,1,(select%201%20from%20information_schema.tables))
通過(guò)布爾類(lèi)型的盲注,利用上述payload進(jìn)行fuzz(省略通過(guò)二分法判斷當(dāng)前數(shù)據(jù)庫(kù)長(zhǎng)度的步驟):

查找對(duì)應(yīng)ascii所代表的字符,獲得當(dāng)前數(shù)據(jù)庫(kù)名:xxxxxxxx,測(cè)試結(jié)束。
三、Review
在整個(gè)測(cè)試階段里,雖然注入成功,但是也引發(fā)了自己的兩個(gè)問(wèn)題,這兩個(gè)問(wèn)題也是自己在面試的過(guò)程中所碰到的。
Q1、為什么預(yù)編譯不太好防order by注入(就mysql數(shù)據(jù)庫(kù)來(lái)談)?
A1:
這個(gè)問(wèn)題不管在面試的過(guò)程中還是個(gè)人的平時(shí)積累過(guò)程中都能夠折射出個(gè)人的學(xué)習(xí)深度,很遺憾,我并沒(méi)有在面試的過(guò)程中很好的回答這個(gè)問(wèn)題,其實(shí)并不是不知道這個(gè)問(wèn)題的答案,而是不太好組織語(yǔ)言去系統(tǒng)性的帶擴(kuò)展的回答它,并且在之前的挖洞經(jīng)歷里沒(méi)有對(duì)應(yīng)的場(chǎng)景支撐,所以還是比較遺憾吧,另一方面更說(shuō)明自己的知識(shí)體系太弱,表面徘徊較多。
言歸正傳,為什么預(yù)編譯不太好防order by注入?這個(gè)問(wèn)題等于是在問(wèn)為什么在預(yù)編譯中order by后不能參數(shù)化?一般的sql執(zhí)行片段代碼(預(yù)編譯方式)是這樣的:
Connection conn = DBConnect.getConnection();
String sql = " SELECT xxx FROM xxx WHERE xxx = ? ";
ps = conn.prepareStatement(sql);
ps.setString(1, xxx); //或者ps.setInt(1, username);
rs = ps.executeQuery();
當(dāng)我們輸入xxx=abc時(shí),預(yù)編譯的代碼會(huì)自動(dòng)給abc加上引號(hào),變成'abc',sql語(yǔ)句也變成了:
String sql = " SELECT xxx FROM xxx WHERE xxx = 'abc' ";
這樣可以有效的防止用戶的輸入直接拼接在sql語(yǔ)句之后,譬如用戶輸入xxx=' or '1'='1時(shí),實(shí)際上的sql語(yǔ)句卻為:
String sql = " SELECT xxx FROM xxx WHERE xxx = '' or '1'='1' ";
無(wú)法達(dá)到攻擊的效果。說(shuō)回order by,order by的用法一般為order by [字段名] [desc/asc],如果對(duì)order by之后的輸入進(jìn)行參數(shù)化,那么sql語(yǔ)句將會(huì)變成這樣:
String sql = " SELECT xxx FROM xxx WHERE xxx ='xxx' order by 'xxx' "
這樣會(huì)造成sql語(yǔ)法錯(cuò)誤,因?yàn)榇藭r(shí)'xxx'是字符串而不是字段名。
那么為什么預(yù)編譯的函數(shù)在參數(shù)化時(shí)非要把輸入加上引號(hào)呢?如果沒(méi)有引號(hào)不就可以防御order by注入了嗎?是的,但確實(shí)沒(méi)有不加引號(hào)的預(yù)編譯的方法哈哈。
引伸來(lái)說(shuō),這樣的sql注入不僅僅發(fā)生在order by處,任何需要字符串且不能夠加引號(hào)的地方都有可能發(fā)生類(lèi)似的注入,因?yàn)椴荒軈?shù)化的位置,不管怎么拼接,最終都是和使用“+”號(hào)拼接字符串的功效一樣。
那么又引出了新的問(wèn)題,既然預(yù)編譯防不了order by,那么該怎么樣防?答案是采用白名單的方式,因?yàn)閛rder by之后跟的字段名肯定是有限的并且是數(shù)據(jù)庫(kù)中已經(jīng)存在的字段,只要對(duì)這些有限字段設(shè)置白名單,任何不在白名單內(nèi)的數(shù)據(jù)統(tǒng)一報(bào)錯(cuò),那么就可以解決啦。
Q2、面對(duì)時(shí)間較長(zhǎng)的Time-based或者Boolean-Base,除了用工具自動(dòng)化跑結(jié)果外,有沒(méi)有其他較好的方式?
A2
答案是利用Dnslog,當(dāng)時(shí)面試的時(shí)候比較緊張,一直想著payload的改進(jìn)和工具自動(dòng)化,把這個(gè)給忘了,其實(shí)也跟平時(shí)使用這個(gè)技巧不多的原因有關(guān),所以認(rèn)了。。不過(guò)在面試過(guò)后確實(shí)對(duì)Dnslog又強(qiáng)化了一波,的確很好用。直接上鏈接把->Dnslog-<,這個(gè)博主關(guān)于Dnslog在各個(gè)場(chǎng)景下的使用技巧總結(jié)的十分詳細(xì)了。
四、Re-review
參與面試的過(guò)程其實(shí)是對(duì)自己之前所積累的技術(shù)體系的一種測(cè)試,更重要的對(duì)我來(lái)說(shuō)收獲最多是了解圈內(nèi)的大牛們都在關(guān)注著哪些他們感興趣的方向和技術(shù)細(xì)節(jié),在丟人的同時(shí)的確獲得了很多自己想要的信息哈哈。也發(fā)現(xiàn)了自己在hack的過(guò)程中深度的確不夠,容易滿足于眼前的成果,挖洞是一方面,學(xué)習(xí)知識(shí)也是。因?yàn)閔ack的過(guò)程永遠(yuǎn)比挖到漏洞更重要。
五、To-Do
1、接下來(lái)的時(shí)間里繼續(xù)靶場(chǎng)的練習(xí),回顧之前浮躁?duì)顟B(tài)下所忽略的技術(shù)細(xì)節(jié),直到hack清楚為止。
2、思考自己的知識(shí)框架和技術(shù)框架,乘早跳出滲透的圈子,接觸真正的企業(yè)體系安全建設(shè)。
3、培養(yǎng)好奇心,保持好奇心。