实验课写写之前做过的题叭

Guess-the-Number

下载文件,得到一个jar包,解压得到一个class文件

这个地方要用到一个反编译插件jadclipse,得到guess.class文件的源代码如下(全部)。

if (my_number / 5 == guess_number) {//可求得guess_number为309137378,

输入命令java -jar guess.jar 309137378

Shuffle

查看是32位文件,拖入ida查看,F5

按R查看字符串得到flag

re-for-50-plz-50

打开ida,发现这是MIPS代码。本来准备安装RetDec,哎…还是恶补MIPS指令知识吧:https://www.cnblogs.com/thoupin/p/4018455.html

分析重点

这实际上就是一个对字符串的异或操作

str1 = 'cbtcqLUBChERV[[Nh@_X^D]X_YPV[CJ'

flag = ''

for i in str1:
flag += chr(ord(i)^0x37)

print(flag)

dmd-50

可以看到是ELF64位文件,需要在linux环境运行

可以看到需要输入正确的key

F5查看伪代码,发现是md5加密。

然后我们继续往下看,从if判断条件中,可以得知加密后的密文

编写脚本

parallel-comparator-200

C文件

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>

#define FLAG_LEN 20

void * checking(void *arg) {
char *result = malloc(sizeof(char));
char *argument = (char *)arg;
*result = (argument[0]+argument[1]) ^ argument[2];//argument[0]>97
return result;
}

int highly_optimized_parallel_comparsion(char *user_string)
{
int initialization_number;
int i;
char generated_string[FLAG_LEN + 1];
generated_string[FLAG_LEN] = '\0';

while ((initialization_number = random()) >= 64);//开始认为随机数且大于64,事实上为一固定数37

int first_letter;
first_letter = (initialization_number % 26) + 97;//97-123

pthread_t thread[FLAG_LEN];
char differences[FLAG_LEN] = {0, 9, -9, -1, 13, -13, -4, -11, -9, -1, -7, 6, -13, 13, 3, 9, -13, -11, 6, -7};
char *arguments[20];
//没有全部执行,
for (i = 0; i < FLAG_LEN; i++) {
arguments[i] = (char *)malloc(3*sizeof(char));
arguments[i][0] = first_letter;//三个数拼接到一起 随机的
arguments[i][1] = differences[i];//固定的
arguments[i][2] = user_string[i];//输入的

pthread_create((pthread_t*)(thread+i), NULL, checking, arguments[i]);
}

void *result;
int just_a_string[FLAG_LEN] = {115, 116, 114, 97, 110, 103, 101, 95, 115, 116, 114, 105, 110, 103, 95, 105, 116, 95, 105, 115};
for (i = 0; i < FLAG_LEN; i++) {
pthread_join(*(thread+i), &result);
generated_string[i] = *(char *)result + just_a_string[i];
free(result);
free(arguments[i]);
}

int is_ok = 1;
for (i = 0; i < FLAG_LEN; i++) {
if (generated_string[i] != just_a_string[i])
return 0;
}

return 1;
}

int main()
{
char *user_string = (char *)calloc(FLAG_LEN+1, sizeof(char));
fgets(user_string, FLAG_LEN+1, stdin);
int is_ok = highly_optimized_parallel_comparsion(user_string);
if (is_ok)
printf("You win!\n");
else
printf("Wrong!\n");
return 0;
}

粗略看一遍,发现 pthread_t 以及pthread_join pthread_create函数看不懂,于是网上查资料,得知

pthread_t

typedef unsigned __int64 uintptr_t
typedef uintptr_t pthread_t;

pthread_create :作用为创建新线程,如果创建成功则返回0,否则返回error number``

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine)(void*), void *arg);
  • pthread_t *thread 是线程的标识符
  • pthread_attr_t *attr用来设置线程属性(如果为NULL,则为默认属性}
  • void *(*start_routine)(void*) 是运行函数的起始地址
  • void *arg运行函数的参数

prhread_join : 作用为等待一个线程的结束,如果成功则返回0,否则返回error number``

int pthread_join(pthread_t thread, void **value_ptr);
  • pthread_t thread线程标识符
  • void **value_ptr 存储被等待线程的返回值

