1. 程式人生 > >CTF中sql注入的一些知識

CTF中sql注入的一些知識

最近一直在學習sql注入的知識,感覺sql注入確實是漏洞中的一大難點。首先是自己對資料庫結構的不熟悉,所以構造的一些語句總是不能理解。其次是沒有對自己學習的知識做好總結,看了很多視訊、部落格、題目,每次我都感覺自己好像知道要怎麼去做了,可是再拿到一道題目,我還是隻會加單引號,甚至在單引號沒有報錯的時候就不知所措。最後是沒有好的狀態,急功近利,想要一蹴而就,但這sql注入又哪是幾天就能弄明白的,所以我還是想明白了,要多花時間去鑽研,要多做思考,不能眼高手低,真正的把原理和方法弄懂。

所以我先對最近遇到的一些問題進行總結,等慢慢學習更多以後,再對此進行補充。

1、為什麼有時候要用單引號閉合前面的引號,而有的時候卻不用閉合呢?

2、為什麼union前面搜尋的值不存在,卻還是可以把union聯合查詢的值給輸出來呢?

3、為什麼在url中不能用#號,而要用%23來表示呢?

4、在猜解列名時為什麼要在表名前後加引號,而猜解欄位內容時卻不用加呢?

5、information_schema是啥?為啥猜解的時候要一直用這個東西?

6、為什麼有時候引號輸進去也不會報錯?這個時候要怎麼做?

 

 

 

 

 

1、關於引號的問題,其實這是因為sql語句的兩種寫法

這兩種寫法都是正確的,只是安全性不同罷了,所以在你看不到原始碼的時候,也不能確定是否要加單引號去閉合,只能先加一個單引號來閉合嘗試。

這兩張圖片是來自於:http://cbb.sjtu.edu.cn/course/database/lab8.htm,這裡面對sql注入進行了很充分的解釋。

 

 

 

2、union是聯合查詢,查詢的欄位值必須要和前面查詢的相等,所以可以先用order by 語句來確認查詢的欄位值有多少個,然後再用union 查詢,查詢的值可以用數字 1 來填充,也可以查當前資料庫database(),資料庫版本 version(),使用者user(),只要後面的欄位值和前面相同就行了。

但是有的時候顯示的地方被前面查詢的值給佔用了,導致後面我們想查詢的值沒有地方顯示怎麼辦呢,就把前面要查詢的值給去掉,因為union查詢的時候,如果有一邊查詢的是不存在或錯誤的就不顯示,只顯示另一邊查詢正確的語句。

有時候頁面可以顯示資料的地方只有一個,那麼就要用union後面查詢的值來確定顯示的是哪一個欄位值。然後把想要查詢的值放在那個能顯示的欄位處。

 

 

 

 

 

3、其實這個問題之前就有考慮過,而且也在其他部落格上得到了答案,在這裡就當作記錄吧,在url中#會被當作錨鏈接,如果在url中直接提交#就會變為空,所以要用url編碼後的%23來代替,這樣url會在傳遞時解碼為#就可以把之後不需要的給註釋掉。

 

 

4、在猜解列名時,後端的查詢語句最後是 where table_name = 所以要將表名打引號,作為字串形式來查詢,不然就會報錯。而在猜解欄位內容時,後端的查詢語句最後是 from ,就可以直接填表名。

 

 

5、information_schema是一個擁有資料庫中所有資訊的庫,包含了所有的庫,表,列。所以在猜解的過程中要使用這個庫來進行猜解。猜解的過程如下:

在使用union查詢時,已經得知了當前資料庫 database(),就可以進行下一步表名的猜解了。

union select 1,2,table_name from information_schema.table where table_schema=database()

table_name就是表名,information_schema.table就是這個information_schema庫存放表資訊的表,table_schema就是表所屬的資料庫。這樣就可以得到當前資料庫中所有的表名。當然也可以使用group_concat(table_name)來將這些表名連線起來輸出。接下來再進行列名的猜解。

union select 1,2,column_name from information_schema.columns where table_name = 'XXX'

這裡和上面一個步驟是差不多的,這些單詞就不再解釋了。繼續下一步猜想要的列的欄位內容吧。

union select 1,2,YYY from XXX

最後就得到了我們想要的內容。

 

 

6、在我遇到的題目中,目前有一種情況是叫“寬位元組注入”,如果程式碼中用了addslashes()函式,這個函式會把所傳進來的引數中帶有的預定義字元前面加上轉義符'\'。那我們自己加進去想要閉合的單引號就失去了效果,但是有一種方法可以讓這個引號重新起到效果,就是寬位元組注入,因為gb2312或者gbk這種編碼方式,是兩個字元編碼一個漢字,所以我們如果在構造payload的時候在引號之前加一個 %df 讓這個%df和轉義符'\'一起編碼成一個漢字,那後面的引號就可以逃逸出來了。為什麼是%df,因為在gbk編碼裡一般第一個字元的ascii碼大於128就會認為這兩個字元組成一個漢字了。

 

因為這一篇部落格中的內容,是我先在筆記中寫好然後複製過來的,所以可能格式看起來不太舒服,見諒,sql注入中的問題遠不止這些,這裡只是記錄了一些我作為新手時遇到的問題,希望如果有其他和我一樣有這樣困惑的人可以得到大致的答案。我還會繼續補充的,寫的不好多多包涵。如果有朋友願意和我交朋友討論技術等等的話,可以加我的qq:1013024906 備註CSDN+名字。。。謝謝