1.010打开,直接搜flag,得到flag
二、reverse1
1.先查壳,得知是64位无壳,直接用IDA打开
2.shiftF12查找字符串,发现关键语句
3.查看相应代码,F5反编译
4.发现关键的比较函数,看一下分别比较的字符串
5.发现是输入的str1和程序中的str2({hello_world})相比较,那么flag就是{hello_world}
三.reverse2
1.查壳,64位,非exe
2.IDA打开,shift12发现关键语段
3.找到对应的函数,发现是一个将flag和输入的字符串进行对比
4.代码表现出了flag的加密过程,但是根据代码的判断应该会存在一个原flag字符串,回去查找字符串,发现了一个特殊意义的str
5.之前提到的flag加密代码的含义就是逐个遍历flag的字符,如果字符为i或者r,那就把它改为1。直接写个脚本跑一下(或者可直接手动)。
点击查看代码
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
int main() {
int i = 0;
char flag[] = "hacking_for_fun}";
for (i = 0; i <= 15; ++i)
{
if (flag[i] == 'i' || flag[i] == 'r')
flag[i] = '1';
}
printf("%s", flag);
return 0;
}
6.得到flag
flag{hack1ng_fo1_fun}
四.内涵的软件
1.查壳,无壳,IDA(非64位)打开,进入main函数,进入main_0函数
2.找到一串字符串,就是flag(改一下前面的头)
flag{49d3c93df25caad81232130f3d2ebfad}
五、新年快乐
1.查壳,发现是UPX
2.使用UPXshell解压缩去壳
3.IDA(非32位)打开,找到main函数,发现关键语句
4.根据比较函数发现,str2就是flag的正确形式,再看str2的来源,是使用了strcpy函数,那么flag就是HappyNewYear!
flag{HappyNewYear!}
六、xor
1.查壳,发现是64位无壳,使用IDA打开,找到main函数
2.代码的意思就是将首先判断长度是否为33,不是就failed,然后如果长度正确,就使用for循环由后一个异或前一个。找到原来的字符串
3.写个脚本,利用异或的特点,得到flag(需要注意到的是有一些字符本身就是ASCII码,不能再将其转为ASCII码,否则会异或出错)
点击查看代码
s = ['f','10','k','12','w','&','O','.','@','17','x','13','Z',';','U','17','p','25','F','31','v','"','M','#','D','14','g','6','h','15','G','2','O','0']
ls = []
for i in range(0,len(s)):
if len(s[i]) > 1 or s[i] == '6' or s[i] == '0':
ls.append(int(s[i]))
else:
ls.append(ord(s[i]))
for i in range(1,33):
print(chr(ls[i] ^ ls[i - 1]),end = '')
4.得到flag(直接异或得到的字符串前面少一个f)
flag{QianQiuWanDai_YiTongJiangHu}
七、helloword
1.得到一个apk文件,使用IDA打开,注意选择APK
2.shiftF12搜索字符串,发现flag
flag{7631a988259a00816deda84afb29430a}
八、reverse3
1.查壳,无壳,使用IDA(非64)打开
2.shift12搜索字符串,看到了base64和加密表以及关键词flag
3.追踪找到关键函数
4.关键函数代码审计一下,简单来说就是先将输入的str经过base64加密然后逐位与0123...相加,然后与str2进行比较,str2可以直接找到。直接写脚本逆回去
点击查看代码
str = "e3nifIH9b_C@n@dH"
s = list(str)
ls = ''
for i in range(len(s)):
ls += chr(ord(s[i]) - i)
print(base64.b64decode(ls))
5.运行后得到flag
flag{i_l0ve_you}
九、不一样的flag
1.查壳,无壳,使用IDA(非64)打开,shiftF12查找字符串
2.发现一串01串,觉得像迷宫题,进入到函数
3.果然是迷宫题,根据最后的输出语句可以得知flag就是走出迷宫的1234选择,根据exit()函数可以得知遇到1就退出,那就是从头走到尾同时只走0
4.01串一共是25个字符,那就是5x5的矩阵
5.直接目测,得到flag
222441144222
十、SimpleRev
1.查壳,无壳,使用IDA(64位)打开
2.shiftF12发现关键语句
3.找到关键的程序函数main函数中的Decry()函数
点击查看代码
unsigned __int64 Decry()
{
char v1; // [rsp+Fh] [rbp-51h]
int v2; // [rsp+10h] [rbp-50h]
int v3; // [rsp+14h] [rbp-4Ch]
int i; // [rsp+18h] [rbp-48h]
int v5; // [rsp+1Ch] [rbp-44h]
char src[8]; // [rsp+20h] [rbp-40h] BYREF
__int64 v7; // [rsp+28h] [rbp-38h]
int v8; // [rsp+30h] [rbp-30h]
__int64 v9[2]; // [rsp+40h] [rbp-20h] BYREF
int v10; // [rsp+50h] [rbp-10h]
unsigned __int64 v11; // [rsp+58h] [rbp-8h]
v11 = __readfsqword(0x28u);
*(_QWORD *)src = 0x534C43444ELL;
v7 = 0LL;
v8 = 0;
v9[0] = 0x776F646168LL;
v9[1] = 0LL;
v10 = 0;
text = (char *)join(key3, v9);
strcpy(key, key1);
strcat(key, src);
v2 = 0;
v3 = 0;
getchar();
v5 = strlen(key);
for ( i = 0; i < v5; ++i )
{
if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 )
key[i] = key[v3 % v5] + 32;
++v3;
}
printf("Please input your flag:");
while ( 1 )
{
v1 = getchar();
if ( v1 == 10 )
break;
if ( v1 == 32 )
{
++v2;
}
else
{
if ( v1 <= 96 || v1 > 122 )
{
if ( v1 > 64 && v1 <= 90 )
{
str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;
++v3;
}
}
else
{
str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;
++v3;
}
if ( !(v3 % v5) )
putchar(32);
++v2;
}
}
if ( !strcmp(text, str2) )
puts("Congratulation!\n");
else
puts("Try again!\n");
return __readfsqword(0x28u) ^ v11;
}
4.代码审计,首先看比较函数,得知是将text和str2相比较,str2目前找不到相应的字符串,text是由 join(key3, (const char *)v9);组成,key3追踪可得是kills,v9在代码的前面部分,查看十六进制可以看出是大端序存储的,但是在CPU和x86中一般为小端序存储,那么原本的字串就是IDA中转为char后倒转一下
5.所以src = NDCLS , v9 = hadow,再查看join函数的源码,可以看出作用就是将key3和v9连接在一起
6.所以text=killshadow,接着向下,strcpy(key, key1),key1=ADSFK,将key1复制为key,key=key1=ADSFK;strcat(key, src),将key和src连接,key = ADSFKNDCLS;v5就是key的长度,为10,接下来for循环函数的作用就是判断字符是否为大写,如果为大写就将其变为小写
7.接下来就是主要的输入字串处理,而最后与text对比的str2仅由一句话决定str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97,text已经知道了,直接写脚本跑一下
点击查看代码
v3 = 0
key = 'adsfkndcls'
text = 'killshadow'
key = list(key)
text = list(text)
for i in range(10):
for j in range(128):
if (j < ord('A') or j > ord('Z')) or (j < ord('z') and j > ord('a')):
continue
if ((j - 39 - ord(key[v3 % 10]) + 97) % 26 + 97 == ord(text[i])):
print(chr(j),end='');
v3 += 1
break
8.需要注意,因为源码中的key在与str2比较前,经过一个函数转变全部为小写字母,所以写脚本时使用的key也应是小写字母
9.得到flag
KLDQCUDFZO