有了以上知识,可以很容易可以知道user_string[20] (输入数组)的每个元素加上first_letter(经调试为固定值108),然后再与 differences[20]的元素异或,最后与just_a_string[20]的元素进行比较,用代码描述就是:

strcmp(     ( user_string[i] + first_letter ) ^ differences[i]    , just_a_string[i]    )

脚本:

1 a = [0, 9, -9, -1, 13, -13, -4, -11, -9, -1, -7, 6, -13, 13, 3, 9, -13, -11, 6, -7]
2 flag = ''
3 for i in range(len(a)):
4 for j in range(127):
5 if ((a[i]+108) ^ (j+1)) == 0:
6 flag += chr(j+1)
7 break
8 print(flag)

secret-galaxy-300

运行程序

ida查看字符串

动态调试,看运行后内存信息

发现了一串字符 aliens_are_around_us提交,成功。

srm-50

exe文件

运行程序,可知是 MFC 框架的对话框程序,随便输入数据,显示注册失败。IDA 静态分析 IDA 分析,找到 winmain,是 MFC 的主函数

读程序可知先是验证邮箱的合法性,然后验证 v11,可推测 flag 长度为 16,但是 v11 是 一个长度为 4 的 char 数组 CHAR v11[4],如果输入超过四位就到 v12-v23,刚好 16 个。

编写程序

得到flag

simple-check-100

这道题值得记录一下,因为这道题让我第一次接触peda。

 1 int __cdecl main(int argc, const char **argv, const char **envp)
2 {
3 void *v3; // esp
4 void *v4; // esp
5 char *v6; // [esp+4h] [ebp-44h]
6 char v7; // [esp+8h] [ebp-40h]
7 char v8; // [esp+1Bh] [ebp-2Dh]
8 char *v9; // [esp+1Ch] [ebp-2Ch]
9 int v10; // [esp+20h] [ebp-28h]
10 char v11; // [esp+25h] [ebp-23h]
11 char v12; // [esp+26h] [ebp-22h]
12 char v13; // [esp+27h] [ebp-21h]
13 char v14; // [esp+28h] [ebp-20h]
14 char v15; // [esp+29h] [ebp-1Fh]
15 char v16; // [esp+2Ah] [ebp-1Eh]
16 char v17; // [esp+2Bh] [ebp-1Dh]
17 char v18; // [esp+2Ch] [ebp-1Ch]
18 char v19; // [esp+2Dh] [ebp-1Bh]
19 char v20; // [esp+2Eh] [ebp-1Ah]
20 char v21; // [esp+2Fh] [ebp-19h]
21 char v22; // [esp+30h] [ebp-18h]
22 char v23; // [esp+31h] [ebp-17h]
23 char v24; // [esp+32h] [ebp-16h]
24 char v25; // [esp+33h] [ebp-15h]
25 char v26; // [esp+34h] [ebp-14h]
26 char v27; // [esp+35h] [ebp-13h]
27 char v28; // [esp+36h] [ebp-12h]
28 char v29; // [esp+37h] [ebp-11h]
29 char v30; // [esp+38h] [ebp-10h]
30 char v31; // [esp+39h] [ebp-Fh]
31 char v32; // [esp+3Ah] [ebp-Eh]
32 char v33; // [esp+3Bh] [ebp-Dh]
33 char v34; // [esp+3Ch] [ebp-Ch]
34 char v35; // [esp+3Dh] [ebp-Bh]
35 char v36; // [esp+3Eh] [ebp-Ah]
36 char v37; // [esp+3Fh] [ebp-9h]
37 int *v38; // [esp+40h] [ebp-8h]
38
39 v38 = &argc;
40 __main();
41 v8 = 'T';
42 v37 = -56;
43 v36 = 126;
44 v35 = -29;
45 v34 = 100;
46 v33 = -57;
47 v32 = 22;
48 v31 = -102;
49 v30 = -51;
50 v29 = 17;
51 v28 = 101;
52 v27 = 50;
53 v26 = 45;
54 v25 = -29;
55 v24 = -45;
56 v23 = 67;
57 v22 = -110;
58 v21 = -87;
59 v20 = -99;
60 v19 = -46;
61 v18 = -26;
62 v17 = 109;
63 v16 = 44;
64 v15 = -45;
65 v14 = -74;
66 v13 = -67;
67 v12 = -2;
68 v11 = 106;
69 v10 = 19;
70 v3 = alloca(32);
71 v4 = alloca(32);
72 v9 = &v7;
73 printf("Key: ");
74 v6 = v9;
75 scanf("%s", v9);
76 if ( check_key((int)v9) )
77 interesting_function((int)&v8);
78 else
79 puts("Wrong");
80 return 0;
81 }

