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/

相关文章
相关标签/搜索