ctf-misc

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

CTF Miscellaneous

CTF杂项挑战速查

Quick reference for misc challenges. For detailed techniques, see supporting files.
CTF杂项挑战快速参考手册。如需详细技术细节,请参考配套文件。

Additional Resources

额外参考资源

  • pyjails.md - Python jail/sandbox escape techniques
  • bashjails.md - Bash jail/restricted shell escape techniques
  • encodings.md - Encodings, QR codes, audio, esolangs
  • RF/SDR/IQ signal processing section below covers QAM, PSK, carrier recovery, timing sync

  • pyjails.md - Python沙箱逃逸技巧
  • bashjails.md - Bash受限shell逃逸技巧
  • encodings.md - 编码、二维码、音频、小众编程语言相关内容
  • 下方的RF/SDR/IQ信号处理章节涵盖QAM、PSK、载波恢复、时序同步等内容

General Tips

通用技巧

  • Read all provided files carefully
  • Check file metadata, hidden content, encoding
  • Power Automate scripts may hide API calls
  • Use binary search when guessing multiple answers
  • 仔细阅读所有提供的文件
  • 检查文件元数据、隐藏内容和编码格式
  • Power Automate脚本可能隐藏API调用
  • 猜测多个答案时使用二分查找法

Common Encodings

常见编码解码

bash
undefined
bash
undefined

Base64

Base64

echo "encoded" | base64 -d
echo "encoded" | base64 -d

Base32 (A-Z2-7=)

Base32 (A-Z2-7=)

echo "OBUWG32D..." | base32 -d
echo "OBUWG32D..." | base32 -d

Hex

Hex

echo "68656c6c6f" | xxd -r -p
echo "68656c6c6f" | xxd -r -p

ROT13

ROT13

echo "uryyb" | tr 'a-zA-Z' 'n-za-mN-ZA-M'

**Identify by charset:**
- Base64: `A-Za-z0-9+/=`
- Base32: `A-Z2-7=` (no lowercase)
- Hex: `0-9a-fA-F`
echo "uryyb" | tr 'a-zA-Z' 'n-za-mN-ZA-M'

**通过字符集识别:**
- Base64: `A-Za-z0-9+/=`
- Base32: `A-Z2-7=`(无小写字母)
- Hex: `0-9a-fA-F`

IEEE-754 Float Encoding (Data Hiding)

IEEE-754浮点数编码(数据隐藏)

Pattern (Floating): Numbers are float32 values hiding raw bytes.
Key insight: A 32-bit float is just 4 bytes interpreted as a number. Reinterpret as raw bytes → ASCII.
python
import struct
特征(浮点数类): 以32位浮点数形式存储原始字节数据。
核心思路: 一个32位浮点数本质上是被解释为数字的4个字节。将其重新解释为原始字节即可转换为ASCII字符。
python
import struct

List of suspicious floating-point numbers

可疑的浮点数列表

floats = [1.234e5, -3.456e-7, ...] # Whatever the challenge gives
floats = [1.234e5, -3.456e-7, ...] # 挑战题目给出的数值

Convert each float to 4 raw bytes (big-endian)

将每个浮点数转换为4个原始字节(大端序)

flag = b'' for f in floats: flag += struct.pack('>f', f) print(flag.decode())

**CyberChef solution:**
1. Paste numbers (space-separated)
2. "From Float" → Big Endian → Float (4 bytes) → Space delimiter

**Variations:**
- Double (8 bytes): `struct.pack('>d', val)`
- Little-endian: `struct.pack('<f', val)`
- Mixed endianness: try both if first doesn't produce ASCII
flag = b'' for f in floats: flag += struct.pack('>f', f) print(flag.decode())

**CyberChef解决方案:**
1. 粘贴以空格分隔的数值
2. 选择“From Float” → 大端序 → Float(4字节) → 空格分隔符

**变体:**
- 双精度浮点数(8字节):`struct.pack('>d', val)`
- 小端序:`struct.pack('<f', val)`
- 混合端序:如果第一种方式无法得到ASCII字符,尝试两种端序