很明显只要绕过第76行代码,我们就能够获取我们需要的flag,而且v8还是已知的

将Linux下的那个文件放入Linux调试。

task9_x86_64_46d01fe312d35ecf69c4ff8ab8ace75d080891dc

命令

gdb

file task9_x86_64_46d01fe312d35ecf69c4ff8ab8ace75d080891dc

b main

r

然后一直执行命令next,运行到check_key函数处

把test eax,eax改为真就行,也就是把eax改为1。

修改eax

set $eax=1

Mysterious

int __stdcall sub_401090(HWND hWnd, int a2, int a3, int a4)
{
char v5; // [esp+50h] [ebp-310h]
CHAR Text[4]; // [esp+154h] [ebp-20Ch]
char v7; // [esp+159h] [ebp-207h]
__int16 v8; // [esp+255h] [ebp-10Bh]
char v9; // [esp+257h] [ebp-109h]
int v10_108; // [esp+258h] [ebp-108h]
CHAR myinput; // [esp+25Ch] [ebp-104h]
char v11_101; // [esp+25Fh] [ebp-101h]
char v12_100; // [esp+260h] [ebp-100h]
char v13_FF; // [esp+261h] [ebp-FFh]

memset(&myinput, 0, 0x104u);
v10_108 = 0;
if ( a2 == 16 )
{
DestroyWindow(hWnd);
PostQuitMessage(0);
}
else if ( a2 == 273 )
{
if ( a3 == 1000 )
{
GetDlgItemTextA(hWnd, 1002, &myinput, 260);
strlen(&myinput);
if ( strlen(&myinput) > 6 ) // 输入小于7
ExitProcess(0);
v10_108 = atoi(&myinput) + 1; // int atoi(const char *nptr);是把字符串转换成整型数的一个函数。扫描nptr,如果遇到‘0-9’之外的字符便停止。
// v10=转换的数字+1
if ( v10_108 == 123 && v11_101 == 'x' && v13_FF == 'z' && v12_100 == 'y' )// 输入atoi转整形得到结果+1等于123,则输入开始的数字部分为122
// 输入的后3位为xyz
{
strcpy(Text, "flag"); // 下面开始拼接flag
memset(&v7, 0, 0xFCu);
v8 = 0;
v9 = 0;
_itoa(v10_108, &v5, 10);
strcat(Text, "{");
strcat(Text, &v5);
strcat(Text, "_");
strcat(Text, "Buff3r_0v3rf|0w");
strcat(Text, "}");
MessageBoxA(0, Text, "well done", 0);
}
SetTimer(hWnd, 1u, 0x3E8u, TimerFunc);
}
if ( a3 == 1001 )
KillTimer(hWnd, 1u);
}
return 0;
}

flag{123_Buff3r_0v3rf|0w}

Newbie_calculations

题目名百度翻译成新手计算,那我猜应该是个实现计算器的题目。。。。

IDA打开程序,发现一长串的函数反复调用,而且程序没有输入,只有输出。额,那这样的话程序运行就应该输出flag,但程序中肯定会有垃圾循环操作,就让你跑不出来。

这种题目就要分析函数作用,简化,自己实现算法。

