立聪堂德州十三局店 发表于 2024-6-14 21:29:09

CSAPP--ATTACKLAB实验

目录
一、实验步调
        二、目的程序
三、实验内容第一部分:代码注入攻击
3.1.        第一关
3.2.        第二关
3.3.        第三关
四.   实验内容第二部分:面向返回的编程
4.1.        第四关
4.2.        第五关
附录A HEX2RAW的利用
附录B 生成字节代码

一、实验步调

1.1       第一步:获取文件
在远程桌面中用浏览器访问网页:http://172.16.2.207:15513,输入你的学号和email地址,得到targetXXXX.tar文件。解压targetXXXX.tar文件(tar -xvf targetXXXX.tar)得到一个目录./targetXXXX,其中包含如下文件:
Ø  README.txt:描述本目录内容的文件。
Ø  ctarget:一个轻易遭受code-injection攻击的可执行程序。
Ø  rtarget:一个轻易遭受return-oriented-programming攻击的可执行程序。
Ø  cookie.txt:一个8位的十六进制码,是你的唯一标识符,用于验证身份。
Ø  farm.c:你的目的“gadget farm”的源代码,在产生return-oriented programming攻击时会用到。
Ø  hex2raw:一个生成攻击字符串的工具。
1.2       要点说明
Ø  要在我们提供的实验平台上完成该实验,我们不保证在其他平台上作出的效果能在我们的验证平台上成功执行。
Ø  你的解答不能绕开程序中的验证代码。也就是说,ret指令利用的攻击字符串中注入的地址必须是一下几种之一:
n  函数touch1,touch2或touch3的地址
n  你注入的代码的地址
n  gadget farm中gadget的地址
Ø  只能从文件rtarget中地址范围在函数start_farm和end_farm之间的地址构造gadget。
        二、目的程序

CTARGET和RTARGET都是用getbuf函数从标准输入读入字符串,getbuf函数定义如下:
1                unsigned getbuf()
2                {
3                                  char buf; 

4                                  Gets(buf); 

5                                  return 1; 

6                }
函数Gets类似于标准库函数gets,从标准输入读入一个字符串(以’\n’或者end-of-file结束),将字符串(带null结束符)存储在指定的目的地址。从这段代码可以看出,目的地址是数组buf,声明为BUFFER_SIZE个字节。BUFFER_SIZE是一个编译时常量,在你的target程序生成时就具体确定了。
     函数Gets()和gets()都无法确定目的缓冲区是否够大,能够存储下读入的字符串。它们都只会简单地拷贝字节序列,可能会超出目的地址处分配的存储空间的边界。
https://img-blog.csdnimg.cn/5e33b3bd3c79498a96e04d4f4b7c0b03.png

 
         如果用户输入和getbuf读入的字符串充足短,getbuf会返回1,如下执行示例所示:
         如果你输入的字符串很长,就会堕落:
https://img-blog.csdnimg.cn/365a39e8c85f4143ac574792e304fdb9.png
(注意cookie的值会每个人有所不同。)RTARGET程序有类似的活动。正如错误消息提示的那样,超出缓冲区巨细通常会导致程序状态被破坏,引起内存访问错误。你的任务是巧妙的计划输入给CTARGET和RTARGET的字符串,让它们做些更风趣的事情。这样的字符串称为攻击(exploit)字符串。
CTARGET和RTARGET有这样一些命令行参数:
-h:输出可能的命令行参数列表
-q:不向打分服务器发送效果
-i FILE:输入来自于文件FILE而不是标准输入
一般来说,你的攻击字符串包含的字节值并不都对应着能够打印出来的字符的ASCII值。HEX2RAW程序的利用见附录A。
要点说明:
·       你的攻击字符串不能包含字节值0x0a,这是换行符(’\n’)的ASCII代码。Gets碰到这个字节时会认为你意在结束该字符串。
·       HEX2RAW要求输入的十六进制值必须是两位的,值与值之间以一个或多个空缺分隔。如果你想得到一个十六进制值为0的字节,必须输入00。要得到字0xdeadbeef,必须向HEX2RAW输入“ef be ad de”(注意顺序相反是由于利用的是小端法字节序)。
 
