XCTF-攻防世界CTF平台-Reverse逆向类——31hackme

Posted 大灬白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了XCTF-攻防世界CTF平台-Reverse逆向类——31hackme相关的知识,希望对你有一定的参考价值。

先用ExeinfoPE查壳查看文件信息:

是Linux ELF 64位文件,没有加壳
然后用IDA64打开文件,打开字符串窗口:

可以看到“Give me the password:”、“Congras\\n”、“Oh no!\\n”字符串,可能是程序输出的字符串,双击 “Give me the password:”找到它在数据段中存储的位置:

选中aGiveMeThePassw按X快捷键,找到使用该变量的地方:

跳转到函数中使用aGiveMeThePassw变量的地方:

尝试按F5反编译代码:

我们也可以先找到Linux ELF文件的start函数,程序启动都是从它开始的,它负责初始化一些环境变量之类的参数,然后调用main函数,main函数结束之后又会返回start函数:

其中sub_400F8E函数便是main函数所在的位置,其他函数都是main函数之前的初始化以及main函数之后的清除。
sub_400F8E函数中:

sub_407470((__int64)"Give me the password: ", a2);
sub_4075A0((__int64)"%s", v3);

sub_407470函数很像printf函数输出提示语句“Give me the password: ”,sub_4075A0函数则很像scanf函数获取我们的输入,注意的是sub_4075A0函数在我的IDA中刚开始F5反编译识别出来是:

sub_4075A0((__int64)"%s");

点进sub_4075A0函数查看之后返回又变成了

sub_4075A0((__int64)"%s", v3);

这里应该是IDA的反编译识别参数出了问题,也是IDA的F5反编译功能的弊端,它能给我们提供方便,但有时候也会给我们带来困扰误导我们。
查看源汇编代码:

可以看到sub_407470函数和sub_4075A0函数,都有edi和rsi两个参数。
再回到源代码的分析:

所以程序的逻辑就是:
1、输入的字符串保存在v3[136],长度i为22时就给BOOL变量v13赋值1,否则为0;(也就是说输入字符串的长度必须为22,否则下面v13的值就会为0输出“Oh no!”);
2、之后由v12从10递减到0控制10次循环,10次循环中每次v9通过sub_406D90()函数 % 22获得一个22以内的数,作为输入的字符数组和指定的字节数组byte_6B4270的下标;
3、然后由v10从0递增到v9+1控制v9次循环,v9次循环次循环中v11 = 1828812941 * v11 + 12345,经过v9次循环之后得到一个v11的值;
4、判断如果v8(字节数组byte_6B4270中下标v9的值)不等于v11异或v7(输入字符数组的值中下标v9的值),就会把v13的值变为0;
5、最后判断v13的值如果为1就输出"Congras\\n",如果为0就输出"Oh no!\\n"。
其中sub_406D90()函数是一个随机数发生器,随机产生一个伪随机数,sub_406D90() % 22得到的就是一个22以内的数,作为输入的字符数组和指定的字节数组byte_6B4270的下标。
也就是我们要输入一个长度为22的字符串,然后程序有10次循环,每次生成一个随机下标,从指定字节数组byte_6B4270中取出随机下标的字节v8,从输入的字符数组中取出随机下标的字符v7,以及经过随机下标次递归的v11,要求每次v8等于v7异或v11,就能通过判断输出"Congras\\n"。
所以我们要得到输入的字符串,只需要循环22次从0到21,每次把byte_6B4270[i]和每次计算得到的v11异或即可得到对应的输入的字符。
其中byte_6B4270[]的值:

直接在IDA中编写idc脚本,可以直接使用byte_6B4270[]的值
源代码flag.idc:

auto i;
auto v11 = 0;
auto v7;
for(i = 0;i < 22; ++i){
v11 = 1828812941 * v11 + 12345;
v7 = v11 ^ Byte(0x6B4270 + i);
Message("%s",v7);
}

运行截图:

得到falg是flag{d826e6926098ef46}
把byte_6B4270[]的值dump出来,C语言写的代码
flag.c:

#include<stdio.h>

int main()
{
    int byte_6B4270[] ={
    0x5F, 0xF2, 0x5E, 0x8B, 0x4E, 0x0E, 0xA3, 0xAA, 0xC7, 0x93,
    0x81, 0x3D, 0x5F, 0x74, 0xA3, 0x09, 0x91, 0x2B, 0x49, 0x28,
    0x93, 0x67, 0x00, 0x00
    };
    //输入的字符串
    int v7 = 0;
    int v11 = 0;
    int i;
	for(i=0;i<22;i++)
	{
        v11 = v11 * 1828812941 + 12345;
		v7 = byte_6B4270[i] ^ v11;
		printf("%c",v7);
	}
    return 0;
}

运行截图:

得到falg是flag{d826e6926098ef46}

以上是关于XCTF-攻防世界CTF平台-Reverse逆向类——31hackme的主要内容,如果未能解决你的问题,请参考以下文章

XCTF-攻防世界CTF平台-Reverse逆向类——53easyCpp

XCTF-攻防世界CTF平台-Reverse逆向类——65reverse-box

XCTF-攻防世界CTF平台-Reverse逆向类——59mfc逆向-200

XCTF-攻防世界CTF平台-Reverse逆向类——52handcrafted-pyc

XCTF-攻防世界CTF平台-Reverse逆向类——56tar-tar-binks

XCTF-攻防世界CTF平台-Reverse逆向类——54echo-server