USB Mouse PCAP Reconstruction

USB鼠标流量包重建

Pattern (Hunt and Peck): USB HID mouse traffic captures on-screen keyboard typing.
Workflow:
  1. Open PCAP in Wireshark — identify USBPcap with HID interrupt transfers
  2. Identify device (Device Descriptor → manufacturer/product)
  3. Use USB-Mouse-Pcap-Visualizer:
    github.com/WangYihang/USB-Mouse-Pcap-Visualizer
  4. Extract click coordinates (falling edges of
    left_button_holding
    )
  5. Plot clicks on scatter plot with matplotlib
  6. Overlay on image of Windows On-Screen Keyboard
  7. Animate clicks in order to read typed text
Key details:
  • Mouse reports relative coordinates (deltas), not absolute
  • Cumulative sum of deltas gives position track
  • Rising/falling edges of button state = click start/end
  • Need to scale/stretch overlay to match OSK layout
python
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv('mouse_data.csv')
特征(点击输入类): USB HID鼠标流量包记录了屏幕键盘的输入操作。
操作流程:
  1. 在Wireshark中打开PCAP文件,识别包含HID中断传输的USBPcap流量
  2. 识别设备(设备描述符 → 制造商/产品信息)
  3. 使用USB-Mouse-Pcap-Visualizer工具:
    github.com/WangYihang/USB-Mouse-Pcap-Visualizer
  4. 提取点击坐标(
    left_button_holding
    信号的下降沿)
  5. 使用matplotlib将点击位置绘制成散点图
  6. 将散点图叠加在Windows屏幕键盘的图片上
  7. 按顺序播放点击动画以读取输入的文本
关键细节:
  • 鼠标报告的是相对坐标(增量值),而非绝对坐标
  • 对增量值求和可得到位置轨迹
  • 按键状态的上升/下降沿代表点击的开始/结束
  • 需要调整叠加层的缩放比例以匹配屏幕键盘布局
python
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv('mouse_data.csv')

Find click positions (falling edges)

查找点击位置(信号下降沿)

clicks = df[df['left_button_holding'].shift(1) == True & (df['left_button_holding'] == False)]
clicks = df[(df['left_button_holding'].shift(1) == True) & (df['left_button_holding'] == False)]

Cumulative position from relative deltas

通过相对增量计算累计位置

x_pos = df['x'].cumsum() y_pos = df['y'].cumsum()
x_pos = df['x'].cumsum() y_pos = df['y'].cumsum()

Plot clicks over OSK image

在屏幕键盘图片上绘制点击点

plt.scatter(click_x, click_y, c='red', s=50)
undefined
plt.scatter(click_x, click_y, c='red', s=50)
undefined

File Type Detection

文件类型检测

bash
file unknown_file
xxd unknown_file | head
binwalk unknown_file
bash
file unknown_file
xxd unknown_file | head
binwalk unknown_file

Archive Extraction

归档文件提取

bash
7z x archive.7z           # Universal
tar -xzf archive.tar.gz   # Gzip
tar -xjf archive.tar.bz2  # Bzip2
tar -xJf archive.tar.xz   # XZ
bash
7z x archive.7z           # 通用提取命令
tar -xzf archive.tar.gz   # Gzip压缩包
tar -xjf archive.tar.bz2  # Bzip2压缩包
tar -xJf archive.tar.xz   # XZ压缩包

Nested Archive Script

嵌套归档自动提取脚本

bash
while f=$(ls *.tar* *.gz *.bz2 *.xz *.zip *.7z 2>/dev/null|head -1) && [ -n "$f" ]; do
    7z x -y "$f" && rm "$f"
done
bash
while f=$(ls *.tar* *.gz *.bz2 *.xz *.zip *.7z 2>/dev/null|head -1) && [ -n "$f" ]; do
    7z x -y "$f" && rm "$f"
done

QR Codes

二维码处理

bash
zbarimg qrcode.png       # Decode
qrencode -o out.png "data"
bash
zbarimg qrcode.png       # 解码二维码
qrencode -o out.png "data"

Audio Challenges