本实验分为五个阶段,CTARGET的三个利用的是CI(code-injection),RTARGET的两个阶段利用的是ROP(return-oriented-programming),如图1所示。
阶段
程序
关数
方法
函数
分数
1
CTARGET
1
CI
touch1
10
2
CTARGET
2
CI
touch2
20
3
CTARGET
3
CI
touch3
20
4
RTARGET
2
ROP
touch2
35
5
RTARGET
3
ROP
touch3
15
图1. attack lab阶段小结

三、实验内容第一部分:代码注入攻击

3.1.        第一关

在这一关中,你不消注入新的代码,你的攻击字符串要指引程序去执行一个已经存在的函数。
CTARGET中函数test调用了函数getbuf,test的代码如下:
1 void test()
2 {
3     int val;
4     val = getbuf(); 
5     printf("No exploit.  Getbuf returned 0x%x\n", val);
6 }
getbuf执行返回语句时(getbuf的第5行),按照规则,程序会继承执行test函数中的语句,而我们想改变这个活动。在文件ctarget中,函数touch1的代码如下:
1 void touch1()
2 {
3     vlevel = 1;       /* Part of validation protocol */
4     printf("Touch1!: You called touch1()\n");
5     validate(1);
6     exit(0);
7 }
你的任务是让CTARGET在getbuf执行返回语句后执行touch1的代码。注意,你的攻击字符串可以破坏栈中不直接和本阶段相干的部分,这不会造成问题,由于touch1会使得程序直接退出。
要点说明:
·       计划本阶段的攻击字符串所需的信息都从检查CTARGET的反汇编代码中获得。用objdump -d进行反汇编。
·       重要思绪是找到touch1的起始地址的字节表示的位置,使得getbuf结尾处的ret指令会将控制转移到touch1。
·       注意字节顺序。
·       可能需要用GDB单步跟踪调试getbuf的末了几条指令,确保它按照你期望的方式工作。
·       buf在getbuf栈帧中的位置取决于编译时常数BUFFER_SIZE的值,以及GCC利用的分配战略。你需要检查反汇编带来来确定它的位置。
Test的汇编代码如下:
https://img-blog.csdnimg.cn/5fbf0983bd8b4dcf877b6f0150e68ac2.png
Sub $0x8,%rsp表明开发了8字节的栈空间
4018e8地址处调用了getbuf函数
将getbuf反编译后代码如下,
https://img-blog.csdnimg.cn/ce87460343da4cc9b30f61da66181d3a.png
Sub $0x28,%rsp表明开发了40字节的栈空间
因此此时的栈帧布局为:
https://img-blog.csdnimg.cn/2e663a063c0447b886a8c834a529bd64.png

看前面的任务,我们要让getbuf执行返回语句后,执行touch1的代码
也就是返回地址处应该改为touch1的值
检察touch1的地址为 0x40177b
因此解决办法即,让输入占满getbuf开发的40字节栈空间,并写入touch1的地址值。
https://img-blog.csdnimg.cn/b2f3a9255afa4fa0a88fb03f49b3d9f6.png
因此本题的答案如上图
执行,成功过了第一关
https://img-blog.csdnimg.cn/8bdb4e49d1d94ca787a4c6acf78a07ea.png

3.2.        第二关

