湘湖杯2020wp(只有RE部分)

easyZ

  1. 使用strings找到input相关字符串

  2. 使用vim搜索到偏移量

  3. 根据偏移量找到主函数汇编指令代码

  4. 判断相关的字符串偏移量

    1000bc2 wrong

    1000bb2 win

  5. 猜测 brasl 为跳转指令,后面还有判断指令

  6. 网上搜索到一个pdf http://read.pudn.com/downloads92/ebook/356133/IBM%20S390%20%BB%E3%B1%E0%D3%EF%D1%D4.pdf

    从这里面看到了函数结尾的形式,即先加载地址,然后br跳转到那个地址,由此可以确定两个关键函数的结尾

  7. 1000910 判断字符集合法性,只能0-9 a-f 长度为32

    1000a08 验证函数

  8. google搜索 llcr site:www.ibm.com得到一个指令集文档

    https://www.ibm.com/support/pages/sites/default/files/2020-07/SA22-7871-10.pdf

    起飞

  9. 实际程序逻辑是一个多项式,可以按位穷举

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
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>

void printArray(char *name,uint8_t *data,size_t len){
printf("==============%s========\n",name);
for(size_t i=0;i<len;i++){
printf("0x%02x,",data[i]);
}
printf("\n================================\n");
}
uint32_t calc(uint32_t d1,uint32_t d2,uint32_t d3,uint32_t d4){
return d1*d1*d2+d1*d3+d4;
}
int main(){
uint32_t addDat[] = {0xb2b0,0x6e72,0x6061,0x565d,0x942d,0xac79,0x391c,0x643d,0xec3f,0xbd10,0xc43e,0x7a65,0x184b,0xef5b,0x5a06,0xa8c0,0xf64b,0xc774,0x02ff,0x8e57,0xaed9,0xd8a9,0x230c,0x74e8,0xc2a6,0x88b3,0xaf2a,0x9ea7,0xce8a,0x5924,0xd276,0x56d4,0x77d7,0x990e,0xb585,0x4bcd,0x5277,0x1afc,0x8c8a,0xcdb5,0x6e26,0x4c22,0x673f,0xdaff,0x0fac,0x86c7,0xe048,0xc483,0x85d3,0x2204,0xc2ee,0xe07f,0x0caf,0xbf76,0x63fe,0xbffb,0x4b09,0xe5b3,0x8bda,0x96df,0x866d,0x1719,0x6bcf,0xadcc,0x0f2b,0x51ce,0x1549,0x20c1,0x3a8d,0x05f5,0x5403,0x1125,0x9161,0xe2a5,0x5196,0xd8d2,0xd644,0xee86,0x3896,0x2e71,0xa6f1,0xdfcf,0x3ece,0x7d49,0xc24d,0x237e,0x9352,0x7a97,0x7bfa,0xcbaa,0x10dc,0x3bd9,0x7d7b,0x3b88,0xb0d0,0xe8bc};
uint32_t cmpDat[] = {0x08a73233,0x116db0f6,0x0e654937,0x03c374a7,0x16bc8ed9,0x0846b755,0x08949f47,0x04a13c27,0x0976cf0a,0x07461189,0x1e1a5c12,0x11e64d96,0x03cf09b3,0x093cb610,0x0d41ea64,0x07648050,0x092039bf,0x08e7f1f7,0x004d871f,0x1680f823,0x06f3c3eb,0x2205134d,0x015c6a7c,0x11c67ed0,0x0817b32e,0x06bd9b92,0x08806b0c,0x06aaa515,0x205b9f76,0x0de963e9,0x2194e8e2,0x047593bc};
printf("%d\n",sizeof(addDat)/4);
printf("%d\n",sizeof(cmpDat)/4);
printf("0x%08x 0x%08x 0x%08x\n",addDat[0],addDat[1],cmpDat[0]);
uint8_t flag[33]={0};
uint32_t addT;
char dic[] = "0123456789abcdef";

for(size_t i=0;i<32;i++){

// flag[i]=(uint32_t)sqrt(cmpDat[i]);
for(size_t j=0;j<16;j++){
if(calc(dic[j],addDat[i],addDat[i+32],addDat[i+64])==cmpDat[i]){
flag[i]=dic[j];
break;
}
}
}
printArray("flag",flag,32);
printf("%s\n",flag);
printf("%d\n",strlen(flag));
return 0;
}

