Photo Gallery - Hacker101 Write Up

pan30pan30
3 min read

Flag 0

ở chall này cho mình một trang web như sau, đầu tiên nhìn vào mình không thấy bất kỳ đầu vào nào nên mình kiểm tra src code của nó

có một số 3 endpoint ở thuộc tính src và khi mình click vào thử thì đầu ra như sau

do chưa có thông tin gì nên từ tham số id trong url mình thêm một dấu ‘ vào sao giá trị 1 (để kiểm tra có lỗ hổng sqli nào không) và đúng như dự đoán máy chủ phản hồi mã 500 ⇒ có tồn tại lỗ hổng SQLi

tới đây mình thử nhiều payload khác nhau nhưng không thu được gì, nên mình quyết định xin tí hint….

  • Hint:

    1. Consider how you might build this system yourself. What would the query for fetch look like?

    2. Take a few minutes to consider the state of the union

    3. This application runs on the uwsgi-nginx-flask-docker image

sau khi tìm hiểu uwsgi-nginx-flask-docker là gì thì mình biết được đây là một ứng dụng server WSGI (Web Server Gateway Interface) cho phép các ứng dụng Python (như Flask) tương tác với server web

nguồn mình tham khảo:

https://github.com/tiangolo/uwsgi-nginx-flask-docker

có một tệp gọi là uwsgi.ini đây là tệp cấu hình cho uWSGI

vì vậy mình xây dựng một payload để query tệp uwsgi.ini này thử, thì đây là kết quả mình nhận được

từ đầu ra mình biết được có một tệp gọi là main.py nên tiếp theo mình thay main.py vào payload và nhận được src code và flag đầu tiên như sau

Flag 1,2

Sau một hồi phân tích src code thì cụ thể như sau:

tên database hiện tại: level5

và có một filters encode các ký tự (mình nghĩ là để filters này chặn lỗ hổng XSS)

và các tables: albums, photos

Nhưng đều đặc biệt nằm ở route / cụ thể ở đoạn này

cur.execute('SELECT id, title, filename FROM photos WHERE parent=%s LIMIT 3', (id,))
fns = []
for pid, ptitle, pfn in cur.fetchall():
rep += '<div><img src="fetch?id=%i" width="266" height="150"><br>%s</div>' % (pid, sanitize(ptitle))
fns.append(pfn)

lấy trực tiếp tham số id truyền vào câu query ⇒ sqli

rep += '<i>Space used: ' + subprocess.check_output('du -ch %s || exit 0' % ' '.join('files/' + fn for fn in fns), shell=True, stderr=subprocess.STDOUT).strip().rsplit('\\n', 1)[-1] + '</i>'

lấy trực tiếp tên tệp và cộng vào chuỗi lệnh để thực hiện một lệnh shell, cụ thể mình có thể lợi dụng sqli để update tên tệp thành một chuỗi lệnh sau đó sẽ có thể khai thác lỗ hổng command injection này.

vậy bây giờ đã có đầy đủ thông tin mình có thể xây dựng một payload để khai thác lỗ hổng command injection rồi

đầu tiên mình cần update là tên tệp trong table photos

id=1;%20update%20photos%20set%20filename=%27*%20||%20ls%20./files%20%3Etemp.txt%20%27%20where%20id=3;%20commit;%20--

cụ thể payload này cập nhật lại tên tệp của ảnh thứ 3 trong bảng photos thành * || ls ./files >temp.txt (liệt kê tất cả thư mục lưu vào tệp temp.txt)

sau đó mình sử dụng lại payload ban đầu để đọc tệp temp.txt, và không có gì đặc biệt

sau một lát thay đổi payload để xem các biến môi trường thì mình đã nhận được cờ ^^

id=1;%20update%20photos%20set%20filename=%27*%20||%20env%20%3Etemp.txt%20%27%20where%20id=3;%20commit;%20--

0
Subscribe to my newsletter

Read articles from pan30 directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

pan30
pan30

Red