第二关中,你需要在攻击字符串中注入少量代码。
在ctarget文件中,函数touch2的代码如下:
1 void touch2(unsigned val)
2 {
3     vlevel = 2;       /* Part of validation protocol */
4     if (val == cookie) {
5             printf("Touch2!: You called touch2(0x%.8x)\n", val);
6             validate(2);
7     } else {
8             printf("Misfire: You called touch2(0x%.8x)\n", val);
9             fail(2);
10    }
11    exit(0);
12 }
你的任务是使CTARGET执行touch2的代码而不是返回到test。在这个例子中,你必须让touch2以为它收到的参数是你的cookie。
建议:
·       需要确定你注入代码的地址的字节表示的位置,使getbuf代码末了的ret指令会将控制转移到那里。
·       注意,函数的第一个参数是放在寄存器%rdi中的。
·       你注入的代码必须将寄存器的值设定为你的cookie,然后利用ret指令将控制转移到touch2的第一条指令。
·       不要在攻击代码中利用jmp或call指令。所有的控制转移都要利用ret指令,纵然现实上你并不是要从一个函数调用返回。
·       参见附录B学习如何生成指令序列的字节级表示。
本关的任务相比第一关,多了一些操作。不但需要修改返回地址调用touch2函数,还需要将我们的cookie值作为参数传递给touch2
题目给出建议,不要在攻击代码中利用jmp和call指令,所有转移利用ret指令,因此我们的输入应该在栈中保存目的代码的地址,再利用ret进行跳转。

借用另一篇关于attacklab的实验报告的内容,关于ret指令有如下解释:
https://blog.csdn.net/qq_25591221/article/details/123301271?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166996863216800184131554%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166996863216800184131554&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-123301271-null-null.142^v67^control,201^v3^add_ask,213^v2^t3_esquery_v3&utm_term=attacklab&spm=1018.2226.3001.4187
https://img-blog.csdnimg.cn/b2580f00e4c946e3aeff07e2a8c4557d.png
因此,本题的重要思绪如下:
编写注入代码,跳转注入代码的地址并执行。

注入代码的作用如下:
起首肯定是通过字符串输入,将返回地址设置成touch2函数的地址
其次是设置第一个参数寄存器的值,将cookie传入调用touch2
经过检察,我的cookie值为:
0x479a8e36
Touch2代码的地址为:
0x4017a7
所以本题应该注入的代码内容为:
https://img-blog.csdnimg.cn/ecb0e7e6df544bb2ac1a18cba63843ed.png

之后应该确认存放注入代码的地址,在test调用完getbuf之后能够跳转到注入代码的存放位置,去执行我们的注入代码
我们发现,getbuf函数开发的40字节的栈空间可以用于存放我们的注入代码。
因此我们利用gdb在getbuf分配完栈帧后
打断点并检察栈指针的位置
https://img-blog.csdnimg.cn/396b6287904646ba93ed0bbdeb9f5931.png
因此,getbuf函数分配完空间以后,栈指针位置为0x5567fc18
这个地方是我们注入代码保存的位置,应该将返回地址修改成这个值
所以我们盼望将栈布局修改成这样
https://img-blog.csdnimg.cn/a63458a416284badbb285fbe775a95c2.png

本题的解决办法就此明晰,起首,通过将返回地址设置为注入代码的存放地址,执行注入代码。注入代码中,将cookie作为第一个参数寄存器的值,并将touch2的地址压入栈中,末了ret将touch2地址值取出并执行touch2

知道相识决的全过程,就要开始写我们的输入内容了。
起首,要将我们的注入汇编代码转化成16进制的字节级表示形式。
https://img-blog.csdnimg.cn/1a7f87d49b1541d491186ca7235d6cb6.pnghttps://img-blog.csdnimg.cn/34db579a2a494c80ae0a9f6e027840ca.png

我的做法是,将汇编代码保存在c2.s文件中
利用如下指令:
https://img-blog.csdnimg.cn/98b5e2b7822f4117997b0738d55db07c.png
这样会生成一个c2.o的文件,将其反编译
https://img-blog.csdnimg.cn/d92aaed0299f4936970dde876ebc1a46.png
打开c2.d,得到我们注入代码的字节级表示
https://img-blog.csdnimg.cn/e272a66824fd4b6999eafeec166268b1.png
这样就可以动手写输入了,终极的输入为:
https://img-blog.csdnimg.cn/bfb7de13785d447a9c78c876c383a1f2.png
成功,顺利通过第二关
https://img-blog.csdnimg.cn/ebb3ff3345894b7cba15f4f5235bb351.png