[rev] easyre

  1. IDA进入主函数没发现什么

  2. 使用调试器发现返回后进入变换和检测函数

  3. 程序逻辑为所有数组成一个整体循环右移5位,之后每一个数异或自己的下标。第0Byte异或0所以不受影响。

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
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>

void printArray(char *name,uint8_t *data,size_t len){
printf("==============%s========\n",name);
for(size_t i=0;i<len;i++){
printf("0x%02x,",data[i]);
}
printf("\n================================\n");
}
int main(){
uint8_t a[] = {0x2b, 0x08, 0xa9, 0xc8, 0x97, 0x2f, 0xff, 0x8c, 0x92, 0xf0, 0xa3, 0x89, 0xf7, 0x26, 0x07, 0xa4, 0xda, 0xea, 0xb3, 0x91, 0xef, 0xdc, 0x95, 0xab,0};
printf("%d\n",sizeof(a));
uint8_t flag[25]={0};
for(size_t i=0;i<24;i++){
a[i]^=i;
}
for(size_t i=0;i<24;i++){
flag[i]=a[(i-1)%24]<<5|a[i]>>3;
}
printArray("flag",flag,24);
printf("%s\n",flag);
return 0;
}

这个脚本跑出来最后一位错误,但是根据语义推测最后一位为u

easy_c++

把用户输入和下标做异或处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <math.h>

void printArray(char *name,uint8_t *data,size_t len){
printf("==============%s========\n",name);
for(size_t i=0;i<len;i++){
printf("0x%02x,",data[i]);
}
printf("\n================================\n");
}
int main(){
char s[] = "7d21e<e3<:3;9;ji t r#w\"$*{*+*$|,";
for(size_t i=0;i<strlen(s);i++){
s[i]^=i;
}
printf("%s\n",s);
printf("%d\n",strlen(s));

return 0;
}

[rev]ReMe

  1. 有个python图标,猜测是pyinstaller打包的

    这一点也可以ida打开查看字符串

  2. 使用pyinstxtractor解包程序

  3. 解包之后,猜测文件夹中ReMe是主程序的pyc文件,但是没有pyc的文件头

  4. 找个同文件夹下的pyc文件头,插入到这个文件开头,使用uncompyle6反编译,得到1.py文件

  5. 查看程序逻辑之后发现可以按位穷举

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import base64
import hashlib
import random,string
from Crypto.Cipher import AES
from math import *
import string
import base64
import ctypes
import time

check = [
'e5438e78ec1de10a2693f9cffb930d23',
'08e8e8855af8ea652df54845d21b9d67',
'a905095f0d801abd5865d649a646b397',
'bac8510b0902185146c838cdf8ead8e0',
'f26f009a6dc171e0ca7a4a770fecd326',
'cffd0b9d37e7187483dc8dd19f4a8fa8',
'4cb467175ab6763a9867b9ed694a2780',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'cffd0b9d37e7187483dc8dd19f4a8fa8',
'fd311e9877c3db59027597352999e91f',
'49733de19d912d4ad559736b1ae418a7',
'7fb523b42413495cc4e610456d1f1c84',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'acb465dc618e6754de2193bf0410aafe',
'bc52c927138231e29e0b05419e741902',
'515b7eceeb8f22b53575afec4123e878',
'451660d67c64da6de6fadc66079e1d8a',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'fe86104ce1853cb140b7ec0412d93837',
'acb465dc618e6754de2193bf0410aafe',
'c2bab7ea31577b955e2c2cac680fb2f4',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'f077b3a47c09b44d7077877a5aff3699',
'620741f57e7fafe43216d6aa51666f1d',
'9e3b206e50925792c3234036de6a25ab',
'49733de19d912d4ad559736b1ae418a7',
'874992ac91866ce1430687aa9f7121fc']

def func(num):
result = []
while num != 1:
num = num * 3 + 1 if num % 2 else num // 2
result.append(num)

return result


if __name__ == '__main__':
print('Your input is not the FLAG!')
flag = ''
for j in range(27):
for i in range(0x20,0x7f):
ret_list = func(i)
s = ''
for idx in range(len(ret_list)):
s += str(ret_list[idx])
s += str(ret_list[(len(ret_list) - idx - 1)])
md5 = hashlib.md5()
md5.update(s.encode('utf-8'))
if md5.hexdigest()==check[j]:
flag+=chr(i)
print(flag)
break

md5 = hashlib.md5()
md5.update(flag.encode('utf-8'))
print('You win!')
print('flag{' + md5.hexdigest() + '}')