音频类挑战

bash
sox audio.wav -n spectrogram  # Visual data
qsstv                          # SSTV decoder
bash
sox audio.wav -n spectrogram  # 可视化音频数据
qsstv                          # SSTV信号解码器

RF / SDR / IQ Signal Processing

RF / SDR / IQ信号处理

IQ File Formats

IQ文件格式

  • cf32 (complex float 32): GNU Radio standard,
    np.fromfile(path, dtype=np.complex64)
  • cs16 (complex signed 16-bit):
    np.fromfile(path, dtype=np.int16).reshape(-1,2)
    , then
    I + jQ
  • cu8 (complex unsigned 8-bit): RTL-SDR raw format
  • cf32(32位复浮点数):GNU Radio标准格式,使用
    np.fromfile(path, dtype=np.complex64)
    读取
  • cs16(16位复有符号整数):
    np.fromfile(path, dtype=np.int16).reshape(-1,2)
    ,之后转换为
    I + jQ
    格式
  • cu8(8位复无符号整数):RTL-SDR原始输出格式

Analysis Pipeline

分析流程

python
import numpy as np
from scipy import signal
python
import numpy as np
from scipy import signal

1. Load IQ data

1. 加载IQ数据

iq = np.fromfile('signal.cf32', dtype=np.complex64)
iq = np.fromfile('signal.cf32', dtype=np.complex64)

2. Spectrum analysis - find occupied bands

2. 频谱分析 - 定位信号频段

fft_data = np.fft.fftshift(np.fft.fft(iq[:4096])) freqs = np.fft.fftshift(np.fft.fftfreq(4096)) power_db = 20*np.log10(np.abs(fft_data)+1e-10)
fft_data = np.fft.fftshift(np.fft.fft(iq[:4096])) freqs = np.fft.fftshift(np.fft.fftfreq(4096)) power_db = 20*np.log10(np.abs(fft_data)+1e-10)

3. Identify symbol rate via cyclostationary analysis

3. 通过循环平稳分析识别符号率

x2 = np.abs(iq_filtered)**2 # squared magnitude fft_x2 = np.abs(np.fft.fft(x2, n=65536))
x2 = np.abs(iq_filtered)**2 # 幅度平方 fft_x2 = np.abs(np.fft.fft(x2, n=65536))

Peak in fft_x2 = symbol rate (samples_per_symbol = 1/peak_freq)

fft_x2中的峰值即为符号率(符号采样率 = 1/峰值频率)

4. Frequency shift to baseband

4. 将信号频移至基带

center_freq = 0.14 # normalized frequency of band center t = np.arange(len(iq)) baseband = iq * np.exp(-2j * np.pi * center_freq * t)
center_freq = 0.14 # 频段中心归一化频率 t = np.arange(len(iq)) baseband = iq * np.exp(-2j * np.pi * center_freq * t)

5. Low-pass filter to isolate band

5. 低通滤波以分离目标频段

lpf = signal.firwin(101, bandwidth/2, fs=1.0) filtered = signal.lfilter(lpf, 1.0, baseband)
undefined
lpf = signal.firwin(101, bandwidth/2, fs=1.0) filtered = signal.lfilter(lpf, 1.0, baseband)
undefined

QAM-16 Demodulation with Carrier + Timing Recovery

带载波与时序恢复的QAM-16解调

The key challenge is carrier frequency offset causing constellation rotation (circles instead of points).
Decision-directed carrier recovery + Mueller-Muller timing:
python
undefined
核心挑战是载波频率偏移导致星座图旋转(呈现圆形而非离散点)。
基于判决的载波恢复 + Mueller-Muller时序恢复:
python
undefined

Loop parameters (2nd order PLL)

二阶锁相环参数

carrier_bw = 0.02 # wider BW = faster tracking, more noise damping = 1.0 theta_n = carrier_bw / (damping + 1/(4*damping)) Kp = 2 * damping * theta_n # proportional gain Ki = theta_n ** 2 # integral gain
carrier_phase = 0.0 carrier_freq = 0.0
for each symbol sample: # De-rotate by current phase estimate symbol = raw_sample * np.exp(-1j * carrier_phase)
# Find nearest constellation point (decision)
nearest = min(constellation, key=lambda p: abs(symbol - p))