for ( i = 0; i < 32; ++i )
flag[i] = 1;
v121 = 0;
puts("Your flag is:");
v3 = mul_401100(flag, 0x3B9ACA00);
v4 = sub_401220(v3, 0x3B9AC9CE);
mul_401100(v4, 2);
v5 = add_401000(&flag[1], 0x4C4B40);
v6 = sub_401220(v5, 0x65B9AA);
v7 = add_401000(v6, 1666666);
v8 = add_401000(v7, 45);
v9 = mul_401100(v8, 2);
add_401000(v9, 5);
v10 = mul_401100(&flag[2], 0x3B9ACA00);
v11 = sub_401220(v10, 999999950);
v12 = mul_401100(v11, 2);
add_401000(v12, 2);
v13 = add_401000(&flag[3], 55);
v14 = sub_401220(v13, 3);
v15 = add_401000(v14, 4);
sub_401220(v15, 1);
v16 = mul_401100(&flag[4], 100000000);
v17 = sub_401220(v16, 99999950);
v18 = mul_401100(v17, 2);
add_401000(v18, 2);
v19 = sub_401220(&flag[5], 1);
v20 = mul_401100(v19, 1000000000);
v21 = add_401000(v20, 55);
sub_401220(v21, 3);
v22 = mul_401100(&flag[6], 1000000);
v23 = sub_401220(v22, 999975);
mul_401100(v23, 4);
v24 = add_401000(&flag[7], 55);
v25 = sub_401220(v24, 33);
v26 = add_401000(v25, 44);
sub_401220(v26, 11);
v27 = mul_401100(&flag[8], 10);
v28 = sub_401220(v27, 5);
v29 = mul_401100(v28, 8);
add_401000(v29, 9);
v30 = add_401000(&flag[9], 0);
v31 = sub_401220(v30, 0);
v32 = add_401000(v31, 11);
v33 = sub_401220(v32, 11);
add_401000(v33, 53);
v34 = add_401000(&flag[10], 49);
v35 = sub_401220(v34, 2);
v36 = add_401000(v35, 4);
sub_401220(v36, 2);
v37 = mul_401100(&flag[11], 1000000);
v38 = sub_401220(v37, 999999);
v39 = mul_401100(v38, 4);
add_401000(v39, 50);
v40 = add_401000(&flag[12], 1);
v41 = add_401000(v40, 1);
v42 = add_401000(v41, 1);
v43 = add_401000(v42, 1);
v44 = add_401000(v43, 1);
v45 = add_401000(v44, 1);
v46 = add_401000(v45, 10);
add_401000(v46, 32);
v47 = mul_401100(&flag[13], 10);
v48 = sub_401220(v47, 5);
v49 = mul_401100(v48, 8);
v50 = add_401000(v49, 9);
add_401000(v50, 48);
v51 = sub_401220(&flag[14], 1);
v52 = mul_401100(v51, -294967296);
v53 = add_401000(v52, 55);
sub_401220(v53, 3);
v54 = add_401000(&flag[15], 1);
v55 = add_401000(v54, 2);
v56 = add_401000(v55, 3);
v57 = add_401000(v56, 4);
v58 = add_401000(v57, 5);
v59 = add_401000(v58, 6);
v60 = add_401000(v59, 7);
add_401000(v60, 20);
v61 = mul_401100(&flag[16], 10);
v62 = sub_401220(v61, 5);
v63 = mul_401100(v62, 8);
v64 = add_401000(v63, 9);
add_401000(v64, 48);
v65 = add_401000(&flag[17], 7);
v66 = add_401000(v65, 6);
v67 = add_401000(v66, 5);
v68 = add_401000(v67, 4);
v69 = add_401000(v68, 3);
v70 = add_401000(v69, 2);
v71 = add_401000(v70, 1);
add_401000(v71, 20);
v72 = add_401000(&flag[18], 7);
v73 = add_401000(v72, 2);
v74 = add_401000(v73, 4);
v75 = add_401000(v74, 3);
v76 = add_401000(v75, 6);
v77 = add_401000(v76, 5);
v78 = add_401000(v77, 1);
add_401000(v78, 20);
v79 = mul_401100(&flag[19], 1000000);
v80 = sub_401220(v79, 999999);
v81 = mul_401100(v80, 4);
v82 = add_401000(v81, 50);
sub_401220(v82, 1);
v83 = sub_401220(&flag[20], 1);
v84 = mul_401100(v83, -294967296);
v85 = add_401000(v84, 49);
sub_401220(v85, 1);
v86 = sub_401220(&flag[21], 1);
v87 = mul_401100(v86, 1000000000);
v88 = add_401000(v87, 54);
v89 = sub_401220(v88, 1);
v90 = add_401000(v89, 1000000000);
sub_401220(v90, 1000000000);
v91 = add_401000(&flag[22], 49);
v92 = sub_401220(v91, 1);
v93 = add_401000(v92, 2);
sub_401220(v93, 1);
v94 = mul_401100(&flag[23], 10);
v95 = sub_401220(v94, 5);
v96 = mul_401100(v95, 8);
v97 = add_401000(v96, 9);
add_401000(v97, 48);
v98 = add_401000(&flag[24], 1);
v99 = add_401000(v98, 3);
v100 = add_401000(v99, 3);
v101 = add_401000(v100, 3);
v102 = add_401000(v101, 6);
v103 = add_401000(v102, 6);
v104 = add_401000(v103, 6);
add_401000(v104, 20);
v105 = add_401000(&flag[25], 55);
v106 = sub_401220(v105, 33);
v107 = add_401000(v106, 44);
v108 = sub_401220(v107, 11);
add_401000(v108, 42);
add_401000(&flag[26], flag[25]);
add_401000(&flag[27], flag[12]);
v109 = flag[27];
v110 = sub_401220(&flag[28], 1);
v111 = add_401000(v110, v109);
sub_401220(v111, 1);
v112 = flag[23];
v113 = sub_401220(&flag[29], 1);
v114 = mul_401100(v113, 1000000);
add_401000(v114, v112);
v115 = flag[27];
v116 = add_401000(&flag[30], 1);
mul_401100(v116, v115);
add_401000(&flag[31], flag[30]);
print_401C7F("CTF{");
for ( j = 0; j < 32; ++j )
print_401C7F("%c", SLOBYTE(flag[j]));
print_401C7F("}\n");
return 0;
}