3.3.        第三关

第三阶段照旧代码注入攻击,但是是要传递字符串作为参数。
ctarget文件中函数hexmatch和touch3的C代码如下:
1 int hexmatch(unsigned val, char *sval)
2 {
3    char cbuf;
4    /* Make position of check string unpredictable */
5    char *s = cbuf + random() % 100;
6    sprintf(s, "%.8x", val);
7    return strncmp(sval, s, 9) == 0;
8 }
9
10 void touch3(char *sval)
11 {
12    vlevel = 3;       /* Part of validation protocol */
13    if (hexmatch(cookie, sval)) {
14     printf("Touch3!: You called touch3(\"%s\")\n", sval);
15     validate(3);
16    } else {
17     printf("Misfire: You called touch3(\"%s\")\n", sval);
18     fail(3);
19    }
20    exit(0);
21 }
你的任务是让CTARGET执行touch3而不要返回到test。要使touch3以为你传递你的cookie的字符串表示作为它的参数。
建议:
·       你的攻击字符串中要包含你的cookie的字符串表示。这个字符串由8个十六进制数字组成(顺序是从最高位到最低位),开头没有“0x”。
·       注意,C中的字符串表示是一个字节序列,末了跟一个值为0的字节。“man ascii”能够找到你需要的字符的字节表示。
·       你的注入代码应该将寄存器%rdi设置为攻击字符串的地址。
·       调用hexmatch和strncmp函数时,会将数据压入栈中,覆盖getbuf利用的缓冲区的内存,你需要很小心把你的cookie字符串表示放在哪里。
分析完第三关的要求,发现本题与第二关十分类似
区别在于,本题要求传入字符串,且字符串放置的位置需要考虑
起首将我们的cookie转化为字符串

https://img-blog.csdnimg.cn/e156fdf586864c2f9e07be46bbf2a01c.png
https://img-blog.csdnimg.cn/c1fbed0c55de45f5b2c064ab1335a86e.png
我的cookie值是0x479a8e36
转化为字符串后成为: 34 37 39 61 38 65 33 36

接下来,分析题目建议中一个比较奇怪的点
https://img-blog.csdnimg.cn/97b2df2668584edcb7bd55f08fd8cfde.png
这段话相当于把调用这两个函数对我们输入产生的限制告诉我们,我们如今不能将cookie放在getbuf的栈空间中了,一旦cookie被覆盖,那么就不能在调用touch3时比较出正确的效果。
不放在getbuf中,就很自然的想到可以放在test的栈空间中
若要放在test的栈空间中,就需要知道当test分配栈空间时,栈指针的位置:
https://img-blog.csdnimg.cn/fcf13236a68448da93862bb1cb240792.png
得知栈指针的位置为0x5567fc48
这个就是我们字符串存放的位置,即调用touch3应该传入参数的位置
因此,本题的栈布局应该是这样的
https://img-blog.csdnimg.cn/4f61afbc435b49bb8a3574bd5a9e89bb.png


注入代码应该为:
https://img-blog.csdnimg.cn/2f0ee3725ef447d8bf0d21970e97e004.png
字节级表示为: 

https://img-blog.csdnimg.cn/840631c883d3490e9e74af4b196c84ae.png
因此终极我们的输入为:
https://img-blog.csdnimg.cn/5d0d943859124287805e01f4b3d83327.png
运行,成功过关
https://img-blog.csdnimg.cn/04f602a45ec14f18b00b23d3423716e4.png

四.   实验内容第二部分:面向返回的编程