# Phase error (decision-directed)
error = np.imag(symbol * np.conj(nearest)) / (abs(nearest)**2 + 0.1)

# Update 2nd order loop
carrier_freq += Ki * error
carrier_phase += Kp * error + carrier_freq

**Mueller-Muller timing error detector:**
```python
timing_error = (Re(y[n]-y[n-1]) * Re(d[n-1]) - Re(d[n]-d[n-1]) * Re(y[n-1]))
             + (Im(y[n]-y[n-1]) * Im(d[n-1]) - Im(d[n]-d[n-1]) * Im(y[n-1]))
carrier_bw = 0.02 # 带宽越宽,跟踪速度越快,但噪声也越大 damping = 1.0 theta_n = carrier_bw / (damping + 1/(4*damping)) Kp = 2 * damping * theta_n # 比例增益 Ki = theta_n ** 2 # 积分增益
carrier_phase = 0.0 carrier_freq = 0.0
for each symbol sample: # 根据当前相位估计值去旋转 symbol = raw_sample * np.exp(-1j * carrier_phase)
# 查找最近的星座点(判决)
nearest = min(constellation, key=lambda p: abs(symbol - p))

# 相位误差(基于判决)
error = np.imag(symbol * np.conj(nearest)) / (abs(nearest)**2 + 0.1)

# 更新二阶锁相环
carrier_freq += Ki * error
carrier_phase += Kp * error + carrier_freq

**Mueller-Muller时序误差检测器:**
```python
timing_error = (Re(y[n]-y[n-1]) * Re(d[n-1]) - Re(d[n]-d[n-1]) * Re(y[n-1]))
             + (Im(y[n]-y[n-1]) * Im(d[n-1]) - Im(d[n]-d[n-1]) * Im(y[n-1]))

y = received symbol, d = decision (nearest constellation point)

y = 接收符号, d = 判决结果(最近的星座点)

undefined
undefined

Key Insights for RF CTF Challenges

RF类CTF挑战关键要点

  • Circles in constellation = frequency offset not corrected
  • Spirals = frequency offset + time-varying phase
  • Blobs on grid = correct sync, just noise
  • 4-fold ambiguity: DD carrier recovery can lock with 0°/90°/180°/270° rotation — try all 4
  • Bandwidth vs symbol rate: BW = Rs × (1 + α), where α is roll-off factor (0 to 1)
  • RC vs RRC: "RC pulse shaping" at TX means receiver just samples (no matched filter needed); "RRC" means apply matched RRC filter at RX
  • Cyclostationary peak at Rs confirms symbol rate even without knowing modulation order
  • AGC: normalize signal power to match constellation power:
    scale = sqrt(target_power / measured_power)
  • GNU Radio's QAM-16 default mapping is NOT Gray code — always check the provided constellation map
  • 星座图呈圆形:载波频率偏移未校正
  • 星座图呈螺旋形:载波频率偏移 + 时变相位
  • 星座点呈模糊团状:同步正确,仅存在噪声
  • 4倍模糊性:基于判决的载波恢复可能锁定在0°/90°/180°/270°相位,需尝试所有4种情况
  • 带宽与符号率关系:BW = Rs × (1 + α),其中α为滚降系数(0到1)
  • RC与RRC滤波:发射端使用“RC脉冲成型”时,接收端仅需采样(无需匹配滤波器);使用“RRC”时,接收端需应用匹配的RRC滤波器
  • 符号率处的循环平稳峰值:即使未知调制阶数,也可确认符号率
  • AGC自动增益控制:归一化信号功率以匹配星座图功率:
    scale = sqrt(target_power / measured_power)
  • GNU Radio默认QAM-16映射:不使用格雷码,务必检查题目提供的星座图映射

Common Framing Patterns

