晚上做几个简单的ctf逆向睡的更好
logmein
elf文件 ida看看main函数伪代码
void __fastcall __noreturn main(__int64 a1, char **a2, char **a3) { size_t v3; // rsi int i; // [rsp+3Ch] [rbp-54h] char s[36]; // [rsp+40h] [rbp-50h] int v6; // [rsp+64h] [rbp-2Ch] __int64 v7; // [rsp+68h] [rbp-28h] char v8[8]; // [rsp+70h] [rbp-20h] int v9; // [rsp+8Ch] [rbp-4h] v9 = 0; strcpy(v8, ":\"AL_RT^L*.?+6/46"); v7 = 28537194573619560LL; v6 = 7; printf("Welcome to the RC3 secure password guesser.\n", a2, a3); printf("To continue, you must enter the correct password.\n"); printf("Enter your guess: "); __isoc99_scanf("%32s", s); v3 = strlen(s); if ( v3 < strlen(v8) ) sub_4007C0(v8); for ( i = 0; i < strlen(s); ++i ) { if ( i >= strlen(v8) ) ((void (*)(void))sub_4007C0)(); if ( s[i] != (char)(*((_BYTE *)&v7 + i % v6) ^ v8[i]) ) ((void (*)(void))sub_4007C0)(); } sub_4007F0(); }
这里要看懂他的算法:
看到19行sacnf接收输入 然后v3为输入的长度v3 < strlen(v8)调用sub_4007C0函数传入v8
sub_4007C0:
接着看sub_4007F0
函数看完 26行左右就是flag的行
输入的字符要等于 经过处理的v7和v8的异或。
v7 int64 v7要转换为16进制然后在转换为字符串,而且字符是小端序,所以把得到的字符翻转然后和v8的每一位进行异或。
#include#include #include <string.h> #define BYTE unsigned char int main(int argc, char* argv[]) { unsigned int i; char v8[18] = ":\"AL_RT^L*.?+6/46"; __int64 v7 = 28537194573619560; int v6 = 7; char s[18] = ""; for (i = 0; i < strlen(v8); ++i) { s[i] = (char)(*((BYTE*)&v7 + i % v6)^v8[i]); } printf("%s\n", s); system("PAUSE"); return 0; }
re1
F5看看伪代码
将用户输入的flag存入v9,然后将v9和v5比较,如果值相同输出aFlag
既然需要比较flag,那正确的flag应该已经作为一个常量保存在程序内部,可以尝试直接查找flag
ida查看程序的字符串 有时候ida会把字符串当数据 所以这里直接查看hex view
game
看看有没得壳
打开程序,是一个小游戏,直接输入12345678就能直接拿到flag
在函数中搜索main
看main_0()
void __cdecl main_0() { signed int i; // [esp+DCh] [ebp-20h] int v1; // [esp+F4h] [ebp-8h] sub_13FA7BE(&unk_14AB110); sub_13FA7BE(&unk_14AB158); sub_13FA7BE(&unk_14AB1A0); sub_13FA7BE(&unk_14AB1E8); sub_13FA7BE(&unk_14AB230); sub_13FA7BE(&unk_14AB278); sub_13FA7BE(&unk_14AB2C0); sub_13FA7BE(&unk_14AB308); sub_13FA7BE(&unk_14AAFD0); sub_13FA7BE("| by 0x61 |\n"); sub_13FA7BE("| |\n"); sub_13FA7BE("|------------------------------------------------------|\n"); sub_13FA7BE( "Play a game\n" "The n is the serial number of the lamp,and m is the state of the lamp\n" "If m of the Nth lamp is 1,it's on ,if not it's off\n" "At first all the lights were closed\n"); sub_13FA7BE("Now you can input n to change its state\n"); sub_13FA7BE( "But you should pay attention to one thing,if you change the state of the Nth lamp,the state of (N-1)th and (N+1)th w" "ill be changed too\n"); sub_13FA7BE("When all lamps are on,flag will appear\n"); sub_13FA7BE("Now,input n \n"); while ( 1 ) { while ( 1 ) { sub_13FA7BE("input n,n(1-8)\n"); sub_13F9418(); sub_13FA7BE("n="); sub_13F96D4("%d", &v1); sub_13FA7BE("\n"); if ( v1 >= 0 && v1 <= 8 ) break; sub_13FA7BE("sorry,n error,try again\n"); } if ( v1 ) { sub_13F76D6(v1 - 1); } else { for ( i = 0; i < 8; ++i ) { if ( (unsigned int)i >= 9 ) j____report_rangecheckfailure(); byte_14D2E28[i] = 0; } } j__system("CLS"); sub_13F8054(); if ( byte_14D2E28[0] == 1 && byte_14D2E28[1] == 1 && byte_14D2E28[2] == 1 && byte_14D2E28[3] == 1 && byte_14D2E28[4] == 1 && byte_14D2E28[5] == 1 && byte_14D2E28[6] == 1 && byte_14D2E28[7] == 1 ) { sub_13F7AB4(); } } }
发现最后跳转的sub_13F7AB4()的函数可能有东西 跟进
int sub_457AB4(void) { return sub_45E940(); }
再跟进sub_45E940()
int sub_13FE940() { signed int i; // [esp+D0h] [ebp-94h] char v2; // [esp+DCh] [ebp-88h] char v3; // [esp+DDh] [ebp-87h] char v4; // [esp+DEh] [ebp-86h] char v5; // [esp+DFh] [ebp-85h] char v6; // [esp+E0h] [ebp-84h] char v7; // [esp+E1h] [ebp-83h] char v8; // [esp+E2h] [ebp-82h] char v9; // [esp+E3h] [ebp-81h] char v10; // [esp+E4h] [ebp-80h] char v11; // [esp+E5h] [ebp-7Fh] char v12; // [esp+E6h] [ebp-7Eh] char v13; // [esp+E7h] [ebp-7Dh] char v14; // [esp+E8h] [ebp-7Ch] char v15; // [esp+E9h] [ebp-7Bh] char v16; // [esp+EAh] [ebp-7Ah] char v17; // [esp+EBh] [ebp-79h] char v18; // [esp+ECh] [ebp-78h] char v19; // [esp+EDh] [ebp-77h] char v20; // [esp+EEh] [ebp-76h] char v21; // [esp+EFh] [ebp-75h] char v22; // [esp+F0h] [ebp-74h] char v23; // [esp+F1h] [ebp-73h] char v24; // [esp+F2h] [ebp-72h] char v25; // [esp+F3h] [ebp-71h] char v26; // [esp+F4h] [ebp-70h] char v27; // [esp+F5h] [ebp-6Fh] char v28; // [esp+F6h] [ebp-6Eh] char v29; // [esp+F7h] [ebp-6Dh] char v30; // [esp+F8h] [ebp-6Ch] char v31; // [esp+F9h] [ebp-6Bh] char v32; // [esp+FAh] [ebp-6Ah] char v33; // [esp+FBh] [ebp-69h] char v34; // [esp+FCh] [ebp-68h] char v35; // [esp+FDh] [ebp-67h] char v36; // [esp+FEh] [ebp-66h] char v37; // [esp+FFh] [ebp-65h] char v38; // [esp+100h] [ebp-64h] char v39; // [esp+101h] [ebp-63h] char v40; // [esp+102h] [ebp-62h] char v41; // [esp+103h] [ebp-61h] char v42; // [esp+104h] [ebp-60h] char v43; // [esp+105h] [ebp-5Fh] char v44; // [esp+106h] [ebp-5Eh] char v45; // [esp+107h] [ebp-5Dh] char v46; // [esp+108h] [ebp-5Ch] char v47; // [esp+109h] [ebp-5Bh] char v48; // [esp+10Ah] [ebp-5Ah] char v49; // [esp+10Bh] [ebp-59h] char v50; // [esp+10Ch] [ebp-58h] char v51; // [esp+10Dh] [ebp-57h] char v52; // [esp+10Eh] [ebp-56h] char v53; // [esp+10Fh] [ebp-55h] char v54; // [esp+110h] [ebp-54h] char v55; // [esp+111h] [ebp-53h] char v56; // [esp+112h] [ebp-52h] char v57; // [esp+113h] [ebp-51h] char v58; // [esp+114h] [ebp-50h] char v59; // [esp+120h] [ebp-44h] char v60; // [esp+121h] [ebp-43h] char v61; // [esp+122h] [ebp-42h] char v62; // [esp+123h] [ebp-41h] char v63; // [esp+124h] [ebp-40h] char v64; // [esp+125h] [ebp-3Fh] char v65; // [esp+126h] [ebp-3Eh] char v66; // [esp+127h] [ebp-3Dh] char v67; // [esp+128h] [ebp-3Ch] char v68; // [esp+129h] [ebp-3Bh] char v69; // [esp+12Ah] [ebp-3Ah] char v70; // [esp+12Bh] [ebp-39h] char v71; // [esp+12Ch] [ebp-38h] char v72; // [esp+12Dh] [ebp-37h] char v73; // [esp+12Eh] [ebp-36h] char v74; // [esp+12Fh] [ebp-35h] char v75; // [esp+130h] [ebp-34h] char v76; // [esp+131h] [ebp-33h] char v77; // [esp+132h] [ebp-32h] char v78; // [esp+133h] [ebp-31h] char v79; // [esp+134h] [ebp-30h] char v80; // [esp+135h] [ebp-2Fh] char v81; // [esp+136h] [ebp-2Eh] char v82; // [esp+137h] [ebp-2Dh] char v83; // [esp+138h] [ebp-2Ch] char v84; // [esp+139h] [ebp-2Bh] char v85; // [esp+13Ah] [ebp-2Ah] char v86; // [esp+13Bh] [ebp-29h] char v87; // [esp+13Ch] [ebp-28h] char v88; // [esp+13Dh] [ebp-27h] char v89; // [esp+13Eh] [ebp-26h] char v90; // [esp+13Fh] [ebp-25h] char v91; // [esp+140h] [ebp-24h] char v92; // [esp+141h] [ebp-23h] char v93; // [esp+142h] [ebp-22h] char v94; // [esp+143h] [ebp-21h] char v95; // [esp+144h] [ebp-20h] char v96; // [esp+145h] [ebp-1Fh] char v97; // [esp+146h] [ebp-1Eh] char v98; // [esp+147h] [ebp-1Dh] char v99; // [esp+148h] [ebp-1Ch] char v100; // [esp+149h] [ebp-1Bh] char v101; // [esp+14Ah] [ebp-1Ah] char v102; // [esp+14Bh] [ebp-19h] char v103; // [esp+14Ch] [ebp-18h] char v104; // [esp+14Dh] [ebp-17h] char v105; // [esp+14Eh] [ebp-16h] char v106; // [esp+14Fh] [ebp-15h] char v107; // [esp+150h] [ebp-14h] char v108; // [esp+151h] [ebp-13h] char v109; // [esp+152h] [ebp-12h] char v110; // [esp+153h] [ebp-11h] char v111; // [esp+154h] [ebp-10h] char v112; // [esp+155h] [ebp-Fh] char v113; // [esp+156h] [ebp-Eh] char v114; // [esp+157h] [ebp-Dh] char v115; // [esp+158h] [ebp-Ch] sub_13FA7BE("done!!! the flag is "); v59 = 18; v60 = 64; v61 = 98; v62 = 5; v63 = 2; v64 = 4; v65 = 6; v66 = 3; v67 = 6; v68 = 48; v69 = 49; v70 = 65; v71 = 32; v72 = 12; v73 = 48; v74 = 65; v75 = 31; v76 = 78; v77 = 62; v78 = 32; v79 = 49; v80 = 32; v81 = 1; v82 = 57; v83 = 96; v84 = 3; v85 = 21; v86 = 9; v87 = 4; v88 = 62; v89 = 3; v90 = 5; v91 = 4; v92 = 1; v93 = 2; v94 = 3; v95 = 44; v96 = 65; v97 = 78; v98 = 32; v99 = 16; v100 = 97; v101 = 54; v102 = 16; v103 = 44; v104 = 52; v105 = 32; v106 = 64; v107 = 89; v108 = 45; v109 = 32; v110 = 65; v111 = 15; v112 = 34; v113 = 18; v114 = 16; v115 = 0; v2 = 123; v3 = 32; v4 = 18; v5 = 98; v6 = 119; v7 = 108; v8 = 65; v9 = 41; v10 = 124; v11 = 80; v12 = 125; v13 = 38; v14 = 124; v15 = 111; v16 = 74; v17 = 49; v18 = 83; v19 = 108; v20 = 94; v21 = 108; v22 = 84; v23 = 6; v24 = 96; v25 = 83; v26 = 44; v27 = 121; v28 = 104; v29 = 110; v30 = 32; v31 = 95; v32 = 117; v33 = 101; v34 = 99; v35 = 123; v36 = 127; v37 = 119; v38 = 96; v39 = 48; v40 = 107; v41 = 71; v42 = 92; v43 = 29; v44 = 81; v45 = 107; v46 = 90; v47 = 85; v48 = 64; v49 = 12; v50 = 43; v51 = 76; v52 = 86; v53 = 13; v54 = 114; v55 = 1; v56 = 117; v57 = 126; v58 = 0; for ( i = 0; i < 56; ++i ) { *(&v2 + i) ^= *(&v59 + i); *(&v2 + i) ^= 0x13u; } return sub_13FA7BE("%s\n"); }
这应该就是打印flag的函数了 这个两个57字节的变量进行循环打印异或 写个脚本 有点麻烦静态分析出来的
a=[18,64,98,5,2,4,6,3,6,48,49,65,32,12,48,65,31,78,62,32,49,32, 1,57,96,3,21,9,4,62,3,5,4,1,2,3,44,65,78,32,16,97,54,16,44, 52,32,64,89,45,32,65,15,34,18,16,0] b=[123,32,18,98,119,108,65,41,124,80,125,38,124,111,74,49, 83,108,94,108,84,6,96,83,44,121,104,110,32,95,117,101,99, 123,127,119,96,48,107,71,92,29,81,107,90,85,64,12,43,76,86, 13,114,1,117,126,0] i=0 c='' while (i<56): a[i]^=b[i] a[i]^=19 c=c+chr(a[i]) i=i+1 print (c)
Hello, CTF
打开 发现是输入然后比对
看看main函数
strcpy把那串字符串复制给v13地址
第36~39行代码是判断输入字符串和right serial是否匹配
将初始化v13的十六进制转换为字符串即可。
open-source
直接给的源码
第29行计算flag,第32行代码输出十六进制形式
printf("Brr wrrr grr\n"); unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207; printf("Get your key: "); printf("%x\n", hash); return 0;
然后看看我们需要满足的条件
if (argc != 4) { printf("what?\n"); exit(1); } unsigned int first = atoi(argv[1]); if (first != 0xcafe) { printf("you are wrong, sorry.\n"); exit(2); } unsigned int second = atoi(argv[2]); if (second % 5 == 3 || second % 17 != 8) { printf("ha, you won't get it!\n"); exit(3); } if (strcmp("h4cky0u", argv[3])) { printf("so close, dude!\n"); exit(4); }
first=0xcafe
second = 25
argv[3]=“h4cky0u”
ok 写个c++打印下flag
#include#include <string.h> int main(int argc, char* argv[]) { int first = 0xcafe; int second = 25; argv[3] = "h4cky0u"; printf("Brr wrrr grr\n"); unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207; printf("Get your key: "); printf("%x\n", hash); system("PAUSE"); return 0; }
simple-unpack
查壳
elf格式文件 upx壳
首先ida查看字符串直接可以找到
当然也可以
直接kali upx脱壳
打开脱壳后的 main函数