攻防世界-4th-WHCTF-2017-EASYHOOK

感觉好久没刷CTF的题了,今天啥也不干刷点题减轻一下罪恶感哈哈

EASYHOOK

image

32位程序,没有壳,拖到 IDA 中 f5,查看主函数逻辑,发现只要输入的长度为19,它就会把我们的输入保存在名为Your_Input的文件中,且判断逻辑的结果保存在NumberOfBytesWritten中。
image
因为sub_401240函数操作了BufferNumberOfBytesWritten,以为它是检验算法,但是点进去看了半天也看不出什么名堂。。。

image
试着运行一下程序,随便输入 1234567890123456789,打开程序创建并写入我们输入字符串的文件 Your_input,发现并不是我们的输入:

image

然而在这个程序中,文件写入部分看上去并没有对我们的输入做任何操作:

image

联想题目名称 EasyHOOK ,猜测一定是 sub_401220() 这个函数 HOOK 了其他函数,点击进入该函数:

image

果然,这个函数逻辑清晰地找到了库函数 WriteFile 的地址,向 byte_40C9BC 中载入了 JUMP 指令的字节码 E9,计算了 sub_401080 距离 WriteFile 的第五个字节的距离。至于为什么是 5 个字节,那是因为 JUMP Address(32 bit) 指令有五个字节。

准备工作做完,进入 sub_4010D0 函数,WriteProcessMemory 函数将这五个字节的指令写入 WriteFile 函数的开始处,HOOK成功。

image

进入 sub_401080 ,在 sub_401000 函数加密完 lpBuffer 后,sub_401140 又把 WriteFile 函数还原,继续写操作。

image

进入加密函数 sub_401000

image

写出逆算法脚本:

#include <stdio.h>
unsigned char res[] = {
    0x61, 0x6A, 0x79, 0x67, 0x6B, 0x46, 0x6D, 0x2E,
    0x7F, 0x5F, 0x7E, 0x2D, 0x53, 0x56, 0x7B, 0x38,
    0x6D, 0x4C, 0x6E, 0x00};
char flag[19];
int main()
{
    for (int i = 18; i >= 0; i--)
    {
        if (i == 18)
            flag[i] = res[i] ^ 0x13;
        else
        {
            if (i % 2){
                flag[i] = (res[i] ^ i) + i;
            }else{
                flag[i+2] = (res[i] ^ i);
            }
        }
    }
    for (int i = 1; i < 19; i++)
        printf("%c", flag[i]);
}

得到 flag。

image

posted @ 2022-03-09 22:31  oneQuiz  阅读(225)  评论(1)    收藏  举报