Python 手册——模块、反射、迭代器与常用库速查
前言
写 CTF EXP 和代码审计时,Python 的各种内置函数和模块特性经常需要速查。本文按主题整理了 Python 最常用的 40+ 个知识点——从模块导入到反射、从迭代器到装饰器、从 Flask 到 FastAPI——每个都附带可直接复制的代码示例。
一、模块与包
1.1 模块——单个 .py 文件
1 | # 文件: my_module.py |
每个模块都有一个内置属性 __name__:
- 当模块被直接运行时,
__name__被设置为'__main__' - 当模块被导入时,
__name__被设置为模块本身的名称
1 | # 文件末尾常见写法: |
1.2 包——含 __init__.py 的目录
1 | my_package/ |
1 | # 使用: |
1.3 importlib —— 动态导入模块
1 | import importlib |
二、动态调用——反射三大方法
2.1 hasattr —— 检查是否拥有属性/方法
1 | class Person: |
2.2 getattr —— 动态获取属性值
1 | class Person: |
与字符串反转结合绕过关键字检测:
1 | getattr(obj, 'metsys'[::-1])('whoami') |
2.3 setattr —— 动态设置属性
1 | class Config: |
2.4 type() —— 动态创建类
1 | User = type('User', (object,), { |
| 参数 | 含义 |
|---|---|
'User' |
类名 |
(object,) |
继承的父类(元组) |
{...} |
类属性和方法的字典 |
三、函数与迭代器
3.1 lambda —— 匿名函数
1 | # def 写法 |
直接调用:
1 | (lambda x: x * 2)(5) # 10 |
高阶函数配合:
1 | numbers = [1, 2, 3, 4, 5, 6] |
3.2 装饰器
基本结构:
1 | def 装饰器名(被装饰函数): |
实战示例:
1 | import time |
3.3 迭代器
Python 中许多内置对象都是可迭代的,可以用 iter() 获取其迭代器,用 next() 逐元素消费。
文件迭代器:
1 | with open('test.txt', 'r') as file: |
字典迭代器:
1 | my_dict = {'a': 1, 'b': 2, 'c': 3} |
range / 字符串 / 集合迭代器:
1 | # range |
3.4 compile + exec
compile 接受三个参数:
| 参数 | 含义 |
|---|---|
code_str |
要执行的代码字符串 |
filename |
命名,方便报错定位(如 "test") |
mode |
'exec' / 'eval' / 'single'——与后面执行用的函数保持一致 |
1 | locals_dict = {} |
exec 三个参数:
| 参数 | 含义 |
|---|---|
code |
要执行的代码字符串或 code 对象 |
globals |
全局命名空间字典,代码中可以直接用里面的变量 |
locals |
局部命名空间字典,执行后可从中取回代码块中赋值的新变量 |
3.5 ** —— 关键字参数解包
1 | def render_user_template(tpl: str, **context) -> str: |
3.6 海象表达式(:=)
1 | # 海象运算符是表达式,有返回值 |
实战用法(栈帧逃逸精简 payload 中):
1 | {}[[*((l := []).append(...) or l[0])][0]] |
四、字典与字符串
4.1 items() 方法
1 | src = {'name': 'Alice', 'age': 25, 'city': 'New York'} |
4.2 get() 方法
1 | d = {'a': 1} |
4.3 字符串常用方法
1 | path = "////etc/passwd" |
五、路径与文件操作
5.1 os.path 常用函数
1 | import os |
目录拼接漏洞:
os.path.join(UPLOAD_FOLDER, filename)中,如果filename以/开头(绝对路径),os.path.join会忽略前面的路径,直接使用该绝对路径。这是 Zip Slip 和路径穿越的经典原因。
5.2 pathlib.Path
1 | from pathlib import Path |
| 方法 | 作用 |
|---|---|
.resolve() |
解析为绝对路径 |
.parent |
获取父目录 |
.is_absolute() |
判断是否绝对路径 |
.relative_to(base) |
计算相对于 base 的路径 |
path.parent.mkdir(parents=True, exist_ok=True)— 创建的是 Path 对象的父目录;os.makedirs(target, exist_ok=True)— 创建的是 target 目录本身。
5.3 with 语句 —— 自动关闭资源
1 | # 普通写法(需手动关闭) |
with 不仅用于文件, socket、zipfile.ZipFile、subprocess.Popen 等也支持。
5.4 zipfile —— ZIP 压缩包操作
1 | import zipfile |
Zip Slip 漏洞: ZIP 包内文件名如果包含 ../,解压时可能写入任意目录。应在解压前检查 info.filename 是否有路径穿越风险。
5.5 tempfile —— 临时文件
1 | import tempfile |
六、网络请求
6.1 requests 基本用法
1 | import requests |
常见 HTTP 状态码:200(成功)、301/302(重定向)、401(未授权)、403(禁止)、404(不存在)、500(服务器错误)。
代理:
1 | proxies = { |
6.2 requests.Session —— 保持会话
1 | session = requests.Session() |
6.3 urllib —— 原生 HTTP 请求
1 | import urllib.request |
urllib.request.urlopen 的两个特性:
- 可以通过
file:///协议读取本地文件(绕过某些 WAF) - 内部会对 URL 做一次 decode——如果服务端也 decode 一次,可以用二次编码绕过 WAF
七、Flask 专题
7.1 Flask app 对象结构
1 | app(Flask 应用对象) |
7.2 常见敏感文件
| 文件 | 内容 |
|---|---|
/etc/passwd |
系统用户信息(用户名:口令:UID:GID:注释:主目录:Shell) |
/proc/self/cmdline |
当前进程的启动命令(如 python /app/app.py) |
/proc/self/environ |
当前进程环境变量(含 SECRET_KEY) |
/proc/self/maps |
当前进程内存映射(结合 /proc/self/mem 读内存) |
/proc/self/cwd |
当前工作目录的软链接 |
/proc/self/fd/<N> |
打开的文件描述符 |
7.3 flask.request 对象
1 | from flask import request |
文件保存:
1 | file = request.files.get('plugin') # <input type="file" name="plugin"> |
7.4 url_for —— 动态生成 URL
1 | from flask import Flask, url_for |
7.5 flask.make_response —— 构造响应
1 | from flask import make_response |
flask.redirect如果next_url可控,可以跳转到恶意网站(Open Redirect)。
7.6 SSTI 关联——模板渲染
1 | person = request.args.get('name') |
7.7 正则黑名单绕过示例
Flask 应用中常见的 WAF 写法:
1 | import re |
re.escape(word) 对关键字做转义防止被当作正则特殊字符。(^|[^\w]) 和 ([^\w]|$) 确保是完整单词匹配而不是子串——例如 flag 不会误杀 flag_content。
八、命令执行速查
8.1 os 模块
1 | import os |
os.popen2/os.popen3/os.popen4可以替代os.popen。
8.2 subprocess.run
1 | import subprocess |
8.3 Python 中可用于执行系统命令的函数(完整清单)
1 | eval, execfile, compile, open, file, map, input, |
8.4 base64.b64decode —— 双面行为
1 | import base64 |
这个特性在 Python 和 Shell 对 base64 的容错差异场景中是经典的命令注入绕过点。
九、线程与进程
9.1 threading 基本用法
1 | import threading |
9.2 subprocess.Popen —— 子进程管理
1 | self.process.poll() # 检查进程是否终止 |
十、数据库
10.1 SQLite3
1 | import sqlite3 |
row_factory = sqlite3.Row 的作用:
默认(None) |
sqlite3.Row |
|---|---|
结果返回元组 (1, 'admin', 25) |
结果返回 Row 对象 |
只能用索引访问 row[0] |
可用列名访问 row['username'] |
| 列顺序变化会导致索引失效 | 列名访问不受顺序影响 |
1 | conn.row_factory = sqlite3.Row |
10.2 Redis 模块
Redis 常用于 Flask session 存储、缓存和消息队列。在 CTF 中经常配合 SSRF 的 gopher:// 协议进行未授权访问攻击。
十一、其他常用模块速查
11.1 pydash.set_ —— 深层赋值(原型链污染)
1 | import pydash |
如果 key 可控则可能造成原型链污染。
11.2 uuid.getnode() —— 获取 MAC 地址
1 | import uuid |
11.3 random —— 伪随机(可预测)
1 | import random |
11.4 re.sub —— 正则替换
1 | import re |
11.5 socket.getaddrinfo —— DNS 解析
1 | import socket |
11.6 FastAPI —— 现代异步 Web 框架
1 | from fastapi import FastAPI, Request |