常见帧结构模式

  • Idle/sync pattern repeating while link is idle
  • Start delimiter (often a single symbol like 0)
  • Data payload (nibble pairs for QAM-16: high nibble first, low nibble)
  • End delimiter (same as start, e.g., 0)
  • The idle pattern itself may contain the delimiter value — distinguish by context (is it part of the 16-symbol repeating pattern?)
  • 链路空闲时重复的空闲/同步模式
  • 起始分隔符(通常为单个符号如0)
  • 数据载荷(QAM-16为半字节对:高半字节在前,低半字节在后)
  • 结束分隔符(与起始分隔符相同,如0)
  • 空闲模式本身可能包含分隔符,需通过上下文区分(是否属于16符号重复模式的一部分)

pwntools Interaction

pwntools交互脚本

python
from pwn import *

r = remote('host', port)
r.recvuntil(b'prompt: ')
r.sendline(b'answer')
r.interactive()
python
from pwn import *

r = remote('host', port)
r.recvuntil(b'prompt: ')
r.sendline(b'answer')
r.interactive()

Python Jail Quick Reference

Python沙箱速查

Enumerate functions:
python
for c in string.printable:
    result = test(f"{c}()")
    if "error" not in result.lower():
        print(f"Found: {c}()")
Oracle pattern (L, Q, S functions):
python
flag_len = int(test("L()"))
for i in range(flag_len):
    for c in range(32, 127):
        if query(i, c) == 0:
            flag += chr(c)
            break
Bypass character restrictions:
python
undefined
枚举可用函数:
python
for c in string.printable:
    result = test(f"{c}()")
    if "error" not in result.lower():
        print(f"Found: {c}()")
Oracle模式(L、Q、S函数):
python
flag_len = int(test("L()"))
for i in range(flag_len):
    for c in range(32, 127):
        if query(i, c) == 0:
            flag += chr(c)
            break
绕过字符限制:
python
undefined

Walrus operator

海象运算符

(abcdef := "new_allowed_chars")
(abcdef := "new_allowed_chars")

Octal escapes

八进制转义

'\141' = 'a'

**Decorator bypass (ast.Call banned, no quotes, no `=`):**
```python
'\141' = 'a'

**装饰器绕过(禁止ast.Call、无引号、无`=`):**
```python

Decorators = function calls + assignment without ast.Call or =

装饰器 = 函数调用 + 无需ast.Call或
=
的赋值

function.name = strings without quotes

function.name = 无需引号的字符串

See pyjails.md "Decorator-Based Escape" for full technique

完整技巧请参考pyjails.md中的“基于装饰器的逃逸”章节

@import @func.class.dict[name.name].get # name extractor def os(): 0
@import @func.class.dict[name.name].get # 名称提取器 def os(): 0

Result: os = import("os")

结果:os = import("os")

undefined
undefined

Z3 Constraint Solving

Z3约束求解

python
from z3 import *

flag = [BitVec(f'f{i}', 8) for i in range(FLAG_LEN)]
s = Solver()
s.add(flag[0] == ord('f'))  # Known prefix
python
from z3 import *

flag = [BitVec(f'f{i}', 8) for i in range(FLAG_LEN)]
s = Solver()
s.add(flag[0] == ord('f'))  # 已知前缀

Add constraints...

添加其他约束...

if s.check() == sat: print(bytes([s.model()[f].as_long() for f in flag]))
undefined
if s.check() == sat: print(bytes([s.model()[f].as_long() for f in flag]))
undefined

Hash Identification

哈希算法识别

By constants:
  • MD5:
    0x67452301
  • SHA-256:
    0x6a09e667
  • MurmurHash64A:
    0xC6A4A7935BD1E995
通过常量识别:
  • MD5:
    0x67452301
  • SHA-256:
    0x6a09e667
  • MurmurHash64A:
    0xC6A4A7935BD1E995

PyInstaller Extraction

PyInstaller打包文件提取

bash
python pyinstxtractor.py packed.exe
bash
python pyinstxtractor.py packed.exe

Look in packed.exe_extracted/

提取后的文件位于packed.exe_extracted/目录下

undefined
undefined

Marshal Code Analysis

Marshal代码分析

