什么是REGadgets

REGadgets,顾名思义,就是一个Reverse中常用的,提供给使用者代码片段的库,可以加快逆向速度,甚至直接爆破出结果。

REGadgets 如何获取

REGadgets目前还在开发中,也就是只在小范围测试中,开发者将用它参加每一场XCTF分站赛,所有的WP都是用它来写的,以保证REGadgets库与时俱进。

REGadgets 项目结构

截至到 2024/09/30 REGadgets项目目录如下。

C:.
│   .gitignore
│   README.md
│   __init__.py
│
├───bases
│       base128.py
│       base2048.pyd
│       base2048.pyi
│       base45.py
│       base58.py
│       base62.py
│       base65536.py
│       base91.py
│       bases.py
│       py3base92.py
│       __init__.py
│
├───bits
│       bits.py
│       cstyle.py
│       __init__.py
│
├───bruteforce
│       bruteforcer.py
│       __init__.py
│
├───crypto
│       aes.py
│       blowfish.py
│       bxors.py
│       rc4.py
│       tea.py
│       xtea.py
│       xxtea.py
│       __init__.py
│
├───trans
│       sbox.py
│       __init__.py
│
└───utils
        z3util.py
        __init__.py

REGadgets库相关介绍及使用方法

regadgets.bases

这个库中,提供了 base 相关的编码解码,而且,regadgets提供了换表的快捷方案。

例题 BaseCTF2024 BasePlus

from regadgets import *
enc = b'lvfzBiZiOw7<lhF8dDOfEbmI]i@bdcZfEc^z>aD!'
k = 0xe
dec = decode_b64(bxor(enc, [k for _ in range(len(enc))]).decode(),
                  '/128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdEC')

print(dec)
# b'BaseCTF{BA5e_DEcoD1N6_sEcr3t}\x00'

在本例中,通过regadgets.bases.decode_b64我们对enc异或后的东西(base64编码后的东西)进行了解码,表是第二个参数。

例题 CDDC2024 Quals Emoji32

regadget的bases,支持换emoji表,因为Python的str对于Unicode非常友好。

from regadgets import *
emoji_table = ['😀','😥','😠','😱','😴','🤢','😇','😈','👋','✊','👌','✌','🤲','🙌','👏','🤝','🐶','🐱','🐭','🐹','🐰','🦊','🐻','🐼','🍎','🍌','🍓','🍑','🍕','🍔','🍟','🍦']
emoji_table = "".join(emoji_table)
encoded = "🤢😥😇😴🐭🦊😥✊✌️🍕🐰😴🍎🐭👌🐰🤢😴"
s = encoded.replace('\ufe0f', '') # Remove Wrong Char
while True:
    try:
        print(decode_b32(s, emoji_table))
        # (LIT)_(LIT)
        break
    except:
        s += '=' # Fix Padding
        continue

regadgets.bits

这个子库中,提供了位与数的相关操作。

# 相关提供的函数有这些
from .bits import rol16, rol32, rol64, rol8, ror16, ror32, ror64, ror8, byte2dword, dword2byte, byte2qword, qword2byte, pack_dword, unpack_dword, b2l, l2b
from .cstyle import cstyle_arr32

rol & ror

这些函数用于在Python下执行相应位数的循环左移和循环右移。

byte2word byte2dword byte2qword

用于将Python的bytes 2个/4个/8个 打包成为 List[int],可选是否进行Padding。其中int是word或dword或qword,小端序,方便后续进行TEA族加密。

word2byte dword2byte qword2byte

用于将List[int] 解包为Python bytes,小端序。用于将外部的数据(程序中提取出来的)快速进行处理。

pack_dword

用于将[1, 2, 3, 4, 5, 6] 这样的List[int],两两打包为形如 [(1, 2), (3, 4), (5, 6)] ,方便进行TEA族加密。

unpack_dword

用于将 [(1, 2), (3, 4), (5, 6)] 解包为 [1, 2, 3, 4, 5, 6] 这样的List[int]

l2b b2l

从Crypto.Util.number里面复制出来的long_to_bytes和bytes_to_long,用于大端序的互相转换。

regadgets.bruteforce

本子库用于解决逆向工程中的一些基础爆破问题。

regadgets.bruteforce.rg_brute_forcer

基础的Reverse下的爆破函数,通过检测解密后文本是否含有flag(可以进行修改),且解密后均为明文,来进行反向爆破,并还原出解密链。
本函数可以进行定制化扩展,由于特殊的模块化设计,可以自己手写一些常见算法,并在这些算法中爆破。
未来的话,这个函数可能会写成Cython实现的,用来加速爆破进程。

使用例

from regadgets import *

raw = list(b'flag{124214782134798217}')

for i in range(len(raw)):
    raw[i] ^= 114
    raw[i] += 514
    raw[i] ^= 810
    raw[i] &= 0xff