对程序RTARGET进行代码注入攻击要难一些,它采用了以下两种技术对抗攻击:
·       采用了随机化,每次运行栈的位置都不同。所以无法决定你的注入代码应该放在哪里。
·       将保存栈的内存区域设置为不可执行,所以纵然你能把注入的代码的起始地址放到程序计数器中,程序也会报段错误失败。
荣幸的是,聪明的人们计划了一些战略,通过执行现有程序中的代码来做他们期望的事情,而不是注入新的代码。这种方法称为面向返回的编程(ROP)。
比方,rtarget可能包含如下代码:
void setval_210(unsigned *p)
{
    *p = 3347663060U;
}
这个函数不太可能会攻击到一个系统,但是这段代码反汇编出来的机器代码是:
0000000000400f15 <setval_210>:
  400f15:       c7 07 d4 48 89 c7       movl   $0xc78948d4,(%rdi)
  400f1b:       c3                      retq
字节序列48 49 c7是指令movq %rax, %rdi的编码。图2A展示了一些有效的movq指令的编码。你的RTARGET的攻击代码由一组类似于setval_210的函数组成,我们称为gadget farm。你的工作是从gadget farm中挑选出有效的gadget执行类似于前述第二关和第三关的攻击。
要点说明:
函数start_farm和end_farm之间的所有函数构成了你的gadget farm。不要用程序代码中的其他部分作为你的gadget。
4.1.        第四关

在第四阶段,你将重复第二阶段的攻击,不过要利用gadget farm里的gadget来攻击RTARGET程序。你的答案只利用如下指令范例的gadget,也只能利用前八个x86-64寄存器(%rax-%rdi)。
movq:代码如图2A所示。
popq;代码如图2B所示。
ret:该指令编码为0xc3。
nop:该指令编码为0x90。
建议:
·       只能用两个gadget来实现该次攻击。
·       如果一个gadget利用了popq指令,那么它会从栈中弹出数据。这样一来,你的攻击代码能既包含gadget的地址也包含数据。
https://img-blog.csdnimg.cn/97d9bf22c839411899ea56f811df2050.png
图2. 指令的字节编码。所有的值均为十六进制。
本题的任务与第二关雷同,需要我们修改返回地址,调用touch2函数
第二关注入代码为:
https://img-blog.csdnimg.cn/4e0d0042d31f4b0a998544ab5775f576.png
但我们很轻易地发现,我们很难获取到一个含有立即数的gadget代码
因此只能思考其他的办法。
检察第四关建议中的一条,
https://img-blog.csdnimg.cn/35e010ba00e34d2797af5ea071fbffce.png
我们得到线索:只需要把数据和我们的popq指令编码一同输入进去就可以了
因此,我们可以通过将cookie数据和以下指令配合,
pop %rdi
ret
将我们的cookie放入第一个参数寄存器%rdi中,这样实现了参数的赋值
值得注意的是,题目有如是要求:
https://img-blog.csdnimg.cn/b54d3e4b2c37455086a42fae4de8ff4b.png
我们在提供的gadget farm中找不到可以直接表示pop %rdi ret的代码片断
因此,我们可以利用类似拼积木一样的方法,利用两个gadget完成任务
Popq %rax
Ret

Movq %rax,%rdi
Ret

此时我们盼望的栈布局为:
https://img-blog.csdnimg.cn/5cc1fc2eb69948009f8b7de6a76d28e2.png
 Getbuf函数返回后,执行我们插入的gadget1
它会将我们的cookie值弹出,存入%rax寄存器中后ret
接下来执行我们的gadget2,

它会将我们的cookie值从%rax转移到%rdi中,ret
Gadget2执行后的ret将弹出touch2函数的地址值
调用touch2函数

