picoCTF 2018 – ReverseEngineering

題目: Reversing Warmup 1

下載一個program
檔案名稱叫做run 要你執行它

用chmod +x run
讓它變成可執行
然後執行 就拿到flag了

picoCTF{welc0m3_t0_r3VeRs1nG}


題目: Reversing Warmup 2

decode 下面這段string
dGg0dF93NHNfczFtcEwz

#decode 也可以把-d改成--decode
echo 'dGg0dF93NHNfczFtcEwz' | base64 -d
#得到th4t_w4s_s1mpL3

所以flag應該是
picoCTF{th4t_w4s_s1mpL3}

輸入答對


題目: assembly-0

題目問asm0(0xb6, 0xc6)返回甚麼?

.intel_syntax noprefix
.bits 32
.global asm0
asm0:
    push    ebp
    mov ebp,esp
    mov eax,DWORD PTR [ebp+0x8]
    mov ebx,DWORD PTR [ebp+0xc]
    mov eax,ebx
    mov esp,ebp
    pop ebp 
    ret

看一下hint的教學網站
https://www.tutorialspoint.com/assembly_programming/assembly_basic_syntax.htm
https://www.tutorialspoint.com/assembly_programming/assembly_registers.htm
也可以參考中文的教學
https://blog.gtwang.org/programming/memory-layout-of-c-program/
:::success
An assembly program can be divided into three sections −
The data section,
The bss section, and
The text section.

Assembly language Comments是用分號(;)
:::

下面這段是組語的Hello world

section    .text
   global _start     ;must be declared for linker (ld)
_start:                ;tells linker entry point
   mov    edx,len     ;message length
   mov    ecx,msg     ;message to write
   mov    ebx,1       ;file descriptor (stdout)
   mov    eax,4       ;system call number (sys_write)
   int    0x80        ;call kernel
   mov    eax,1       ;system call number (sys_exit)
   int    0x80        ;call kernel
section    .data
msg db 'Hello, world!', 0xa  ;string to be printed
len equ $ - msg     ;length of the string

嘗試執行看看

回頭看一下程式碼
首先要先去了解eax,ebx還有ebp,esp這些是甚麼
除了hint的網站也可以直接google找中文說明
然後eax,DWORD PTR [ebp+0x8]
DWORD 是四個字節 也就是32bits
PTR 是pointer的縮寫
也就是說將32bits的暫存位址大小賦予給eax 位址在[ebp+0x8]

從題目來看asm0(0xb6, 0xc6)
所以eax會被賦予值0xb6 位址在[ebp+0x8]
而ebx會被賦予值0xc6 位址在[ebp+0xc]

mov eax, ebx 這一段意思就是用ebx取代掉eax
後面還有點不懂
不過出來應該就是ebx的值
也就是0xc6

flag直接輸入0xc6答對


題目: assembly-1

Hint:
關於CMP與JMP
https://www.tutorialspoint.com/assembly_programming/assembly_conditions.htm

輸入值0xc8

code如下

.intel_syntax noprefix
.bits 32
.global asm1
asm1:
    push    ebp
    mov ebp,esp
    cmp DWORD PTR [ebp+0x8],0x9a
    jg  part_a  
    cmp DWORD PTR [ebp+0x8],0x8
    jne part_b
    mov eax,DWORD PTR [ebp+0x8]
    add eax,0x3
    jmp part_d
part_a:
    cmp DWORD PTR [ebp+0x8],0x2c
    jne part_c
    mov eax,DWORD PTR [ebp+0x8]
    sub eax,0x3
    jmp part_d
part_b:
    mov eax,DWORD PTR [ebp+0x8]
    sub eax,0x3
    jmp part_d
    cmp DWORD PTR [ebp+0x8],0xc8
    jne part_c
    mov eax,DWORD PTR [ebp+0x8]
    sub eax,0x3
    jmp part_d
part_c:
    mov eax,DWORD PTR [ebp+0x8]
    add eax,0x3
part_d:
    pop ebp
    ret

[ebp+0x8]這個位置存的就是0xc8

比較0xc8跟0x9a
因為0xc8比較大
jg是大於則跳轉的的意思
所以跳到part_a

因為0xc8也比0x2c大
jne是不等於則跳轉
所以跳到part_c

將0xc8存在eax
將eax + 0x3
所以eax會變成 0xcb

最後pop出來0xcb