python
import marshal, dis
with open('file.bin', 'rb') as f:
    code = marshal.load(f)
dis.dis(code)
python
import marshal, dis
with open('file.bin', 'rb') as f:
    code = marshal.load(f)
dis.dis(code)

Python Environment RCE

Python环境远程代码执行

bash
PYTHONWARNINGS=ignore::antigravity.Foo::0
BROWSER="/bin/sh -c 'cat /flag' %s"
bash
PYTHONWARNINGS=ignore::antigravity.Foo::0
BROWSER="/bin/sh -c 'cat /flag' %s"

Floating-Point Precision Exploitation

浮点数精度漏洞利用

Pattern (Spare Me Some Change): Trading/economy games where large multipliers amplify tiny floating-point errors.
Key insight: When decimal values (0.01-0.99) are multiplied by large numbers (e.g., 1e15), floating-point representation errors create fractional remainders that can be exploited.
特征(零钱利用类): 交易/经济类游戏中,大乘数会放大微小的浮点数误差。
核心思路: 当十进制数值(0.01-0.99)乘以大数(如1e15)时,浮点数表示误差会产生可被利用的小数余数。

Finding Exploitable Values

寻找可利用的数值

python
mult = 1000000000000000  # 10^15
python
mult = 1000000000000000  # 10^15

Find values where multiplication creates useful fractional errors

寻找乘法后产生有用小数误差的数值

for i in range(1, 100): x = i / 100.0 result = x * mult frac = result - int(result) if frac > 0: print(f'x={x}: {result} (fraction={frac})')
for i in range(1, 100): x = i / 100.0 result = x * mult frac = result - int(result) if frac > 0: print(f'x={x}: {result} (小数部分={frac})')

Common values with positive fractions:

常见的正小数误差数值:

0.07 → 70000000000000.0078125

0.07 → 70000000000000.0078125

0.14 → 140000000000000.015625

0.14 → 140000000000000.015625

0.27 → 270000000000000.03125

0.27 → 270000000000000.03125

0.56 → 560000000000000.0625

0.56 → 560000000000000.0625

undefined
undefined

Exploitation Strategy

利用策略

  1. Identify the constraint: Need
    balance >= price
    AND
    inventory >= fee
  2. Find favorable FP error: Value where
    x * mult
    has positive fraction
  3. Key trick: Sell the INTEGER part of inventory, keeping the fractional "free money"
Example (time-travel trading game):
Initial: balance=5.00, inventory=0.00, flag_price=5.00, fee=0.05
Multiplier: 1e15 (time travel)
  1. 识别约束条件:需要满足
    余额 >= 目标价格
    库存 >= 手续费
  2. 寻找有利的浮点数误差:找到
    x * mult
    产生正小数部分的数值
  3. 关键技巧:仅出售库存的整数部分,保留小数部分作为“免费资产”
示例(时间旅行交易游戏):
初始状态:余额=5.00,库存=0.00,旗帜价格=5.00,手续费=0.05
乘数:1e15(时间旅行放大倍数)

Buy 0.56, travel through time:

购买0.56单位资产,进行时间旅行:

balance = (5.0 - 0.56) * 1e15 = 4439999999999999.5 inventory = 0.56 * 1e15 = 560000000000000.0625
余额 = (5.0 - 0.56) * 1e15 = 4439999999999999.5 库存 = 0.56 * 1e15 = 560000000000000.0625

Sell exactly 560000000000000 (integer part):

出售恰好560000000000000单位(整数部分):

balance = 4439999999999999.5 + 560000000000000 = 5000000000000000.0 (FP rounds!) inventory = 560000000000000.0625 - 560000000000000 = 0.0625 > 0.05 fee ✓
余额 = 4439999999999999.5 + 560000000000000 = 5000000000000000.0(浮点数自动舍入!) 库存 = 560000000000000.0625 - 560000000000000 = 0.0625 > 0.05 手续费 ✓

Now: balance >= flag_price ✓ AND inventory >= fee ✓

最终状态:余额 >= 旗帜价格 ✓ 且 库存 >= 手续费 ✓

