Cavern.sigma
Welcome to Cavern.sigma
# flag **先備知識** - basic assembly **知識點** - basic use of gdb - objdump - packer ``` Papa brought me a packed present! let's open it. Download : http://pwnable.kr/bin/flag This is reversing task. all you need is binary ``` 下載下來之後,先跑一下看看 ```shell $ ./flag I will malloc() and strcpy the flag there. take it. ``` 什麼輸入都沒有,就印這行字 代表我們可能要直接進去找flag `checksec`一下看看程式開了哪些保護 ```shell $ checksec flag [*] '/flag' Arch: amd64-64-little RELRO: No RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x400000) RWX: Has RWX segments Packer: Packed with UPX ``` 注意到最後面寫了個`Packer: Packed with UPX` 這個packer的中文叫做「殼」 這個運作原理我也搞不懂 總而言之,「殼」就是一層包在原本程式外面的東東 有些殼能減少程式的大小,有些能讓程式反編譯後解讀困難等等的 所以他這個`Packer: Packed with UPX` 意思就是外面有個UPX殼就對了 啊既然有殼,我們就解 UPX的網址放在這裡 [https://upx.github.io](https://upx.github.io) 想辦法搞到upx之後 ```shell $ upx -d flag Ultimate Packer for eXecutables Copyright (C) 1996 - 2017 UPX 3.94 Markus Oberhumer, Laszlo Molnar & John Reiser May 12th 2017 File size Ratio Format Name -------------------- ------ ----------- ----------- 883745 <- 335288 37.94% linux/amd64 flag Unpacked 1 file. ``` 現在殼拿掉了,我們可以用`objdump`這個指令來看看assembly `-M`指定語法(assembly大致上有兩種語法:intel跟AT&T,我習慣看intel) `-d`指定要看哪個檔案 ```shell $ objdump -M intel -d flag flag: file format elf64-x86-64 Disassembly of section .init: 00000000004002f8 <_init>: 4002f8: 48 83 ec 08 sub rsp,0x8 4002fc: e8 83 0d 00 00 call 401084 <call_gmon_start> 400301: e8 1a 0e 00 00 call 401120 <frame_dummy> 400306: e8 f5 49 09 00 call 494d00 <__do_global_ctors_aux> 40030b: 48 83 c4 08 add rsp,0x8 40030f: c3 ret Disassembly of section .plt: 0000000000400310 <.plt>: 400310: ff 25 ea 1c 2c 00 jmp QWORD PTR [rip+0x2c1cea] # 6c2000 <_GLOBAL_OFFSET_TABLE_+0x18> 400316: 68 00 00 00 00 push 0x0 40031b: e9 00 00 00 00 jmp 400320 <.plt+0x10> 400320: ff 25 e2 1c 2c 00 jmp QWORD PTR [rip+0x2c1ce2] # 6c2008 <_GLOBAL_OFFSET_TABLE_+0x20> 400326: 68 00 00 00 00 push 0x0 40032b: e9 00 00 00 00 jmp 400330 <.plt+0x20> 400330: ff 25 da 1c 2c 00 jmp QWORD PTR [rip+0x2c1cda] # 6c2010 <_GLOBAL_OFFSET_TABLE_+0x28> 400336: 68 00 00 00 00 push 0x0 40033b: e9 00 00 00 00 jmp 400340 <.plt+0x30> 400340: ff 25 d2 1c 2c 00 jmp QWORD PTR [rip+0x2c1cd2] # 6c2018 <_GLOBAL_OFFSET_TABLE_+0x30> 400346: 68 00 00 00 00 push 0x0 40034b: e9 00 00 00 00 jmp 400350 <.plt+0x40> 400350: ff 25 ca 1c 2c 00 jmp QWORD PTR [rip+0x2c1cca] # 6c2020 <_GLOBAL_OFFSET_TABLE_+0x38> 400356: 68 00 00 00 00 push 0x0 40035b: e9 00 00 00 00 jmp 400360 <.plt+0x50> 400360: ff 25 c2 1c 2c 00 jmp QWORD PTR [rip+0x2c1cc2] # 6c2028 <_GLOBAL_OFFSET_TABLE_+0x40> 400366: 68 00 00 00 00 push 0x0 40036b: e9 00 00 00 00 jmp 400370 <.plt+0x60> 400370: ff 25 ba 1c 2c 00 jmp QWORD PTR [rip+0x2c1cba] # 6c2030 <_GLOBAL_OFFSET_TABLE_+0x48> 400376: 68 00 00 00 00 push 0x0 40037b: e9 00 00 00 00 jmp 400380 <.plt+0x70> 400380: ff 25 b2 1c 2c 00 jmp QWORD PTR [rip+0x2c1cb2] # 6c2038 <_GLOBAL_OFFSET_TABLE_+0x50> 400386: 68 00 00 00 00 push 0x0 40038b: e9 00 00 00 00 jmp 400390 <.plt+0x80> 400390: ff 25 aa 1c 2c 00 jmp QWORD PTR [rip+0x2c1caa] # 6c2040 <_GLOBAL_OFFSET_TABLE_+0x58> 400396: 68 00 00 00 00 push 0x0 40039b: e9 00 00 00 00 jmp 4003a0 <.plt+0x90> 4003a0: ff 25 a2 1c 2c 00 jmp QWORD PTR [rip+0x2c1ca2] # 6c2048 <_GLOBAL_OFFSET_TABLE_+0x60> 4003a6: 68 00 00 00 00 push 0x0 4003ab: e9 00 00 00 00 jmp 4003b0 <.plt+0xa0> 4003b0: ff 25 9a 1c 2c 00 jmp QWORD PTR [rip+0x2c1c9a] # 6c2050 <_GLOBAL_OFFSET_TABLE_+0x68> 4003b6: 68 00 00 00 00 push 0x0 4003bb: e9 00 00 00 00 jmp 4003c0 <.plt+0xb0> 4003c0: ff 25 92 1c 2c 00 jmp QWORD PTR [rip+0x2c1c92] # 6c2058 <_GLOBAL_OFFSET_TABLE_+0x70> 4003c6: 68 00 00 00 00 push 0x0 4003cb: e9 00 00 00 00 jmp 4003d0 <check_one_fd.part.0> Disassembly of section .text: 00000000004003d0 <check_one_fd.part.0>: 4003d0: 55 push rbp 4003d1: 89 f0 mov eax,esi 4003d3: 89 fd mov ebp,edi 4003d5: 83 e0 03 and eax,0x3 4003d8: bf d8 66 49 00 mov edi,0x4966d8 4003dd: 53 push rbx 4003de: 31 db xor ebx,ebx 4003e0: 48 81 ec 98 00 00 00 sub rsp,0x98 4003e7: ff c8 dec eax 4003e9: b8 e2 66 49 00 mov eax,0x4966e2 4003ee: 0f 94 c3 sete bl 4003f1: 48 0f 45 f8 cmovne rdi,rax 4003f5: 31 d2 xor edx,edx 4003f7: 31 c0 xor eax,eax 4003f9: 48 8d 1c 9d 03 01 00 lea rbx,[rbx*4+0x103] 400400: 00 400401: e8 93 8b 01 00 call 418f99 <__open_nocancel> 400406: 39 e8 cmp eax,ebp 400408: 75 2a jne 400434 <check_one_fd.part.0+0x64> 40040a: 48 89 e2 mov rdx,rsp ....... ``` 長到我我找不到main在哪裏,所以我就放棄了 但是我們可以注意到 裡面用的register大多是r開頭,這是64 bit register的開頭 讓人覺得這是個64 bit程式,用`file`看看吧 ```shell $ file flag flag: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=96ec4cc272aeb383bd9ed26c0d4ac0eb5db41b16, not stripped ``` 恩他確實是 來用gdb吧 (順帶一提,我這裡使用的是有裝peda plugin的,所以看起來會跟純的gdb有點不一樣) ```shell $ gdb flag GNU gdb (Ubuntu 8.2-0ubuntu1~18.04) 8.2 Copyright (C) 2018 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. gdb-peda$ ``` gdb使用`b`指令來下斷點(breakpoint) 我們先在main下個斷點吧 ```shell gdb-peda$ b main Breakpoint 1 at 0x401168 ``` 很幸運的成功了 使用`r`讓程式跑起來 ```shell gdb-peda$ r Starting program: /home/secminhr/flag [----------------------------------registers-----------------------------------] RAX: 0x7fffffffe490 --> 0x401ae0 (<__libc_csu_fini>: push rbx) RBX: 0x401ae0 (<__libc_csu_fini>: push rbx) RCX: 0x0 RDX: 0x7fffffffe568 --> 0x7fffffffe79a ("LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc"...) RSI: 0x7fffffffe558 --> 0x7fffffffe786 ("/home/secminhr/flag") RDI: 0x1 RBP: 0x7fffffffe460 --> 0x0 RSP: 0x7fffffffe460 --> 0x0 RIP: 0x401168 (<main+4>: sub rsp,0x10) R8 : 0x40 ('@') R9 : 0xb ('\x0b') R10: 0xd ('\r') R11: 0x800 R12: 0x401a50 (<__libc_csu_init>: push r14) R13: 0x0 R14: 0x0 R15: 0x0 EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x401163 <frame_dummy+67>: nop 0x401164 <main>: push rbp 0x401165 <main+1>: mov rbp,rsp => 0x401168 <main+4>: sub rsp,0x10 0x40116c <main+8>: mov edi,0x496658 0x401171 <main+13>: call 0x402080 <puts> 0x401176 <main+18>: mov edi,0x64 0x40117b <main+23>: call 0x4099d0 <malloc> [------------------------------------stack-------------------------------------] 0000| 0x7fffffffe460 --> 0x0 0008| 0x7fffffffe468 --> 0x401344 (<__libc_start_main+404>: mov edi,eax) 0016| 0x7fffffffe470 --> 0x0 0024| 0x7fffffffe478 --> 0x100000000 0032| 0x7fffffffe480 --> 0x7fffffffe558 --> 0x7fffffffe786 ("/home/secminhr/flag") 0040| 0x7fffffffe488 --> 0x401164 (<main>: push rbp) 0048| 0x7fffffffe490 --> 0x401ae0 (<__libc_csu_fini>: push rbx) 0056| 0x7fffffffe498 --> 0x0 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Breakpoint 1, 0x0000000000401168 in main () ``` 中間`[-------------------------------------code-------------------------------------]` 的地方就是,嗯,code 但是只能看到執行的附近幾行而已 我們可以用`disas`(代表disassemble反編譯)來看看完整的main ```shell gdb-peda$ disas main Dump of assembler code for function main: 0x0000000000401164 <+0>: push rbp 0x0000000000401165 <+1>: mov rbp,rsp => 0x0000000000401168 <+4>: sub rsp,0x10 0x000000000040116c <+8>: mov edi,0x496658 0x0000000000401171 <+13>: call 0x402080 <puts> 0x0000000000401176 <+18>: mov edi,0x64 0x000000000040117b <+23>: call 0x4099d0 <malloc> 0x0000000000401180 <+28>: mov QWORD PTR [rbp-0x8],rax 0x0000000000401184 <+32>: mov rdx,QWORD PTR [rip+0x2c0ee5] # 0x6c2070 <flag> 0x000000000040118b <+39>: mov rax,QWORD PTR [rbp-0x8] 0x000000000040118f <+43>: mov rsi,rdx 0x0000000000401192 <+46>: mov rdi,rax 0x0000000000401195 <+49>: call 0x400320 0x000000000040119a <+54>: mov eax,0x0 0x000000000040119f <+59>: leave 0x00000000004011a0 <+60>: ret End of assembler dump. ``` 那個箭頭很好心的告訴我們現在停在哪一行上 我們可以明明白白地看到有一行寫著`<flag>` 怎麼好意思放過他 打個斷點在他身上 ```shell gdb-peda$ b *0x0000000000401184 Breakpoint 2 at 0x401184 ``` 然後用`c`(代表continue)來讓程式繼續 ```shell gdb-peda$ c Continuing. I will malloc() and strcpy the flag there. take it. [----------------------------------registers-----------------------------------] RAX: 0x6c96b0 --> 0x0 RBX: 0x401ae0 (<__libc_csu_fini>: push rbx) RCX: 0x8 RDX: 0x6c27c0 --> 0x100000000 RSI: 0x0 RDI: 0x4 RBP: 0x7fffffffe460 --> 0x0 RSP: 0x7fffffffe450 --> 0x401a50 (<__libc_csu_init>: push r14) RIP: 0x401184 (<main+32>: mov rdx,QWORD PTR [rip+0x2c0ee5] # 0x6c2070 <flag>) R8 : 0x1 R9 : 0x3 R10: 0x22 ('"') R11: 0x0 R12: 0x401a50 (<__libc_csu_init>: push r14) R13: 0x0 R14: 0x0 R15: 0x0 EFLAGS: 0x206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x401176 <main+18>: mov edi,0x64 0x40117b <main+23>: call 0x4099d0 <malloc> 0x401180 <main+28>: mov QWORD PTR [rbp-0x8],rax => 0x401184 <main+32>: mov rdx,QWORD PTR [rip+0x2c0ee5] # 0x6c2070 <flag> 0x40118b <main+39>: mov rax,QWORD PTR [rbp-0x8] 0x40118f <main+43>: mov rsi,rdx 0x401192 <main+46>: mov rdi,rax 0x401195 <main+49>: call 0x400320 [------------------------------------stack-------------------------------------] 0000| 0x7fffffffe450 --> 0x401a50 (<__libc_csu_init>: push r14) 0008| 0x7fffffffe458 --> 0x6c96b0 --> 0x0 0016| 0x7fffffffe460 --> 0x0 0024| 0x7fffffffe468 --> 0x401344 (<__libc_start_main+404>: mov edi,eax) 0032| 0x7fffffffe470 --> 0x0 0040| 0x7fffffffe478 --> 0x100000000 0048| 0x7fffffffe480 --> 0x7fffffffe558 --> 0x7fffffffe787 ("/home/secminhr/flag") 0056| 0x7fffffffe488 --> 0x401164 (<main>: push rbp) [------------------------------------------------------------------------------] Legend: code, data, rodata, value Breakpoint 2, 0x0000000000401184 in main () ``` 大概可以猜就是把flag有關的東東移到rdx 用`ni`(代表next instruction)執行這一行指令 ```shell gdb-peda$ ni [----------------------------------registers-----------------------------------] RAX: 0x6c96b0 --> 0x0 RBX: 0x401ae0 (<__libc_csu_fini>: push rbx) RCX: 0x8 RDX: 0x496628 ("UPX...? sounds like a delivery service :)") RSI: 0x0 RDI: 0x4 RBP: 0x7fffffffe460 --> 0x0 RSP: 0x7fffffffe450 --> 0x401a50 (<__libc_csu_init>: push r14) RIP: 0x40118b (<main+39>: mov rax,QWORD PTR [rbp-0x8]) R8 : 0x1 R9 : 0x3 R10: 0x22 ('"') R11: 0x0 R12: 0x401a50 (<__libc_csu_init>: push r14) R13: 0x0 R14: 0x0 R15: 0x0 EFLAGS: 0x206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x40117b <main+23>: call 0x4099d0 <malloc> 0x401180 <main+28>: mov QWORD PTR [rbp-0x8],rax 0x401184 <main+32>: mov rdx,QWORD PTR [rip+0x2c0ee5] # 0x6c2070 <flag> => 0x40118b <main+39>: mov rax,QWORD PTR [rbp-0x8] 0x40118f <main+43>: mov rsi,rdx 0x401192 <main+46>: mov rdi,rax 0x401195 <main+49>: call 0x400320 0x40119a <main+54>: mov eax,0x0 [------------------------------------stack-------------------------------------] 0000| 0x7fffffffe450 --> 0x401a50 (<__libc_csu_init>: push r14) 0008| 0x7fffffffe458 --> 0x6c96b0 --> 0x0 0016| 0x7fffffffe460 --> 0x0 0024| 0x7fffffffe468 --> 0x401344 (<__libc_start_main+404>: mov edi,eax) 0032| 0x7fffffffe470 --> 0x0 0040| 0x7fffffffe478 --> 0x100000000 0048| 0x7fffffffe480 --> 0x7fffffffe558 --> 0x7fffffffe787 ("/home/secminhr/flag") 0056| 0x7fffffffe488 --> 0x401164 (<main>: push rbp) [------------------------------------------------------------------------------] Legend: code, data, rodata, value 0x000000000040118b in main () ``` 往上看看rdx,flag到手 sumbit,通過,開心
2021-01-23 16:45:03
留言
Last fetch: --:-- 
現在還沒有留言!