flag輸入0xcb答對


題目: be-quick-or-be-dead-1

一個youtube影片
https://www.youtube.com/watch?v=CTt1vk9nM9c
還有一個檔案可以下載

連題目都看不懂0.0

cat看一下下載的檔案 似乎不是要看code

# file be-quick-or-be-dead-1 
be-quick-or-be-dead-1: 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]=ee0a1c60b83fce4115a98c9cb14bb23c04e71716, not stripped

執行看看

說你太慢

找到一個工具叫objdump
利用-d參數可以查看組合語言

發現到calculate_key這一段值得注意

0000000000400706 <calculate_key>:
  400706:    55                      push   %rbp
  400707:    48 89 e5                mov    %rsp,%rbp
  40070a:    c7 45 fc 11 91 fe 72    movl   $0x72fe9111,-0x4(%rbp)
  400711:    83 45 fc 01             addl   $0x1,-0x4(%rbp)
  400715:    81 7d fc 22 22 fd e5    cmpl   $0xe5fd2222,-0x4(%rbp)
  40071c:    75 f3                   jne    400711 <calculate_key+0xb>
  40071e:    8b 45 fc                mov    -0x4(%rbp),%eax
  400721:    5d                      pop    %rbp
  400722:    c3                      retq  

其中關於movl
:::success
GNU彙編器為 mov 指令添加了一個維度,在其中必須宣告要傳送的資料元素的長度。
通過一個附加字元新增到 MOV 助記符來宣告這個長度。
因此,指令就變成了如movx, 其中 x 可以是下面的字元:

  • l用於32位的長字值
  • w用於16位的字值
  • b用於8位的位元組值
movl  %eax, %ebx #把32位的EAX暫存器值傳送給32為的EBX暫存器值
movw  %ax, %bx #把32位的EAX暫存器值傳送給32為的EBX暫存器值
movb  %al, %lx #把32位的EAX暫存器值傳送給32為的EBX暫存器值

:::

這一段function的流程是這樣
設定了一個值0x72fe9111
接著讓這個值加1過後就跟0xe5fd2222去比較
如果不等於的話(JNE)就跳到400711

所以想要讓他快點結束這個過程
試試看直接修改初始設定的值0x72fe9111
把他改成0xe5fd2221好了
這樣只要加一次就可以變成0xe5fd2222

用hexedit打開檔案

hexedit用法
F2: save
F3: load file
F1: help
Ctrl-L: redraw
Ctrl-Z: suspend
Ctrl-X: save and exit
Ctrl-C: exit without saving
Tab: toggle hex/ascii
Return: go to
Backspace: undo previous character
Ctrl-U: undo all
Ctrl-S: search forward
Ctrl-R: search backward

找到 11 91 fe 72
這邊因為x86是用little endian
所以值0x72fe9111在hex模式下是顯示11 91 fe 72
所以我們要把值改成0xe5fd2221
就把內容改成21 22 fd e5

執行之後拿到flag

picoCTF{why_bother_doing_unnecessary_computation_d0c6aace}


題目: quackme

有個program

root@hackercat:~/CTF/picoCTF2018/ReverseEngineering/quackme# file main
main: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=0670b606f18db820bfa412d2003e6fc712774830, not stripped

執行看看顯示以下內容

You have now entered the Duck Web, and you're in for a honkin' good time.
Can you figure out my trick?
That's all folks.

看別人的write up發現有個工具叫Radare2 (指令是r2) 感覺滿猛的
https://github.com/Dvd848/CTFs/blob/master/2018_picoCTF/quackme.md

太天真了 這種鬼東西新手還是先緩緩再說XD

載了IDA來用比較實際
下載IDA安裝在win10
開啟main程式看看

找到do_magic這個function
會顯示整個執行流程圖
就像下面這個write up一樣
https://github.com/sefi-roee/CTFs-Writeups/blob/master/picoCTF-2018/Reversing/06-quackme-200/solution.md
更詳細的講解
https://pwnthemole.github.io/reverse/2018/10/18/PicoCTF2018-QuackMe.html

中文
https://ithelp.ithome.com.tw/articles/10221352

到do_magic() function中觀察
輸入的值會被存在var_14
長度被存在var_10

You are winner位於0x080486F8

https://github.com/sefi-roee/CTFs-Writeups/blob/master/picoCTF-2018/Reversing/06-quackme-200/solution.md

發佈留言