这道题目的关键就在于如何识别出上面这些函数的作用

_DWORD *__cdecl mul_401100(_DWORD *a1, int a2)
{
int v2; // ST20_4
signed int v4; // [esp+Ch] [ebp-1Ch]
int v5; // [esp+14h] [ebp-14h]
int v6; // [esp+18h] [ebp-10h]
int v7; // [esp+1Ch] [ebp-Ch]
int v8; // [esp+20h] [ebp-8h]

v5 = *a1;
v6 = a2;
v4 = -1;
v8 = 0;
v7 = a2 * v5;
while ( a2 ) // a1累加a2次 相当于a1*a2
{
v2 = v7 * v5;
add_401000(&v8, *a1);
++v7;
--a2;
v6 = v2 - 1;
}
while ( v4 ) // 循环结束a1=a1-1
{
++v7;
++*a1;
--v4;
--v6;
}
++*a1;
*a1 = v8;
return a1;
}
1 int *__cdecl add_401000(int *a1, int a2)
2 {
3 int v2; // edx
4 int v4; // [esp+Ch] [ebp-18h]
5 int v5; // [esp+10h] [ebp-14h]
6 int v6; // [esp+18h] [ebp-Ch]
7 signed int v7; // [esp+1Ch] [ebp-8h]
8
9 v5 = -1;
10 v4 = -1 - a2 + 1;
11 v7 = 1231;
12 v2 = *a1;
13 v6 = a2 + 1231;
14 while ( v4 ) 15 // 循环结束 a1=a1+a2
16 {
17 ++v7;
18 --*a1;                       //循环- 相当于-(-a2) +a2
19 --v4;
20 --v6;
21 }
22 while ( v5 )
23 {
24 --v6;
25 ++*a1;
26 --v5;
27 }
28 ++*a1; // a1在上面的循环中-1,现在+1,还是原值
29 return a1;
30 }
_DWORD *__cdecl sub_401220(_DWORD *a1, int a2)
{
int v3; // [esp+8h] [ebp-10h]
signed int v4; // [esp+Ch] [ebp-Ch]
signed int v5; // [esp+14h] [ebp-4h]
int v6; // [esp+14h] [ebp-4h]

v4 = -1;
v3 = -1 - a2 + 1;
v5 = -1;
while ( v3 ) // -a2
{
++*a1; // 循环结束,相当于 a1=a1-a2
--v3;
--v5;
}
v6 = v5 * v5;
while ( v4 ) // 这个循环后 a1=a1-1
{
v6 *= 123;
++*a1;
--v4;
}
++*a1; // a1+=1,恢复上一个循环前的值
return a1;
}

WP

