전체 글

포너블/Stack

out of bound

Out Of Boundary란? 배열의 범위를 벗어난 메모리에 접근할 수 있는 취약점으로 개발자가 인덱스에 대한 검사를 제대로 하지 않으면 발생한다. 임의의 주소 읽기, 쓰기로 이어질 수 있다. 예시 #inlcude int main(){ int a[10]; printf("%p\\n", a); printf("%p\\n", &a[0]); printf("----\\n"); printf("%p\\n", a[-1]); printf("%p\\n", a[100]); return 0; } a의 배열이 0부터 9까지 있지만 범위를 넘어서서 오프셋에 따른 메모리를 참조한다. 예제_Dreamhack_out of bound 보호기법 체크 32bit인것을 알 수 있다. c코드 char name[16]; char *command..

포너블/Stack

format string bug

FSB란? printf와 같은 함수의 인자 개수는 포맷 문자 개수로 결정된다. 이때 사용자의 포맷 스트링 입력이 그대로 buf에 값이 넣어지면 우리가 원하는 값을 출력이 가능하다. 예제 #include void initialize() { setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); } int main() { initialize(); char* buf[0x40] = {0,}; printf("입력 : "); read(0, buf, 0x50); printf(buf); return 0; } 해당 코드에 aaaaaaaa를 입력하면 aaaaaaaa를 출력한다. 그런데 buf를 포멧스트링이 아니라 buf 변수 자체로 출력을 하기 때문에 FSB..

포너블/Stack

RELRO

RELRO란? Relocation Read-Only elf 바이너리 프로세스의 데이터 섹션의 메모리가 변경되는 것을 보호하는 기법이다. 크게 3가지가 있다. NO RELRO, Partial RELRO, FULL RELRO NO RELRO ELF의 기본헤더, 코드 영역을 제외한 거의 모든 부분에 Read, Write 권한을 주는 것이다. 거의 모든 부분을 읽고 쓰고 할 수 있으니 보안에 매우 취약하다. 파란선 아래로 쓰기가 가능하다. .fini_array overwrite, got overwrite 이 가능하다. Partial RELRO 몇몇 부분에 쓰기권한이 없어졌다. 파란선 아래로 쓰기가 가능하다. .fini_array overwrite는 불가능하다. got overwrite는 가능하다. 참고로 got..

포너블/Stack

PIE

위치독립실행, 바이너리 주소 랜덤화 즉 메모리상의 명렁어들의 위치가 매번 바뀐다. ASLR이 코드 영역에도 적용되게 해주는 기술이라고 볼 수 있다. 이때 ASLR이 0이면 PIE를 적용해도 주소랜덤화는 작동을 하지 않는다. ASLR이 1이면 PIE를 적용했을 때 전체 주소가 랜덤화된다. (2일때도 마찬가지) 예 #include int hello(){ printf("hello"); return 0; } int x; int y = 10; int main(){ int a; int *b = (int_)malloc(10); printf("code : %p\n", hello); printf("Data : %p\n", &y); printf("BSS : %p\n", &x); printf("heap : %p\n", b)..

포너블/Stack

ROP

ROP란? Return Oriented Programming GOT overwrite, RTL, RTL chaining 등을 종합적으로 쓰는 공격기법 구해야 하는 것들 read_plt, read_got, write_plt, write_got, read에 대한 system의 offset, pppr가젯주소, bss주소 등이 있고 꼭 위의 것들이 아니여도 유연하게 할 수 있다. 공격순서 buf,sfp 채우기 write_plt로 write함수 호출하고 pppr 가젯을 사용, 인자값으로 read_got참조, 즉 read의 실제 주소 출력한다. read의 실제주소 - read_offset 으로 libc_base 를 구해낸다. libc_base + system_offset 으로 system의 실제 주소를 구해낸다. ..

포너블/Stack

one gadget & GOT Overwrite

one gadget조건이 충족되면 한번에 셸을 따버리는 가젯이다.분석리눅스 명령어 strings를 이용해서 libc.so.6 파일에서 /bin/sh 문자열을 찾아낸다.그리고 objdump로 /bin/sh 가 들어간 곳을 모두 찾아낸 후 근처에 execve 함수가 있는 곳을 찾아본다.이런식으로 one gadget을 찾을 수 있다.그리고 이것을 one shot gadget 툴을 이용해서 쉽게 찾을 수 있다.이는offset 값 함수의 형태constraints:조건와 같은 형태를 지닌다.예를 들어서 이 부분에 해당하는 부분을 보면 아래와 같다.조건이 충족되면 execve(”/bin/sh”, rsp+0x30, environ) 라는 함수가 실행이된다. 그리고 그 조건으로는 rsp+0x30부분이 null이면 된다. ..

포너블/Stack

PLT, GOT

PLT 외부 프로시저를 연결해주는 테이블, PLT를 통해 다른 라이브러리에 있는 프로시저를 호출해 사용할 수 있다. GOT PLT가 참조하는 테이블, 프로시저들의 주소가 들어있다. 처음 호출 함수 호출 -> PLT 이동 -> GOT 참조(null) -> dl_resolve 함수 실행 -> GOT에 함수 주소 쓰여짐 -> 해당 함수로 점프 처음 이후의 호출 함수 호출 -> PLT 이동 -> GOT 참조(주소 존재) -> 해당 함수로 점프 debugging 처음 printf를 실행한다. printf_got 로 jump 한다. _dl_runtime_resolve_xsavec 실행 한 번 실행 후에는 got에 실제 주소가 쓰여 있다.

포너블/Stack

ASLR

ASLR이란? 주소 공간 배열 무작위화, 즉 실행할때마다 데이터 영역의 주소를 무작위화시켜서 직접적인 메모리 주소 참조가 힘들어진다. echo [NUM] > /proc/sys/kernel/randomize_va_space num = 0 : aslr 해제 num = 1 : 스택, 라이브러리 랜덤화 num = 2 : 스택, 라이브러리, 힙 랜덤화 예시 #include #include int main() { int stack; int *heap = (int*)malloc(3); printf("stack address : %p\n", &stack); printf("printf address : %p\n", printf); printf("heap address : %p\n", heap); return 0; } s..

K0n9
K0n9.log