BUUCTF_REVERSE_学习日记
7.2
1.easyre
拖入DIE中,发现是64位的,无壳
用ida64打开,按F5反编译,flag是flag{this_Is_a_EaSyRe}
- IDA中按F5反编译
- DIE查看位数以及壳信息
2.reverse1
依然是先拖入DIE中,发现是64位,无壳
在ida64中打开,按< SHIFT + F12 >查看所有可打印字符,发现有"this is the right flag"
双击后,按< ctrl + X >查看该字符串引用,按< F5 >进行反编译,
伪码显示如下:
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
char *v3; // rdi
__int64 i; // rcx
size_t v5; // rax
char v7; // [rsp+0h] [rbp-20h] BYREF
int j; // [rsp+24h] [rbp+4h]
char Str1[224]; // [rsp+48h] [rbp+28h] BYREF
__int64 v10; // [rsp+128h] [rbp+108h]
v3 = &v7;
for ( i = 82i64; i; --i )
{
*(_DWORD *)v3 = -858993460;
v3 += 4;
}
for ( j = 0; ; ++j )
{
v10 = j;
if ( j > j_strlen(Str2) )
break;
if ( Str2[j] == 'o' )
Str2[j] = 48;
}
sub_1400111D1("input the flag:");
sub_14001128F("%20s", Str1);
v5 = j_strlen(Str2);
if ( !strncmp(Str1, Str2, v5) )
sub_1400111D1("this is the right flag!\n");
else
sub_1400111D1("wrong flag\n");
return 0;
}
分析代码,先打印了一个"input the flag"语句,然后读入一个字符串作为str1,之后将str1与str2进行比较,如果无差别就输出flag正确,所以现在需要找到str2,继续分析前面的代码,按< R >将ASCII码转化为字符
发现需要将’o’换成’0’,点击str2进去,发现str2是{hello_world}
于是flag就是flag{hell0_w0rld}
- < SHIFT + F12 >查看所有可打印的字符串
- < ctrl + X >查看目标字符串的引用情况
- < R >将ASCII码转化为字符
3.reverse2
依然是先拖入DIE中检测,发现是64位,无壳
在ida64中打开,依然是先< SHIFT + F12 >查看所有可打印字符串,发现关键语句"input the flag",于是双击后< ctrl + X >查看引用情况,按< F5 >反编译
int __cdecl main(int argc, const char **argv, const char **envp)
{
int stat_loc; // [rsp+4h] [rbp-3Ch] BYREF
int i; // [rsp+8h] [rbp-38h]
__pid_t pid; // [rsp+Ch] [rbp-34h]
char s2[24]; // [rsp+10h] [rbp-30h] BYREF
unsigned __int64 v8; // [rsp+28h] [rbp-18h]
v8 = __readfsqword(0x28u);
pid = fork();
if ( pid )
{
waitpid(pid, &stat_loc, 0);
}
else
{
for ( i = 0; i <= strlen(&flag); ++i )
{
if ( *(&flag + i) == 'i' || *(&flag + i) == 114 )
*(&flag + i) = 49;
}
}
printf("input the flag:");
__isoc99_scanf("%20s", s2);
if ( !strcmp(&flag, s2) )
return puts("this is the right flag!");
else
return puts("wrong flag!");
}
分析代码,发现flag就是要找的字符串,这里按< R >将ASCII码转化为字符,发现还需要将flag中的’i’和’r’换成’1’
于是flag就是flag{hack1ng_fo1_fun}
4.内涵的文件
首先依然是先在DIE中进行检测,发现是32位,无壳
在ida中打开,接下来的思路是一般思路,但是这道题不适用:
按< SHIFT + F12 >查看可打印字符串,发现flag字样
于是双击后按< ctrl + X >进入一个函数中,但是分析后发现这个函数中的flag仅仅只是作为一个判断条件,并没有更多有效的信息
于是我们直接在左边的函数窗口中点击进入main函数
在main函数中只有v5比较像flag,于是将v5作为flag提交就对了,于是flag就是flag{49d3c93df25caad81232130f3d2ebfad},也是比较草率
5.新年快乐
依旧是先拖入DIE中进行分析,发现是32位的,但是有upx壳(下方的红色字段可以判断)
这道题需要脱壳,我选用万能脱壳工具(可以参考这篇博客进行下载万能脱壳工具介绍-CSDN博客)
脱壳后在ida中打开,< SHIFT + F12 >查看所有可打印字符串,发现关键字句,双击后< ctrl + X >查看引用情况
随后< F5 >反编译,代码如下:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char Str2[14]; // [esp+12h] [ebp-3Ah] BYREF
char Str1[44]; // [esp+20h] [ebp-2Ch] BYREF
sub_401910();
strcpy(Str2, "HappyNewYear!");
*(_WORD *)Str1 = word_40306B;
memset(&Str1[2], 0, 0x1Eu);
printf("please input the true flag:");
scanf("%s", Str1);
if ( !strncmp(Str1, Str2, strlen(Str2)) )
return puts(aThisIsTrueFlag);
else
return puts(Buffer);
}
分析代码,发现是将str1与str2进行比较,如果相同就是正确的flag,也就是说str2就是flag,由前面的strcpy函数可以知道str2是"HappyNewYear!",于是flag就是flag{HappyNewYear!}
利用DIE查看是否有壳,再通过万能脱壳工具进行脱壳
6.xor
依然是先拖入DIE中检测,64位,无壳
于是在ida64中打开,按< SHIFT + F12 >找到关键字句
双击,按< ctrl + X >后找到引用地址,按< F5 >反编译,代码如下:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // [rsp+2Ch] [rbp-124h]
char __b[264]; // [rsp+40h] [rbp-110h] BYREF
memset(__b, 0, 0x100uLL);
printf("Input your flag:\n");
get_line(__b, 256LL);
if ( strlen(__b) != 33 )
goto LABEL_7;
for ( i = 1; i < 33; ++i )
__b[i] ^= __b[i - 1];
if ( !strncmp(__b, global, 0x21uLL) )
printf("Success");
else
LABEL_7:
printf("Failed");
return 0;
}
从下往上分析,将b与global这两个字符串进行比较,如果相同就正确,往上看,先是读入一个字符串b,然后将b(除第一个)后的所有字符一次进行异或操作(也是呼应了题目的xor)
现在的目标也就清晰了,找到global这个变量的值,编写程序,再做一遍xor得到原始输入的值就是flag,双击global后将光标放在‘aFKWOXZUPFVMDGH’处,发现有我们需要的值,于是继续双击跟进,点击‘aFKWOXZUPFVMDGH’并按< SHIFT + E >提取目标值
编写脚本进行异或运算,这里可以选择C语言或者python进行编写
str1=[ 102, 10, 107, 12, 119, 38, 79, 46, 64, 17,
120, 13, 90, 59, 85, 17, 112, 25, 70, 31,
118, 34, 77, 35, 68, 14, 103, 6, 104, 15,
71, 50, 79, 0]
str2=chr(str1[0])
i=1
for i in range(1,len(str1)):
str2+=chr(str1[i]^str1[i-1])
print(str2)
于是得到flag{QianQiuWanDai_YiTongJiangHu}
< SHIFT + E >提取目标值
25, 70, 31,
118, 34, 77, 35, 68, 14, 103, 6, 104, 15,
71, 50, 79, 0]
str2=chr(str1[0])
i=1
for i in range(1,len(str1)):
str2+=chr(str1[i]^str1[i-1])
print(str2)
于是得到flag{QianQiuWanDai_YiTongJiangHu}
- ### 知识点:
< SHIFT + E >提取目标值