
1.easyApp
是一个apk文件,拖入模拟器中运行需要输入flag进行判断,然后拖入jadx中静态分析MainActivity中的代码:

可以看到首先读取了dex.zip文件(在assets里面,导出后再用jadx加载即可),然后判断输入的flag是否长度是42,再截取前26位,进行base64编码,编码后需要等于:MHhHYW1le0RvX3kwdV9sMHYzX2FuZHIwMWQ=,把这个base64解码即可得到flag的前面部分:

然后再读取输入字符串从第26个字符到末尾转换为字节数组,以hexstring的形式传入刚才动态加载的dex.zip中的Secret.Check方法中,接下来把dex.zip直接拖入jadx,查看Secret.Check方法:
package com.example.easyapp;import java.math.BigInteger;/* loaded from: dex.bin */public class Secret {public static boolean check(String str) {BigInteger bigInteger = new BigInteger(str.substring(0, 16), 16);BigInteger bigInteger2 = new BigInteger(str.substring(8, 24), 16);BigInteger bigInteger3 = new BigInteger(str.substring(16, 32), 16);return bigInteger2.add(bigInteger.multiply(new BigInteger(”3”))).subtract(new BigInteger(”27454419028250566601”)).equals(BigInteger.ZERO) &&bigInteger3.multiply(new BigInteger(”2”)).subtract(bigInteger2.multiply(new BigInteger(”5”))).add(new BigInteger(”20616666104378640363”)).equals(BigInteger.ZERO) &&bigInteger.add(bigInteger3.multiply(new BigInteger(”4”))).subtract(new BigInteger(”1dce62be9f0fa2f6c”, 16)).equals(BigInteger.ZERO);}}
前面截取了26到42的字符串,一共16个字符串,转换成hexstring正好32个字节,这里第一个16字节数为0-16字节,第二个16字节数为8-24字节,第三个16字节数为16-32字节,然后需要满足下面的方程:
(big2+(big1*3))-27454419028250566601 = 0big3*2 - big2*5 + 20616666104378640363 = 0big1 + big3*4 - 0x1dce62be9f0fa2f6c = 0
使用python的sympy库求解并输出,脚本如下:
import sympy as spimport base64big1, big2, big3 = sp.symbols('big1 big2 big3')eq1 = sp.Eq(big2 + 3*big1, 27454419028250566601)eq2 = sp.Eq(big3 * 2 - big2 * 5, -20616666104378640363)eq3 = sp.Eq(big1 + big3*4, 0x1dce62be9f0fa2f6c)solution = sp.solve((eq1, eq2, eq3), (big1, big2, big3))print(solution[big1])print(solution[big2])print(solution[big3])big1 = solution[big1]big2 = solution[big2]big3 = solution[big3]str1_hex = hex(big1)str2_hex = hex(big2)str3_hex = hex(big3)print(str1_hex)print(str2_hex)print(str3_hex)str1 = base64.b16decode(str1_hex[2:].encode(), casefold=True)print(str1)str2 = base64.b16decode(str2_hex[2:].encode(), casefold=True)print(str2)str3 = base64.b16decode(str3_hex[2:].encode(), casefold=True)print(str3)
输出:

