CTFd é uma plataforma desenvolvida em Python para organização de jogos no estilo Capture sua Bandeira (Capture The Flag) muito comum em ambientes controlados de Segurança Ofensiva e Defensiva. Segue a url do fabricante (https://ctfd.io/)
Como demorei para encontrar tutoriais completos e atualizados resolvi juntar tudo em um só e funcional para vocês. Até a versão 18.04 do Ubuntu há um tutorial funcional utilizando a aplicação gunicorn, porém como este pacote foi descontinuado na versão 20.04 do Ubuntu tive que buscar uma forma de fazer e é este trabalho que trago para vocês de forma organizada e comando por comando.
Instalando pacotes e dependências
Antes de mais nada se faz necessário realizar a instalação de todas as dependências necessárias para o correto funcionamento do ambiente.
Adicionando repositório do nginx no ambiente
1
2
root@M4v3r1ck:~# echo deb http://nginx.org/packages/mainline/ubuntu/ `lsb_release --codename --short` nginx > /etc/apt/sources.list.d/nginx.list
root@M4v3r1ck:~# curl -s http://nginx.org/keys/nginx_signing.key | apt-key add -
Atualizando o ambiente
1
root@M4v3r1ck:~# apt-get update && apt-get -y upgrade
Instalando pacotes e dependências
1
root@M4v3r1ck:~# apt install nginx python3 python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools python3-venv
Pré-configurando o NGINX
Como utilizaremos o NGINX como um proxy reverso para expor o CTFd para a internet, então vamos realizar uma pré-configuração do mesmo, para posteriormente ajustar para a configuração final. Estamos fazendo isso neste ponto pois logo a frente iremos realizar um teste inicial de acesso ao CTFd, e para isso precisaremos que essa comunicação já seja realizada via NGINX.
Edite o arquivo /etc/nginx/nginx.conf para que o mesmo fique exatamente conforme abaixo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
limit_conn_zone $binary_remote_addr zone=addr:10m;
server_names_hash_bucket_size 256;
client_max_body_size 10m;
log_format log_standard '$remote_addr, $http_x_forwarded_for - $remote_user [$time_local] "$request_method $scheme://$host$request_uri $server_protocol" $status $body_bytes_sent "$http_referer" "$http_user_agent" to: $upstream_addr';
access_log /var/log/nginx/access.log log_standard;
error_log /var/log/nginx/error.log;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
Edite o arquivo /etc/nginx/conf.d/default.conf de forma que o mesmo fique com o conteúdo abaixo:
1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80;
server_name _;
location / {
proxy_pass http://127.0.0.1:8080;
#include uwsgi_params;
#uwsgi_pass unix:/home/ctfd/CTFd/ctfd.sock;
}
}
Reinicie o nginx
1
root@M4v3r1ck:~# /etc/init.d/nginx restart
Instalando e configurando o CTFd
Agora que temos o nginx já funcional, podemos instalar o CTFd e suas dependências.
Adicione o usuário e grupo conforme abaixo
1
2
root@M4v3r1ck:~# groupadd ctfd
root@M4v3r1ck:~# adduser --disabled-password --ingroup ctfd ctfd
Altere para o contexto do usuário
1
root@M4v3r1ck:~# su - ctfd
Realize o download do CTFd. Note que o comando está sendo executado com o usuário ctfd e dentro do seu diretório home (/home/ctfd)
1
ctfd@M4v3r1ck:~$ git clone https://github.com/CTFd/CTFd.git
Agora vamos criar um ambiente virtual para isolar o nosso ambiente de outras aplicações python.
1
ctfd@M4v3r1ck:~$ python3 -m venv CTFd
Isso instalará uma cópia local do Python e do pip para um diretório chamado CTFd.
Antes de instalar aplicativos no ambiente virtual, você precisa ativá-lo. Faça isso digitando:
1
ctfd@M4v3r1ck:~$ source CTFd/bin/activate
Seu prompt mudará para indicar que você agora está operando no ambiente virtual. Ele se parecerá com isso (CTFd) ctfd@M4v3r1ck:~$
.
Agora vamos instalar todas as dependências python necessárias para o ctfd.
Independente da versão do Python neste ponto usar o pip ao invés do pip3 (pois já estamos dentro de um ambiente python3)
Primeiramente, vamos instalar o wheel com a instância local do pip para garantir que nossos pacotes serão instalados mesmo se estiverem faltando arquivos wheel:
1
(CTFd) ctfd@M4v3r1ck:~$ pip install wheel
Posteriormente, iremos instalar o uwsgi, flask e as dependências
1
2
(CTFd) ctfd@M4v3r1ck:~$ pip install uwsgi flask testresources werkzeug==0.16.0
(CTFd) ctfd@M4v3r1ck:~$ pip install -r CTFd/requirements.txt
Agora podemos testar o sistema
1
2
(CTFd) ctfd@M4v3r1ck:~$ cd CTFd
(CTFd) ctfd@M4v3r1ck:~/CTFd$ uwsgi --socket 0.0.0.0:8080 --protocol=http -w wsgi:app
Abra o seu navegador e acesse o IP do seu servidor http://[IP], a imagem igual abaixo deve ser exibida
Quando você tiver confirmado que ele está funcionando corretamente, pressione CTRL-C na janela do seu terminal.
Acabamos agora o nosso ambiente virtual, para que possamos desativá-lo:
1
(CTFd) ctfd@M4v3r1ck:~$ deactivate
Agora, qualquer comando Python voltará a usar o ambiente do sistema Python.
Criar arquivo ctfd.ini
Note que neste arquivo iremos definir o modo de conexão (entre o nginx e o wsgi) como sendo um socket unix que é mais rápido e seguro.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[uwsgi]
module = wsgi:app
master = true
processes = 5
pidfile = ctfd.pid
socket = ctfd.sock
chmod-socket = 660
vacuum = true
die-on-term = true
logto = /var/log/ctfd/%n.log
Volte ao acesso como root
1
ctfd@M4v3r1ck:~$ exit
Os comandos agora são executados como root.
Crie o diretório de logs e defina sua permissão
1
2
ctfd@M4v3r1ck:~# mkdir /var/log/ctfd
ctfd@M4v3r1ck:~# chown ctfd:adm /var/log/ctfd/
Crie o arquivo para logrotate com nome /etc/logrotate.d/ctfd com o seguinte conteúdo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/var/log/ctfd/*.log {
daily
missingok
rotate 365
compress
datetext
delaycompress
notifempty
create 640 ctfd adm
sharedscripts
postrotate
if [ -f /home/ctfd/CTFd/ctfd.pid ]; then
kill -HUP `cat /home/ctfd/CTFd/ctfd.pid`
fi
endscript
}
Crie o arquivo /etc/systemd/system/ctfd.service
1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=CTFd Service
After=network.target
[Service]
User = ctfd
Group = nginx
WorkingDirectory=/home/ctfd/CTFd
Environment="PATH=/home/ctfd/CTFd/bin"
ExecStart=/home/ctfd/CTFd/bin/uwsgi --ini ctfd.ini
[Install]
WantedBy=multi-user.target
Podemos agora iniciar o serviço uWSGI que criamos e habilitá-lo para que ele seja iniciado na inicialização:
1
2
3
root@M4v3r1ck:~# systemctl daemon-reload
root@M4v3r1ck:~# systemctl enable ctfd
root@M4v3r1ck:~# systemctl start ctfd
Verifique o status
1
root@M4v3r1ck:~# systemctl status ctfd
Você deve ver um resultado como este:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@M4v3r1ck:~# systemctl status ctfd
● ctfd.service - CTFd Service
Loaded: loaded (/etc/systemd/system/ctfd.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2020-06-20 03:51:28 UTC; 8s ago
Main PID: 27730 (uwsgi)
Tasks: 6 (limit: 2249)
Memory: 59.2M
CGroup: /system.slice/ctfd.service
├─27730 /home/ctfd/CTFd/bin/uwsgi --ini ctfd.ini
├─27740 /home/ctfd/CTFd/bin/uwsgi --ini ctfd.ini
├─27741 /home/ctfd/CTFd/bin/uwsgi --ini ctfd.ini
├─27742 /home/ctfd/CTFd/bin/uwsgi --ini ctfd.ini
├─27743 /home/ctfd/CTFd/bin/uwsgi --ini ctfd.ini
└─27744 /home/ctfd/CTFd/bin/uwsgi --ini ctfd.ini
Estando tudo correto agora vamos editar o nginx para se conectar ao wsgi através do socket unix que criamos.
Altere o arquivo /etc/nginx/conf.d/default.conf para:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
server {
listen 80;
server_name _;
location / {
uwsgi_param Host $host;
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto;
proxy_read_timeout 600;
proxy_connect_timeout 1d
;
proxy_max_temp_file_size 5024m;
proxy_send_timeout 600;
uwsgi_read_timeout 600;
uwsgi_send_timeout 600;
include uwsgi_params;
uwsgi_pass unix:/home/ctfd/CTFd/ctfd.sock;
}
}
Recarregue a configuração do nginx
1
root@M4v3r1ck:~# nginx -s reload
Realize o teste de acesso ao CTFd através da URL http://[IP]
Agora você tem o CTFd rodando na porta 80 do seu servidor, basta o teste de acesso ao CTFd através da URL http://[IP].
Fontes: