前言
去年我做了一个可以压缩流量的socks5代理whisper-socks, 很显然不会有什么用处. 毕竟这年头服务商为了节约宽带, 流量基本都启用了压缩,并且HTTPS加密后的数据因为信息熵的原因, 数据没有规律可言, 更不好压缩了.
这会想写一个后门, socket什么的正好也就用上了. 一些代码直接就啪的一下复制过来用.
功能也就只有执行命令, 特点就是通过DH密钥交换得到密钥加密流量.
代码已经在github上了.
[simple-py-rat]
除了运行程序以外没有别的功能. 仅作为一个简单的例子.
但是的确没触发杀软警报并且经过测试, 可以在windows和linux上运行.
构思
- 反向连接, 走TCP协议.
- 支持Windows和linux.
- 流量加密. 使用Diffie–Hellman和AES-ECB配合.
- 简单, 做到执行命令即可. 尽可能绕过杀软.
由于代码没有注释, 简单说一下, 懒得画状态机:
- 攻击者运行
server.py
, 靶机运行client.py
或者被pyinstaller打包过的程序上线. client
上线后会进入一个循环, 尝试连接server
.- 一旦连接上便会进入握手阶段, 握手阶段CS会互相发送一个大约2048bits的数字(偶尔小于2048), 这个阶段的任务是DH密钥交换, 可以通过这种方式安全地生成一个密钥. 而这个密钥远超过16一个AES块大小, 于是我使用了md5处理, 正好缩短到16字节.
- 密钥交换完成,
client
阻塞, 等待server
传递指令; 而server
则阻塞等待用户输入. - 如果用户输入了命令,
server
便会用AES-ECB和之前的密钥加密命令并发送, 而后进入监听结果的阻塞.client
收到后解密. client
执行并加密返回结果, server
收到后解密, 检查编码以兼容不同编码, 默认GBK.结束后, 回到阶段4
粘包问题怎么解决?
这就是为什么我使用AES-ECB的原因. 虽然说ECB这种加密存在一定缺陷, 但是每个16字节的块的解密相对独立. 我们可以一个块一个块解密.
为了能让每个块都有16字节, 明文在加密之前进行了pkcs7标准的Padding, 所以我们可以在解密每一个块后都检查这个块是否有padding过, 一旦发现这个块存在padding那么这就是最后一个块, 这条消息应该到此为止.
所以可以说, 粘包问题是和加密一起解决的.
为什么不用CBC? 因为CBC的解密过程, 下一个块的解密结果取决于之前的块. 解密库的函数貌似不支持解密每个块的时候返回结果, 我不方便这样检查padding确定消息边界. 除非我自己实现一遍, 不然我只能不停地接一个块, 带着之前的块试着解密检查padding, 效率会很低. 所以放弃了CBC.
Comments
(no comments...maybe you can be the first?)