CTF-All-In-One/doc/6.1.8_pwn_dctf2017_flex.md
2017-12-09 14:27:34 +08:00

16 KiB
Raw Blame History

6.1.8 pwn DCTF2017 Flex

下载文件

题目解析

$ file flex 
flex: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=30a1acbc98ccf9e8f4b3d1fc06b6ba6f0cbe7c9e, stripped
$ checksec -f flex 
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FORTIFY  Fortified Fortifiable  FILE
Partial RELRO   Canary found      NX enabled    No PIE          No RPATH   No RUNPATH   Yes      0               4       flex

随便玩一下,了解程序的基本功能:

$ ./flex 
1.start flexmd5
2.start flexsha256
3.start flexsha1
4.test security
0 quit
option:
1
FlexMD5 bruteforce tool V0.1
custom md5 state (yes/No)
No
custom charset (yes/No)
yes
charset length:
10
charset:
a
bruteforce message pattern:
aaaa

第四个选项很吸引人,但似乎没有发现什么突破点,而第一个选项可以输入的东西较多,问题应该在这里,查看该函数 sub.bruteforcing_start:_85f

 0x00401500      55             push rbp
|           0x00401501      4889e5         mov rbp, rsp
|           0x00401504      4883ec10       sub rsp, 0x10
|           0x00401508      e83bfcffff     call sub.FlexMD5_bruteforce_tool_V0.1_148
|           0x0040150d      e87dfaffff     call fcn.00400f8f
|           0x00401512      bf4f464000     mov edi, str.bruteforcing_start: ; 0x40464f ; "bruteforcing start:"
|           0x00401517      e8b4f6ffff     call sym.imp.puts           ; int puts(const char *s)
|              ; JMP XREF from 0x00401534 (sub.bruteforcing_start:_500)
|       .-> 0x0040151c      e88cfeffff     call sub.strlen_3ad         ; size_t strlen(const char *s)
|       :   0x00401521      85c0           test eax, eax
|       :   0x00401523      0f94c0         sete al
|       :   0x00401526      84c0           test al, al
|      ,==< 0x00401528      740c           je 0x401536
|      |:   0x0040152a      bf01000000     mov edi, 1
|      |:   0x0040152f      e83cf7ffff     call sym.imp.sleep          ; int sleep(int s)
|      |`=< 0x00401534      ebe6           jmp 0x40151c
|      |       ; JMP XREF from 0x00401528 (sub.bruteforcing_start:_500)
|      |       ; JMP XREF from 0x0040155d (sub.bruteforcing_start:_500 + 93)
|      `.-> 0x00401536      b800000000     mov eax, 0
|      ,==< 0x0040153b      eb22           jmp 0x40155f
       |:   0x0040153d      4883fa01       cmp rdx, 1                  ; 1
      ,===< 0x00401541      7408           je 0x40154b
      ||:   0x00401543      4889c7         mov rdi, rax
      ||:   0x00401546      e8f5f7ffff     call sym.imp._Unwind_Resume
      ||:      ; JMP XREF from 0x00401541 (sub.bruteforcing_start:_500 + 65)
      `---> 0x0040154b      4889c7         mov rdi, rax
       |:   0x0040154e      e8bdf7ffff     call sym.imp.__cxa_begin_catch
       |:   0x00401553      8b00           mov eax, dword [rax]
       |:   0x00401555      8945fc         mov dword [rbp - 4], eax
       |:   0x00401558      e8a3f7ffff     call sym.imp.__cxa_end_catch
       |`=< 0x0040155d      ebd7           jmp 0x401536                ; sub.bruteforcing_start:_500+0x36
|      |       ; JMP XREF from 0x0040153b (sub.bruteforcing_start:_500)
|      `--> 0x0040155f      c9             leave
\           0x00401560      c3             ret

函数 sub.FlexMD5_bruteforce_tool_V0.1_148

[0x00400d80]> pdf @ sub.FlexMD5_bruteforce_tool_V0.1_148 
/ (fcn) sub.FlexMD5_bruteforce_tool_V0.1_148 613
|   sub.FlexMD5_bruteforce_tool_V0.1_148 ();
|           ; var int local_124h @ rbp-0x124
|           ; var int local_120h @ rbp-0x120
|           ; var int local_18h @ rbp-0x18
|              ; CALL XREF from 0x00401508 (sub.bruteforcing_start:_500)
|           0x00401148      55             push rbp
|           0x00401149      4889e5         mov rbp, rsp
|           0x0040114c      53             push rbx
|           0x0040114d      4881ec280100.  sub rsp, 0x128
|           0x00401154      64488b042528.  mov rax, qword fs:[0x28]    ; [0x28:8]=-1 ; '(' ; 40
|           0x0040115d      488945e8       mov qword [local_18h], rax
|           0x00401161      31c0           xor eax, eax
|           0x00401163      bf47454000     mov edi, str.FlexMD5_bruteforce_tool_V0.1 ; 0x404547 ; "FlexMD5 bruteforce tool V0.1"
|           0x00401168      e863faffff     call sym.imp.puts           ; int puts(const char *s)
|           0x0040116d      bf64454000     mov edi, str.custom_md5_state__yes_No_ ; 0x404564 ; "custom md5 state (yes/No)"                                                            
|           0x00401172      e859faffff     call sym.imp.puts           ; int puts(const char *s)
|           0x00401177      488d85e0feff.  lea rax, [local_120h]
|           0x0040117e      be04000000     mov esi, 4
|           0x00401183      4889c7         mov rdi, rax
|           0x00401186      e8ebfcffff     call sub.read_e76           ; ssize_t read(int fildes, void *buf, size_t nbyte)
|           0x0040118b      488d85e0feff.  lea rax, [local_120h]
|           0x00401192      ba03000000     mov edx, 3
|           0x00401197      be7e454000     mov esi, 0x40457e           ; "yes"
|           0x0040119c      4889c7         mov rdi, rax
|           0x0040119f      e85cfaffff     call sym.imp.strncmp        ; int strncmp(const char *s1, const char *s2, size_t n)
|           0x004011a4      85c0           test eax, eax
|       ,=< 0x004011a6      755e           jne 0x401206
|       |   0x004011a8      c705f24f2000.  mov dword [0x006061a4], 1   ; [0x6061a4:4]=0
|       |   0x004011b2      bf82454000     mov edi, str.initial_state_0_: ; 0x404582 ; "initial state[0]:"
|       |   0x004011b7      e814faffff     call sym.imp.puts           ; int puts(const char *s)
|       |   0x004011bc      e884fdffff     call sub.atoi_f45           ; int atoi(const char *str)
|       |   0x004011c1      8905e94f2000   mov dword [0x006061b0], eax ; [0x6061b0:4]=0
|       |   0x004011c7      bf94454000     mov edi, str.initial_state_1_: ; 0x404594 ; "initial state[1]:"
|       |   0x004011cc      e8fff9ffff     call sym.imp.puts           ; int puts(const char *s)
|       |   0x004011d1      e86ffdffff     call sub.atoi_f45           ; int atoi(const char *str)
|       |   0x004011d6      8905d84f2000   mov dword [0x006061b4], eax ; [0x6061b4:4]=0
|       |   0x004011dc      bfa6454000     mov edi, str.initial_state_2_: ; 0x4045a6 ; "initial state[2]:"
|       |   0x004011e1      e8eaf9ffff     call sym.imp.puts           ; int puts(const char *s)
|       |   0x004011e6      e85afdffff     call sub.atoi_f45           ; int atoi(const char *str)
|       |   0x004011eb      8905c74f2000   mov dword [0x006061b8], eax ; [0x6061b8:4]=0
|       |   0x004011f1      bfb8454000     mov edi, str.initial_state_3_: ; 0x4045b8 ; "initial state[3]:"
|       |   0x004011f6      e8d5f9ffff     call sym.imp.puts           ; int puts(const char *s)
|       |   0x004011fb      e845fdffff     call sub.atoi_f45           ; int atoi(const char *str)
|       |   0x00401200      8905b64f2000   mov dword [0x006061bc], eax ; [0x6061bc:4]=0
|       |      ; JMP XREF from 0x004011a6 (sub.FlexMD5_bruteforce_tool_V0.1_148)
|       `-> 0x00401206      bfca454000     mov edi, str.custom_charset__yes_No_ ; 0x4045ca ; "custom charset (yes/No)"
|           0x0040120b      e8c0f9ffff     call sym.imp.puts           ; int puts(const char *s)
|           0x00401210      488d85e0feff.  lea rax, [local_120h]
|           0x00401217      be04000000     mov esi, 4
|           0x0040121c      4889c7         mov rdi, rax
|           0x0040121f      e852fcffff     call sub.read_e76           ; ssize_t read(int fildes, void *buf, size_t nbyte)
|           0x00401224      488d85e0feff.  lea rax, [local_120h]
|           0x0040122b      ba03000000     mov edx, 3
|           0x00401230      be7e454000     mov esi, 0x40457e           ; "yes"
|           0x00401235      4889c7         mov rdi, rax
|           0x00401238      e8c3f9ffff     call sym.imp.strncmp        ; int strncmp(const char *s1, const char *s2, size_t n)
|           0x0040123d      85c0           test eax, eax
|       ,=< 0x0040123f      0f858a000000   jne 0x4012cf
|       |   0x00401245      c705554f2000.  mov dword [0x006061a4], 1   ; [0x6061a4:4]=0
|       |   0x0040124f      bfe2454000     mov edi, str.charset_length: ; 0x4045e2 ; "charset length:"
|       |   0x00401254      e877f9ffff     call sym.imp.puts           ; int puts(const char *s)
|       |   0x00401259      e8e7fcffff     call sub.atoi_f45           ; int atoi(const char *str)
|       |   0x0040125e      8905ac4e2000   mov dword [0x00606110], eax ; [0x606110:4]=62
|       |   0x00401264      8b05a64e2000   mov eax, dword [0x00606110] ; [0x606110:4]=62
|       |   0x0040126a      3d00010000     cmp eax, 0x100              ; 256
|      ,==< 0x0040126f      7e22           jle 0x401293
|      ||   0x00401271      bf04000000     mov edi, 4
|      ||   0x00401276      e855faffff     call sym.imp.__cxa_allocate_exception
|      ||   0x0040127b      c70002000000   mov dword [rax], 2
|      ||   0x00401281      ba00000000     mov edx, 0
|      ||   0x00401286      be70616000     mov esi, obj.typeinfoforint ; 0x606170
|      ||   0x0040128b      4889c7         mov rdi, rax
|      ||   0x0040128e      e85dfaffff     call sym.imp.__cxa_throw
|      ||      ; JMP XREF from 0x0040126f (sub.FlexMD5_bruteforce_tool_V0.1_148)
|      `--> 0x00401293      bff2454000     mov edi, str.charset:       ; 0x4045f2 ; "charset:"
|       |   0x00401298      e833f9ffff     call sym.imp.puts           ; int puts(const char *s)
|       |   0x0040129d      8b056d4e2000   mov eax, dword [0x00606110] ; [0x606110:4]=62
|       |   0x004012a3      83c001         add eax, 1
|       |   0x004012a6      89c2           mov edx, eax
|       |   0x004012a8      488d85e0feff.  lea rax, [local_120h]
|       |   0x004012af      89d6           mov esi, edx
|       |   0x004012b1      4889c7         mov rdi, rax
|       |   0x004012b4      e8bdfbffff     call sub.read_e76           ; ssize_t read(int fildes, void *buf, size_t nbyte)
|       |   0x004012b9      488d85e0feff.  lea rax, [local_120h]
|       |   0x004012c0      4889c7         mov rdi, rax
|       |   0x004012c3      e8e8f9ffff     call sym.imp.strdup         ; char *strdup(const char *src)
|       |   0x004012c8      488905494e20.  mov qword str.ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789, rax ; [0x606118:8]=0x404508 str.ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
|       |      ; JMP XREF from 0x0040123f (sub.FlexMD5_bruteforce_tool_V0.1_148)
|       `-> 0x004012cf      bffb454000     mov edi, str.bruteforce_message_pattern: ; 0x4045fb ; "bruteforce message pattern:"
|           0x004012d4      e8f7f8ffff     call sym.imp.puts           ; int puts(const char *s)
|           0x004012d9      be00040000     mov esi, 0x400              ; 1024
|           0x004012de      bfc0616000     mov edi, 0x6061c0
|           0x004012e3      e836fcffff     call sub.read_f1e           ; ssize_t read(int fildes, void *buf, size_t nbyte)
|           0x004012e8      bfc0616000     mov edi, 0x6061c0
|           0x004012ed      e85ef9ffff     call sym.imp.strlen         ; size_t strlen(const char *s)
|           0x004012f2      8905a84e2000   mov dword [0x006061a0], eax ; [0x6061a0:4]=0
|           0x004012f8      c785dcfeffff.  mov dword [local_124h], 0
|              ; JMP XREF from 0x00401334 (sub.FlexMD5_bruteforce_tool_V0.1_148)
|       .-> 0x00401302      8b85dcfeffff   mov eax, dword [local_124h]
|       :   0x00401308      4863d8         movsxd rbx, eax
|       :   0x0040130b      bfc0616000     mov edi, 0x6061c0
|       :   0x00401310      e83bf9ffff     call sym.imp.strlen         ; size_t strlen(const char *s)
|       :   0x00401315      4839c3         cmp rbx, rax
|      ,==< 0x00401318      731d           jae 0x401337
|      |:   0x0040131a      8b85dcfeffff   mov eax, dword [local_124h]
|      |:   0x00401320      4898           cdqe
|      |:   0x00401322      0fb680c06160.  movzx eax, byte [rax + 0x6061c0] ; [0x6061c0:1]=0
|      |:   0x00401329      3c2e           cmp al, 0x2e                ; '.' ; 46
|     ,===< 0x0040132b      7409           je 0x401336
|     ||:   0x0040132d      8385dcfeffff.  add dword [local_124h], 1
|     ||`=< 0x00401334      ebcc           jmp 0x401302
|     ||       ; JMP XREF from 0x0040132b (sub.FlexMD5_bruteforce_tool_V0.1_148)
|     `---> 0x00401336      90             nop
|      |       ; JMP XREF from 0x00401318 (sub.FlexMD5_bruteforce_tool_V0.1_148)
|      `--> 0x00401337      8b85dcfeffff   mov eax, dword [local_124h]
|           0x0040133d      4863d8         movsxd rbx, eax
|           0x00401340      bfc0616000     mov edi, 0x6061c0
|           0x00401345      e806f9ffff     call sym.imp.strlen         ; size_t strlen(const char *s)
|           0x0040134a      4839c3         cmp rbx, rax
|       ,=< 0x0040134d      7522           jne 0x401371
|       |   0x0040134f      bf04000000     mov edi, 4
|       |   0x00401354      e877f9ffff     call sym.imp.__cxa_allocate_exception
|       |   0x00401359      c70000000000   mov dword [rax], 0
|       |   0x0040135f      ba00000000     mov edx, 0
|       |   0x00401364      be70616000     mov esi, obj.typeinfoforint ; 0x606170
|       |   0x00401369      4889c7         mov rdi, rax
|       |   0x0040136c      e87ff9ffff     call sym.imp.__cxa_throw
|       |      ; JMP XREF from 0x0040134d (sub.FlexMD5_bruteforce_tool_V0.1_148)
|       `-> 0x00401371      bf17464000     mov edi, str.md5_pattern:   ; 0x404617 ; "md5 pattern:"
|           0x00401376      e855f8ffff     call sym.imp.puts           ; int puts(const char *s)
|           0x0040137b      be21000000     mov esi, 0x21               ; '!' ; 33
|           0x00401380      bfc0656000     mov edi, 0x6065c0
|           0x00401385      e8ecfaffff     call sub.read_e76           ; ssize_t read(int fildes, void *buf, size_t nbyte)
|           0x0040138a      b800000000     mov eax, 0
|           0x0040138f      488b4de8       mov rcx, qword [local_18h]
|           0x00401393      6448330c2528.  xor rcx, qword fs:[0x28]
|       ,=< 0x0040139c      7405           je 0x4013a3
|       |   0x0040139e      e81df9ffff     call sym.imp.__stack_chk_fail ; void __stack_chk_fail(void)
|       |      ; JMP XREF from 0x0040139c (sub.FlexMD5_bruteforce_tool_V0.1_148)
|       `-> 0x004013a3      4881c4280100.  add rsp, 0x128
|           0x004013aa      5b             pop rbx
|           0x004013ab      5d             pop rbp
\           0x004013ac      c3             ret

0x004012b4 下断点,以检查溢出点:

gdb-peda$ x/s $rbp
0x7fffffffe3f0: "5A%KA%gA%6A%"
gdb-peda$ pattern_offset 5A%KA%gA%6A%
5A%KA%gA%6A% found at offset: 288

所以 rbp 的地址为 288 / 8 = 36

找到 libc 的 do_system 函数里的 one_gadget_rce地址为 0x00041ee7

|           0x00041ee7      488b056aff36.  mov rax, qword [0x003b1e58] ; [0x3b1e58:8]=0
|           0x00041eee      488d3d409313.  lea rdi, str._bin_sh        ; 0x17b235 ; "/bin/sh"
|           0x00041ef5      c70521253700.  mov dword [obj.lock_4], 0   ; [0x3b4420:4]=0
|           0x00041eff      c7051b253700.  mov dword [obj.sa_refcntr], 0 ; [0x3b4424:4]=0
|           0x00041f09      488d742430     lea rsi, [local_30h]        ; sym.lm_cache ; 0x30
|           0x00041f0e      488b10         mov rdx, qword [rax]
|           0x00041f11      67e8c9260800   call sym.execve

Exploit

完整的 exp 如下:


参考资料