题目描述:菜鸡发现Flag似乎并不一定是明文比较的
用ida打开附件,然后F5查看伪代码
int __cdecl main(int argc, const char **argv, const char **envp) { signed int v3; // ebx char v4; // al int result; // eax int v6; // [esp+0h] [ebp-70h] int v7; // [esp+0h] [ebp-70h] char v8; // [esp+12h] [ebp-5Eh] char v9[20]; // [esp+14h] [ebp-5Ch] char v10; // [esp+28h] [ebp-48h] __int16 v11; // [esp+48h] [ebp-28h] char v12; // [esp+4Ah] [ebp-26h] char v13; // [esp+4Ch] [ebp-24h] strcpy(&v13, "437261636b4d654a757374466f7246756e");//复制字符 while ( 1 ) { memset(&v10, 0, 0x20u); v11 = 0; v12 = 0; sub_40134B(aPleaseInputYou, v6); scanf(aS, v9); if ( strlen(v9) > 0x11 )//如果长度过长则跳出循环 break; v3 = 0; do { v4 = v9[v3]; if ( !v4 ) break; sprintf(&v8, asc_408044, v4); strcat(&v10, &v8); ++v3; }//将输入的字符整成16进制,然后和v13比较 如果相同则得到答案 while ( v3 < 17 ); if ( !strcmp(&v10, &v13) ) sub_40134B(aSuccess, v7); else sub_40134B(aWrong, v7); } sub_40134B(aWrong, v7); result = stru_408090._cnt-- - 1; if ( stru_408090._cnt < 0 ) return _filbuf(&stru_408090); ++stru_408090._ptr; return result; }
将16进制转换为字符串
则v13的字符串解码为:CrackMeJustForFun,得到flag。
题目描述:菜鸡发现这个程序偷偷摸摸在自己的机器上搞事情,它决定一探究竟 用IDA打开附件,F5反编译为c语言代码int __cdecl main(int argc, const char **argv, const char **envp) { char v3; // al __int64 v5; // [rsp+0h] [rbp-40h] int i; // [rsp+4h] [rbp-3Ch] FILE *stream; // [rsp+8h] [rbp-38h] char filename[8]; // [rsp+10h] [rbp-30h] unsigned __int64 v9; // [rsp+28h] [rbp-18h] v9 = __readfsqword(0x28u);//变量定义初始化 LODWORD(v5) = 0; while ( (signed int)v5 < strlen(s) ) { if ( v5 & 1 ) v3 = 1; else v3 = -1; *(&t + (signed int)v5 + 10) = s[(signed int)v5] + v3; LODWORD(v5) = v5 + 1; }//定义flag的值 strcpy(filename, "/tmp/flag.txt"); stream = fopen(filename, "w"); fprintf(stream, "%s\n", u, v5); for ( i = 0; i < strlen(&t); ++i ) { fseek(stream, p[i], 0); fputc(*(&t + p[i]), stream); fseek(stream, 0LL, 0); fprintf(stream, "%s\n", u); }//将所得的值写入文件 fclose(stream); remove(filename); return 0; }
分析代码后,可以发现我们需要得到s和t的值,双击查看参数的值
.data:00000000006010A0 s db 'c61b68366edeb7bdce3c6820314b7498',0 .data:00000000006010A0 ; DATA XREF: main+25↑o .data:00000000006010A0 ; main+3F↑r .data:00000000006010C1 align 20h .data:00000000006010E0 public t .data:00000000006010E0 ; char t .data:00000000006010E0 t db 53h ; DATA XREF: main+65↑w .data:00000000006010E0 ; main+C9↑o ... .data:00000000006010E1 aHarifctf db 'harifCTF{????????????????????????????????}',0
则s的值为‘c61b68366edeb7bdce3c6820314b7498’,t的值为“0x53H+harifCTF{???}”,则t的值为SharifCTF{???}’。
改写中间十行生成flag的代码,输出flag即可
#include<stdio.h> #include<string.h> int main() { char v3; // al __int64 v5=0; // [rsp+0h] [rbp-40h] int i; // [rsp+4h] [rbp-3Ch] FILE *stream; // [rsp+8h] [rbp-38h] char filename[8]; // [rsp+10h] [rbp-30h] unsigned __int64 v9; // [rsp+28h] [rbp-18h] char s[] = "c61b68366edeb7bdce3c6820314b7498"; char t[] = "SharifCTF{????????????????????????????????}"; while ( (signed int)v5 < strlen(s) ) { if ( v5 & 1 ) v3 = 1; else v3 = -1; *(t + (signed int)v5 + 10) = s[(signed int)v5] + v3; v5++; } printf("%s",t); return 0; }题目描述:菜鸡开始学习逆向工程,首先是最简单的题目 使用IDA将其打开,使用shift f12打开string窗口,找出所有字符串
双击flag get进入IDA View-A图标架构,在这里查看程序的逻辑树形图。
定位其中地址00413E60后使用快捷键:CTRL X引用交叉列表。
F5进入伪代码后分析代码
int __cdecl main(int argc, const char **argv, const char **envp) { int v3; // eax __int128 v5; // [esp+0h] [ebp-44h] __int64 v6; // [esp+10h] [ebp-34h] int v7; // [esp+18h] [ebp-2Ch] __int16 v8; // [esp+1Ch] [ebp-28h] char v9; // [esp+20h] [ebp-24h] _mm_storeu_si128((__m128i *)&v5, _mm_loadu_si128((const __m128i *)&xmmword_413E34)); v7 = 0; v6 = qword_413E44; v8 = 0; printf(&byte_413E4C); printf(&byte_413E60); printf(&byte_413E80); scanf("%s", &v9); v3 = strcmp((const char *)&v5, &v9);//v5和v9进行字符串比较,v9为随意输入的值,v5为函数xmmword_413E34赋值的,找到函数xmmword_413E34的值即可 v3 = -(v3 < 0) | 1; if ( v3 ) printf(aFlag); else printf((const char *)&unk_413E90); system("pause"); return 0; }
双击函数后,发现其值后转为字符串,则得到flagDUTCTF{We1c0met0DUTCTF}。
题目描述:菜鸡听说有的程序运行就能拿Flag? 用IDA打开附件,F5查看伪代码int __cdecl main(int argc, const char **argv, const char **envp) { setlocale(6, &locale); banner(); prompt_authentication(); authenticate(); return 0; }
对每个函数进行跟进,发现authenricate(),符合获得flag的函数。
void authenticate() { wchar_t ws[8192]; // [esp+1Ch] [ebp-800Ch] wchar_t *s2; // [esp+801Ch] [ebp-Ch] s2 = (wchar_t *)decrypt(&s, &dword_8048A90);//decrypt,字面意思为加密。 if ( fgetws(ws, 0x2000, stdin) ) { ws[wcslen(ws) - 1] = 0; if ( !wcscmp(ws, s2) ) wprintf(&unk_8048B44); else wprintf(&unk_8048BA4); } free(s2); }
在authenticate函数的第七行设置断点,进入断点后查看s2的值
则可得flag: 9447{you_are_an_international_mystery}
题目描述:听说运行就能拿到Flag,不过菜鸡运行的结果不知道为什么是乱码 将程序放入IDA并在main函数下F5生成伪代码int __cdecl __noreturn main(int argc, const char **argv, const char **envp) { int v3; // ecx CHAR *lpMem; // [esp+8h] [ebp-Ch] HANDLE hHeap; // [esp+10h] [ebp-4h] hHeap = HeapCreate(0x40000u, 0, 0); lpMem = (CHAR *)HeapAlloc(hHeap, 8u, MaxCount + 1); memcpy_s(lpMem, MaxCount, &unk_409B10, MaxCount); if ( sub_40102A() || IsDebuggerPresent() )//如果在动态调试器中就进入判断运行,如果没有就直接弹窗显示乱码 { __debugbreak(); sub_401000(v3 + 4, lpMem); ExitProcess(0xFFFFFFFF); } MessageBoxA(0, lpMem + 1, "Flag", 2u); HeapFree(hHeap, 0, lpMem); HeapDestroy(hHeap); ExitProcess(0); }
对比IDA,则可以看出mov edx,[ebp+lpMem]对应的汇编指令地址,单步运行F8
则已经执行了mov指令,接下来调用call,F8继续执行,执行完,edx存的就是flag的地址
则flag是:flag{reversing_is_not_that_hard!}
题目描述:菜鸡想要走出菜狗设计的迷宫 用IDA打开附件,F5查看伪代码__int64 __fastcall main(__int64 a1, char **a2, char **a3) { const char *v3; // rsi signed __int64 v4; // rbx signed int v5; // eax char v6; // bp char v7; // al const char *v8; // rdi __int64 v10; // [rsp+0h] [rbp-28h] v10 = 0LL; puts("Input flag:"); scanf("%s", &s1, 0LL); if ( strlen(&s1) != 24 || (v3 = "nctf{", strncmp(&s1, "nctf{", 5uLL)) || *(&byte_6010BF + 24) != 125 )//进行判断,如果以nctf{开头则继续进行 { LABEL_22: puts("Wrong flag!"); exit(-1); } v4 = 5LL; if ( strlen(&s1) - 1 > 5 ) { while ( 1 ) { v5 = *(&s1 + v4); v6 = 0; if ( v5 > 78 ) { v5 = (unsigned __int8)v5; if ( (unsigned __int8)v5 == 79 ) { v7 = sub_400650((char *)&v10 + 4, v3); goto LABEL_14; } if ( v5 == 111 ) { v7 = sub_400660((char *)&v10 + 4, v3); goto LABEL_14; } } else { v5 = (unsigned __int8)v5; if ( (unsigned __int8)v5 == 46 ) { v7 = sub_400670(&v10, v3); goto LABEL_14; } if ( v5 == 48 ) { v7 = sub_400680(&v10, v3);//进行了四个判断,进入了四个函数 LABEL_14: v6 = v7; goto LABEL_15; } } LABEL_15: v3 = (const char *)HIDWORD(v10); if ( !(unsigned __int8)sub_400690(asc_601060, HIDWORD(v10), (unsigned int)v10) ) goto LABEL_22; if ( ++v4 >= strlen(&s1) - 1 ) { if ( v6 ) break; LABEL_20: v8 = "Wrong flag!"; goto LABEL_21; } } } if ( asc_601060[8 * (signed int)v10 + SHIDWORD(v10)] != 35 ) goto LABEL_20; v8 = "Congratulations!"; LABEL_21: puts(v8); return 0LL; }
bool __fastcall sub_400650(_DWORD *a1) { int v1; // eax v1 = (*a1)--; return v1 > 0; }
bool __fastcall sub_400660(int *a1) { int v1; // eax v1 = *a1 + 1; *a1 = v1; return v1 < 8; }
bool __fastcall sub_400670(_DWORD *a1) { int v1; // eax v1 = (*a1)--; return v1 > 0; }
bool __fastcall sub_400680(int *a1) { int v1; // eax v1 = *a1 + 1; *a1 = v1; return v1 < 8; }
我们输入的应该是'.','0','o','O',并以此来确定上下左右移动
从上往下以此追踪,可以发现这些函数会跳到lable15的位置,然后,对lable15分析,发现特殊的字符串
则其可能为一个8*8的迷宫
根据迷宫最后得到的flag: nctf{o0oo00O000oooo..OO}