iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 12
0
Security

資安隨意分享的30天系列 第 12

Day12 - 簡單的靜態分析(一)

前言

這次講的是 attackdefense.com 這個 wargame 平台上面的逆向裡的靜態分析

這平台總共有四題,但我覺得其實難度都一樣,題型也大同小異,

今天會講第一題,會講比較細,後面講其他題就可以快速帶過去了

正文

這次講的是第一個 "Recover Passcode",可以先簡單看一下題目敘述,

大概意思是說可以用 gdb 去看他的組合語言,但 gdb 無法 run ,也就是

他禁止我們做動態分析這樣


首先用 gdb 看組合語言:

$ gdb -q ./challenge
$ set disassembly-flavor intel
$ disass main

這樣可以得到以下的資訊:


Dump of assembler code for function main:
   0x0000000000400d2e <+0>:     push   rbp
   0x0000000000400d2f <+1>:     mov    rbp,rsp
   0x0000000000400d32 <+4>:     sub    rsp,0x30
   0x0000000000400d36 <+8>:     mov    DWORD PTR [rbp-0x24],edi
   0x0000000000400d39 <+11>:    mov    QWORD PTR [rbp-0x30],rsi
   0x0000000000400d3d <+15>:    mov    rax,QWORD PTR fs:0x28      
   0x0000000000400d46 <+24>:    mov    QWORD PTR [rbp-0x8],rax  # save canary
   0x0000000000400d4a <+28>:    xor    eax,eax
   0x0000000000400d4c <+30>:    mov    QWORD PTR [rbp-0x15],0x0
   0x0000000000400d54 <+38>:    mov    DWORD PTR [rbp-0xd],0x0
   0x0000000000400d5b <+45>:    mov    BYTE PTR [rbp-0x9],0x0
   0x0000000000400d5f <+49>:    cmp    DWORD PTR [rbp-0x24],0x1 # [rbp-0x24] = argc (number)  
   0x0000000000400d63 <+53>:    jg     0x400d78 <main+74>       # if no args then exit
   0x0000000000400d65 <+55>:    lea    rdi,[rip+0xb05dc]        # 0x4b1348, "\nEnter password as command line argument\n\ni.e. challenge <password> "
   0x0000000000400d6c <+62>:    call   0x411b80 <puts>
   0x0000000000400d71 <+67>:    mov    eax,0x1
   0x0000000000400d76 <+72>:    jmp    0x400df5 <main+199>      # jump to exit
   0x0000000000400d78 <+74>:    mov    eax,DWORD PTR [rbp-0x24] # eax = argc
   0x0000000000400d7b <+77>:    cdqe                            # let edx = 0
   0x0000000000400d7d <+79>:    shl    rax,0x3                  # rax = rax << 3, rax = 16
   0x0000000000400d81 <+83>:    lea    rdx,[rax-0x8]            # rdx = 8
   0x0000000000400d85 <+87>:    mov    rax,QWORD PTR [rbp-0x30] # [rbp-0x30] is argv (set args xxxx) 
   0x0000000000400d89 <+91>:    add    rax,rdx                  # argv + 0x8
   0x0000000000400d8c <+94>:    mov    rcx,QWORD PTR [rax]
   0x0000000000400d8f <+97>:    lea    rax,[rbp-0x15]
   0x0000000000400d93 <+101>:   mov    edx,0xc
   0x0000000000400d98 <+106>:   mov    rsi,rcx
   0x0000000000400d9b <+109>:   mov    rdi,rax
   0x0000000000400d9e <+112>:   call   0x4004b0                 #  strncpy([rbp-0x15] , argv + 0x8,12)
   0x0000000000400da3 <+117>:   lea    rax,[rbp-0x15]
   0x0000000000400da7 <+121>:   mov    rdi,rax
   0x0000000000400daa <+124>:   call   0x400508                 # strlen( rbp-0x15 )
   0x0000000000400daf <+129>:   cmp    rax,0x9                  # if > 9 then say "Wrong"
   0x0000000000400db3 <+133>:   ja     0x400de4 <main+182>       # puts("Wrong")
   0x0000000000400db5 <+135>:   lea    rax,[rbp-0x15]
   0x0000000000400db9 <+139>:   mov    edx,0x9
   0x0000000000400dbe <+144>:   lea    rsi,[rip+0x2d932b]        # 0x6da0f0 <correct_password> , "hardbuteasy"
   0x0000000000400dc5 <+151>:   mov    rdi,rax
   0x0000000000400dc8 <+154>:   call   0x4004a8                  # strncmp(rbp-0x15, "hardbuteasy", 9) 
   0x0000000000400dcd <+159>:   test   eax,eax
   0x0000000000400dcf <+161>:   jne    0x400de4 <main+182>       # puts("Wrong")
   0x0000000000400dd1 <+163>:   lea    rdi,[rip+0xb05b8]        # 0x4b1390 , "190da373f10ae1afeb51fbc85609f9ce"
   0x0000000000400dd8 <+170>:   call   0x400cd3 <print_flag>
   0x0000000000400ddd <+175>:   mov    eax,0x0
   0x0000000000400de2 <+180>:   jmp    0x400df5 <main+199>
   0x0000000000400de4 <+182>:   lea    rdi,[rip+0xb05c6]        # 0x4b13b1 , "Wrong"
   0x0000000000400deb <+189>:   call   0x411b80 <puts>
   0x0000000000400df0 <+194>:   mov    eax,0x1
   0x0000000000400df5 <+199>:   mov    rcx,QWORD PTR [rbp-0x8]    # exit ..
   0x0000000000400df9 <+203>:   xor    rcx,QWORD PTR fs:0x28
   0x0000000000400e02 <+212>:   je     0x400e09 <main+219>
   0x0000000000400e04 <+214>:   call   0x4512d0 <__stack_chk_fail_local>
   0x0000000000400e09 <+219>:   leave
   0x0000000000400e0a <+220>:   ret
End of assembler dump.

上面組語我有先加一些註解,不過函數名稱是我亂寫的,大概意思有對就好

首先我們要知道在 x64 中,函數呼叫大概長相是:

rax = func(rdi, rsi, rdx)

那我們知道 main 的寫法應該是 int main(int argc, char **argv, char **envp)

換句話說

rdi = argc
rsi = argv

所以一開始看組合語言可以知道

[rbp-0x24] 存 argc
[rbp-0x30] 存 argv

所以在 main+49 的位置可以知道是先看 argc 是否大於 1 ,不是就 exit

然後 main+112 那邊函數是我隨便猜的,因為看起來很像,感覺就是

把我們輸入的前 12 bytes 存到 [rbp - 0x15],然後往下看

main+124 那邊呼叫一個函數,之後和數字 9 比是不是超過,所以猜函數是 strlen

最後在 main+154 那邊把 [rbp-0x15]hardbuteasy 比前 9 個字

所以很明顯就是整個流程是要我們輸入九個字要等於 hardbutea 即可


結語

其實這樣單純看組合語言對我自己來說,蠻好加深印象的


上一篇
Day11 - DSA 小小研究
下一篇
Day13 - 簡單的靜態分析(二)
系列文
資安隨意分享的30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言