def mul_401100(a,b):
return a*b
def sub_401220(a,b):
return a-b
def add_401000(a,b):
return a+b
flag=[1 for i in range(32)]
v121 = 0
print("Your flag is:")
v3 = mul_401100(flag[0], 0x3B9ACA00)
v4 = sub_401220(v3, 0x3B9AC9CE)
flag[0]=mul_401100(v4, 2)
v5 = add_401000(flag[1], 0x4C4B40)
v6 = sub_401220(v5, 0x65B9AA)
v7 = add_401000(v6, 1666666)
v8 = add_401000(v7, 45)
v9 = mul_401100(v8, 2)
flag[1]=add_401000(v9, 5)
v10 = mul_401100(flag[2], 0x3B9ACA00)
v11 = sub_401220(v10, 999999950)
v12 = mul_401100(v11, 2)
flag[2]=add_401000(v12, 2)
v13 = add_401000(flag[3], 55)
v14 = sub_401220(v13, 3)
v15 = add_401000(v14, 4)
flag[3]=sub_401220(v15, 1)
v16 = mul_401100(flag[4], 100000000)
v17 = sub_401220(v16, 99999950)
v18 = mul_401100(v17, 2)
flag[4]=add_401000(v18, 2)
v19 = sub_401220(flag[5], 1)
v20 = mul_401100(v19, 1000000000)
v21 = add_401000(v20, 55)
flag[5]=sub_401220(v21, 3)
v22 = mul_401100(flag[6], 1000000)
v23 = sub_401220(v22, 999975)
flag[6]=mul_401100(v23, 4)
v24 = add_401000(flag[7], 55)
v25 = sub_401220(v24, 33)
v26 = add_401000(v25, 44)
flag[7]=sub_401220(v26, 11)
v27 = mul_401100(flag[8], 10)
v28 = sub_401220(v27, 5)
v29 = mul_401100(v28, 8)
flag[8]=add_401000(v29, 9)
v30 = add_401000(flag[9], 0)
v31 = sub_401220(v30, 0)
v32 = add_401000(v31, 11)
v33 = sub_401220(v32, 11)
flag[9]=add_401000(v33, 53)
v34 = add_401000(flag[10], 49)
v35 = sub_401220(v34, 2)
v36 = add_401000(v35, 4)
flag[10]=sub_401220(v36, 2)
v37 = mul_401100(flag[11], 1000000)
v38 = sub_401220(v37, 999999)
v39 = mul_401100(v38, 4)
flag[11]=add_401000(v39, 50)
v40 = add_401000(flag[12], 1)
v41 = add_401000(v40, 1)
v42 = add_401000(v41, 1)
v43 = add_401000(v42, 1)
v44 = add_401000(v43, 1)
v45 = add_401000(v44, 1)
v46 = add_401000(v45, 10)
flag[12]=add_401000(v46, 32)
v47 = mul_401100(flag[13], 10)
v48 = sub_401220(v47, 5)
v49 = mul_401100(v48, 8)
v50 = add_401000(v49, 9)
flag[13]=add_401000(v50, 48)
v51 = sub_401220(flag[14], 1)
v52 = mul_401100(v51, -294967296)
v53 = add_401000(v52, 55)
flag[14]=sub_401220(v53, 3)
v54 = add_401000(flag[15], 1)
v55 = add_401000(v54, 2)
v56 = add_401000(v55, 3)
v57 = add_401000(v56, 4)
v58 = add_401000(v57, 5)
v59 = add_401000(v58, 6)
v60 = add_401000(v59, 7)
flag[15]=add_401000(v60, 20)
v61 = mul_401100(flag[16], 10)
v62 = sub_401220(v61, 5)
v63 = mul_401100(v62, 8)
v64 = add_401000(v63, 9)
flag[16]=add_401000(v64, 48)
v65 = add_401000(flag[17], 7)
v66 = add_401000(v65, 6)
v67 = add_401000(v66, 5)
v68 = add_401000(v67, 4)
v69 = add_401000(v68, 3)
v70 = add_401000(v69, 2)
v71 = add_401000(v70, 1)
flag[17]=add_401000(v71, 20)
v72 = add_401000(flag[18], 7)
v73 = add_401000(v72, 2)
v74 = add_401000(v73, 4)
v75 = add_401000(v74, 3)
v76 = add_401000(v75, 6)
v77 = add_401000(v76, 5)
v78 = add_401000(v77, 1)
flag[18]=add_401000(v78, 20)
v79 = mul_401100(flag[19], 1000000)
v80 = sub_401220(v79, 999999)
v81 = mul_401100(v80, 4)
v82 = add_401000(v81, 50)
flag[19]=sub_401220(v82, 1)
v83 = sub_401220(flag[20], 1)
v84 = mul_401100(v83, -294967296)
v85 = add_401000(v84, 49)
flag[20]=sub_401220(v85, 1)
v86 = sub_401220(flag[21], 1)
v87 = mul_401100(v86, 1000000000)
v88 = add_401000(v87, 54)
v89 = sub_401220(v88, 1)
v90 = add_401000(v89, 1000000000)
flag[21]=sub_401220(v90, 1000000000)
v91 = add_401000(flag[22], 49)
v92 = sub_401220(v91, 1)
v93 = add_401000(v92, 2)
flag[22]=sub_401220(v93, 1)
v94 = mul_401100(flag[23], 10)
v95 = sub_401220(v94, 5)
v96 = mul_401100(v95, 8)
v97 = add_401000(v96, 9)
flag[23]=add_401000(v97, 48)
v98 = add_401000(flag[24], 1)
v99 = add_401000(v98, 3)
v100 = add_401000(v99, 3)
v101 = add_401000(v100, 3)
v102 = add_401000(v101, 6)
v103 = add_401000(v102, 6)
v104 = add_401000(v103, 6)
flag[24]=add_401000(v104, 20)
v105 = add_401000(flag[25], 55)
v106 = sub_401220(v105, 33)
v107 = add_401000(v106, 44)
v108 = sub_401220(v107, 11)
flag[25]=add_401000(v108, 42)
flag[26]=add_401000(flag[26], flag[25])
flag[27]=add_401000(flag[27], flag[12])
v109 = flag[27]
v110 = sub_401220(flag[28], 1)
v111 = add_401000(v110, v109)
flag[28]=sub_401220(v111, 1)
v112 = flag[23]
v113 = sub_401220(flag[29], 1)
v114 = mul_401100(v113, 1000000)
flag[29]=add_401000(v114, v112)
v115 = flag[27]
v116 = add_401000(flag[30], 1)
flag[30]=mul_401100(v116, v115)
flag[31]=add_401000(flag[31], flag[30])
print("CTF{"+''.join(map(chr,flag))+"}")