在写我们的输入内容之前,起首查表,找到我们用到的gadget
Gadget1:popq %rax
Ret
https://img-blog.csdnimg.cn/7425421a5dec40cbafb9ae341804f14b.png
https://img-blog.csdnimg.cn/742c8632414b4d73b6c778c8ffa50d84.png
地址值为0x40193a
Gadget2:movq %rax,%redi
              Ret
https://img-blog.csdnimg.cn/6a5ce017eeb44658861449beb93968b4.png
https://img-blog.csdnimg.cn/64c934712bad446caa72379afa647fb4.png
因此终极效果为:
https://img-blog.csdnimg.cn/d139e352c2fa4518bd7fc160ca08af42.png
成功通过第四关:
https://img-blog.csdnimg.cn/b7a171e545d74d7b998c8a92400a3d44.png

4.2.        第五关

阶段五要求你对RTARGET程序进行ROP攻击,用指向你的cookie字符串的指针,使程序调用touch3函数。
这一关,允许你利用函数start_farm和end_farm之间的所有gadget。除了第四阶段允许的那些指令,还允许利用movl指令(如图2C所示),以及图2D中的2字节指令,它们可以作为有功能的nop,不改变任何寄存器或内存的值,比方,andb %al, %al,这些指令对寄存器的低位字节做操作,但是不改变它们的值。
提示:
·       官方答案需要8个gadgets。
本题要我们传入cookie并调用touch3函数
第三关时,我们要注入的代码为:
https://img-blog.csdnimg.cn/97beb2bbc3ba411db9923e45079817bd.png


如今需要利用gadget来进行代替。
值得注意的是,题目告诉我们官方答案用了8个gadgets
https://img-blog.csdnimg.cn/ec0a468afbda493c91eb5279e1b3a99b.png
因此我们拼gadgets积木的时候,需要注意利用gadgets的个数
其中,0x5567fc48是在原来第三关中,cookie的地址
如今在本题中,栈的位置是随机的,我们这时候若要将cookie放在栈中,则没有办法通过绝对的地址访问到cookie,因此可以采取偏移量的计算方法,用相对地址访问。
计算相对地址需要利用%rsp寄存器保存的地址,因此想办法用gadget进行获取
由于要进行地址计算,而attacklab中给出的字节形式表格的指令只有mov,pop,ret和nop等指令,并没有lea用于计算
检察探求gadget的gadget farm,我们发现,有唯一加法函数:
https://img-blog.csdnimg.cn/f5ed08798bf441c2b5a7f02b5f6b6d8d.png
因此,我们只能利用这个函数进行计算,计算的操作数有%rdi,%rsi。效果放在%rax中
这肯定是8个gadgets中的一个,还要找7个
而计算的效果地址放在了%rax中,我们终极调用函数时,效果应当在%rdi第一个寄存器中
因此需要
Movq %rax,%rdi
Ret
这个gadget也是必须的,还差探求6个gadget

由于计算的操作数为栈指针位置和偏移量,操作数寄存器分别为%rdi和%rsi
所以,我们应当将栈指针位置取出,放到%rdi寄存器中
将偏移量取出,放到%rsi(%esi)寄存器中
注意,%rsi和%esi指向同一个寄存器,只不过利用的位数不同
偏移量利用32位表示即可,所以利用%esi来表示

起首,获取栈指针位置
需要利用movq %rsp,X取出寄存器的值
由于%rdi终极存放栈指针的位置参与加法运算,最理想的状态便是:
Movq %rsp,%rdi
查表可知,此时字节表示应该为:48 89 e7
但是在gadget farm中并没有找到满足条件的字节代码
因此,只能通过多次movq达到我们的目的
先考虑movq两次,达到我们的目的
将所有movq %rsp,A的字节表示列出
再将所有movq A,%rdi的字节表示列出
再此过程省略,得到了两条可以满足条件的gadget:
Movq %rsp,%rax
Ret
///
Movq %rax,%rdi
Ret
此时利用最少gadget达到将栈指针的位置放到了%rdi中
这两个gadget也是我们需要的8个gadget之二,还需要找4个gadget

