題目: 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
Code language: PHP (php)
所以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
Code language: CSS (css)
看一下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
Code language: PHP (php)
嘗試執行看看
回頭看一下程式碼
首先要先去了解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
Code language: CSS (css)
[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
Code language: PHP (php)
執行看看
說你太慢
找到一個工具叫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
Code language: HTML, XML (xml)
其中關於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暫存器值
Code language: PHP (php)
:::
這一段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
Code language: PHP (php)
找到 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
Code language: PHP (php)
執行看看顯示以下內容
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.
Code language: JavaScript (javascript)
看別人的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