|
本帖最后由 SYSTEM-RAMOS 于 2025-1-15 22:38 编辑
1.攻防世界:re1
1.使用IDA打开,进入main函数,转为C代码,,可以看到,输入v9之后,与v5比较,判断我们输入的flag是否正确。分别进入if...else判断之后的输出,正确输出flag get.. 错误输出flag不太对呦...
进入ds:xmmword_413E34,将16进制转换为字符,进行倒序后得到FLAG
2.攻防世界:logmein 反编译器打开,将main函数转换为C语言代码,
- 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();
- }
复制代码 进入sub_4007F0();,通过第26行代码,我们了解到flag的获取通过对判断部分的代码进行修改,直接打印出正确字符,即可得到最终的密码:
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define BYTE unsigned char
- int main()
- {
- size_t v3; // rsi
- int i; // [rsp+3Ch] [rbp-54h]
- char s[360]; // [rsp+40h] [rbp-50h]
- int v6; // [rsp+64h] [rbp-2Ch]
- __int64 v7; // [rsp+68h] [rbp-28h]
- char v8[80]; // [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");
- printf("To continue, you must enter the correct password.\n");
- printf("Enter your guess: ");
- scanf("%s",s);
- v3 = strlen(s);
- if ( v3 < strlen(v8) )
-
- for ( i = 0; i < strlen(v8); ++i )
- {
- putchar((char)(*((BYTE*)&v7 + i % v6) ^ v8[i]));
- }
- return 0;
- }
复制代码
3.攻防世界:no-strings-attached
4.攻防世界:insanity
5.攻防世界:Hello, CTF
6.BUUCTF:[ACTF新生赛2020]easyre1.老规矩,IDA反编译。找到main函数:
2.找到关键语句:
3.点进_data_start__ 查看字符串,一点要注意上面的7Eh也是算进去的.
4.打开Hex View
5.写python脚本对flag进行解密
7.BUUCTF:[MRCTF2020]Xor
一样先反编译,再查密码的算法。红框圈出来的是重点,依靠位运算对flag进行计算。
直接用C++编写一个一模一样的算法,将逻辑运算替换:直接打印出计算后的字符串即可。
8.BUUCTF:[Zer0pts2020]easy strcmp
elf格式的64位程序,无壳
int64指的是64位有符号整型,fastcall是一种函数调用规定
按理来说main函数的写法上是只能有2个参数的,不知道为什么这里有3个
初看main函数的逻辑是输入的第一个参数和"zer0pts{CENSORED}"一样就成功了
所以直接把"zer0pts{CENSORED}"提交,错了。
看一下这些函数,名字格式是sub_xxx的函数时ida没能识别的函数,后面的数字是函数的起始地址
这里可以看到,init函数在main函数之前调用了,进去看看init函数干了什么
signed指的是有符号数,不写的情况下默认是signed。
db指的是1个字节,dw:2, dd:4, dq:8。
&off_200DF0的值应该是这个变量的地址,也就是上图中的0x200DF0
所以v4>0。
这里前面是把(&funcs_889 + i)解引用,解引用之后是一个函数地址,然后再把这个函数地址强制类型转化成函数,后面跟的(a1, a2, a3)是这个函数的参数。
这里for循环给的条件是i != v4,所以for循环里面不会调用sub_6A0,只会调用6E0和795这两个函数,6E0函数里面啥也没有,现在进到795里面去看一下。
off_201028的值设为了sub_6EA函数的地址,我们来看看off_201028里面存的原本是什么东西。
off_201028是函数表中的数据,原本存的是strcmp函数的地址,这么说来,main函数中,每次调用strcmp函数的时候,实际上调用的其实是sub_6EA函数,接下来好好看看sub_6EA中的内容。
首先i获取了输入的flag字符串的长度,然后把字符串的每8个字节作为一个整体,减去qword_201060数组中对应的8个字节,最后再执行qword_201090函数,返回结果,qword_201090的值在795函数中被赋值成了&strcmp,所以在减完之后的字符串要与"zer0pts{CENSORED}"相等,于是可以写这样一个脚本
|
|