前言
继续ctf的旅程
攻防世界Reverse高手进阶区的2分题
本篇是easyre-153的writeup
攻防世界的题目分数是动态的
就仅以做题时的分数为准了
解题过程
首先扔入exeinfope中查看信息,发现有upx壳:

扔进kali脱壳:

扔进IDA,F5,如下:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int pipedes[2]; // [esp+18h] [ebp-38h] BYREF
__pid_t v5; // [esp+20h] [ebp-30h]
int v6; // [esp+24h] [ebp-2Ch] BYREF
char buf[30]; // [esp+2Eh] [ebp-22h] BYREF
unsigned int v8; // [esp+4Ch] [ebp-4h]
v8 = __readgsdword(0x14u);
pipe(pipedes);
v5 = fork();
if ( !v5 )
{
puts("\nOMG!!!! I forgot kid's id");
write(pipedes[1], "69800876143568214356928753", 0x1Du);
puts("Ready to exit ");
exit(0);
}
read(pipedes[0], buf, 0x1Du);
__isoc99_scanf("%d", &v6);
if ( v6 == v5 )
{
if ( (unsigned __int8)*(_DWORD *)((char *)lol + 3) == 204 )
{
puts(":D");
exit(1);
}
printf("\nYou got the key\n ");
lol(buf);
}
wait(0);
return 0;
}
pipe函数的读元素和写元素如下:

fork函数:
- 在父进程中返回新创建子进程的进程ID
- 在子进程中返回0
- 如果出现错误返回一个负值
然后对fork的v5做个判断(是父还是子)
- 子进程就给管道写入
69800876143568214356928753 - 父进程就读取并复制到缓存
buf,然后进行两个判断,显然flag在lol
但是跟踪lol:

emmmm
搁这搁这的
感觉不太对
去看了眼汇编

这不是有东西的嘛
看了看问题在于jnz short loc_80486D3永恒跳转了
将jnz改为jz,即hex中75改成74


然后lol变为他原本的样子:

这显然是生成flag的逻辑
写成脚本就是了
key="69800876143568214356928753"
flag=""
flag+=chr(2*ord(key[1]))
flag+=chr(ord(key[4])+ord(key[5]))
flag+=chr(ord(key[8])+ord(key[9]))
flag+=chr(2*ord(key[12]))
flag+=chr(ord(key[18])+ord(key[17]))
flag+=chr(ord(key[10])+ord(key[21]))
flag+=chr(ord(key[9])+ord(key[25]))
print(flag)
得到flag:rhelheg
(提交的时候要加上RCTF{})
结语
汇编中有些小手脚
838

被折叠的 条评论
为什么被折叠?



