UNF
2008-04-09 04:00:07来源:互联网 阅读 ()
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
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 巡风源码阅读与分析---view.py 2018-08-02
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash