# 格式化字符串
在 Python 中,有两种格式化字符串的方式,在 Python2 的较低版本中,格式化字符串的方式为 "this is a %s" % "test"
,之后增加了 format 的方式, 语法为 "this is a {}".format('test')
或者 "this is a {test}".format(test='test')
当格式化字符串由用户输入时,则可能会造成一些问题,下面是一个最简单的例子
>>> 'class of {0} is {0.__class__}'.format(42)
"class of 42 is <class 'int'>"
从上面这个简单的例子不难知道,当我们可以控制要 format 的字符串时,则可以使用 __init__
/ __globals__
等属性读取一些比较敏感的值,甚至任意执行代码。
# 反序列化
# pickle demo
Python Pickle 在反序列化时会调用 __reduce__
,可用自定义的 __reduce__
函数来实现攻击。
import pickle | |
import pickletools | |
import subprocess | |
class A(object): | |
a = 1 | |
b = 2 | |
def __reduce__(self): | |
return (subprocess.Popen, (('cmd.exe',),)) | |
data = pickle.dumps(A()) | |
pickletools.dis(data) |
# 其他序列化库
- PyYAML
- marshal
- shelve
# 沙箱
# 常用函数
- eval / exec / compile
- dir / type
- globals / locals / vars
- getattr / setattr
# 导入包方式
import os
from os import *
__import__("os")
importlib
imp
reload(os)
execfile
仅 Python2 支持
# 绕过
dir(__builtins__)
查看内置模块- 最简单的思路是在已有的模块中 import,如果那个模块中已经 import 可以利用的模块就可以使用了
- 在父类中寻找可用的模块,最常见 payload 是
().__class__.__bases__[0].__subclasses__()
或者用魔术方法获取全局作用域__init__.__func__.__globals__
- 有些网站没有过滤 pickle 模块,可以使用 pickle 实现任意代码执行,生成 payload 可以使用
https://gist.github.com/freddyb/3360650
- 有的沙箱把相关的模块代码都被删除了,则可以使用 libc 中的函数,Python 中调用一般可以使用 ctypes 或者 cffi。
"A""B" == "AB"
# 防御
Python 官方给出了一些防御的建议
- 使用 Jython 并尝试使用 Java 平台来锁定程序的权限
- 使用 fakeroot 来避免
- 使用一些 rootjail 的技术
# 框架
# Django
# 历史漏洞
- CVE-2016-7401 CSRF Bypass
- CVE-2017-7233/7234 Open redirect vulnerability
- CVE-2017-12794 debug page XSS
# 配置相关
- Nginx 在为 Django 做反向代理时,静态文件目录配置错误会导致源码泄露。访问 /static.. 会 301 重定向到 /static../
# Flask
Flask 默认使用客户端 session,使得 session 可以被伪造
# 代码混淆
# 常见混淆方式
- 基于 AST 变换
- 编译为 pyc 文件
- Pyinstaller
- PyArmor
- 通过 AES 加密为 pye 文件
# Sink
# 命令执行
- asyncio.new_event_loop().subprocess_exec
- asyncio.subprocess
- bdb.os
- cgi.os.system
- cgi.sys
- code.InteractiveInterpreter
- commands
- ctypes.CDLL
- eval
- exec
- execfile
- input // python2 only
- os.exec
- os.exec*
- os.fork
- os.popen
- os.spawn
- os.system
- platform.os
- platform.popen
- platform.sys
- popen2
- pty.os
- pty.spawn
- subprocess
- timeit.sys
- timeit.timeit
- typing.get_type_hints() +
__annotations__
- ...
# 文件读取
- open
- os.open
- urllib.request.urlopen('[file:///](file:///)')
- codecs.open
- fileinput
- 仅 Python2
- types.FileType
# 危险第三方库
- Template
- subprocess32
# 反序列化
- marshal
- PyYAML
- pickle
- cPickle
- shelve
- PIL
# 参考链接
# 反序列化
- Python pickle 反序列化
- Python 沙箱 官方 wiki
- [Python eval 的常见错误封装及利用原理](http://xxlegend.com/2015/07/31/Python eval 的常见错误封装及利用原理 /)
- pickle Python 对象序列化
- Sour Pickles A serialised exploitation guide in one part
- How pickle works in Python
# 沙箱
- Python 沙箱通用绕过
- 一文看懂 Python 沙箱逃逸
# 格式化字符串
- Python 字符串格式化漏洞
- Be Careful with Python's New-Style String Format
# 综合
- python security
- Python 安全和代码审计相关资料收集