计算相对地址的另一个操作数是%rsi,保存着地址偏移值
所以,地址偏移值是我们自己手动输入的,需要利用
popq %rax
ret
将其取出,它在%rax(%eax寄存器中)
这个gadget也是我们需要的8个gadget之一,还需要找3个gadget

后续的任务就是将%eax的值存放到%esi中,到场加法运算


[*]起首看是否可以一次mov达到目的
检察gadget farm中是否有
mov %eax,%esi
ret
效果是没有


[*]再看是否可以利用两次mov达到目的
检察gadget farm中是否有
mov %eax,A
ret

Mov A,%esi
Ret
效果也没有


[*]不要气馁,再看看是否可以利用3次mov达到目的
检察gadget farm中是否有
Mov %eax,A
Ret
/
Mov A,B
Ret
/
Mov B,%esi
Ret
探求的过程省略
终极能够找到这样的指令,
Mov %eax,%ecx
Ret
//
Mov %ecx,%edx
Ret
//
Mov %edx,%esi
Ret
这三条gadget是我们需要的,目前已经找到了所有的gadget啦
将找到的gadget进行排序,并标号①~⑧
https://img-blog.csdnimg.cn/fb9fa1d6d2b6402197cd6a08eea0ea11.jpeg
将栈布局画出来,利用标号表示gadget的具体内容
https://img-blog.csdnimg.cn/a2cb53eb5b0f44fc9333b73cc46e23ea.png
在栈空间示意图中,
计算得cookie的偏移量,相对于栈指针位置,
Cookie前面有9条指令,9*8=72=0x48
因此偏移量应该即0x48
终极得到的答案为:
https://img-blog.csdnimg.cn/ca1f40e7a35748b2841f0804d968086c.png
运行,顺利解决第五关
https://img-blog.csdnimg.cn/d11968d7747f496d8a78bf155d1676ad.png

附录A HEX2RAW的利用

HEX2RAW的输入是一个十六进制格式的字符串,用两个十六进制数字表示一个字节值。比方,字符串“012345”,必须输入“30 31 32 33 34 35 00”。十六进制字符之间以空缺符(空格或新行)分隔。
可以把攻击字符串存入文件中,比方exploit.txt,以下列几种方式调用:
1.      unix> cat exploit.txt | ./hex2raw | ./ctarget
2.      unix> ./hex2raw < exploit.txt > exploit-raw.txt
unix> ./ctarget < exploit-raw.txt
这种方法也可以结合gdb利用。
unix> gdb ctarget

(gdb) run < exploit-raw.txt
3.      unix> ./hex2raw < exploit.txt > exploit-raw.txt
unix> ./ctarget -i exploit-raw.txt
这种方法也可以和gdb一起利用。
附录B 生成字节代码

假设编写一个汇编文件example.s,代码如下:
# Example of hand-generated assembly code
pushq   $0xabcdef             # Push value onto stack
addq    $17,%rax              # Add 17 to %rax
movl    %eax,%edx                       # Copy lower 32 bits to %edx
可以汇编和反汇编文件:
unix> gcc -c example.s

unix> objdump -d example.o > example.d
生成的example.d包含如下内容:
example.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
   0: 68 ef cd ab 00                         pushq  $0xabcdef
   5: 48 83 c0 11                add    $0x11,%rax
   9: 89 c2                                   mov    %eax,%edx
由此可以推出这段代码的字节序列:
68 ef cd ab 00 48 83 c0 11 89 c2
可以通过HEX2RAW生成目的程序的输入字符串。也可以手动修改example.d的代码,得到下面的内容:
   68 ef cd ab 00   /* pushq  $0xabcdef  */
   48 83 c0 11     /* add    $0x11,%rax */
   89 c2          /* mov    %eax,%edx  */
这也是正当的HEX2RAW的输入。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: CSAPP--ATTACKLAB实验