Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Linux Pwn 101

229b1596ce57cd0935a2bacd410d87a0?s=47 adr
July 07, 2017

Linux Pwn 101

229b1596ce57cd0935a2bacd410d87a0?s=128

adr

July 07, 2017
Tweet

Transcript

  1. aaaddress1 // hackingWeekend Linux Pwn 101 aaaddress1@chroot.org

  2. aaaddress1 // hackingWeekend #murmur

  3. aaaddress1 // hackingWeekend 寫過 C/C++ 的舉個⼿手

  4. aaaddress1 // hackingWeekend ⽤用過 Linux 的舉⼿手

  5. aaaddress1 // hackingWeekend 會下終端機命令的舉⼿手

  6. aaaddress1 // hackingWeekend $ echo `python -c "a = 0x7b;

    print a;"`
  7. aaaddress1 // hackingWeekend 有沒有特別痛恨資料結構跟作業系統的朋友, 想離場的現在趕快喔,不然你會無聊八個⼩小時

  8. aaaddress1 // hackingWeekend Outline

  9. aaaddress1 // hackingWeekend 課程環境 • Ubuntu GNOME 訓練平台虛擬機⼀一份(*.ova) • GCC

    編譯 • GDB+PEDA 調試練習 • x86 ELF 練習題⽬目 • 關掉 ASLR • 練習題⽬目原始碼(*.C) • 虛擬機帳號 pwn 密碼 pwn
  10. aaaddress1 // hackingWeekend Pwn基礎知識篇章 1. 逆向⼯工程基礎(⼀一):記憶體 2. 逆向⼯工程基礎(⼆二):機械碼 3. 逆向⼯工程基礎(三):組合語⾔言

    • nasm 練習(⼀一) hello hacker! • nasm 練習(⼆二)sys_execve(/bin/sh) 4. 逆向⼯工程基礎(四):x86 Calling Convetion 5. gdb+peda 6. ipython+pwntools
  11. aaaddress1 // hackingWeekend Pwn實戰練習篇章 • Pwn 實例例: AIS3 Pwn1 •

    Pwn1 實戰練習: Touch Cat • Pwn2 實戰練習: bof • Pwn3 實戰練習: Secret Keeper
  12. aaaddress1 // hackingWeekend Bonus 篇章 1. Intel Syntax v.s. AT&T

    Syntax 2. ELF 架構、GOT、PLT 函數呼叫關係
  13. aaaddress1 // hackingWeekend Pwn 基礎知識篇章

  14. aaaddress1 // hackingWeekend 逆向⼯工程基礎(⼀一) 記憶體

  15. aaaddress1 // hackingWeekend 為什什麼要逆向⼯工程 • 你想知道某個程式怎麼運作的 • 寫線上外掛、機器⼈人 • 破解付費驗證、撰寫註冊機

    • 挖掘程式漏洞洞 • 你朋友的程式碼太醜,還不如看組合語⾔言的時候...
  16. aaaddress1 // hackingWeekend 編譯/ 中介碼/ 直譯 • 編譯為原⽣生機械碼(Native)
 C、C++、Objective-C、Swfit、Go •

    編譯為中介碼(Intermediate Language, aka IL)
 .NET(C#, VB)、Java、Python(pyc) • 直譯(interpreting)
 Python、Ruby、Javascript、VBScript
  17. aaaddress1 // hackingWeekend 編譯/ 中介碼/ 直譯 • 編譯為原⽣生機械碼(Native)
 C、C++、Objective-C、Swfit、Go 原始碼

    執⾏行行檔 (機械碼) 編譯器編譯
  18. aaaddress1 // hackingWeekend 編譯/ 中介碼/ 直譯 • 編譯為原⽣生機械碼(Native)
 C、C++、Objective-C、Swfit、Go 原始碼

    執⾏行行檔 (機械碼) 逆向⼯工程理理解 從逆向⼯工程上只能理理解⼤大致上運作的過程, 並無法真正取得開發者的原始碼
  19. aaaddress1 // hackingWeekend 記憶體 addr 0 1 2 3 4

    5 6 7 8 9 A B C D E F 100 11 110 120 • 記憶體由⼀一個個格⼦子組成,每個格⼦子⼤大⼩小為 1 byte • 1 byte 可儲存 0 ~ 255 的數值(也就是 0x00 ~ 0xFF) • 每個格⼦子都有對應的記憶體地址編號 0x11 被存放在 0x100 的格⼦子上
  20. aaaddress1 // hackingWeekend 記憶體 addr 0 1 2 3 4

    5 6 7 8 9 A B C D E F 100 11 22 110 120 • 記憶體由⼀一個個格⼦子組成,每個格⼦子⼤大⼩小為 1 byte • 每個格⼦子都有對應的記憶體地址編號 0x22 被存放在 0x10F 的格⼦子上
  21. aaaddress1 // hackingWeekend 記憶體 addr 0 1 2 3 4

    5 6 7 8 9 A B C D E F 100 11 22 110 120 33 • 記憶體由⼀一個個格⼦子組成,每個格⼦子⼤大⼩小為 1 byte • 每個格⼦子都有對應的記憶體地址編號 0x33 被存放在 0x123 的格⼦子上
  22. aaaddress1 // hackingWeekend 記憶體 (int) addr 0 1 2 3

    4 5 6 7 8 9 A B C D E F 100 110 120 printf("size of int = %i\n", sizeof(int)); // size of int = 4
  23. aaaddress1 // hackingWeekend 記憶體 (int) addr 0 1 2 3

    4 5 6 7 8 9 A B C D E F 100 110 EF BE AD DE 120 int* ptr = (int *)(0x116); printf("data = %x\n", *ptr); // data = 0xDEADBEEF
  24. aaaddress1 // hackingWeekend 記憶體 (int) addr 0 1 2 3

    4 5 6 7 8 9 A B C D E F 100 110 EF BE AD DE 120 int* ptr = (int *)(0x116); printf("data = %x\n", *ptr); // data = 0xDEADBEEF little-endian
  25. aaaddress1 // hackingWeekend 記憶體 (int) 問題 addr 0 1 2

    3 4 5 6 7 8 9 A B C D E F 100 110 EF BE AD DE 120 int* ptr = (int *)(0x117); *ptr = 0xDEADBEEF;
  26. aaaddress1 // hackingWeekend 記憶體 (int) 問題 addr 0 1 2

    3 4 5 6 7 8 9 A B C D E F 100 110 EF EF BE AD DE 120 int* ptr = (int *)(0x117); *ptr = 0xDEADBEEF;
  27. aaaddress1 // hackingWeekend 記憶體 (array) addr 0 1 2 3

    4 5 6 7 8 9 A B C D E F 100 110 A4 A3 A2 A1 B1 B2 B3 B4 CC CC 120 CC CC int arr[3] = { 0xA1A2A3A4, 0xB4B3B2B1, 0xCCCCCCCC };
  28. aaaddress1 // hackingWeekend • ⼤大端序(big-endian)
 記憶體中擺放: AA BB CC DD


    
 • ⼩小端序(little-endian)
 記憶體中擺放: DD CC BB AA 位元組順序 以數值 0xAABBCCDD 為例例 https://zh.wikipedia.org/wiki/字节序
  29. aaaddress1 // hackingWeekend 逆向⼯工程基礎(⼆二) 機械碼

  30. aaaddress1 // hackingWeekend 機械碼 0 1 2 3 4 5

    6 7 8 9 A B C D E F 100 55 8B EC 83 EC 08 C7 45 F8 00 00 00 00 C7 45 FC 110 00 00 00 00 C7 45 F8 01 00 00 00 EB 09 8B 45 F8 120 83 C0 01 89 45 F8 8B 4D F8 3B 4D 08 7F 0B 8B 55 130 FC 03 55 F8 89 55 FC EB E4 8B 45 FC 50 68 30 60 140 40 00 E8 62 00 00 00 83 C4 08 8B E5 5D C3 在記憶體裡⾯面看得到的機械碼長得像這樣 (沒錯,就是那個經過編譯器處理理原始碼過後產⽣生的東⻄西)
  31. aaaddress1 // hackingWeekend 機械碼 0 1 2 3 4 5

    6 7 8 9 A B C D E F 100 55 8B EC 83 EC 08 C7 45 F8 00 00 00 00 C7 45 FC 110 00 00 00 00 C7 45 F8 01 00 00 00 EB 09 8B 45 F8 120 83 C0 01 89 45 F8 8B 4D F8 3B 4D 08 7F 0B 8B 55 130 FC 03 55 F8 89 55 FC EB E4 8B 45 FC 50 68 30 60 140 40 00 E8 62 00 00 00 83 C4 08 8B E5 5D C3 看不懂嗎?
  32. aaaddress1 // hackingWeekend 九九乘法表 背過齁

  33. aaaddress1 // hackingWeekend 我們來來背FF指令表吧,耶比

  34. aaaddress1 // hackingWeekend 機械碼 0 1 2 3 4 5

    6 7 8 9 A B C D E F 100 55 8B EC 83 EC 08 C7 45 F8 00 00 00 00 C7 45 FC 110 00 00 00 00 C7 45 F8 01 00 00 00 EB 09 8B 45 F8 120 83 C0 01 89 45 F8 8B 4D F8 3B 4D 08 7F 0B 8B 55 130 FC 03 55 F8 89 55 FC EB E4 8B 45 FC 50 68 30 60 140 40 00 E8 62 00 00 00 83 C4 08 8B E5 5D C3 執⾏行行緒由 0x100 開始運⾏行行,fetch 到第⼀一個 byte 為 0x55
  35. aaaddress1 // hackingWeekend 機械碼 0 1 2 3 4 5

    6 7 8 9 A B C D E F 100 55 8B EC 83 EC 08 C7 45 F8 00 00 00 00 C7 45 FC 110 00 00 00 00 C7 45 F8 01 00 00 00 EB 09 8B 45 F8 120 83 C0 01 89 45 F8 8B 4D F8 3B 4D 08 7F 0B 8B 55 130 FC 03 55 F8 89 55 FC EB E4 8B 45 FC 50 68 30 60 140 40 00 E8 62 00 00 00 83 C4 08 8B E5 5D C3 反查 0x55 在 FF 乘法表上為 push ebp,接著讀下⼀一個指令
  36. aaaddress1 // hackingWeekend 機械碼 0 1 2 3 4 5

    6 7 8 9 A B C D E F 100 55 8B EC 83 EC 08 C7 45 F8 00 00 00 00 C7 45 FC 110 00 00 00 00 C7 45 F8 01 00 00 00 EB 09 8B 45 F8 120 83 C0 01 89 45 F8 8B 4D F8 3B 4D 08 7F 0B 8B 55 130 FC 03 55 F8 89 55 FC EB E4 8B 45 FC 50 68 30 60 140 40 00 E8 62 00 00 00 83 C4 08 8B E5 5D C3 反查 0x55 在 FF 乘法表上為 push ebp,接著讀下⼀一個指令
  37. aaaddress1 // hackingWeekend 機械碼 0 1 2 3 4 5

    6 7 8 9 A B C D E F 100 55 8B EC 83 EC 08 C7 45 F8 00 00 00 00 C7 45 FC 110 00 00 00 00 C7 45 F8 01 00 00 00 EB 09 8B 45 F8 120 83 C0 01 89 45 F8 8B 4D F8 3B 4D 08 7F 0B 8B 55 130 FC 03 55 F8 89 55 FC EB E4 8B 45 FC 50 68 30 60 140 40 00 E8 62 00 00 00 83 C4 08 8B E5 5D C3 fetch 到 0x8B 為 mov Gv, Ev,讀取到下⼀一個 byte 為 0xEC, 可以得知 8B, EC 的意思對應為:mov ebp, esp
  38. aaaddress1 // hackingWeekend 機械碼 逆向⼯工程就是熟背 FF 指令表, ⾁肉眼讀機械碼,今天就教到這邊, 回去⼤大家記得多背 FF

    指令表,結束 (咦?
  39. aaaddress1 // hackingWeekend 善⽤用⼯工具,⼯工具很棒 www.onlinedisassembler.com/odaweb

  40. aaaddress1 // hackingWeekend void print_sum(int num_in) { int i =

    0, sum = 0; for (i = 1; i <= num_in; i++) sum += i; printf("sum: %i\n", sum); } 開發者的程式碼
  41. aaaddress1 // hackingWeekend .text:00401006 mov [ebp+var_8], 0 .text:0040100D mov [ebp+var_4],

    0 .text:00401014 mov [ebp+var_8], 1 .text:0040101B jmp short loc_401026 .text:0040101D loc_40101D: .text:0040101D mov eax, [ebp+var_8] .text:00401020 add eax, 1 .text:00401023 mov [ebp+var_8], eax .text:00401026 loc_401026: .text:00401026 mov ecx, [ebp+var_8] .text:00401029 cmp ecx, [ebp+arg_0] .text:0040102C jg short loc_401039 .text:0040102E mov edx, [ebp+var_4] .text:00401031 add edx, [ebp+var_8] .text:00401034 mov [ebp+var_4], edx .text:00401037 jmp short loc_40101D .text:00401039 loc_401039: .text:00401039 mov eax, [ebp+var_4] .text:0040103C push eax .text:0040103D push offset aSumI ; "sum: %i\n" .text:00401042 call _printf 組合語⾔言
  42. aaaddress1 // hackingWeekend 逆向⼯工程基礎(三) 組合語⾔言

  43. aaaddress1 // hackingWeekend 暫存器 • 每個執⾏行行緒(Thread)運⾏行行時會配發⼀一組暫存器: eax、ebx、ecx、edx、esi、edi、ebp、esp、eip • 每個暫存器可以儲存 4

    bytes ⼤大⼩小的資料,也就是⼀一 個 Integer • esp 指向⼀一組堆疊(⼀一⼤大片記憶體空間)
  44. aaaddress1 // hackingWeekend 暫存器 EAX AX AH AL 4 Bytes

    2 Bytes 1 Bytes 1 Bytes
  45. aaaddress1 // hackingWeekend ⼀一組暫存器 EAX EBX ECX EDX ESI EDI

    ESP EBP EIP ⼀一組暫存器 ⏞
  46. aaaddress1 // hackingWeekend 暫存器公定⽤用法 ⼤大家約好必須這樣做(ㄩㄇ) EAX EBX ECX EDX ESI

    EDI ESP EBP EIP 指向堆疊(Stack) 指向下⼀一⾏行行指令地址 當層函數的堆疊基礎指標
  47. aaaddress1 // hackingWeekend EAX EBX ECX EDX ESI EDI ESP

    EBP EIP 很常拿來來被當⽬目標 Index ⽤用 (特別是字串串拷⾙貝) 很常被拿來來當來來源 Index ⽤用 (特別是字串串拷⾙貝) 慣性被拿來來當暫時⽤用變數 與函數回傳值 暫存器不成⽂文約定... ⼤大家很愛這麼做,但事實上沒特別規定這樣做 很常被拿來來儲存某個指標 被當計數器⽤用
  48. aaaddress1 // hackingWeekend EAX EBX ECX EDX ESI EDI ESP

    EBP EIP 很常拿來來被當⽬目標 Index ⽤用 (特別是字串串拷⾙貝) 很常被拿來來當來來源 Index ⽤用 (特別是字串串拷⾙貝) 慣性被拿來來當暫時⽤用變數 與函數回傳值 暫存器不成⽂文約定... 不要問我為什什麼,我真的不知道XD(不⽤用死記) 很常被拿來來儲存某個指標 被當計數器⽤用
  49. aaaddress1 // hackingWeekend 組合語⾔言 • 指令集定義在那張 FF 指令表上(⼤大部分啦) • 指令形式如下


    opcode arg1, arg2, arg3 • 常⾒見見指令如 add、sub、mul、div(加減乘除) • add eax, ebx //eax = (eax + ebx) • [arg] 即為將 arg 當作 pointer ⽤用(*arg)
  50. aaaddress1 // hackingWeekend • mov eax, ebx
 //eax = ebx

    • mov [eax], ebx 
 mov dword ptr [eax], ebx
 // *(dword*)eax = ebx • mov [ax], bx
 mov word ptr [ax], bx
 // *(word*)eax = bx • mov [al], bl
 mov byte ptr [al], bl
 // *((byte*)eax) = bl 基本運算 搬移
  51. aaaddress1 // hackingWeekend 舉個 mov eax , 0xDEADBEEF mov [eax],

    0xEA7C0FEE
  52. aaaddress1 // hackingWeekend 舉個 mov eax , 0xDEADBEEF mov [eax],

    0xEA7C0FEE 暫存器
  53. aaaddress1 // hackingWeekend 舉個 mov eax , 0xDEADBEEF mov [eax],

    0xEA7C0FEE 指令
  54. aaaddress1 // hackingWeekend 舉個 mov eax , 0xDEADBEEF mov [eax],

    0xEA7C0FEE addr 0 1 2 3 4 5 6 7 8 9 A B C D E F DEADBEEF EE 0F 7C EA
  55. aaaddress1 // hackingWeekend • add eax, ebx //eax += ebx

    • sub eax, ebx //eax -= ebx • inc eax //eax ++ • dec eax //eax -- 基本運算 加法、減法
  56. aaaddress1 // hackingWeekend • cmp eax, ebx // T =

    eax - ebx • je 0xdead // if (T==0) EIP=0xdead • jl 0xbeef // if (T <0) EIP=0xbeef • jg 0xf00d // if (T >0) EIP=0xf00d • jle 0xb00c // if (T<=0) EIP=0xb00c • jmp 0xcafe // EIP = 0xcafe 基本運算 比對、跳轉
  57. aaaddress1 // hackingWeekend 基本運算 無號數乘法 mov eax, 0x02 mov edx,

    0x03 mul edx 結果: eax = 6, edx = 0 mov eax, 0x02 mov edx, 0x03 mul eax 結果: eax = 4, edx = 0 mul 將 eax 乘 乘數 後,答案為 8bytes ⾼高 4bytes 寫入 edx、低 4bytes 寫入 eax
  58. aaaddress1 // hackingWeekend 基本運算 無號數乘法 mov eax, 0x02 mov edx,

    0xFFFFFFFF mul edx 結果: eax = 0xFFFFFFFE, edx = 0x00000001, Carry = 1, Overflow = 1 mul 將 eax 乘 乘數 後,答案為 8bytes ⾼高 4bytes 寫入 edx、低 4bytes 寫入 eax
  59. aaaddress1 // hackingWeekend 基本運算 有號數乘法 mov eax, 0x02 mov edx,

    0x03 imul edx 結果: eax = 6, edx = 0 mov eax, -2 mov edx, 3 imul eax 結果: eax = 0xFFFFFFFA, edx = 0xFFFFFFFF imul 將 eax 乘 乘數 後,答案為 8bytes ⾼高 4bytes 寫入 edx、低 4bytes 寫入 eax
  60. aaaddress1 // hackingWeekend 基本運算 無號數除法 mov eax, 0x7 mov ecx,

    0x2 mov edx, 0x0 div ecx 結果: eax = 3, edx = 1, ecx = 2 div 將 eax 除 除數 後,答案為 8bytes 結果寫入 eax,餘數寫入 edx *使⽤用 div 前記得將 edx 清為 0
  61. aaaddress1 // hackingWeekend 基本運算 有號數除法 mov eax, 0x7 mov ecx,

    0x2 mov edx, 0x0 idiv ecx 結果: eax = 3, edx = 1, ecx = 2 idiv 將 eax 除 除數 後,答案為 8bytes 結果寫入 eax,餘數寫入 edx *使⽤用 idiv 前記得將 edx 清為 0
  62. aaaddress1 // hackingWeekend 堆疊(Stack) 堆疊 堆疊 push 1 push 2

    pop ebx push 3 pop eax
  63. aaaddress1 // hackingWeekend 堆疊(Stack) 堆疊 堆疊 push 1 push 2

    pop ebx push 3 pop eax 1
  64. aaaddress1 // hackingWeekend 堆疊(Stack) 堆疊 堆疊 push 1 push 2

    pop ebx push 3 pop eax 1 2
  65. aaaddress1 // hackingWeekend 堆疊(Stack) 堆疊 堆疊 push 1 push 2

    pop ebx push 3 pop eax 1 2 EBX
  66. aaaddress1 // hackingWeekend 堆疊(Stack) 堆疊 堆疊 push 1 push 2

    pop ebx push 3 pop eax 1 EBX: 2
  67. aaaddress1 // hackingWeekend 堆疊(Stack) 堆疊 堆疊 push 1 push 2

    pop ebx push 3 pop eax 1 EBX: 2 3
  68. aaaddress1 // hackingWeekend 堆疊(Stack) 堆疊 堆疊 push 1 push 2

    pop ebx push 3 pop eax 1 EBX: 2 3 EAX
  69. aaaddress1 // hackingWeekend 堆疊(Stack) 堆疊 堆疊 push 1 push 2

    pop ebx push 3 pop eax 1 EBX: 2 EAX: 3
  70. aaaddress1 // hackingWeekend 堆疊(Stack) 堆疊 堆疊 1 2 3 12FFF8

    12FFF4 12FFF0 記憶體位址 push 1 push 2 push 3
  71. aaaddress1 // hackingWeekend 堆疊(Stack) 堆疊 1 2 3 12FFF8 12FFF4

    12FFF0 記憶體位址 越早推入堆疊的資料所在的記憶體地址越⾼高; 越晚推入堆疊的資料所在的記憶體地址越低。
  72. aaaddress1 // hackingWeekend 堆疊(Stack) push 01 = sub esp, 4;

    mov [esp], 01 pop eax = mov eax,[esp]; add esp, 04 堆疊 1 2 3 12FFF8 12FFF4 12FFF0 記憶體位址
  73. aaaddress1 // hackingWeekend NASM 組語撰寫

  74. aaaddress1 // hackingWeekend Linux Syscall Reference http://syscalls.kernelgrok.com

  75. aaaddress1 // hackingWeekend NASM 練習(⼀一) Hello Hacker!

  76. aaaddress1 // hackingWeekend NASM

  77. aaaddress1 // hackingWeekend $ nasm -felf32 hello.asm 根據 hello.asm 組合語⾔言指令內容

    產出對應 x86 指令集的 object file(hello.o) $ objdump -d ./hello.o -M intel ./hello.o: file format elf32-i386 Disassembly of section .text: 00000000 <_start>: 0: ba 0f 00 00 00 mov edx,0xf 5: b9 22 00 00 00 mov ecx,0x22 a: bb 01 00 00 00 mov ebx,0x1 f: b8 04 00 00 00 mov eax,0x4 14: cd 80 int 0x80 16: bb ff 00 00 00 mov ebx,0xff 1b: b8 01 00 00 00 mov eax,0x1 20: cd 80 int 0x80
  78. aaaddress1 // hackingWeekend $ ld -m elf_i386 -o hello hello.o

    連結器將 hello.o(object file)產出 x86 elf(hello) $ ld -m elf_i386 -o hello hello.o $ file hello hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped $ ./hello hello, hacker!
  79. aaaddress1 // hackingWeekend /bin/sh /bin/sh 被喚起時會提供⼀一個 shell,可以直接輸入指令控制主機 因此經常 /bin/sh 成為兵家必爭之地

  80. aaaddress1 // hackingWeekend NASM 練習(⼆二) /bin/sh

  81. aaaddress1 // hackingWeekend

  82. aaaddress1 // hackingWeekend 其實到這邊,你們已經掌握了了 Linux Shellcode 撰寫的基礎了了 :P

  83. aaaddress1 // hackingWeekend 逆向⼯工程基礎(四) x86 Calling Convention

  84. aaaddress1 // hackingWeekend 呼叫約制 Calling Convention add(1, 2, 3) int

    add(int a, int b, int c) { int tmp = (a + b + c); return tmp; }
  85. aaaddress1 // hackingWeekend 呼叫約制 Calling Convention push 3 push 2

    push 1 call add add esp,0x0C //add(1, 2, 3) int add(int a, int b, int c) { int tmp = (a + b + c); return tmp; } 1. 參參數由右⾄至左推入堆疊中 2. 呼叫者負責清理理堆疊(stdcall)
  86. aaaddress1 // hackingWeekend 呼叫約制 堆疊清理理問題 zh.wikipedia.org/wiki/X86调⽤用约定

  87. aaaddress1 // hackingWeekend 呼叫約制 Calling Convention push 3 push 2

    push 1 call add add esp,0x0C //add(1, 2, 3) 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3
  88. aaaddress1 // hackingWeekend 呼叫約制 Calling Convention push 3 push 2

    push 1 call add add esp,0x0C //add(1, 2, 3) 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3
  89. aaaddress1 // hackingWeekend 呼叫約制 Calling Convention push 3 push 2

    push 1 call add add esp,0x0C //add(1, 2, 3) 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3 2
  90. aaaddress1 // hackingWeekend 呼叫約制 Calling Convention push 3 push 2

    push 1 call add add esp,0x0C //add(1, 2, 3) 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3 2
  91. aaaddress1 // hackingWeekend 呼叫約制 Calling Convention push 3 push 2

    push 1 call add add esp,0x0C //add(1, 2, 3) 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3 2 1
  92. aaaddress1 // hackingWeekend 呼叫約制 Calling Convention push 3 push 2

    push 1 call add add esp,0x0C //add(1, 2, 3) 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3 2 1 12FFEC
  93. aaaddress1 // hackingWeekend 呼叫約制 Calling Convention push 3 push 2

    push 1 call add add esp,0x0C //add(1, 2, 3) 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3 2 1 12FFEC return addr
  94. aaaddress1 // hackingWeekend 呼叫約制 Calling Convention push 3 push 2

    push 1 call add add esp,0x0C //add(1, 2, 3) 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3 2 1 12FFEC 12FFE8 return addr
  95. aaaddress1 // hackingWeekend 呼叫約制 Calling Convention add: push ebp mov

    ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3 2 1 12FFEC 12FFE8 return addr
  96. aaaddress1 // hackingWeekend 呼叫約制 Calling Convention add: push ebp mov

    ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3 2 1 12FFEC caller ebp 12FFE8 return addr
  97. aaaddress1 // hackingWeekend 呼叫約制 Calling Convention add: push ebp mov

    ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3 2 1 12FFEC ebp 12FFE8 return addr caller ebp
  98. aaaddress1 // hackingWeekend add: push ebp mov ebp, esp sub

    esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3 2 1 12FFEC 12FFE8 ebp 12FFE4 呼叫約制 Calling Convention return addr caller ebp local buffer
  99. aaaddress1 // hackingWeekend add: push ebp mov ebp, esp sub

    esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3 2 1 12FFEC 12FFE8 ebp 12FFE4 呼叫約制 Calling Convention EAX: 1 return addr caller ebp local buffer
  100. aaaddress1 // hackingWeekend add: push ebp mov ebp, esp sub

    esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3 2 1 12FFEC 12FFE8 ebp 12FFE4 呼叫約制 Calling Convention EAX: 1+2 return addr caller ebp local buffer
  101. aaaddress1 // hackingWeekend add: push ebp mov ebp, esp sub

    esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3 2 1 12FFEC 12FFE8 ebp 12FFE4 呼叫約制 Calling Convention local buffer EAX: 1+2+3 return addr caller ebp
  102. aaaddress1 // hackingWeekend add: push ebp mov ebp, esp sub

    esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3 2 1 12FFEC 12FFE8 ebp 12FFE4 呼叫約制 Calling Convention 6 EAX: 1+2+3 return addr caller ebp
  103. aaaddress1 // hackingWeekend add: push ebp mov ebp, esp sub

    esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 esp 3 2 1 12FFEC 12FFE8 ebp 12FFE4 呼叫約制 Calling Convention EAX: 1+2+3 return addr 6 caller ebp
  104. aaaddress1 // hackingWeekend add: push ebp mov ebp, esp sub

    esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 3 2 1 12FFEC 12FFE8 12FFE4 呼叫約制 Calling Convention EAX: 1+2+3 esp ebp return addr 6 caller ebp
  105. aaaddress1 // hackingWeekend add: push ebp mov ebp, esp sub

    esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 3 2 1 12FFEC 12FFE8 12FFE4 呼叫約制 Calling Convention EAX: 1+2+3 esp return addr 6 caller ebp
  106. aaaddress1 // hackingWeekend add: push ebp mov ebp, esp sub

    esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 3 2 1 12FFEC 12FFE8 12FFE4 呼叫約制 Calling Convention EAX: 1+2+3 esp EBP: caller ebp return addr 6 caller ebp
  107. aaaddress1 // hackingWeekend add: push ebp mov ebp, esp sub

    esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 3 2 1 12FFEC 12FFE8 12FFE4 呼叫約制 Calling Convention EAX: 1+2+3 esp EBP: caller ebp EIP: return addr return addr 6 caller ebp
  108. aaaddress1 // hackingWeekend 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 3

    2 1 12FFEC 12FFE8 12FFE4 呼叫約制 Calling Convention EAX: 1+2+3 esp EBP: caller ebp push 3 push 2 push 1 call add add esp,0x0C //add(1, 2, 3) return addr 6 caller ebp
  109. aaaddress1 // hackingWeekend 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 3

    2 1 12FFEC 12FFE8 12FFE4 呼叫約制 Calling Convention EAX: 1+2+3 esp push 3 push 2 push 1 call add add esp,0x0C //add(1, 2, 3) return addr 6 caller ebp
  110. aaaddress1 // hackingWeekend 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 12FFEC

    12FFE8 12FFE4 呼叫約制 Calling Convention EAX: 1+2+3 esp push 3 push 2 push 1 call add add esp,0x0C //add(1, 2, 3)
  111. aaaddress1 // hackingWeekend 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 12FFEC

    12FFE8 12FFE4 懶懶⼈人筆記 esp 1. esp 永遠指向 Stack 最⾼高處
 2. [ebp] 保存呼叫者 base pointer
 3. [ebp+4] 指向 return address
 4. [ebp+8+4*0] 為第⼀一個參參數
 [ebp+8+4*1] 為第⼆二個參參數
 [ebp+8+4*2] 為第三個參參數
 ...etc ebp arg 3 arg 2 arg 1 return addr caller ebp 區域變數1 區域變數2 12FFE0 12FFDC 12FFD8 12FFD4 區域變數3
  112. aaaddress1 // hackingWeekend 堆疊 堆疊 12FFF8 12FFF4 12FFF0 記憶體位址 12FFEC

    12FFE8 12FFE4 懶懶⼈人筆記 esp ebp 區域變數1 區域變數2 12FFE0 12FFDC 12FFD8 12FFD4 區域變數3 void func ( int arg1, int* arg2, char* arg3 ){ int buffer = 0; int arr[3]; char data[2]; /* do something */ } arg 3 arg 2 arg 1 return addr caller ebp
  113. aaaddress1 // hackingWeekend 練習 II: 嘗試撰寫出組合語⾔言 http://carlosrafaelgn.com.br/asm86 int add(int a,

    int b) { int tmp = a + b; return tmp; } add(1, 2);
  114. aaaddress1 // hackingWeekend

  115. aaaddress1 // hackingWeekend $ gdb ./a.out gdb-peda$ disassemble add Dump

    of assembler code for function add: 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: sub esp,0x10 0x08048411 <+6>: mov edx,DWORD PTR [ebp+0x8] 0x08048414 <+9>: mov eax,DWORD PTR [ebp+0xc] 0x08048417 <+12>: add edx,eax 0x08048419 <+14>: mov eax,DWORD PTR [ebp+0x10] 0x0804841c <+17>: add eax,edx 0x0804841e <+19>: mov DWORD PTR [ebp-0x4],eax 0x08048421 <+22>: mov eax,DWORD PTR [ebp-0x4] 0x08048424 <+25>: leave 0x08048425 <+26>: ret End of assembler dump.
  116. aaaddress1 // hackingWeekend ; enter push ebp mov ebp, esp

    ; leave mov esp, ebp pop ebp
  117. aaaddress1 // hackingWeekend gdb+peda

  118. aaaddress1 // hackingWeekend 由靜態⽂文件調試 $ gdb <執⾏行行檔案路路徑> gdb-peda$ <gdb 命令>

    http://shell-storm.org/shellcode/files/shellcode-811.php
  119. aaaddress1 // hackingWeekend 列列出函數 gdb-peda$ info functions

  120. aaaddress1 // hackingWeekend 設定不跟蹤⼦子處理理序 gdb-peda$ set follow-fork-mode parent 顯⽰示暫存器內容 gdb-peda$

    print $eax 設定暫存器內容 gdb-peda$ set $eip=xxxxx...
  121. aaaddress1 // hackingWeekend dump 出記憶體內容(hex) gdb-peda$ hexdump 記憶體地址 打印出記憶體內容(以 int

    ⽅方式顯⽰示) gdb-peda$ x/[印出幾組int] 記憶體地址
  122. aaaddress1 // hackingWeekend 確認安全保護狀狀態 gdb-peda$ checksec

  123. aaaddress1 // hackingWeekend breakpoint: gdb-peda$ b *函數名稱 / b *記憶體地址

    ←下斷點 run: gdb-peda$ r ←開始運⾏行行 / 重新創建⼀一個 Process gdb-peda$ r < a.txt ¬開始運⾏行行、並將 a.txt ⽂文字內容傳入作為 input step: gdb-peda$ s ←單步跟蹤 next: gdb-peda$ n ←躍過跟蹤 / 單步跟蹤但不進入 call
  124. aaaddress1 // hackingWeekend 暫存器資訊 gdb-peda$ context register 堆疊狀狀況 gdb-peda$ context

    stack 當前 Program Counter 指向處 gdb-peda$ context code
  125. aaaddress1 // hackingWeekend

  126. aaaddress1 // hackingWeekend gdb 練習(⼀一)

  127. aaaddress1 // hackingWeekend ipython+pwntools

  128. aaaddress1 // hackingWeekend ipython

  129. aaaddress1 // hackingWeekend pwntools 《CTF常⽤用python库PwnTools的使⽤用学习》 www.cnblogs.com/Ox9A82/p/5728149.html

  130. aaaddress1 // hackingWeekend Pwn實戰練習篇章

  131. aaaddress1 // hackingWeekend Pwn 實例例: AIS3 Pwn1

  132. aaaddress1 // hackingWeekend 2017 今年年 AIS3 Pre-Exam ⼤大家有打吧

  133. aaaddress1 // hackingWeekend Pwn1 這題題⽬目,
 我沒有原始碼XD 但我寫了了⼀一模⼀一樣的程式碼, 原汁原味呈現這⼀一題給各位

  134. aaaddress1 // hackingWeekend ⼤大概像這樣啦

  135. aaaddress1 // hackingWeekend

  136. aaaddress1 // hackingWeekend

  137. aaaddress1 // hackingWeekend

  138. aaaddress1 // hackingWeekend

  139. aaaddress1 // hackingWeekend Live Demo

  140. aaaddress1 // hackingWeekend 這題很善良

  141. aaaddress1 // hackingWeekend Pwn1 實戰練習: Touch Cat $ nc pwn.30cm.tw

    1000
  142. aaaddress1 // hackingWeekend

  143. aaaddress1 // hackingWeekend gdb-peda$ disassemble *main

  144. aaaddress1 // hackingWeekend

  145. aaaddress1 // hackingWeekend

  146. aaaddress1 // hackingWeekend Pwn2 實戰練習: bof $ nc pwn.30cm.tw 2000

  147. aaaddress1 // hackingWeekend

  148. aaaddress1 // hackingWeekend gdb-peda$ disassemble *main

  149. aaaddress1 // hackingWeekend 解法⼀一

  150. aaaddress1 // hackingWeekend

  151. aaaddress1 // hackingWeekend 不過並不是每天中樂透, 不會每⽀支 Binary 都會正好有 system("/bin/sh") 給你⽤用...

  152. aaaddress1 // hackingWeekend 解法⼆二 Return-to-libc

  153. aaaddress1 // hackingWeekend 正常的 system 在進入函數前, 會推入字串串指令地址、call會推入 reutrn address。 所以

    Payload 內部得構造為: padding + [eip = system@plt] + [sytem執⾏行行後返回地址] + [/bin/sh 地址] 0x0804851e <+03>: push <指令字串串的地址> 0x08048523 <+08>: call 0x80483d0 <system@plt> 0x08048528 <+13>: add esp,0x4
  154. aaaddress1 // hackingWeekend

  155. aaaddress1 // hackingWeekend

  156. aaaddress1 // hackingWeekend

  157. aaaddress1 // hackingWeekend Pwn3 實戰練習: Secret Keeper $ nc pwn.30cm.tw

    3000
  158. aaaddress1 // hackingWeekend

  159. aaaddress1 // hackingWeekend

  160. aaaddress1 // hackingWeekend

  161. aaaddress1 // hackingWeekend Bonus 篇章

  162. aaaddress1 // hackingWeekend Executable and Linkable Format In computing, the

    Executable and Linkable Format (ELF, formerly named Extensible Linking Format), is a common standard file format for executable files, object code, shared libraries, and core dumps. In 1999, it was chosen as the standard binary file format for Unix and Unix-like systems on x86 processors by the 86open project. refer: en.wikipedia.org/wiki/Executable_and_Linkable_Format
  163. aaaddress1 // hackingWeekend Process 100 110 120 130 140 150

    160 … 當⼀一⽀支執⾏行行⽂文件被點擊時, 會建立為⼀一個 Process(處理理序)內保存執⾏行行⽂文件的機械碼 Executable and Linkable Format
  164. aaaddress1 // hackingWeekend Process 100 A A A A A

    A . . . 110 120 130 140 150 160 … B B B B B B B B B B B B B B B B 不過作業系統不會真的直接開⼀一⼤大片記憶體保存執⾏行行⽂文件內容 Executable and Linkable Format
  165. aaaddress1 // hackingWeekend Executable and Linkable Format

  166. aaaddress1 // hackingWeekend $ objdump -s a.out Contents of section

    .text: 400430 31ed4989 d15e4889 e24883e4 f0505449 1.I..^H..H...PTI 400440 c7c0b005 400048c7 c1400540 0048c7c7 ....@.H..@.@.H.. 400450 26054000 e8b7ffff fff4660f 1f440000 &.@.......f..D.. 400460 b83f1060 0055482d 38106000 4883f80e .?.`.UH-8.`.H... 400470 4889e576 1bb80000 00004885 c074115d H..v......H..t.] 400480 bf381060 00ffe066 0f1f8400 00000000 .8.`...f........ 400490 5dc30f1f 4000662e 0f1f8400 00000000 ]...@.f......... 4004a0 be381060 00554881 ee381060 0048c1fe .8.`.UH..8.`.H.. 4004b0 034889e5 4889f048 c1e83f48 01c648d1 .H..H..H..?H..H. 4004c0 fe7415b8 00000000 4885c074 0b5dbf38 .t......H..t.].8 4004d0 106000ff e00f1f00 5dc3660f 1f440000 .`......].f..D.. 4004e0 803d510b 20000075 11554889 e5e86eff .=Q. ..u.UH...n. 4004f0 ffff5dc6 053e0b20 0001f3c3 0f1f4000 ..]..>. ......@. 400500 bf200e60 0048833f 007505eb 930f1f00 . .`.H.?.u...... 400510 b8000000 004885c0 74f15548 89e5ffd0 .....H..t.UH....
  167. aaaddress1 // hackingWeekend $ objdump -d ./a.out Disassembly of section

    .text: 0000000000400430 <_start>: 400430: 31 ed xor %ebp,%ebp 400432: 49 89 d1 mov %rdx,%r9 400435: 5e pop %rsi 400436: 48 89 e2 mov %rsp,%rdx 400439: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 40043d: 50 push %rax 40043e: 54 push %rsp 40043f: 49 c7 c0 b0 05 40 00 mov $0x4005b0,%r8 400446: 48 c7 c1 40 05 40 00 mov $0x400540,%rcx 40044d: 48 c7 c7 26 05 40 00 mov $0x400526,%rdi 400454: e8 b7 ff ff ff callq 400410 <__libc_start_main@plt> 400459: f4 hlt 40045a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) main function
  168. aaaddress1 // hackingWeekend $ gdb ./a.out gdb-peda$ info functions Non-debugging

    symbols: 0x00000000004003c8 _init 0x0000000000400400 puts@plt 0x0000000000400410 __libc_start_main@plt 0x0000000000400430 _start ... 0x0000000000400500 frame_dummy 0x0000000000400526 main 0x0000000000400540 __libc_csu_init 0x00000000004005b0 __libc_csu_fini ... 0x00007ffff7a2c820 memalign@plt 0x00007ffff7a2c850 _dl_find_dso_for_object@plt 0x00007ffff7a2c870 calloc@plt
  169. aaaddress1 // hackingWeekend gdb-peda$ b *main Breakpoint 1 at 0x400526

    gdb-peda$ r Starting program: /home/pwn/Desktop/a.out
  170. aaaddress1 // hackingWeekend QA aaaddress1@chroot.org

  171. aaaddress1 // hackingWeekend QA aaaddress1@chroot.org