Shellcoding教程:介紹ASM

      網上看到一篇不錯的介紹shellcode的入門文章,我就大體翻譯一下,算是本身真正跨入二進制安全相關領域的學習吧。原文地址:http://www.primalsecurity.net/0x0-shellcoding-tutorial-introduction-to-asm/linux

      如下爲翻譯內容:(非逐句翻譯)shell

      彙編代碼介紹:編程

      彙編語言是一種爲了方便與微處理器交互而設計的低級編程語言。該語言是與處理器系列相關聯的,如Intel、ARM等。在理解彙編的時候,體系結構發揮了重要的做用,由於在32位和64位之間存在很大的不一樣。在這裏咱們主要集中到Linux下的Intel(IA-32)。安全

      今天咱們看到的CPU寄存器爲EAX、EBX、ECX和EDX。在最初設計時,這些寄存器擁有通常的功能。可是基於咱們的目的,咱們能夠在每一個時序存儲任何咱們喜歡的數據。這些寄存器的標準用法以下:編程語言

EAX編輯器

「累加器」一般用於算術運算函數

EBX學習

基址寄存器,做爲數據指針ui

ECXspa

「計算器」,用於循環的索引

EDX

數據寄存器,充當一個I/O指針

      在後續文章中,咱們會介紹其餘一些寄存器。

      操做咱們的寄存器:

      首先,咱們會利用以前提到的寄存器建立一個基本的「hello world」的彙編語言腳本。要作到這一點,咱們先建立一個名爲「helloworld.asm」的新文件(能夠取任何你想取的名字),而後在文本編輯器中建立‘.text’和‘.data’兩個段,以下所示:


section .text
global _start       ;default entry point for linking

_start:             ; entry point for commands

section .data

      .data段咱們將用於存儲字符串(這能夠用於變量等),.text段將建立ELF連接的入口,咱們的指令用於操做寄存器設置咱們的系統調用(多個),以及咱們的指令給內核執行咱們的系統調用。

      首先,咱們須要使用define byte或者db把咱們的字符串添加到.data段中:


msg: db 「Hello World!:,0x0a ; the string, followed by a new line character

      接下來,咱們須要決定什麼系統調用將用於咱們的彙編指令。爲了查看可用的系統調用,咱們須要查看「uninstd_32.h」文件,通常存在於「/usr/include/i386-linux-gnu/asm/」或者可能在其餘位置。咱們能夠打開這個文件查看可用的調用:

48

      當即看到兩個咱們利用的系統調用,exit函數(#define __NR_exit 1)和write函數(#define __NR_write 4)。注意着兩個系統調用號由於咱們會在後面使用到。咱們可使用「man 2」來查看關於這些系統調用的細節。(例如:man 2 write):

49

      查看man文件,看到咱們須要使用多個字段,‘int fd’(字段描述符),‘const void *buf’(緩衝區),‘size_t count’(字符串大小)。在這個例子中,咱們的字段描述符指示咱們將要寫入的位置(0表明標準輸入,1表明標準輸出,2表明標準錯誤)。在這裏,咱們的緩衝區,就是‘Hello World!’字符串,計數器就是緩衝區的長度。總括來講,咱們有幾下幾點:

  • syscall:4;系統調用號表明咱們的write命令
  • fd:1;字段描述符指示咱們的字符串將被寫到標準輸出
  • *buf:msg;咱們在.data段中建立的hello world字符串
  • count:13;咱們緩衝區的長度12加上一個換行符

      如今,咱們已經標識的必要的信息,咱們能夠開始操做寄存器了。要作到這一點,咱們將使用Intel系統結構的寄存器操做的mov命令:


mov [destination],

      咱們將重複mov與四個字段的每個,依次爲EAX,EBX,ECX和EDX寄存器,後面再加上」int 0x80」命令來執行系統調用。


section .text
global _start       ;default entry point for linking
 
_start:             ; entry point for commands
 
     ; use the write syscall to print 'Hello world!' to stdout
     mov eax, 4          ; move syscall 4(write) to the eax register
     mov ebx, 1          ; move field descriptor for stdout to ebx
     mov ecx, msg        ; move the memory address of our string to ecx
     mov edx, 13         ; move the length of the string to edx
     int 0x80       ; execute the syscall
 
section .data
     msg: db 「Hello world!」, 0x0a  ; the string, followed by a new line character

      如今,咱們已經當心的編寫了write系統調用。咱們須要遵循相同的步驟,乾淨執行程序。要作到這一點,咱們將使用前面提到的「exit」的系統調用.這一次,咱們僅須要利用」int status「,下面的步驟用於exit系統調用後,你的代碼將和下面相似:


section .text
global _start       ;default entry point for linking
 
_start:             ; entry point for commands
 
     ; use the write syscall to print 'Hello world!' to stdout
     mov eax, 4          ; move syscall 4(write) to the eax register
     mov ebx, 1          ; move field descriptor for stdout to ebx
     mov ecx, msg        ; move the memory address of our string to ecx
     mov edx, 13         ; move the length of the string to edx
     int 0x80       ; execute the syscall
 
     ; use the exit syscall to exit the program with a status code of 0
     mov eax, 1          ; mov syscall 1(exit) to the eax register)
     mov ebx, 0          ; move status code to ebx
     int 0x80       ; execute the syscall
 
section .data
     msg: db 「Hello world!」, 0x0a  ; the string, followed by a new line character

      建立咱們的可執行程序:

      如今,咱們的彙編代碼已經建立了,接下來將要把它編譯稱爲目標文件,而後使用連接器建立咱們的ELF可執行文件,咱們使用以下的NASM命令來建立咱們的目標文件:

nasm -f elf32 -o <output object file> <input assembly file>

      如今咱們有了一個成功的目標文件,咱們可使用ld來連接它,而後建立最後的執行文件。咱們使用以下命令:

ld -o <output file> <input object file>

      假設這種狀況成功了,咱們應該有了一個全功能的ELF可執行程序。如今,咱們能夠執行咱們的文件,而且保證正確執行。

      附上NASM的下載地址:http://www.nasm.us/pub/nasm/releasebuilds/2.11.08/

相關文章
相關標籤/搜索