UAF(User After Free) Heap 메모리 취약점을 이용하는 공격이다.

 

1. Heap

Heap 동적 메모리 할당을 위해 존재하는 공간이다.

UAF 발생하는 이유는 Heap 메모리 효율 관리목적에서부터 시작한다.

 

Heap 메모리 동적 할당을위해 Operation System 할당을 진행하기 위한 Chunk size별로 관리한다. 예를들어 4byte , 16byte, 256byte 같이 2 제곱수에 의한 사이즈별로 메모리 공간을 관리한다. Linux Kernel Buddy 시스템을 이해하고 있다면 위와같이 이해가 빠를 있다.

결론적으로는 빠른 할당을 위해 size별로 free memory list만들어서 관리하는 것으로 이해하면 된다.

 

그리고 Free -> realloc 속도를 빠르게 하기위해 free 진행된다고 바로 해당 데이터를 제거하지않는 성질이 있다.

보통의 프로그램의 경우 malloc free 반복되며 짧은시간에 다시 재할당된 메모리의 경우 기존과 같은동작을 하기 때문에 이와 같이 효율적으로 heap 공간의 해제와 할당 함수가 구현되어있다.

 

 

내용을 정리하면 아래와 같은 문제점이 발생하게 된다.

 

먼저 Object A malloc 통해 Heap 메모리 공간을 할당받고 사용한다.

 

그리고 free() 통해서 Object A 메모리공간을 해제한다.

 

해제 직후 Object B에서 Object A 같은 size공간을 할당하면 위와 같이 기존 A Heap영역을 그대로 사용하게 된다.

이경우 Object B입장에서는 새로 생성한 obejct임에도 불구하고 이미 chunk data들이 write되어있어문제가 발생할 있다.

 

 

 

2. UAF

User After Free Heap 특징을 이용한 취약점이다.

할당 Free 진행했음에도 기존에 object 관리하기 위해 Heap영역을 가리키던 pointer자체는 null 가리키는 것이아닌 제거되지 않은 메모리 공간을 가리키게된다.

이러한 포인터를 dangling pointer라고 하며 공격자는 dangling pointer 활용하여 프로그래머가 의도하지 않은 공격을 진행할 있다.

 



#include <stdio.h>
#include <stdlib.h>


void print_test(void) {
    printf("Test UaF vuln()\n");
}


typedef struct {
    void (*func)(void*);
    char name[10];
}UAF_TEST;
int main (void) {
    UAF_TEST* M1;
    UAF_TEST* M2;
    M1 = (UAF_TEST*)malloc(256);
    strcpy(M1->name,"TEST_UAF");
    M1->func = (void*)print_test;
    printf("Address : %02x\n", M1);
    printf("Data : %s\n",M1->name);
    printf("function : %02x\n",&M1->func);
    free(M1);
    M2 = (UAF_TEST*)malloc(256);
    printf("Address : %02x\n", M2);
    printf("function : %02x\n",&M2->func);
    M2->func;
    return 0;
}

코드는 User After Free 발생시키는 기본적인 코드이다. Heap 예제와 마찬가지로 Object malloc으로 할당을 진행하고 data, pointer값을 write진행한다. 이후 free -> Object2 바로 할당을 진행한다.

 

Address : 8fc11a0
Data : TEST_UAF
function : 8fc11a0
Address : 8fc11a0
function : 8fc11a0

프로그램을 실행하면 결과 값을 얻을 있다.

만약 scnaf 같은 입력함수가 존재한다면 공격자는 dangling pointer 활용해서 function 가리키는 주소 0x8fc11a0 공격자가 실행시키고자 하는 exploit code 주소를 입력해서 공격할 있을 것이다.

 

 

추가적으로 gdb-peda 통해 debug 진행해보았는데

0x8fc11a0에서 print_test()주소가 입력된 것을 확인할 있었고 Data역시 0x8fc11a4에서 확인 가능했다.

free object2 할당하여 메모리 공간을 확인하였을 때는 data 일부와 print_test() 가리키는 주소 값이 지워져 있었으나 공격자 입장에서 어느 주소 값이 func() 가리키는 값인지 있기 때문에 해당 주소만 overwrite해주면 func() 호출할 공격자가 의도한 프로그램이 실행하는 문제가 발생할 것이다.

 

 

+ Recent posts