UNF

2008-04-09 04:00:07来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折





UNF && pr1 present: Writing Linux/x86 shellcodes for dum dums.
翻译:1cbm(1cbm)

UNF && pr1 present: Writing Linux/x86 shellcodes for dum dums.

=============================================
作者 : pr1 ( pr10n@u-n-f.com )
翻译 : ICBM@cmmail.com
非常感谢keji指出并改正了原文和翻译中出现的错误,Sank u !
http://www.airarms.org
http://icbm.n3.net
=============================================


-----------------------------------------------------------------------------------------------
Copyright (c) February 2002, Sebastian Hegenbart (a.k.a pr1) and UNF (United Net Frontier)
The following material is property of UNF && pr1.
Do not redistribute this article modified and give proper credit to UNF and pr1 if you
redistribute it or if you write your own article based upon the following material.
-----------------------------------------------------------------------------------------------

1.介绍

在网上并没有几篇好文章介绍怎样编写shellcode,而且很不幸,阅读它们需要有很丰富的汇编知识,所以在这篇文章里我会给大家介绍Linux/x86汇编知识,并且讲解怎么为Linux/x86书写shellcode。但是,这篇文章中对于ASM的介绍并不完整,我只是讲到一些在对于编写shellcode方面很重要的部分。我会很好的解释文章里出现过的代码,但是任何东西都代替不了一本好的ASM书籍和一个反编译器。:)

1.2. shellcode是什么

简单地说shellcode就是一组CPU指令。为什么叫做shellcode呢?是因为第一个shellcode只是简单的获得一个shell。实际上这种功能已经非常原始了:)。因为已经有了远程的shellcode(有UDP也有TCP),破坏chroot的shellcode,给文件加一行信息的shellcode,setreuid的shellcode等等...因为每个人都这样叫它shellcode所以我会在全文中使用shellcode一词。

1.3. 我们用shellcode来做什么?

在我们接管了一个进程(希望是root运行的 suid|sgid|deamon)以后,我们通常会让它做一些有用的事情。这里有很多技术像return into libc,GOT overwrite addys,PLT infection,exploiting .dtors ... 如果你不能执行其它函数来完成你需要的任务(像重写函数指针, ...)你就可能需要使用到shellcode。或许只是简单的用某些缓冲地址来改写%eip,然后向后跳到一组NOPS指令中,你的CPU会从已经被改写过的%eip中向前取址.当你已经编好了一个漏洞攻击程序,在你的输入缓冲区中填入shellcode当%eip指向到shellcode的开始处,它就会被运行.这样你就赢了!

1.4 我要怎么写shellcode

好了,现在让我们进行这篇文章的主要部分.我现在假设你至少有一定的c语言知识.

=-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=
2.汇编

ASM是一种低级编程语言。它甚至可以设定你CPU中的晶体管状态.一个IA-32 CPU有很多寄存器,访问这些寄存器要比直接访问内存快得多。你可以通过给寄存器赋值来告诉你的程序要做什么。最重要的寄存器有:陎,離,靫,韝,%esp,%esi,%eip,韎。所有32位CPU的寄存器都是4字节长。你可能认为这些寄存器的名字取得没有一点创意,但你错了:

# 陎 是累加器。当有系统调用发生时内核会检查陎中的值,这个值会被用作系统调用号(每个内核提供的系统调用都有它自己的系统调用号).你可以在/usr/include/asm/unistd.h中具体查找这些系统调用号。

# 離 是基址寄存器.我们传递给函数的第一个参数就被放在这个寄存器里面.

# 靫 第二个参数.

# 韝 第三个参数.

# %esp 是堆栈指针寄存器,它指向当前堆栈储存区域的顶部.

# 雙 是基址寄存器,它指向当前堆栈储存区域的底部.

# %eip 是指令指针(在缓冲区溢出中对我们最有用的寄存器)

# %esi and 韎是段寄存器(用它们可以在你的shellcode里存储用户数据)(译者:原文为%eip and 韎)


2.1 修改寄存器:

有很多命令可以用来修改寄存器.你可以通过给一条指令增加后缀来修改一个字节,一个字或者整个寄存器.

例如:movl,movb,movw (long,byte,word)


# mov ...mov指令用来把某值传送到一个寄存器中(数字或者另一个寄存器的内容...).在AT&T语法中(我会在整篇文章中使用这种语法)目标操作数在右边,原操作数在左边.

# inc,dec ...增加或者减少寄存器的值.

# xor ... 这是位运算操作(包括 not,or,and,xor和neg).

在处理shellcode时xor扮演了一个很特殊的角色.
在这里解释一下xor的基本操作:

1异或0为:1,0和0为:0,1和1为:0,因此 xor 4,4是0(100 xor 100 ==000);

#leal ...(表示读取一个long型的有效地址)你可以使用这个指令把一段内存的地址读取到寄存器中.

# int $0x80这是一个中断.简单地说是用来切换到内核模式然后让内核执行我们的函数.

# push,pop ...在堆栈上读取存储数据.

注意:你可以访问一个寄存器低端字中的高字节或者低字节(%al,%ah),一个寄存器中的低端字或者整个(扩展)寄存器(陎).但是没有方法访问一个寄存器的高端字.
寄存器可以以字节方式(%al,%bh,...),字方式(%ax,%bx,...)和整个方式(陎,離,...)访问.


预备了这些知识后我可以写一些asm代码然后再写一些shellcode.


让我们用一个Hello, world开始:) (这是没有办法来代替的)

.data
message:
.string "Hello, world\n"

.globl main
main:

# write(int fd,char *message,ssize_t size);

movl $0x4,陎 # 把/usr/include/asm/unistd.h里定义的系统调用4放到陎中
movl $0x1,離 # 标准输出文件描述符(stdout)
movl $message,靫 # 把message的地址放到靫中
movl $0xc,韝 # message的长度

#exit(int returncode);

movl $0x1,陎 # 系统调用号1

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Linux/390shellcodedevelopment

下一篇:IIS5_IDQ命令行溢出程序源代码