# 格式化字符串

在 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 安全和代码审计相关资料收集