这边只记录一些有意思的题,主要是记录复现题

unimod

1
2
3
4
5
6
7
8
9
10
11
import random

flag = open('flag.txt', 'r').read()
ct = ''
k = random.randrange(0,0xFFFD)
for c in flag:
ct += chr((ord(c) + k) % 0xFFFD)

open('out', 'w').write(ct)
# out文件
# 饇饍饂饈饜餕饆餗餙饅餒餗饂餗餒饃饄餓饆饂餘餓饅餖饇餚餘餒餔餕餕饆餙餕饇餒餒饞飫

我猜测是unnicode编码,找个网站转一下

flag第一个字符为”f”,算出k,即可。

1
2
3
4
5
6
7
ct = [0x9947,0x994d,0x9942,0x9948,0x995c,0x9915,0x9946,0x9917,0x9919,0x9945,0x9912,0x9917,0x9942,0x9917,0x9912,0x9943,0x9944,0x9913,0x9946,0x9942,0x9918,0x9913,0x9945,0x9916,0x9947,0x991a,0x9918,0x9912,0x9914,0x9915,0x9915,0x9946,0x9919,0x9915,0x9947,0x9912,0x9912,0x995e,0x98eb]
k = ct[0]-ord("f")
flag = ""
for i in ct:
flag += chr(i-k)
print(flag)
# flag{4e68d16a61bc2ea72d5f971344e84f11}

BabyRSAQuiz

这一题还是很有趣的,一共三个挑战,对应三个不同的rsa题型

第一个是最基础的题型

第二个是低加密指数攻击,对n开三次方即可

第三个,给出了p和q的大致关系,需要爆破一下,耽搁了挺久的

解密脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import gmpy2
from Crypto.Util import number

def challenge3():
n = 116977074228599426291587221908436017777467258431559447697924941520570885658886480019669892575150152280335170175559423087532259109936665895429503951416006622462618553942370439526762985810142970058271286185509592222692211236949490404435899918812532981985758364660301644565952909138955690838261582018908922468119
s = gmpy2.iroot(n,2)[0]

for i in range(10000):
a = 2*i
m = (s-a+1)*(s+a+1)
re = n - m
if m == n:
print("done")
print((s-2*i+1),(s+(2*i+1)))
break
elif re >-200000 and re < 200000:
print(-a+1,a+1)
print(re)
p = s - 308
q = s + 310
e = 65537
c = 4229254487221676800780096678163450260842675507793572972787457878570797072562036544554415758463878561718810656685314768162698600790351018583535201368597827407410173247765734037714029965319789400903852994184676867936771131535515140905245959496886324335917176883986099816968694152979333841398712040545041994202
d = gmpy2.invert(e,(q-1)*(p-1))
m = pow(c,d,n)
print(m)
print(number.long_to_bytes(m))
challenge3()

s是n开方之后的结果,通过爆破p和q,获取p*q的值与n的差值,可以确定p = (s-2i),q = (s+2i) ,这样我我们就能确定p和q相对于s的偏移,即可确定p和q的值,进而求解

XORROX

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
r/bin/env python3

import random

with open("flag.txt", "rb") as filp:
flag = filp.read().strip()

key = [random.randint(1, 256) for _ in range(len(flag))]

xorrox = []
enc = []
for i, v in enumerate(key):
k = 1
for j in range(i, 0, -1):
k ^= key[j]
xorrox.append(k)
enc.append(flag[i] ^ v)

with open("output.txt", "w") as filp:
filp.write(f"{xorrox=}\n")
filp.write(f"{enc=}\n")


# output文件
#xorrox=[1, 209, 108, 239, 4, 55, 34, 174, 79, 117, 8, 222, 123, 99, 184, 202, 95, 255, 175, 138, 150, 28, 183, 6, 168, 43, 205, 105, 92, 250, 28, 80, 31, 201, 46, 20, 50, 56]
#enc=[26, 188, 220, 228, 144, 1, 36, 185, 214, 11, 25, 178, 145, 47, 237, 70, 244, 149, 98, 20, 46, 187, 207, 136, 154, 231, 131, 193, 84, 148, 212, 126, 126, 226, 211, 10, 20, 119]

这题还是需要去找规律的,不理解意思,硬逆是行不通的

