본문 바로가기

DreamHack: System Hacking

(45)
__builtin_expect() ( __glibc_unlikely(), __glibc_likely() ) 해당 글은 glibc를 분석할 때 자주 보게 되는 __builtin_expect(), __glibc_unlikely()가 무엇인지 설명하기 위해 작성한 글이다. 사전 지식우리가 코드를 짜서 이를 실행할 때, CPU는 현재의 실행 흐름에 맞게 하나의 코드씩 순차적으로 연산하는 것이 아니다. CPU는 "분기 예측"을 통해 효율성을 극대화 시키는데, 이를 아주 짧게 설명해보자면 다음과 같다. CPU는 앞에서 만나게 될 분기문의 결과를 예측하여 특정 경로를 타고가며 코드를 미리 연산해놓는다. 그리고 그 분기 예측이 맞았을 경우에는 미리 연산해뒀던 결과들을 이용하고, 분기 예측이 틀렸을 경우에는 미리 연산해뒀던 것들을 모두 버리고 분기문의 결과에 맞게 새로 분기 예측을 시작한다.(분기 예측에 관해 몇 줄로 요약하..
ptmalloc2(glibc 2.23) _int_malloc(), _int_free() 동작 분석 2023년 8월 시점에 glibc 2.23에 대해 글을 쓰는 이유 glibc는 버전이 업데이트 될 때마다 새로운 기능을 추가하거나 취약점들을 보완하며, 현재 release된 최신 glibc 버전은 glibc 2.38이다. 그럼 '왜 이런 구닥다리 버전의 glibc를 분석하는 글을 기재하냐?' 라고 물을 수 있는데, 이는 glibc가 업데이트 될 때마다 취약점들을 업데이트하고 새로운 기능들을 추가하긴 하지만, 대부분은 원래 있던 버전의 소스코드에 코드를 "추가" 하는 것이지, 원래 있던 코드를 삭제하고 그것을 "새로 쓰는 것"은 아니기 때문이다. 따라서 한 버전의 glibc를 통해 heap의 동작을 이해한다면, 이후에 나오는 glibc 버전에서는 어떤 요소가 새로 추가되었는지, 또는 변경되었는지만 확인하면..
validator 이 문제와는 별개로 Stage 15 -> Logical Bug: Path Traversal에 관한 내용은 아래에 잘 설명돼있다. https://dreamhack.io/lecture/courses/111 Logical Bug: Path Traversal Path Traversal 취약점에 대해 배우고, 이를 공격에 활용하는 방법을 학습합니다. dreamhack.io 이 문제는 소스코드 없이 바이너리만이 주어진다. 따라서, 바이너리를 리버싱 하여 취약점을 찾아내고 그를 통해 exploit 해야 하는 문제이다. (참고로. 바이너리로 주어진 validate_dist와 validate_server는 코드를 살펴봤을 때 차이가 없어 나는 validate_dist를 타겟으로 삼아 문제를 풀었다.) 보호 기법 어떠한 ..
cmd_center Logical Bug: Command Injection과 관련해서는 https://dreamhack.io/lecture/courses/108 Logical Bug: Command Injection 명령어를 실행해주는 함수를 잘못 사용하여 발생하는 Command Injection취약점에 대해 배워보겠습니다. dreamhack.io 에 아주 자세하고 간략하고 알기 쉽게 설명돼있으니 강의를 꼭 수강하기 바란다. 소스 코드 #include #include #include #include void init() { setvbuf(stdin, 0, 2, 0); setvbuf(stdout, 0, 2, 0); } int main() { char cmd_ip[256] = "ifconfig"; int dummy; char ..
sint Logical Bug: Type Error와 관련된 내용은 https://dreamhack.io/lecture/courses/118 Logical Bug: Type Error 타입을 잘못 사용하여 발생할 수 있는 버그를 학습합니다. dreamhack.io 에 아주 자세히 설명돼있으니 꼭 강의를 수강하길 바란다. 소스코드 #include #include #include #include void alarm_handler() { puts("TIME OUT"); exit(-1); } void initialize() { setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); signal(SIGALRM, alarm_handler); alarm(30);..
tcache_dup2 소스코드 및 보호 기법 Partial RELRO가 적용돼있으니 tcache_dup과 마찬가지로 GOT overwrite 공격을 고려해볼 수 있겠다. 소스코드에 청크의 데이터를 출력해주는 코드가 없으므로 libc base를 구하기 어려워 hook overwrite는 힘들고, while(1)을 통해 무한반복문을 돌기 때문에 bof를 통한 공격도 어렵다. #include #include #include #include char *ptr[7]; void initialize() { setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); } void create_heap(int idx) { size_t size; if (idx >= 7) exit(0)..
tcache_dup 소스코드 및 보호 기법 Partial RELRO가 적용돼있으니 GOT overwrite, hook overwrite 등등을 고려해볼 수 있겠다. while(1)을 통해 반복문이 무한 반복되므로 bof를 이용한 공격은 현실적으로 어렵다. // gcc -o tcache_dup tcache_dup.c -no-pie #include #include #include #include char *ptr[10]; void alarm_handler() { exit(-1); } void initialize() { setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); signal(SIGALRM, alarm_handler); alarm(60); } int cr..
Tcache Poisoning Tcache Poisoning Tcache Poisoning은 free list에 중복되어 있는 청크를 재할당하면, 해당 청크가 해제된 청크임과 동시에 할당된 청크라는 점을 악용하여 원하는 주소에 청크를 할당하고, 원하는 주소에 할당된 청크를 통해 원하는 주소의 값을 읽거나 원하는 주소의 값을 overwrite 시킬 수 있는 기법이다. 소스코드 및 보호 기법 -Full RELRO와 NX가 적용되어 있으니, hook overwrite를 고려해볼 수 있겠다. 소스코드에서 while(1)을 통해 반복문이 무한 반복되므로 bof를 통한 공격은 현실적으로 어렵다. #include #include #include int main() { void *chunk = NULL; unsigned int size; int i..