假期天天学车,这比赛没太好好打就坐了坐re的牢
UPX2023
都说好像有一个壳但是不能直接脱掉,据说是在010里把UPX改成了upx(出题人nb
话说之前校赛做过类似的题,但是我一般遇到这样的壳就直接脱壳机嗦了
分析部分
随后看一下代码
去掉了符号表,点进去简单看了看每一个函数,分析起来估计是有点费时间,直接动调看看数据的变化吧,这里直接尝试性输入:flag{111111111111111111111111111111111111}
位数一定要对不然会退出
本质上就是一个异或,然后对输入的数据进行了一个比较抽象的排列,大概是这样的:
现在问题就来到了有一个为随机数需要去爆破
获得伪随机种子
已知flag的前几位是flag{,所以直接去想办法爆破种子
文件的修改日期是2023/6/3 11:29
所以可以得到一个时间戳
得到了一个时间戳范围之后,就根据异或和排列,进行强制爆破时间戳:
代码如下:
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
| #include<stdio.h> #include<stdlib.h> int main() { int i; int seed; int r[42]={0};
for (seed = 1685762940; seed > 0; seed--) { srand(seed); for(i=0;i<42;i++) r[i]=rand() % 255; if((r[0]^0x09)=='f') if((r[11]^0x0C6)=='l') if((r[32]^0x0FA)=='a') if((r[12]^0x65)=='g') if((r[1]^0x63=='{')) { printf("seed:%d \n",seed); break; } } }
|
得到了seed:1682145110
getflag
之后的异或就使用这个seed去生成就可以了,然后把密文进行一个异或,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include<stdio.h> #include<stdlib.h> int main() { int i; int r[42]={0}; int enc[42] = { 0x9, 0x63, 0x0D9, 0x0F6, 0x58, 0x0DD, 0x3F, 0x4C, 0x0F , 0x0B, 0x98, 0x0C6, 0x65, 0x21, 0x41, 0x0ED, 0x0C4, 0x0B, 0x3A, 0x7B, 0x0E5, 0x75, 0x5D, 0x0A9, 0x31, 0x41, 0x0D7, 0x52, 0x6C, 0x0A, 0x0FA, 0x0FD, 0x0FA, 0x84, 0x0DB, 0x89, 0x0CD, 0x7E, 0x27, 0x85, 0x13, 0x8 }; srand(1682145110); for(i=0;i<42;i++) { r[i]=rand() % 255; enc[i]^=r[i]; printf("%c",enc[i]); } }
|
得到了乱序之后的flag:f{52bgb-281lg00ff-46f7-ca009c8e}a381-b7191
然后既然知道了他是怎么进行混乱的,那么就可以手搓(bushi
再或者可以自己自己输入42个字符,然后得到之前的和之后的进行作对比然后搓一个脚本来:
输入前:abcdefghijklmnopqrstuvwxyz0123456789ASDFGH
输入后:aeimquy26AGbdfhjlnprtvxz13579SFHcgkosw048D
代码奉上:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include<stdio.h> #include<stdlib.h> int main() { char flag[] = "f{52bgb-281lg00ff-46f7-ca009c8e}a381-b7191"; char key1[] = "abcdefghijklmnopqrstuvwxyz0123456789ASDFGH"; char key2[] = "aeimquy26AGbdfhjlnprtvxz13579SFHcgkosw048D"; for (int i = 0; i < 42; i++) { for (int j = 0; j < 42; j++) { if (key1[i] == key2[j]) { printf("%c", flag[j]); } } } }
|
encryptor
占坑,待写