题目首先是随机产生了flag长度的key,然后对每个key[i]与key[0]……key[i-1]元素进行异或,并且将最后异或完成的key[i]值与flag进行异或,所以我们需要求得key列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
xorrox=[1, 209, 108, 239, 4, 55, 34, 174, 79, 117, 8, 222, 123, 99, 184, 202, 95, 255, 175, 138, 150, 28, 183, 6, 168, 43, 205, 105, 92, 250, 28, 80, 31, 201, 46, 20, 50, 56]
enc=[26, 188, 220, 228, 144, 1, 36, 185, 214, 11, 25, 178, 145, 47, 237, 70, 244, 149, 98, 20, 46, 187, 207, 136, 154, 231, 131, 193, 84, 148, 212, 126, 126, 226, 211, 10, 20, 119]
# for i, v in enumerate(key):
key = []

# key = [124, 208, 189, 131, 235]
# for i, v in enumerate(key):
flag = [102, 108, 97, 103, 123]
for i in range(0,len(xorrox)-1):
key.append(xorrox[i]^xorrox[i+1])

flag = ""
key = [124,208, 189, 131, 235, 51, 21, 140, 225, 58, 125, 214, 165, 24, 219, 114, 149, 160, 80, 37, 28, 138, 171, 177, 174, 131, 230, 164, 53, 166, 230, 76, 79, 214, 231, 58, 38, 10]
for i in range(len(key)):
flag += chr(key[i]^enc[i])

print(key)
print(flag)

eayrev

用ida打开,输入用户名之后,输入密码,进入sub_12B2函数

主要加密算法在这边,因为s是char*类型的指针,指向了input传参,v6是input的长度

加密结束之后与dword_4020数组进行比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <stdlib.h>

unsigned char ida_chars[] =
{
0x66, 0x00, 0x00, 0x00, 0xD9, 0x00, 0x00, 0x00, 0x88, 0x01,
0x00, 0x00, 0x41, 0x03, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00,
0xF9, 0x06, 0x00, 0x00, 0xA4, 0x18, 0x00, 0x00, 0x95, 0x00,
0x00, 0x00, 0x0A, 0x01, 0x00, 0x00, 0xD5, 0x01, 0x00, 0x00,
0x7C, 0x03, 0x00, 0x00, 0xA9, 0x03, 0x00, 0x00, 0xB0, 0x07,
0x00, 0x00, 0x69, 0x19, 0x00, 0x00, 0x27, 0x01, 0x00, 0x00,
0xA3, 0x01, 0x00, 0x00, 0xC4, 0x01, 0x00, 0x00, 0xB9, 0x02,
0x00, 0x00, 0x54, 0x07, 0x00, 0x00, 0x89, 0x08, 0x00, 0x00,
0x50, 0x0F, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x54, 0x02,
0x00, 0x00, 0xD9, 0x02, 0x00, 0x00, 0x58, 0x05, 0x00, 0x00,
0x71, 0x05, 0x00, 0x00, 0x24, 0x09, 0x00, 0x00, 0x19, 0x10,
0x00, 0x00, 0x42, 0x03, 0x00, 0x00, 0xAD, 0x03, 0x00, 0x00,
0x08, 0x05, 0x00, 0x00, 0xE9, 0x06, 0x00, 0x00, 0x30, 0x0A,
0x00, 0x00, 0xE1, 0x10, 0x00, 0x00, 0x84, 0x12, 0x00, 0x00,
0x00, 0x05, 0x00, 0x00, 0xD2, 0x05, 0x00, 0x00, 0x4D, 0x07,
0x00, 0x00
};

char flag[40] = {0};
int main(int argc, char** argv[])
{
//printf("%d\n",sizeof(long long unsigned));
int* px = (int *)ida_chars;
for(int i = 0;i<38;i++){

printf("%x\n",*px);
flag[i] = (*px - (i*i))>>(i%7);
px++;
}
for(int i = 0; i< 38;i++){
printf("%c",flag[i]);

}

getchar();
return 0;
}
//flag{7bdeac39cca13a97782c04522aece87a}

Quirky

给出的文件:

1
\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\x00\x00\x6f\x00\x00\x00\x6f\x01\x03\x00\x00\x00\xd8\x0b\x0c\x23\x00\x00\x00\x06\x50\x4c\x54\x45\x00\x00\x00\xff\xff\xff\xa5\xd9\x9f\xdd\x00\x00\x00\x02\x74\x52\x4e\x53\xff\xff\xc8\xb5\xdf\xc7\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x12\x00\x00\x0b\x12\x01\xd2\xdd\x7e\xfc\x00\x00\x01\x25\x49\x44\x41\x54\x38\x8d\xd5\xd4\x31\x8e\xc3\x20\x10\x05\xd0\xb1\x5c\xd0\x25\x17\x40\x9a\x6b\xd0\x71\x25\xfb\x02\xb6\xf7\x02\xce\x95\xe8\xb8\x06\x92\x2f\x40\x3a\x0a\x94\xd9\x8f\x23\x45\xbb\xc5\x66\x68\x52\x2c\xa2\xe0\x21\x21\xcf\x0c\x83\x49\x7e\x0d\xfa\x1f\xcc\x44\x8b\xaf\x6b\xb0\x44\xac\xf2\x2e\x75\x72\xe3\x66\xea\x2a\x1d\x0c\x76\xc1\xe7\x82\x9d\x4c\x17\x27\x97\xc8\xd4\x4e\xae\x91\xd6\x62\xbb\x28\x75\x8e\xf5\x1a\xed\x2b\xc8\x37\x44\xbe\x73\xb4\x98\xaf\xf4\xdf\xf0\x1c\xf6\x5a\x7e\x16\xf6\x4f\x66\xb2\x64\x78\xf3\xc7\xee\x3a\xe8\x0f\xac\x25\x10\x39\x56\x79\x2f\x74\x71\xe3\x57\x94\x87\x11\x9d\xf1\xd8\x5b\x6c\x34\x79\x9d\x0f\x8f\xb3\xb2\xfb\x73\x53\xa5\x3b\x36\x33\xa2\xf8\x73\x60\x95\x52\xea\x10\xd3\xc5\xf0\x7e\x46\xf5\x9e\x77\x19\x6f\x6d\x4a\x76\x3a\x25\xa0\x49\xda\x05\xdd\x22\xab\x44\xbe\x38\x28\x25\xcd\xa5\x83\x92\x86\x82\x90\x0e\x14\x53\x67\x44\x1f\xd6\x39\xa0\xfe\xac\xb3\x9d\x95\xdd\x10\x19\x51\x89\x91\x3d\x21\xa4\xec\x58\x25\x3a\x76\xf2\x69\x68\xaf\x4c\x54\xe2\x2d\x2c\x1e\x95\xe4\xec\x59\x27\xae\x52\xd0\xb4\x34\x3c\xf3\x55\x89\x85\xf0\xc3\x71\x17\x0b\xdf\x42\x22\x27\x3a\xf1\x7e\xd1\x2d\x68\xaa\xa2\xb3\xe5\xdb\x3a\x56\xb2\xd1\xf9\xb9\x5f\xee\xa7\xf8\x0d\x69\xf5\x37\x77\x6e\xf8\x09\x97\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82

在网上找一个数组转二进制文件的脚本跑一下:

1
2
3
4
5
6
7
8
import struct
arr = [0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,0x00,0x00,0x00,0x6f,0x00,0x00,0x00,0x6f,0x01,0x03,0x00,0x00,0x00,0xd8,0x0b,0x0c,0x23,0x00,0x00,0x00,0x06,0x50,0x4c,0x54,0x45,0x00,0x00,0x00,0xff,0xff,0xff,0xa5,0xd9,0x9f,0xdd,0x00,0x00,0x00,0x02,0x74,0x52,0x4e,0x53,0xff,0xff,0xc8,0xb5,0xdf,0xc7,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x12,0x00,0x00,0x0b,0x12,0x01,0xd2,0xdd,0x7e,0xfc,0x00,0x00,0x01,0x25,0x49,0x44,0x41,0x54,0x38,0x8d,0xd5,0xd4,0x31,0x8e,0xc3,0x20,0x10,0x05,0xd0,0xb1,0x5c,0xd0,0x25,0x17,0x40,0x9a,0x6b,0xd0,0x71,0x25,0xfb,0x02,0xb6,0xf7,0x02,0xce,0x95,0xe8,0xb8,0x06,0x92,0x2f,0x40,0x3a,0x0a,0x94,0xd9,0x8f,0x23,0x45,0xbb,0xc5,0x66,0x68,0x52,0x2c,0xa2,0xe0,0x21,0x21,0xcf,0x0c,0x83,0x49,0x7e,0x0d,0xfa,0x1f,0xcc,0x44,0x8b,0xaf,0x6b,0xb0,0x44,0xac,0xf2,0x2e,0x75,0x72,0xe3,0x66,0xea,0x2a,0x1d,0x0c,0x76,0xc1,0xe7,0x82,0x9d,0x4c,0x17,0x27,0x97,0xc8,0xd4,0x4e,0xae,0x91,0xd6,0x62,0xbb,0x28,0x75,0x8e,0xf5,0x1a,0xed,0x2b,0xc8,0x37,0x44,0xbe,0x73,0xb4,0x98,0xaf,0xf4,0xdf,0xf0,0x1c,0xf6,0x5a,0x7e,0x16,0xf6,0x4f,0x66,0xb2,0x64,0x78,0xf3,0xc7,0xee,0x3a,0xe8,0x0f,0xac,0x25,0x10,0x39,0x56,0x79,0x2f,0x74,0x71,0xe3,0x57,0x94,0x87,0x11,0x9d,0xf1,0xd8,0x5b,0x6c,0x34,0x79,0x9d,0x0f,0x8f,0xb3,0xb2,0xfb,0x73,0x53,0xa5,0x3b,0x36,0x33,0xa2,0xf8,0x73,0x60,0x95,0x52,0xea,0x10,0xd3,0xc5,0xf0,0x7e,0x46,0xf5,0x9e,0x77,0x19,0x6f,0x6d,0x4a,0x76,0x3a,0x25,0xa0,0x49,0xda,0x05,0xdd,0x22,0xab,0x44,0xbe,0x38,0x28,0x25,0xcd,0xa5,0x83,0x92,0x86,0x82,0x90,0x0e,0x14,0x53,0x67,0x44,0x1f,0xd6,0x39,0xa0,0xfe,0xac,0xb3,0x9d,0x95,0xdd,0x10,0x19,0x51,0x89,0x91,0x3d,0x21,0xa4,0xec,0x58,0x25,0x3a,0x76,0xf2,0x69,0x68,0xaf,0x4c,0x54,0xe2,0x2d,0x2c,0x1e,0x95,0xe4,0xec,0x59,0x27,0xae,0x52,0xd0,0xb4,0x34,0x3c,0xf3,0x55,0x89,0x85,0xf0,0xc3,0x71,0x17,0x0b,0xdf,0x42,0x22,0x27,0x3a,0xf1,0x7e,0xd1,0x2d,0x68,0xaa,0xa2,0xb3,0xe5,0xdb,0x3a,0x56,0xb2,0xd1,0xf9,0xb9,0x5f,0xee,0xa7,0xf8,0x0d,0x69,0xf5,0x37,0x77,0x6e,0xf8,0x09,0x97,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82]
#待写入的数据

with open("./testfile.png","wb") as fp:
for x in arr:
s = struct.pack('B',x)#转换为字节流字符串,B代表unsigned char
fp.write(s)

之后就会出一个二维码,扫描即可

moblize [复现]

这题记得是没在模拟器上安装成功,就跳过了

赛后复现就尴尬了

OTP Vault (ReactJS逆向)[复现]

参考链接:

使用apktool

1
apk -d OTPVault.apk

不知道能从jadx反汇编的什么特征,得知该程序是使用ReactJS构建的

wp中使用的是以下的工具来反汇编assets目录下的index.android.bundle,需要node环境

在windows中安装就可以了

1
2
npm i -g react-native-decompiler
npx react-native-decompiler -i ./index.android.bundle -o ./output

后面发现提取出来的文件有很多的时候,还是转linux了,需要配置一下npm

–更新–

参考博客

方法原来不止一种,上述方法确实太过麻烦

直接把apk后缀改成zip,解压出来,找到assets下面的index.android.bundle,直接用notepad打开,复制代码到VScode中,shift+alt+f,代码格式化,搜索失败字符串”Invalid OTP”。

我以为要构造头呢……

直接上hackbar就行了

flag{5450384e093a0444e6d3d39795dd7ddd}

clickme [复现]

模拟器版本太低,不能安装