Chắc hẳn khi đọc bài viết này thì mọi người không còn xa lạ gì với CTF - Capture The Flag rồi nhỉ. CTF được chia làm thành 02 loại là Jeopardy và Attack Defense (AD), thường các giải tổ chức thường theo thể thức Jeopardy, dù lớn hay nhỏ. Và để có thể tổ chức được một giải CTF Jeopardy thì cần phải có một nơi để có thể quản trị. Trên thế giới có rất nhiều platform
khác nhau để có thể tổ chức, tuy nhiên trong bài viết này mình sẽ hướng dẫn cách để có thể cấu hình một giải CTF từ A -> Z để các bạn có thể tự host giải CTF cho riêng mình
CẢNH BÁOCác bạn có thể dựa trên doc CTFd để có thể config, tuy nhiên bài viết dựa trên kinh nghiệm cá nhân mỗi khi làm giải CTFd, mình sẽ nói một cách dễ hiểu các bước thực hiện và tại sao cần phải làm như vậy
Setup môi trường chạy
Để tổ chức một giải đấu thì ta cần có một máy để host, chúng ta có thể dùng VPS
để có thể host online hoặc có thể dùng Local Machine
để có thể host
Tại thời điểm bài viết, mình sẽ dùng cấu hình như sau
- Ubuntu 22.04.5
- 08 GB RAM
- 04 Processors
Các Dependency cần thiết
Docker
Để chạy được CTFd
ta cần phải có Docker, để cài được Docker chạy trên máy ta có thể thực hiện theo trang web này tại đây hoặc có thể làm theo các câu lệnh dưới đây
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
Git
Ngoài Docker, Git là công cụ cần thiết để có thể tải các plugins
, themes
hỗ trợ cho giải CTF
sudo apt install git
Setup CTFd
Build from Prebuild Image
CTFd đã cung cấp image sẵn, chúng ta chỉ cần chọn bản phù hợp, kéo image về rồi run. Tại đây mình sẽ chọn phiên bản mới nhất với các cú pháp sau:
docker pull ctfd/ctfd:<version_bạn_muốn>
Đợi sau khi hoàn thành, chúng ta sẽ thực hiện run nó bằng command dưới đây, giải thích câu lệnh thì câu lệnh này giúp ta chạy container tại port 80 map với port 80 của container
docker run -d -p 80:80 ctfd/ctfd:<version_bạn_muốn>
Kiểm tra bằng câu lệnh
docker ps
Sau đó chúng ta đã có thể truy cập vào bên trang web bằng địa chỉ IP
tại port 80
. Kiểm tra địa chỉ IP thông qua lệnh ip a
. Trong trường hợp này là địa chỉ 192.168.88.129
Truy cập thông qua Web, như hình dưới ta đã deploy thành công
Build from source
Vì cách trên có một số hạn chế đó chính là khó để có thể tùy biến
vì thế còn có một cách khác đó chính là build image từ chính trên trang Github
Chỉ cần thực hiện các câu lệnh sau:
git https://github.com/CTFd/CTFd.git
cd CTFd
docker compose up -d
Sau khi chạy xong, chún ta sẽ thấy được 04 containers
đang được chạy
Và cũng thử truy cập vào trang Web bằng địa chỉ IP của máy host CTFd, ta cũng sẽ có kết quả tương tự
Advanced Setup CTFd
Ở trên chỉ là cấu hình để CTFd có thể hoạt động, ngoài ra còn rất nhiều thứ cần phải làm để giúp cho CTFd có thể hoạt động để thi đấu, tại phần này, mình sẽ hướng dẫn cách cài các thành phần sau:
Nếu các bạn đã có VPS hoặc máy bạn có thể nat port
ra bên ngoài thì mình sẽ tới phần Advance setup
- Cấu hình DNS
- SSL
- Remote Database
- Google Mail server
- Remote Docker Instance
Cấu hình DNS
Để cấu hình DNS, ta sẽ cần tới ba thứ:
- Thông tin Domain
- Địa chỉ IP public
- Tài khoản cloudflare
Vê phần thông tin domain, ta có thể lên các trang mạng để có thể mua địa chỉ, và nếu các bạn muốn có một tên domain
free thì có thể làm theo bài viết này tại đây
Về phần địa chỉ IP Public, thì ta có thể lấy từ trên VPS
hoặc từ các máy cloud
Sau khi đã có hai thứ trên, ta sẽ tạo tài khoản Cloudflare
hoàn toàn miễn phí, và thực hiện trỏ tên miền về của mình về.
Giả sử mình có các thông tin sau:
- IP: 35.229.144.39
- Domain: jerryyytheduck.id.vn
Mình sẽ tiến hành vào trong dashboard
của Cloudflare
để tiến hành trỏ IP
vào domain
vơi các bước đầu như hình
Sau khi nhấn Add record
, ta sẽ thêm type A
vào và gắn trường name bằng tên mình muốn, tại đây mình muốn để là subdomain
nên sẽ để là ctf
, nếu các bạn muốn nó là domain chính luôn thì nhập vào @
trong trường name. Phần content sẽ để địa chỉ IPv4
mà mình muốn trỏ, trong trường hợp này là 35.229.144.39
Cloudflare sẽ cho chúng ta biết thông tin, như hình bên dưới, đã ghi rõ url ctf.jerryyytheduck.id.vn
sẽ được mapping với địa chỉ 35.229.144.39
. Sau khi kiểm tra, nhấn save là thành công.
CẢNH BÁOTại đây, để truy cập thì phần
Proxies
trong CF nên được tắt bởi tại đây chúng ta chưa cấu hìnhssl
để có thể truy cập thông quahttp
Đây là khi ta chưa sử dụng trỏ DNS, truy cập thẳng bằng IP
Và sau khi chúng ta mapping rồi truy cập bằng tên domain thành công như hình bên dưới
Kiểm tra lại lần nữa thông qua CMD
Cấu hình chứng chỉ SSl
Khi tạo chứng chỉ SSL, ta có rất nhiều cách khác nhau, có thể xin từ Domain provider
hoặc là có thể tự tạo miễn phí như Let's Encrypt
. Tại đây, mình sẽ thực hiện trên Let's Encrypt
.
Sử dụng các câu lệnh sau:
#cài đặt certbot
sudo apt install certbot
#tạo chứng chỉ
sudo certbot certonly --standalone -d <domain_của_bạn>.com -d www.<domain_của_bạn>.com
CẢNH BÁOTại đây, nếu domain của bạn dùng là subdomain, thì bạn chỉ cần dùng command như ảnh bên dưới, còn nếu bạn dùng host CTFd với main domain thì làm như trên
Sau khi tạo chứng chỉ xong, ta sẽ cd
chúng vào trong folder repo của CTFd
và sử dụng các câu lệnh sau:
#tạo folder ssl trong repo CTFd
mkdir ssl
#cp fullchain.pem --> cert.crt
cp <đường dẫn fullchain.pem> ssl/cert.crt
#cp private.pem --> cert.key
cp <đường dẫn privkey.pem> ssl/cert.key
Sau đó tiến hành chỉnh sửa file docker-compose.yml tại phần service --> nginx
sẽ chỉnh thành
nginx:
image: nginx:stable
restart: always
volumes:
- ./conf/nginx/http.conf:/etc/nginx/nginx.conf
- ./ssl/cert.crt:/etc/nginx/cert.crt
- ./ssl/cert.key:/etc/nginx/cert.key
ports:
- 443:443
depends_on:
- ctfd
Sau đó vào conf/nginx/http.conf
chỉnh một số thông số trong phần server
như sau:
#listen 80 đổi thành như dưới đây
listen 443 ssl;
#thêm cách trường này vào
server_name ctf.jerryyytheduck.id.vn; #tên miền của bạn đã setup
ssl_certificate /etc/nginx/cert.crt;
ssl_certificate_key /etc/nginx/cert.key;
Sau khi cấu hình xong, bấm save và thực hiện các command dưới đây:
# cho container down xuống
docker compose down
#build lại container
docker compose up --build
#xóa đi các thứ không cần thiết
docker system prune -a
Sau khi chạy load trang lại thì ta đã có chứng chỉ (lúc này bật Proxies
CF lên nhe)
Remote Database
Về phần này, khi làm một server thi CTFd
lớn cấp trường chẳng hạn, thì ta cần phải có một Remote Database
để có thể backup lại dữ liệu. Phòng trường hợp máy host CTFd bị downtime.
Trong trường hợp này ta sẽ có một máy khác có chức năng host đề và các thông tin liên quan tới cuộc thi.
Để làm được như vậy, ta cần có một máy khác có sử dụng mysql
. Trong bài viết này, mình giả sử bạn đã cài xong mysql
rồi nhé, còn không thì có thể cài thông qua bài viết tại đây
Tại máy bạn muốn làm Remote Database
, giả sử mình có con máy với địa chỉ IP 35.221.234.224
thì ta sẽ tiến hành như sau:
- Trên máy làm
Remote Database
có thể dùng user root hoặc có thể tự tạo cho mình một user khác với pass cho user đó trên trongmysql
. Ví dụ mình muốn tạo một user tênJerryyy
trongmysql
trên máyRemote Database
ta có thể làm như sau:
#đăng nhập root, nếu lần đầu đăng nhập thì làm theo các bước trong bài viết này:
#https://www.cyberciti.biz/faq/mysql-change-root-password/
mysql -u root -p
#sau khi đăng nhập thì tiến hành tao user
CREATE USER 'Jerryyy'@'<địa chỉ máy CTFd>' IDENTIFIED BY '123456xX';
GRANT ALL PRIVILEGES ON *.* TO 'Jerryyy'@'<địa chỉ máy CTFd>' WITH GRANT OPTION;
FLUSH PRIVILEGES;
Sau khi tạo thành công, ta sẽ vào bên trong config của mysql
để chỉnh bind_address
. Tham khảo các đường dẫn chứa file config
mysql tại đây. Trong trường hợp của mình lúc viết bài là /etc/mysql/mariadb.conf.d/50-server.cnf
Chuyển đổi bind_address
từ 127.0.0.1
thành 0.0.0.0
để listen bên ngoài và tiến hành restart service
giờ ta tiến hành lên trên máy host CTFd
để thực hiện các công việc tiếp theo. Vào phần docker-compose.yml
như phần cấu hình SSL để chỉnh sửa tiếp
Tại phần services --> ctfd --> environment
biến DATABASE_URL
sẽ được thanh đổi thành như sau:
DATABASE_URL=mysql+pymysql://<user>:<password>@<IP_máy_remote_database>/ctfd
Theo như trong trường hợp này thì sẽ là:
- user: Jerryyy
- password: 123456@xX
- IP: 35.221.234.224
Ta sẽ có như sau:
#- DATABASE_URL=mysql+pymysql://ctfd:ctfd@db/ctfd
DATABASE_URL=mysql+pymysql://Jerryyy:[email protected]/ctfd
Sau khi cấu hình xong, bấm save và thực hiện các command dưới đây:
# cho container down xuống
docker compose down
#build lại container
docker compose up --build
#xóa đi các thứ không cần thiết
docker system prune -a
Kiểm tra lại từ máy Remote database
khi show databases
thì thấy có một databases
của CTFd
Google Mail server
Và khi sử dụng CTFd thì chắc chắn phải tạo tới mail server
dùng để xác thực. Tại đây ta có thể sử dụng hai hướng là
- Sử dụng một
mail server
tự host - Sử dụng
mail server
của Google
Mình sẽ làm phương án số 02 do không có đủ kinh phí thuê mail server
:(
Vì những lý do bảo mật mail nên mình sẽ gửi các bạn video hướng dẫn tạo mail server
của Google.
Sau khi làm xong, chúng ta sẽ có được một cái password
để sử dụng SMTP
server. Giả sử mình có một mail tên [email protected]
và muốn gửi thì tại đây ta sẽ nhập các thông số sau:
Mail From Address
: Mail người gửi[email protected]
Mail Server Address
: Server mail, tại đây mình sẽ đểsmtp.gmail.com
Mail Server Port
: để mặc định 456 nếu xài mail google
Tick vào Use Mail Server Username and Password
và chọn
Username
: Cũng là mail người gửiPassword
: Password tạo ra từApp Password
Tick vào TLS/SSL
và nhấn hoàn tất. Kiểm tra bằng cách tạo thử account thì mình sẽ nhận được mail gửi về