题目来源:
SharifCTF 2016
题目描述:
菜鸡发现这个程序偷偷摸摸在自己的机器上搞事情,它决定一探究竟
题目附件:
e3dd9674429f4ce1a25c08ea799fc027
题目思路:
动态调试,结合反编译代码找到flag
解题过程:
在010Editor 中打开该文件,看到magic number 是ELF,说明是Linux 下的可执行文件。放到ida64中,f5反编译,程序大概是把生成的flag,写入文件,放在/tmp/flag.txt 中,但最后又remove 了这个文件。
int __cdecl main(int argc, const char **argv, const char **envp){
char v3; // al
__int64 v5; // [rsp+0h] [rbp-40h]
int i; // [rsp+4h] [rbp-3Ch]
FILE *stream; // [rsp+8h] [rbp-38h]
char filename[8]; // [rsp+10h] [rbp-30h]
unsigned __int64 v9; // [rsp+28h] [rbp-18h]
v9 = __readfsqword(0x28u);
LODWORD(v5) = 0;
while ( (signed int)v5 < strlen(s) ){
if ( v5 & 1 )
v3 = 1;
else
v3 = -1;
*(&t + (signed int)v5 + 10) = s[(signed int)v5] + v3;
LODWORD(v5) = v5 + 1;
}
strcpy(filename, "/tmp/flag.txt");
stream = fopen(filename, "w");
fprintf(stream, "%s\n", u, v5);
for ( i = 0; i < strlen(&t); ++i ){
fseek(stream, p[i], 0);//fseek函数可改变读写文件的位置指针
fputc(*(&t + p[i]), stream);//从文件头开始,在p[i]的位置写入了一个字符
fseek(stream, 0LL, 0);
fprintf(stream, "%s\n", u);//从文件头开始,直接写入了一个字符串u, 双击u可以看到*
}
fclose(stream);
remove(filename);
return 0;
}
在remove之前F2下断点,在虚拟机中运行linux_server64,F9运行起来,输入对应ip,到/tmp目录下查看flag.txt文件,发现该文件加密了。
giantbranch@ubuntu:/tmp$ cat flag.txt
*********{*********************************
在for函数中,两次使用了fseek 函数。也就是说一共写入了两次,第一次写入flag,第二次写入*覆盖了原来的flag,想要获取真正的flag,关键在于26,27 行,循环了strlen(t)次,每次都是取一个字符输入到文件中。双击t,可以看到t 变量在data 段的地址为6010E0,ida安装python模块后,输入get_bytes(0x6010E1,50)得到flag,但是少个S
SharifCTF{b70c59275fcfa8aebf2d5911223c6589}