rg_brute_forcer(raw, 3)
'''
尝试深度 1 的解密...
[失败] 没有在深度 1 找到解密方案,用时 0.003998994827270508秒
尝试深度 2 的解密...
[失败] 没有在深度 2 找到解密方案,用时 2.940094470977783秒
尝试深度 3 的解密...
找到正确解密链: [('xor_decrypt', 20), ('mod_add_decrypt', 2), ('xor_decrypt', 76)]
解密结果: b'flag{124214782134798217}'
[成功] 在深度 3 找到解密方案,用时 59.33841252326965秒
'''

regadgets.crypto

regadgets.crypto.aes

标准的AES实现,根据比赛可以进行手动魔改。

regadgets.crypto.blowfish

标准的blowfish实现,根据比赛可以进行手动魔改。

regadgets.crypto.rc4

提供rc4_init, rc4_crypt, rc4_keystream三个函数,在init的时候返回S盒,crypt的时候提供s盒和data用于加密,keystream函数可以只返回S盒生成的key长度,可以手动指定box_size,因为在 BaseCTF2024 出了一个 S盒大小128的题目。

regadgets.crypto.bxors

提供了相关的XOR实现,比如 x_0 ^ x_1, x_1 ^ x_2, x_2 ^ x_3, ..... , x_(n-1) ^ x_n, x_n (我们称之为向右异或,bxorr)的加密解密。
除此之外,还提供了bxor(用于将两个等长的bytes | list进行互相异或)。
最常用的是,bxor_cycle,用于将第一个参数进行循环异或第二个参数(bytes | list)
一个常用的例子

# 对于一个数组循环异或 b'my_key'
enc = [...]
raw = bxor_cycle(enc, b'my_key')
# 对于一个数组进行异或 0xEE
raw = bxor_cycle(enc, b'\xee')
# 对于一个数组进行异或循环变量 i
raw = bxor_cycle(enc, range(len(enc)))

regadgets.crypto.tea / xtea / xxtea

用 python ctypes 实现的 TEA族加密。可以自行指定 delta / rounds, 对于xxtea可以指定很多参数,甚至是shift函数,具体请见其他题解。

regadgets.trans

用于S盒之类的变换

regadgets.trans.sbox

提供了 generate_sboxsbox_transform 两个函数。
如例题

from regadgets import *
from hashlib import md5
str1 = [0x28, 0x5F, 0x40, 0x34, 0x36, 0x32, 0x30, 0x21, 0x30, 0x38, 0x21, 0x36, 0x5F, 0x30, 0x2A, 0x30, 0x34, 0x34, 0x32, 0x21, 0x40, 0x31, 0x38, 0x36, 0x25, 0x25, 0x30, 0x40, 0x33, 0x3D,
        0x36, 0x36, 0x21, 0x21, 0x39, 0x37, 0x34, 0x2A, 0x33, 0x32, 0x33, 0x34, 0x3D, 0x26, 0x30, 0x5E, 0x33, 0x26, 0x31, 0x40, 0x3D, 0x26, 0x30, 0x39, 0x30, 0x38, 0x21, 0x36, 0x5F, 0x30, 0x2A, 0x26]
str2 = [0x35, 0x35, 0x35, 0x36, 0x35, 0x36, 0x35, 0x33, 0x32, 0x35, 0x35, 0x35, 0x35, 0x32, 0x32, 0x32, 0x35, 0x35, 0x36, 0x35, 0x35, 0x36, 0x35, 0x35, 0x35, 0x35, 0x32, 0x34, 0x33, 0x34,
        0x36, 0x36, 0x33, 0x33, 0x34, 0x36, 0x35, 0x33, 0x36, 0x36, 0x33, 0x35, 0x34, 0x34, 0x34, 0x32, 0x36, 0x35, 0x36, 0x35, 0x35, 0x35, 0x35, 0x35, 0x32, 0x35, 0x35, 0x35, 0x35, 0x32, 0x32, 0x32]
xxx = [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6F, 0x70, 0x5B, 0x5D, 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F,
       0x50, 0x7B, 0x7D, 0x61, 0x73, 0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B, 0x27, 0x41, 0x53, 0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A, 0x22, 0x5A, 0x58, 0x43, 0x56, 0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 0x7A, 0x78, 0x63, 0x76, 0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F]
r = []
for i in range(62):
    a = xxx.index(str1[i])
    b = xxx.index(str2[i])
    r.append(b * 23 + a)
# private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)
print(bytes(r))

# 手动转换一下 查表
r = b'?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z'

###### 从这里开始是S盒变换
data_from = b'abcdefghijklmnopqrstuvwxyz12345'
data_to = b'pqhrsidtujvwkebxylz1mf23n45ogca'
_, ibox = generate_sbox(data_from, data_to)
r = sbox_transform(r, ibox)

print(bytes(r))
print(f"flag{{{md5(bytes(r)).hexdigest()}}}")
# flag{63b148e750fed3a33419168ac58083f5}

regadgets.utils

regadgets.utils.z3util

目前只有z3_get_models,用于获取Z3的Solver的所有解。

标签: none

添加新评论