跟前面的flag进行拼接即可(注意这里需要去掉交叉字符串):0xGame{Do_y0u_l0v3_andr01d_4nd_dex_loader}
2.rand_py
这是一个pyinstaller打包的exe程序,首先使用pyinstxtrator.py提取出pyc文件:
python pyinstxtractor.py D:\桌面\rand_py\rand_py.exe然后找到提取出来的pyc文件:rand_py.pyc,再使用pycdc.exe转换为python代码:
pycdc.exe rand_py.pyc > rand_py.py成功提取出python代码:
# Source Generated with Decompyle++# File: rand_py.pyc (Python 3.10)import randomenc_flag = [5554865,8824328,9324119,2254831,5757818,2986985,1878515,9324119,6857238,5690625,9073978,3189766,4267438,9923116,5042226,4263793,7510142,3443924,4569572,5690625,9923116,4263793,7510142,3443924,9923116,5554865,2464675,6002055,1327718,4569572,7510142,5073474]user_input = input('Check your flag:')for i in range(len(user_input)):random.seed(ord(user_input[i]))num = random.randint(1000000, 9999999)if num != enc_flag[i]:print('WRONG!!!!!!')exit(1)print('YEAH,you are right!!!')
这里通过random.seed设置伪随机数种子,然后enc_flag列表里面的每个数字都是根据flag对应下标位置字符串生成的伪随机数,直接写python脚本爆破即可:
import randomenc_flag = [5554865,8824328,9324119,2254831,5757818,2986985,1878515,9324119,6857238,5690625,9073978,3189766,4267438,9923116,5042226,4263793,7510142,3443924,4569572,5690625,9923116,4263793,7510142,3443924,9923116,5554865,2464675,6002055,1327718,4569572,7510142,5073474]flag = ''for i in range(len(enc_flag)):for seed in range(0x20, 0x7f):random.seed(seed)num = random.randint(1000000, 9999999)if num == enc_flag[i]:flag += chr(seed)breakprint(flag)
输出得到flag:
PDSCTF{Simple_random_and_Python}3.BabyJar
题目是一个jar包文件,使用jd-gui进行反编译查看java源码:

先看BabyJar.class,首先实例化了一个Encrypt类e,然后定义了一个enc字符串,应该是base编码,然后获取到用户输入的flag,再对输入的flag调用e.encrypt方法得到返回值,返回值再跟enc字符串做比较。
package com.BabyJar.demo;import java.util.Scanner;public class BabyJar {public static void main(String[] args) {Encrypt e = new Encrypt();Scanner input = new Scanner(System.in);String enc = ”QsY1V5cX9jJyF2JSAgdikwfCEneTAgICUpNnd1Iyk8IXUkJ3QhcyZ8J3YpY=”;System.out.println(”Please input your flag:”);String flag = input.nextLine();String Encrypted_flag = e.encrypt(flag);if (Encrypted_flag.equals(enc)) {System.out.println(”Congratulations!!”);} else {System.out.println(”Try Again!!”);}}}
然后看Encrypt类,先把输入的字符串转换为字节数组,然后每个字节先跟key异或得到temp,然后temp的高4位和低4位互相交换,得到加密后的字节数组,再进行base64编码得到刚才的enc字符串。
package com.BabyJar.demo;import java.util.Base64;public class Encrypt {int key = 20;public String encrypt(String text) {byte[] originalBytes = text.getBytes();byte[] encryptedBytes = new byte[originalBytes.length];for (int i = 0; i < originalBytes.length; i++) {byte c = originalBytes[i];byte temp = (byte)(c ^ this.key);encryptedBytes[i] = (byte)((temp & 0xF0) >> 4 | (temp & 0xF) << 4);}return Base64.getEncoder().encodeToString(encryptedBytes);}}
只需要把enc字符串使用base64解码,然后再对每个字节重新交换高四位和低四位,然后跟20异或,即可解密,python解密脚本如下:
import base64enc = ”QsY1V5cX9jJyF2JSAgdikwfCEneTAgICUpNnd1Iyk8IXUkJ3QhcyZ8J3YpY=”enc_bytes = base64.b64decode(enc)enc_byte_array = bytearray(enc_bytes)key = 20flag = b''for i in range(len(enc_byte_array)):temp = ((enc_byte_array[i] & 0xf0) >> 4) | ((enc_byte_array[i] & 0x0f) << 4)temp = temp ^ keyflag += bytes([temp])print(flag)
运行后成功得到输出:
b'0xGame{73e214d2-d85c-4441-bc17-8e10c0e7b8c2}'4.ez_pyyy
题目给的是一个pyc文件,直接pycdc转换为py源码:
pycdc.exe ____python_______.pyc > result.py得到的python源码为:
# Source Generated with Decompyle++# File: ____python_______.pyc (Python 3.8)cipher = [48,55,57,50,53,55,53,50,52,50,48,55,101,52,53,50,52,50,52,50,48,55,53,55,55,55,50,54,53,55,54,55,55,55,53,54,98,55,97,54,50,53,56,52,50,52,99,54,50,50,52,50,50,54]def str_to_hex_bytes(s = None):return s.encode('utf-8')def enc(data = None, key = None):return None((lambda .0 = None: [ b ^ key for b in .0 ])(data))def en3(b = None):return b << 4 & 240 | b >> 4 & 15def en33(data = None, n = None):'''整体 bitstream 循环左移 n 位'''bit_len = len(data) * 8n = n % bit_lenval = int.from_bytes(data, 'big')val = (val << n | val >> bit_len - n) & (1 << bit_len) - 1return val.to_bytes(len(data), 'big')if __name__ == '__main__':flag = ''data = str_to_hex_bytes(flag)data = enc(data, 17)data = bytes((lambda .0: [ en3(b) for b in .0 ])(data))data = data[::-1]data = en33(data, 32)if data.hex() == cipher:print('Correct! ')else:print('Wrong!!!!!!!!')
这段代码先把flag以utf8编码成字节数组,然后再调用enc函数进行第一次加密,针对每个字节跟key进行异或,得到的结果再每个字节调用en3函数,对每个字节低4位和高4位互换位置,然后再倒序排序字节数组,再调用en33函数最后加密得到cipher,参考题目的python源码写解密脚本:
import base64cipher = [48,55,57,50,53,55,53,50,52,50,48,55,101,52,53,50,52,50,52,50,48,55,53,55,55,55,50,54,53,55,54,55,55,55,53,54,98,55,97,54,50,53,56,52,50,52,99,54,50,50,52,50,50,54]def en3(b = None):#print(str(b))#print(b)return b << 4 & 240 | b >> 4 & 15def en33(data = None, n = None):'''整体 bitstream 循环左移 n 位'''print(hex(data))bit_len = len(cipher) * 8n = n % bit_lenval = dataval = (val << n | val >> bit_len - n) & ((1 << bit_len) - 1)print(hex(val))return val.to_bytes(len(cipher), 'big')def enc(data = None, key = None):return[b ^ key for b in data]data = bytes(cipher)print(data.decode('utf-8'))data = data.decode('utf-8')str1 = data[:(len(data)) - 8]str2 = data[(len(data)) - 8:]print(str1)print(str2)new_data_str = str2 + str1print(new_data_str)new_data = bytearray.fromhex(new_data_str)print(new_data)new_data = new_data[::-1]temp = [en3(b) for b in new_data]print(temp)temp = enc(temp, 17)print(bytes(temp))
运行后解密成功:
输出:079257524207e45242420757772657677756b7a6258424c6224226079257524207e45242420757772657677756b7a6258424c6224226c6224226079257524207e45242420757772657677756b7a6258424bytearray(b'\xc6”B&\x07\x92WRB\x07\xe4RBB\x07Ww&WgwV\xb7\xa6%\x84$')[66, 72, 82, 106, 123, 101, 119, 118, 117, 98, 119, 117, 112, 36, 36, 37, 78, 112, 36, 37, 117, 41, 112, 98, 36, 34, 108]b'SYC{jtfgdsfda554_a54d8as53}'
5.Minesweeper
题目文件给的是html和js文件,打开html后发现是一个扫雷游戏,应该是需要完成游戏获取flag,这里先查看js代码,发现被混淆了,找个在线网站去混淆(https://webfem.com/tools/js-decode/index.html):

然后在js文件里面搜flag的关键词,找到了flag的生成代码:

这里的打印flag是我加上去的,找个地方主动调用这个函数然后就可以在控制台打印出flag:

夜雨聆风