最近这段时间除了再写iscc外(当然,我比较菜,会做的有限,但是也还是在学习的过程中)在其他时候,也是会写一点buuctf上的题的。在加上一点以前写的一部分,算下来也有20多道题,现在就统一记录一下吧,后面要是在刷题了,在往后面补充。
这道题其实不用多说,拿道题后,直接查壳,发现无壳,且是64位的,拖入IDA中Shift+F12就可以直接看到falg
其实大部分逆向的题,在最开始的地方还是很像的,这题依旧是查壳,
无壳,64位,用IDA打开Shift+F12
点击进入,然后跳转到交叉引用列表,然后F5查看伪代码
在这一部分伪代码中可以发现,Str2是有一定的问题的,点击跟进,发现
这一个很像我们要找的flag,但是提交的时候他是不对的,再回来仔细查看伪代码发现
这一行伪代码很有意思,我们对照ascll码表,发现111对应的是o,48对应的是0(它的意思就是如果Str2中有o,就把o替换成0),所以flag{hell0_w0rld}
还是查壳,感觉有点像例行公务一样,哈哈哈,还是一样,
没壳,64位,就直接拖入IDA 然后Shift+F12
直接点跟进,然后再进入交叉引用列表,F5查看伪代码
很明显伪代码的这一步这一步很重要,我们直接点击flag跟进,查找到
这个应该就是我们需要的flag,但是上次吃过亏,这次就再把伪代码仔细的看一遍
在看的过程中,你会发现这一步似曾相识,进一步解读就会得到真正的flag(将flag中的i(104)和r(114)替换成1(49))
flag如下flag{hack1ng_fo1_fun}
日常查壳
照样是无壳,32位,拖入IDA然后Shift+F12,得到
这一行其实就是我们要找的flag,只需要吧DBAPP换成flag就行了,当时我写出来的时候,也是很怀疑,然后搜了一下WP发现就是这样的flag{49d3c93df25caad81232130f3d2ebfad}
查壳,终于遇见一个有壳的了,我心甚慰:
UPX脱壳,应该都是知道的(如果不知道的话,网上找一找,还是很多的)
这个是32位的,就用32位进行脱壳
这个时候,在进行查壳,和上面有着很明显的区别
在拖入IDA然后shift+F12
操作还是那些,双击,然后进入交叉引用列表,F5查看伪代码
这题没有多余的花里胡哨,除了一个加壳的,其他都是基本操作flag{HappyNewYear!}
这道题,在附件解压后,发现附件是apk,就应该明白它是一道安桌逆向的题目,找到安桌逆向的工具,然后打开,就会发现flag
得到flag{7631a988259a00816deda84afb29430a}
这个题,刚开始的时候,我也是有点蒙的,不知道该咋写,然后我就把它后缀名给改了
然后再拖入IDA,Shift+F12,
点击跟进,进入交叉引用列表,然后F5查看伪代码,得到
在伪代码中global这很重要,点击跟进
编写脚本
s = ['f',0xA,'k',0xC,'w','&','O','.','@',0x11,'x',0xD,'Z',';','U',0x11,'p',0x19,'F',0x1F,'v','"','M','#','D',0xE,'g',6,'h',0xF,'G','2','O']
flag = 'f'#第一个字符不用进行异或运算
for i in range(1,len(s)):
if(isinstance(s[i],int)):#将数字转化为字符
s[i] = chr(s[i])
for i in range(1,len(s)):
flag += chr(ord(s[i]) ^ ord(s[i-1]))#a^b=c 等于 a^c=b
print(flag)
运行后结果如下flag{QianQiuWanDai_YiTongJiangHu}
依旧是先查壳,发现并没有加壳,
且发现其实32位的,拖入IDA,然后Shift+F12
直接点击跟进,查看交叉引用列表,然后F5查看伪代码
我么先查看一下Str2
是这么一串东东,很奇怪,然后在查看一下 sub_4110BE这个很重要
第一次点进去是这?然后再点击进入
void *__cdecl sub_411AB0(char *a1, unsigned int a2, int *a3)
{
int v4; // STE0_4
int v5; // STE0_4
int v6; // STE0_4
int v7; // [esp+D4h] [ebp-38h]
signed int i; // [esp+E0h] [ebp-2Ch]
unsigned int v9; // [esp+ECh] [ebp-20h]
int v10; // [esp+ECh] [ebp-20h]
signed int v11; // [esp+ECh] [ebp-20h]
void *Dst; // [esp+F8h] [ebp-14h]
char *v13; // [esp+104h] [ebp-8h]
if ( !a1 || !a2 )
return 0;
v9 = a2 / 3;
if ( (signed int)(a2 / 3) % 3 )
++v9;
v10 = 4 * v9;
*a3 = v10;
Dst = malloc(v10 + 1);
if ( !Dst )
return 0;
j_memset(Dst, 0, v10 + 1);
v13 = a1;
v11 = a2;
v7 = 0;
while ( v11 > 0 )
{
byte_41A144[2] = 0;
byte_41A144[1] = 0;
byte_41A144[0] = 0;
for ( i = 0; i < 3 && v11 >= 1; ++i )
{
byte_41A144[i] = *v13;
--v11;
++v13;
}
if ( !i )
break;
switch ( i )
{
case 1:
*((_BYTE *)Dst + v7) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[0] >> 2];
v4 = v7 + 1;
*((_BYTE *)Dst + v4++) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | 16 * (byte_41A144[0] & 3)];
*((_BYTE *)Dst + v4++) = aAbcdefghijklmn[64];
*((_BYTE *)Dst + v4) = aAbcdefghijklmn[64];
v7 = v4 + 1;
break;
case 2:
*((_BYTE *)Dst + v7) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[0] >> 2];
v5 = v7 + 1;
*((_BYTE *)Dst + v5++) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | 16 * (byte_41A144[0] & 3)];
*((_BYTE *)Dst + v5++) = aAbcdefghijklmn[((byte_41A144[2] & 0xC0) >> 6) | 4 * (byte_41A144[1] & 0xF)];
*((_BYTE *)Dst + v5) = aAbcdefghijklmn[64];
v7 = v5 + 1;
break;
case 3:
*((_BYTE *)Dst + v7) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[0] >> 2];
v6 = v7 + 1;
*((_BYTE *)Dst + v6++) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | 16 * (byte_41A144[0] & 3)];
*((_BYTE *)Dst + v6++) = aAbcdefghijklmn[((byte_41A144[2] & 0xC0) >> 6) | 4 * (byte_41A144[1] & 0xF)];
*((_BYTE *)Dst + v6) = aAbcdefghijklmn[byte_41A144[2] & 0x3F];
v7 = v6 + 1;
break;
}
}
*((_BYTE *)Dst + v7) = 0;
return Dst;
}
这很长啊,这道题我也是搞了好久才搞明白的,看了好久,忽然发现在下面一直都有这些字符串aAbcdefghijklmn然后点击跟进
然后,你就会发现,这其实是base64加密,接下来就是解密环节了,解密也需要仔细看一下代码
这一段很重要,解读如下
对我们输入的字符串,进行图中函数的变换,然后进行 for ( j = 0; j < v8; ++j ) Dest[j] += j;
然后和str2进行比较,相等就正确了!
直接上脚本
import base64
enc = 'e3nifIH9b_C@n@dH'
flag = ''
for i in range(0,len(enc)):
flag+=chr(ord(enc[i])-i)
flag=flag.encode()
print(base64.b64decode(flag))