网鼎杯 2018 - Web - Unfinish

AI-摘要
Microsoft Xiaoice's GPT
AI初始化中...
介绍自己 🙈
生成本文简介 👋
推荐相关文章 📖
前往主页 🏠
前往爱发电购买
网鼎杯 2018 - Web - Unfinish
Hunter题目信息
| 项 | 内容 |
|---|---|
| 比赛 | 网鼎杯 2018 |
| 方向 | Web |
| 难度 | Easy |
| 环境 | 授权靶场(已脱敏) |
考点:insert 注入 + 数字注入 + 盲注。
信息收集
打开题目只有一个登录界面(字段 email + password),检查源码无有用信息,万能密码登录无效。
目录扫描发现注册界面 register.php(字段 email + username + password)。
漏洞分析
insert 注入
注册时用户名 username 入库时过滤不严,只调用了 waf 函数对黑名单字符串进行判断(过滤 information、逗号 , 等),但没有用 addslashes 转义单引号。因此可以构造 insert 注入。
后端 SQL 大致为:
1 | insert into users (email, username, password) values ('$email', '$username', '$password') |
注意:这题本质上不是二次注入,而是 insert 注入(写入阶段即可注入,payload 直接拼接进 insert 语句)。
数字注入原理
MySQL/MariaDB 中,字符串包裹的数字如果以 + 号连接,会被当作数字处理进行运算:
1 | MariaDB [web]> select '1'+'1'; |
因此构造 payload 时,用 0'+查询+'0 的形式,让查询结果(ascii 值)作为数字参与 + 运算,最终 username 字段存入的是运算后的数字。
盲注 payload
flag 在独立的 flag 表中,通过 + 运算进行无列名获取:
1 | username = 0'+ascii(substr((select * from flag) from N for 1))+'0 |
其中:
substr((select * from flag) from N for 1):取 flag 第 N 个字符(无列名,select *)ascii(...):转 ascii 值0'+...+'0:字符串拼数字,+运算转数字- 结果(ascii 数值)写入 username 字段
注册后登录,登录页面 span.user-name 回显 username(即 ascii 数值),逐字符读取 flag。
利用过程
- 扫到
register.php,确认注册处 username 未转义单引号。 - 构造
0'+ascii(substr((select * from flag) from N for 1))+'0作为 username 注册。 - 用同邮箱密码登录,正则提取
user-name标签回显的数值,转成字符。 - 逐位置循环,遇
}结束,拼接得到 flag。
完整 EXP
归档 payload(脱敏后重组)。核心 payload:
1 | 注册时 username 字段(insert 注入点): |
完整 Python exp:
1 | # -*- coding: utf-8 -*- |
读取结果
逐字符盲注得到(示例前几位):
1 | C=67, T=84, F=70, 2=50, {=123, e=101, f=102, 6=54, ... |
最终 flag 为带 uuid 的 CTF2 格式串,已脱敏。
Flag
脱敏后:flag{xxxx}。原值为 CTF2 格式,由 insert 注入配合 ascii 数值回显逐字符盲注得到。
踩坑与总结
- insert 注入:
username入库时仅waf黑名单过滤(过滤information、逗号),未转义单引号,可直接拼接构造 insert 注入。 - 数字注入:
'0'+查询+'0'利用字符串拼数字被当作数字运算的特性,把查询结果转成数字存入。 - 无列名盲注:
select * from flag无需知道列名,配合ascii(substr(...))逐字符读取。 - 逗号过滤绕过:
substr(... from N for 1)用from/for语法替代substr(x, N, 1)的逗号写法。 - 每个位置用独立会话(新邮箱)注册+登录,避免状态串扰;回显数值为 ascii,需
chr()还原字符。
评论
匿名评论隐私政策
✅ 你无需删除空行,直接评论以获取最佳展示效果






