ctfshow SQL注入(171-175)-牛翰网

ctfshow SQL注入(171-175)

无过滤注入

这两天在打bulibox,对里面的sql注入利用不是很清楚,遂来ctfshow补一会基础,写题时思路带有很多自己的揣测,不一定正确,本人初学者,有什么问题还望各位大佬指正

(我认为对于sql注入语句的分析是很必要的,一来实战中存在注入漏洞时很可能会报错,可以通过报错中的SQL语句来分析该如何注入,二来结合其他漏洞比如任意文件读取之类的时,可以通过代码审计PHP中嵌入的SQL语句来进行分析)

所以这里的笔记会强调对SQL语句的分析

171

` $sql = “select username,password from user where username !=’flag’ and id = ‘”.$_GET[‘id’].”‘ limit 1;”; `

id = '".$_GET['id']."'

limit 1限制了输出第一行,但这里没有过滤注释符,直接注释掉即可

得到flag

172

比上一道题多了一个返回逻辑的处理

这个row应该是用来存储查询结果的,然后对row这个查询结果中的username进行检查,如果是flag,还是会被过滤

也就是说username不输出flag就行,对这题没什么影响

查询语句中已经给出列名和表名,直接用即可(列数看题目语句或order by查询,不过多赘述)

可以看到如果select username,这个表里大概存储了名为flag的username,因为这样查询会被过滤

173

![](https://cdn.nlark.com/yuque/0/2025/png/48966044/1743664212188-d76af5d6-7170-47cf-937e-01f54f390f19.png)

这里的处理方式是把返回给客户端的数据($ret)转换为JSON格式的字符串

例如:

$ret = ['username' => 'admin', 'data' => 'test']; 
// 转换为 {"username":"admin","data":"test"}

用正则表达式检查JSON字符串中是否包含flag,i是ignore忽略大小写

这里的输出,只要不输出疑似名为flag的username(我们知道ctfshow的flag里面没有flag字符串),一样能成功利用

那假如这里密码中的flag带有flag字符串该怎么办?

可以使用hex函数把输出结果的字符串转为16进制字符串

数据库查询时,HEX()函数仅改变数据的显示方式,不改变实际值。

也就是说,处理检查输出结果时,匹配JSON里面的flag,这里输出被转义为16进制字符串,里面没有flag这个字符串,一样输出成功,但是应用层若自动解码16进制,仍会触发过滤

我们来试一试在查询中带上疑似含有flag字符串的username:

成功利用

基于这种思路,我可不可以把输出转化成别的类型的字符串,比如说base64,比如说urlcode?

实践一下,发现把输出编码成base64一样能成功利用

但是一般大部分人是转义成16进制,可能16进制被自动解码的几率更小吧,但是这里可以清楚更多的可行性

174

![](https://cdn.nlark.com/yuque/0/2025/png/48966044/1743666067323-39ce1c53-401e-45e6-9bee-761b22ae3657.png)

不仅是flag,0-9也被过滤了,显然这里password中的flag会受到影响

但是思路和上一道题是一样的,即改变输出结果不与过滤匹配即可

有很多方法,把数字替换成字母挺方便的

写一个python脚本,由于flag中是16进制数,a-f,那就0->g,1->h,2->i,以此类推)

这里脚本的思路是:

生成 一个嵌套的 SQL 语句,该语句使用 SQL 的 REPLACE 函数对一个列(这里为 the_column)中的数字字符进行替换。

1、定义每个数字对应的字母

2、生成一个嵌套的SQL replace函数调用

3、输出最终的SQL表达式

# 生成嵌套SQL REPLACE语句
base = 'the_column' 
for n in range(10):
    replacement = chr(ord('g') + n)#ord:获取字符g的ascii码(103),再用
    #通过chr得到对应字符
    base = f"REPLACE({base}, '{n}', '{replacement}')"
    #每一次循环,把本轮循环中对应的数字n替换为指定replacement方式的字符
    
print({base}")

f:格式化字符串字面量,允许在字符串中直接放入变量和运算表达式

成功利用

175

![](https://cdn.nlark.com/yuque/0/2025/png/48966044/1743669532829-520b8d0f-289e-46c1-b671-0a807450210b.png)

ascii码0-127皆被过滤

得用点别的方法了,一是把密码放进创建的文件中,二是直接SQL语句上传一个木马看能不能利用

(才发现源码有一个小彩蛋)

‘ union select password,1 from ctfshow_user5 into outfile “/var/www/html/1.txt”– –

来源链接:https://www.cnblogs.com/Ex1st/p/18808120/ctfshow

请登录后发表评论

    没有回复内容