undefined
undefined

Why It Works

原理说明

  • Float64 has ~15-16 significant digits precision
  • (5.0 - 0.56) * 1e15
    loses precision → rounds to exact 5e15 when added
  • 0.56 * 1e15
    keeps the 0.0625 fraction as "free inventory"
  • The asymmetric rounding gives you slightly more total value than you started with
  • Float64(双精度浮点数)具有约15-16位有效数字精度
  • (5.0 - 0.56) * 1e15
    会丢失精度,相加后舍入为精确的5e15
  • 0.56 * 1e15
    保留0.0625的小数部分作为“免费库存”
  • 非对称舍入会使总价值略高于初始值

Red Flags in Challenges

挑战中的可疑特征

  • "Time travel amplifies everything" (large multipliers)
  • Trading games with buy/sell + special actions
  • Decimal currency with fees or thresholds
  • "No decimals allowed" after certain operations (forces integer transactions)
  • Starting values that seem impossible to win with normal math
  • “时间旅行会放大一切”(大乘数)
  • 包含买卖+特殊操作的交易类游戏
  • 带手续费或阈值的十进制货币系统
  • 某些操作后“不允许使用小数”(强制整数交易)
  • 初始数值通过常规数学运算无法达成目标

Quick Test Script

快速测试脚本

python
def find_exploit(mult, balance_needed, inventory_needed):
    """Find x where selling int(x*mult) gives balance>=needed with inv>=needed"""
    for i in range(1, 500):
        x = i / 100.0
        if x >= 5.0:  # Can't buy more than balance
            break
        inv_after = x * mult
        bal_after = (5.0 - x) * mult

        # Sell integer part of inventory
        sell = int(inv_after)
        final_bal = bal_after + sell
        final_inv = inv_after - sell

        if final_bal >= balance_needed and final_inv >= inventory_needed:
            print(f'EXPLOIT: buy {x}, sell {sell}')
            print(f'  final_balance={final_bal}, final_inventory={final_inv}')
            return x
    return None
python
def find_exploit(mult, balance_needed, inventory_needed):
    """寻找购买x后,出售int(x*mult)可使余额和库存满足要求的数值"""
    for i in range(1, 500):
        x = i / 100.0
        if x >= 5.0:  # 购买金额不能超过初始余额
            break
        inv_after = x * mult
        bal_after = (5.0 - x) * mult

        # 出售库存的整数部分
        sell = int(inv_after)
        final_bal = bal_after + sell
        final_inv = inv_after - sell

        if final_bal >= balance_needed and final_inv >= inventory_needed:
            print(f'EXPLOIT: 购买{x},出售{sell}')
            print(f'  最终余额={final_bal}, 最终库存={final_inv}')
            return x
    return None

Example usage:

示例用法:

find_exploit(1e15, 5e15, 0.05) # Returns 0.56
undefined
find_exploit(1e15, 5e15, 0.05) # 返回0.56
undefined

Useful One-Liners

实用单行命令

bash
grep -rn "flag{" .
strings file | grep -i flag
python3 -c "print(int('deadbeef', 16))"
bash
grep -rn "flag{" .
strings file | grep -i flag
python3 -c "print(int('deadbeef', 16))"

Keyboard Shift Cipher

键盘移位密码

Pattern (Frenzy): Characters shifted left/right on QWERTY keyboard layout.
Identification: dCode Cipher Identifier suggests "Keyboard Shift Cipher"
Decoding: Use dCode Keyboard Shift Cipher with automatic mode.
特征(混乱输入类): 字符在QWERTY键盘布局上左右移位。
识别方法: dCode密码识别工具提示“Keyboard Shift Cipher”
解码方法: 使用dCode键盘移位密码解码器的自动模式

Pigpen / Masonic Cipher

猪圈密码(共济会密码)

