题目复现1
题目复现
本周做的题
BUU-简单注册器
用jadx打开apk文件
找到MainActivity分析加密方式

| 1 | 
 | 
| 1 | str=['d','d','2','9','4','0','c','0','4','4','6','2','b','4','d','d','7','c','4','5','0','5','2','8','8','3','5','c','c','a','1','5'] | 
BUU-findit
用jadx打开apk文件
找到MainActivity分析加密方式

需要注意的是,两个if条件,第一个if是说如果b[i2]是AZ或az的字符,y[i2] = b[i2]+16,第二个if条件是说,如果y[i2]符合条件,y[i2]=chr(y[i2]-26),两个if条件后得到的才是flag,else也是flag 。由于str中没有AZ的字符,第一个if条件AZ的可以不写
| 1 | str=[ 0x70, 0x76, 0x6b, 0x71, 0x7b, 0x6d, 0x31, 0x36, 0x34, 0x36, 0x37, 0x35, | 
BUU-[GWCTF 2019]pyre
得到的是pyc文件,用在线反编译网站就可以https://www.lddgo.net/string/pyc-compile-decompile
因为:如果 pyc 文件版本 > Python 3.8 ,则只能选择 pycdc 反编译引擎。 pycdc 引擎在某些情况下会反编译失败。
如果 pyc 文件版本 <= Python 3.8 ,推荐使用 uncompyle6 反编译引擎。
 
简单的加密方式,逆回去就好
num = ((input1[i] + i) % 128 + 128) % 128 可以化为 num ≡ input1[i] + i (mod 128)
因为两次 % 128 的目的是确保结果在 [0, 127] 范围内。
input1[i] ≡ num - i (mod 128)
input1[i] = (num - i) % 128
这里 % 128 确保结果在 [0, 127] 范围内,与字符的 ASCII 码兼容。
- num≡input1[i]+i(mod128) - 这意味着: - num=(input1[i]+i)+128k - 其中 k 是某个整数。这个等式表明 - num和- input1[i] + i之间的差值是 128 的倍数。
- 变形等式 - 为了解出 - input1[i],我们需要将等式变形:- input1[i]≡num−i(mod128) - 这意味着: - input1[i]=(num−i)+128m - 其中 m 是某个整数。我们希望 - input1[i]在 [0, 127] 的范围内,因此使用模运算来实现这一点。
- 模运算 - 通过取模 128,我们可以确保结果在 [0, 127] 的范围内: - input1[i]=(num−i)%128 - 这里的 - %运算符表示取余数,确保结果落在 0 到 127 之间。这与字符的 ASCII 码范围兼容,因为标准 ASCII 码的范围就是 0 到 127。
| 1 | code = [ | 
BUU-[FlareOn4]login
得到的是html,打开后查看网页源代码

进行分析:这里有一个三元运算符:(c <= “Z” ? 90 : 122) >= (c = c.charCodeAt(0) +13) ? c : c -26。这里的c是字符,首先判断c是否是小于等于Z的,也就是大写字母的话,上限是90(Z的ASCII码),否则是小写字母,上限是122(z的ASCII码)。然后比较这个上限是否大于等于原字符的ASCII码加上13后的值。如果满足,就直接用原字符加13;否则,减去26(字母表长度)。例如,第一个字符P:大写字母,ASCII码80。80-13=67,也就是C。再例如字符是N(ASCII码78),大写字母。加13后是91,超过了90,所以需要减去26,得到65,也就是A。这个是凯撒密码,key为13

BUU-[WUSTCTF2020]level1
用64位IDA打开

文件里的数据为加密后的,应该将加密方式逆过来得到加密前的数据是flag
| 1 | str=[198,232,816,200,1536,300,6144,984,51200,570,92160,1200, | 
| 1 | str = [0, 198, 232, 816, 200, 1536, 300, 6144, 984, 51200, 570, 92160, 1200, 565248, | 
因为读取了20个字节,但是文本文件里只有19个,for循环是从1到19,没有使用第零位的数据,第零位的数据可以是任意值,这里就习惯写成0,这样的话,解密脚本就不用i-1了
BUU-[WUSTCTF2020]level2
拿到后先查壳,发现了upx壳,脱完壳后用IDA32位打开,这道题开门见山呐

BUU-rsa
这是一道RSA的题
公钥n = p * q,其中p和q是两个大素数
e是随机选择的数,作为公钥
d是跟e有关的一个数,满足条件式:ed=1(mod phi(n))
phi(n)是欧拉函数,phi(n)=(p-1)(q-1)
得到两个文件,flag.enc打不开,pub.key打开查看后发现是加密后的公钥,根据题目可推断出
pub.key是公钥,flag.enc是rsa加密后的文件,因此我们只要通过公钥文件解析出n,e,p,q,d,再利用脚本解密rsa加密文件。

使用在线网站进行公钥解析:http://tool.chacuo.net/cryptrsakeyparse

可以获取到:
e = 65537
n=86934482296048119190666062003494800588905656017203025617216654058378322103517(模数转换为十进制)
然后使用RSA因数分解工具yafu将n进行分解,输入命令
yafu-x64 factor(86934482296048119190666062003494800588905656017203025617216654058378322103517)
yafu工具的安装与使用教程:https://blog.csdn.net/dchua123/article/details/105444230

p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463
| 1 | import gmpy2 | 
flag{decrypt_256}
BUU-CrackRTF
 
查看加密函数发现是哈希函数,使用在线网站解密 https://www.somd5.com/
 
 
蓝色光标部分分别是第一个密码和第二个密码,直接运行输入这两个密码,然后就会自动生成一个文件,里面放着flag

Flag{N0_M0re_Free_Bugs}
BUU-[MRCTF2020]Transform
 
需要注意的是在逆向解密时,要注意先异或赋值给dword_40F040,再进行下一步时,Str[dword_40F040]里的dword_40F040还是原来的值
| 1 | data = [0x67, 0x79, 0x7B, 0x7F, 0x75, 0x2B, 0x3C, 0x52, 0x53, 0x79, | 
MRCTF{Tr4nsp0sltiON_Clph3r_1s_3z}
NSS-[HNCTF 2022 WEEK3]Double
| 1 | pipe(pipedes); | 
对这段代码的解释如下:
这段代码是一个使用管道进行父子进程通信的程序,主要用于验证用户输入的字符串(flag)是否正确。
pipe(pipedes) 创建了一个管道,pipedes[0] 是读端,pipedes[1] 是写端。
fork()函数用于创建一个新的进程,新创建的进程被称为子进程,而调用fork()的进程被称为父进程
fork()返回新创建的子进程的PID(进程标识符),这是一个正整数。因此,如果fork()的返回值大于0,那么当前进程是父进程。fork()返回0。因此,如果fork()的返回值等于0,那么当前进程是子进程。
父进程执行 if 分支,子进程执行 else 分支。
父进程逻辑:
- 输出提示信息 i'm parent。
- 关闭管道的写端 pipedes[1](因为父进程只需读取数据)。
- 循环 30 次(i从 0 到 29),每次从管道读一个字符到buf。
- 计算 v9 = i ^ buf(将当前循环索引i与读取的字符buf异或)。
- 检查预定义数组 arr[v9]是否等于另一个数组enc[i]。若不等,输出错误并退出。
- 若所有字符都通过验证,输出 you are right!。
子进程逻辑:
- 输出提示信息 i am child。
- 关闭管道的读端 pipedes[0](因为子进程只需写入数据)。
- 通过 scanf获取用户输入的字符串s。
- 将字符串 s的每个字符逐个写入管道的写端pipedes[1]。
验证逻辑:
- 用户输入的每个字符 s[j]会被父进程按顺序读取。
- 父进程通过异或操作 i ^ s[i]生成索引v9,检查arr[v9]是否等于enc[i]。
- 最终,只有满足所有 arr[i ^ s[i]] == enc[i]的输入才会被判定为正确。
逆向关键:
简单来看就是i与s[i]异或得到新的下标,arr[v9]=enc[i];只要找到arr[]和enc[],并找到他们都相等时的下标再进行异或,就可以得到输入的flag。
先找到enc[]和arr[]

| 1 | enc = [0x1FAC, 0x4F91, 0x3796, 0xB584, 0xE18, 0xC1E2, 0x7370, 0x1FAC, 0xA880, 0xB8F1, 0x233B, 0x7370, 0x27B8, | 
NSSCTF{I_Have_D0ub1e_Pr0cess!}



