逆向工程实验——lab9(linux的elf文件逆向)

Posted 大灬白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逆向工程实验——lab9(linux的elf文件逆向)相关的知识,希望对你有一定的参考价值。

将bomb拖入linux虚拟机,赋权限4755之后运行:
在这里插入图片描述

再用IDA打开bomb:
在这里插入图片描述

第一关:

在这里插入图片描述

主要目的就是将输入的字符串和Public speaking is very easy.比较。
在这里插入图片描述

所以我们输入Public speaking is very easy.即可过关:
在这里插入图片描述

第二关:

在这里插入图片描述

第二关就是将输入的字符串转换成长度为6的数组:
因为数组的第一个数字如果不为1就爆炸:
在这里插入图片描述

所以字符串的第一个数字为1
又因为v3[v1]不等于result的值就爆炸:
在这里插入图片描述

所以接下来的v3[v1]都等于result = v3[v1 - 1] * (v1 + 1),分别为:2 6 24 120 720。
所以第二关的通关密码为:1 2 6 24 120 720
在这里插入图片描述

第三关:

在这里插入图片描述

打开第三关的函数,发现是要输入一个数、一个字母、一个数
其中输入的第一个数v3负责控制switch跳转:每个switch跳转都有对应的v2和第三个数v5的值,
最后第二个字母v4又必须等于v2
在这里插入图片描述

所以第三关的密码v3、v4、v5有多种对应关系:
0 q 777
1 b 214
2 b 755
3 k 251
4 o 160
5 t 458
6 v 780
7 b 524
输入0 q 777,结果正确:
在这里插入图片描述

输入7 b 524,结果正确:
在这里插入图片描述

第四关:

在这里插入图片描述

第四关输入的是一个数字,之后这个数字作为实参传入func4函数,使得它的返回值为55即可通关。
func4函数:
在这里插入图片描述

进行递归运算,所以我们的目的就是使它的返回值为55。
又返回值result = func4(a1 - 1) + func4(a1 - 2);
所以func4(1) = 1,func4(2) = 2,func4(3) = 3,func4(4) = 5,func4(5) = 8,func4(6) = 13,func4(7) = 21,func4(8) = 34,func4(9) = 55,
所以第四关输入的数字为9:
在这里插入图片描述

第五关:

在这里插入图片描述

首先输入的字符长度为6,之后输入的字符的每一位*(_BYTE *)(v1 + a1)& 0xF低四位即作为数组array_123“isrveawhobpnutfg”的下标,从数组中取值赋给v3[v1]
在这里插入图片描述

之后比较v3和字符串 "giants"是否相等。所以我们通过控制输入的数,来使得v3等于giants
所以array_123“isrveawhobpnutfg”的下标必须依次为:15、0、5、11、13、1
对应输字母可以为:
第一个:/或者?或O或_或o
第二个:空格或0或@或P或`或p
第三个:%或5或E或U或e或u
第四个:+或;或K或[或k或{
第五个:-或=或M或]或m或}
第六个:!或1或A或Q或a或q
在这里插入图片描述

第六关:

在这里插入图片描述

首先判断输入的要求是6个数字,且小于7相邻两个数字大小不相等:
在这里插入图片描述

之后根据输入的数字大小作为&node1地址的指针,再将v4[2]即node1的第三个字节的内容赋值给v4指针,再存放在v13[v3++]数组中:
在这里插入图片描述

之后将v13[v7++]数组中的值取出来赋给v8,再放到*(v6+8)即(v13[0]地址、node1地址后的第八位)上,其实就是根据地址重新排列成一条新的对应的node数据链:
在这里插入图片描述

形成链之后 *(_DWORD *)(v8 + 8) = 0;将链尾赋为0,形成一个长度为6的链
在这里插入图片描述

之后v9对链中的值取前四个字节前后两两比较,如果前面的值比后面的小就退出
在这里插入图片描述

所以我们的目的是将node链中的每个值的前四个字节:00 00 00 FD、00 00 02 D5、00 00 01 2D、00 00 03 E5、00 00 00 D4、00 00 01 B0,按照从大到小排序:4 2 6 3 1 5
所以第六关的密码就是4 2 6 3 1 5
在这里插入图片描述

第七关-隐藏关:

在这里插入图片描述

隐藏关开启步骤:
在这里插入图片描述

发现开启隐藏关必须使num_input_strings等于6,并且还得输入一个字符串满足 数字+”austinpowers”
首先去找num_input_strings在哪儿进行改变
在这里插入图片描述

发现每一次read_line()之后就会进行加一的操作,所以我们必须通过前六关之后才能进入这个if里。
接下来就是去找符合条件的字符串我们用GDB进行调试,在这里的
在这里插入图片描述

0x804954e处下断点然后在第六关通过之后断点断到这个地方的时候我们去打印出对应的字符串。
在这里插入图片描述

发现这个进行判断的字符串就是我们第四关输入的字符串,所以我们第四关的字符串如果输入为9austinpowers即可进入隐藏关
在这里插入图片描述

如图所示成功进入隐藏关卡
进入隐藏关之后,输入的值就进入了secret_phase()函数:
在这里插入图片描述

secret_phase()函数先是读取输入的值,然后经过一个api函数__strtol_internal处理,得到的结果v1不能大于0x3E8+1(1001),不然就会退出程序。
之后就是调用fun7函数,其中第一个参数n1的值为:
在这里插入图片描述

v1作为第二个实参,之后如果func7函数的返回值不是7就会退出程序:
在这里插入图片描述

在IDA7.0反编译的fun7函数伪代码:
在这里插入图片描述

所以第七关的目的就是输入一个数,经过fun7函数得到返回值为7。因为fun7函数是个根据输入的数来不断递归的递归函数,所以我们不能直接逆向由7计算处输入的数;前面要求了输入的值不能大于1001,所以我们就可以尝试0-1001暴力破解。
在IDA中直接运行idc脚本暴力破解(把n1的值dump出来用其他语言的代码暴力破解也是一样的):

#include<idc.idc>

static main(){
    //主函数
    auto test = fun7(0x804B320,1001);
    auto i;
    for(i = 0;i <= 1001; ++i){
        auto temp = fun7(0x804B320,i);
        if(temp == 7){
            print(i);
        }
    }   
}

static fun7(a1,a2)
{
    if ( !a1 )
        return -1;
    if ( a2 < Dword(a1) ){
        return 2 * fun7(Dword(a1 + 4), a2);
}
    if ( a2 == Dword(a1) )
        return 0;
    return 2 * fun7(Dword(a1 + 8), a2) + 1;
}

代码运行结果:
在这里插入图片描述

得到v1为1001时,返回值为7。
我们把1001输入第七关:
在这里插入图片描述

Get!

以上是关于逆向工程实验——lab9(linux的elf文件逆向)的主要内容,如果未能解决你的问题,请参考以下文章

IDF实验室-简单的ELF逆向 writeup

Android 逆向ELF 文件格式 ( ELF 文件简介 | ELF 文件结构 )

Android 逆向ELF 文件格式 ( ELF 文件简介 | ELF 文件结构 )

软件安全实验——lab9(缓冲区溢出:return-to-libc绕过非可执行堆栈)

实验吧逆向catalyst-system Writeup

Linux应用程序的装载和执行