Pattern (Working For Peanuts): Geometric symbols representing letters based on grid positions.
Identification: Angular/geometric symbols, challenge references "Peanuts" comic (Charlie Brown), "dusty looking crypto"
Decoding: Map symbols to Pigpen grid positions, or use online decoder.
特征(花生漫画类): 基于网格位置的几何符号代表字母。
识别方法: 出现几何网格符号,挑战提及“Peanuts”漫画(查理布朗),或描述为“陈旧的密码”
解码方法: 将符号映射到猪圈密码网格,或使用在线解码器

ASCII in Numeric Data Columns

数值列中的ASCII字符

Pattern (Cooked Books): CSV/spreadsheet numeric values (48-126) are ASCII character codes.
python
import csv
with open('data.csv') as f:
    reader = csv.DictReader(f)
    flag = ''.join(chr(int(row['Times Borrowed'])) for row in reader)
print(flag)
CyberChef: "From Decimal" recipe with line feed delimiter.
特征(篡改账目类): CSV/电子表格中的数值(48-126)对应ASCII字符编码。
python
import csv
with open('data.csv') as f:
    reader = csv.DictReader(f)
    flag = ''.join(chr(int(row['Times Borrowed'])) for row in reader)
print(flag)
CyberChef解决方案: 使用“From Decimal”工具,行分隔符为换行符

Python Jail: String Join Bypass

Python沙箱:字符串拼接绕过

Pattern (better_eval):
+
operator blocked for string concatenation.
Bypass with
''.join()
:
python
undefined
特征(better_eval类): 禁止使用
+
运算符进行字符串拼接。
使用
''.join()
绕过:
python
undefined

Blocked: "fl" + "ag.txt"

被禁止: "fl" + "ag.txt"

Allowed: ''.join(["fl","ag.txt"])

允许: ''.join(["fl","ag.txt"])

Full payload:

完整 payload:

open(''.join(['fl','ag.txt'])).read()

**Other bypass techniques:**
- `chr()` + list comprehension: `''.join([chr(102),chr(108),chr(97),chr(103)])`
- Format strings: `f"{'flag'}.txt"` (if f-strings allowed)
- `bytes([102,108,97,103]).decode()` for "flag"
open(''.join(['fl','ag.txt'])).read()

**其他绕过技巧:**
- `chr()` + 列表推导:`''.join([chr(102),chr(108),chr(97),chr(103)])`
- 格式化字符串:`f"{'flag'}.txt"`(若允许f-strings)
- `bytes([102,108,97,103]).decode()`生成"flag"

Backdoor Detection in Source Code

源代码中的后门检测

Pattern (Rear Hatch): Hidden command prefix triggers
system()
call.
Common patterns:
  • strncmp(input, "exec:", 5)
    → runs
    system(input + 5)
  • Hex-encoded comparison strings:
    \x65\x78\x65\x63\x3a
    = "exec:"
  • Hidden conditions in maintenance/admin functions
特征(暗门类): 隐藏的命令前缀触发
system()
调用。
常见模式:
  • strncmp(input, "exec:", 5)
    → 执行
    system(input + 5)
  • 十六进制编码的比较字符串:
    \x65\x78\x65\x63\x3a
    = "exec:"
  • 维护/管理功能中的隐藏条件

Cipher Identification Workflow

密码识别流程

  1. ROT13 - Challenge mentions "ROT", text looks like garbled English
  2. Base64 -
    A-Za-z0-9+/=
    , title hints "64"
  3. Base32 -
    A-Z2-7=
    uppercase only
  4. Atbash - Title hints (Abash/Atbash), preserves spaces, 1:1 substitution
  5. Pigpen - Geometric symbols on grid
  6. Keyboard Shift - Text looks like adjacent keys pressed
  7. Substitution - Frequency analysis applicable
  1. ROT13:挑战提及“ROT”,文本类似乱码的英文
  2. Base64:字符集为
    A-Za-z0-9+/=
    ,标题暗示“64”
  3. Base32:字符集为
    A-Z2-7=
    且仅大写
  4. Atbash:标题暗示(Abash/Atbash),保留空格,一对一替换
  5. 猪圈密码:网格状几何符号
  6. 键盘移位:文本类似按错相邻按键的结果
  7. 替换密码:可应用频率分析
自动识别工具: dCode密码识别器