re1-100

这题竟然放在了高手区

 1 if ( numRead )
2 {
3 if ( childCheckDebugResult() )
4 {
5 responseFalse();
6 }
7 else if ( bufParentRead[0] == ‘{‘ ) // 第一位
8 {
9 if ( strlen(bufParentRead) == 42 ) // 输入的长度为42d
10 {
11 if ( !strncmp(&bufParentRead[1], "53fc275d81", 0xAuLL) )// 输入的1-10位(输入的第2位到第11位)
12 {
13 if ( bufParentRead[strlen(bufParentRead) - 1] == ‘}‘ )// 最后一位
14 {
15 if ( !strncmp(&bufParentRead[31], "4938ae4efd", 0xAuLL) )// 输入的31-40
16 {
17 if ( !confuseKey(bufParentRead, 42) )//关键
18 {
19 responseFalse();
20 }
21 else if ( !strncmp(bufParentRead, "{daf29f59034938ae4efd53fc275d81053ed5be8c}", 0x2AuLL) )// 修改后的结果进行比较
22 {
23 responseTrue(); // {53fc275d81053ed5be8cdaf29f59034938ae4efd}
24 }
25 else
26 {
27 responseFalse();

主要分析confuseKey(bufParentRead, 42)函数

1 bool __cdecl confuseKey(char *szKey, int iKeyLength)
2 {
3 char szPart1[15]; // [rsp+10h] [rbp-50h]
4 char szPart2[15]; // [rsp+20h] [rbp-40h]
5 char szPart3[15]; // [rsp+30h] [rbp-30h]
6 char szPart4[15]; // [rsp+40h] [rbp-20h]
7 unsigned __int64 v7; // [rsp+58h] [rbp-8h]
8
9 v7 = __readfsqword(0x28u);
10 *(_QWORD *)szPart1 = 0LL;
11 *(_DWORD *)&szPart1[8] = 0;
12 *(_WORD *)&szPart1[12] = 0;
13 szPart1[14] = 0;
14 *(_QWORD *)szPart2 = 0LL;
15 *(_DWORD *)&szPart2[8] = 0;
16 *(_WORD *)&szPart2[12] = 0;
17 szPart2[14] = 0;
18 *(_QWORD *)szPart3 = 0LL;
19 *(_DWORD *)&szPart3[8] = 0;
20 *(_WORD *)&szPart3[12] = 0;
21 szPart3[14] = 0;
22 *(_QWORD *)szPart4 = 0LL;
23 *(_DWORD *)&szPart4[8] = 0;
24 *(_WORD *)&szPart4[12] = 0;
25 szPart4[14] = 0;
26 if ( iKeyLength != 42 )
27 return 0;
28 if ( !szKey )
29 return 0;
30 if ( strlen(szKey) != 42 )
31 return 0;
32 if ( *szKey != 123 )
33 return 0;
34 strncpy(szPart1, szKey + 1, 0xAuLL); // 将输入去掉头尾{}后的部分分成4部分
35 strncpy(szPart2, szKey + 11, 0xAuLL);
36 strncpy(szPart3, szKey + 21, 0xAuLL);
37 strncpy(szPart4, szKey + 31, 0xAuLL);
38 memset(szKey, 0, iKeyLength);
39 *szKey = ‘{‘;
40 strcat(szKey, szPart3); // 分割后的部分重新组合
41 strcat(szKey, szPart4);
42 strcat(szKey, szPart1);
43 strcat(szKey, szPart2);
44 szKey[41] = ‘}‘;
45 return 1;
46 }

exp

 1 s1=‘53fc275d81‘
2 s4=‘4938ae4efd‘
3 # 3,4,1,2
4 ss=‘daf29f59034938ae4efd53fc275d81053ed5be8c‘
5 x=[]
6 for i in range(0,len(ss),10):
7 x.append(ss[i:i+10])
8 print(x)
9 print(‘{‘,‘‘.join((x[2],x[3],x[0],x[1])),‘}‘,sep=‘‘)
10
11 # [‘daf29f5903‘, ‘4938ae4efd‘, ‘53fc275d81‘, ‘053ed5be8c‘]
12 # {53fc275d81053ed5be8cdaf29f59034938ae4efd}

answer_to_everything

main.exe 打开

image-20201124165527869
image-20201124165527869

查壳

image-20201124165540233
image-20201124165540233

不是有效的PE文件 即不是window 平台运行的软件 猜测是linux

将main.exe拖入ida 32

image-20201124165553289
image-20201124165553289

得到信息 ELF64 for x86-64 elf即代表是在linux下运行的软件 64 代表 ida 32 分析不了这个 程序 得用ida 64 分析

所以现在拖入linux里 (ubuntu 64)

打开终端

然后查看 main.exe的权限 ls -a main.exe 然后显示

chmod a+x main.exe//变为可执行 //如果权限不够的话执行改命令 发现 -rwxrwxrwx此时有权限执行main.exe

000000
000000

然后输入命令 ./main.exe

显示

然后随便输入

然后提示 YOUSUCK//你真笨 猜测 这个程序 先输出一句话 Gimme 然后又输入东西 错误的话 输出 YOUFUCK 正确的话 输出我们想要的信息

接下来 将main.exe 拖入ida 64 查找 关键字符串 Gimme//因为很少直接看到了就不用再搜索了

双击 进去与之对应的代码段 可以看到

然后敲击键盘上的x键可查看那几个引用它了 敲击 X 键

点进去为一个函数

tab 反汇编

即明白了 我们在linux中应该输入42

然后他输出 Cipher from Bill \nSubmit without any tags\n#kdudpeh 猜测 kdudpeh 是我们想要的flag ISCC{kdudpeh} 提交错误 看题目注意到 sha1 以为是 sha1碰撞 后来发现是 shi1加密 获得flag为: flag{80ee2a3fe31da904c596d993f7f1de4827c1450a}