Skip to content

Commit

Permalink
Merge pull request #968 from proditis/master
Browse files Browse the repository at this point in the history
Update docker containers
  • Loading branch information
proditis authored Aug 18, 2023
2 parents 20f56bb + c611d0f commit 15cf4a0
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 37 deletions.
4 changes: 2 additions & 2 deletions contrib/Dockerfile-mariadb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM mariadb:10.5
LABEL description="echoCTF.RED database and memcache server"
ARG MEMCACHED_MEM=64
ARG MEMCACHED_MEM=128
ENV MYSQL_ALLOW_EMPTY_PASSWORD root
ENV MYSQL_USER vpnuser
ENV MYSQL_PASSWORD vpnuserpass
Expand Down Expand Up @@ -36,7 +36,7 @@ RUN set -ex; \
cp src/.libs/libmemcached_functions_mysql.so /usr/lib/mysql/plugin/; \
sed -i -e 's/127.0.0.1/0.0.0.0/g' /etc/memcached.conf; \
mkdir -p /always-initdb.d; \
echo "/usr/bin/memcached -d -m ${MEMCACHED_MEM} -p 11211 -u mysql -l 0.0.0.0 -o no_modern -P /tmp/memcached.pid" >> /always-initdb.d/00.sh; \
echo "/usr/bin/memcached -d -M -m ${MEMCACHED_MEM} -p 11211 -u mysql -l 0.0.0.0 -o no_modern -P /tmp/memcached.pid; sleep 1" >> /always-initdb.d/00.sh; \
chmod +x /always-initdb.d/00.sh; \
cat sql/install_functions.sql>> /docker-entrypoint-initdb.d/00.sql; \
sed -i -e "s/echoCTF/${MYSQL_DATABASE}/g" /always-initdb.d/99_mysql-init.sql; \
Expand Down
7 changes: 4 additions & 3 deletions contrib/Dockerfile-vpn
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ARG MYSQL_USER=vpnuser
ARG MYSQL_PASSWORD=vpnuserpass
ARG MYSQL_DATABASE=echoCTF
ARG GITHUB_OAUTH_TOKEN

ENV OPENVPN_ADMIN_PASSWORD OPENVPN_ADMIN_PASSWORD
ENV DEBIAN_FRONTEND noninteractive
WORKDIR /var/www/echoCTF.RED
COPY ${RED_APP} ./${RED_APP}/
Expand All @@ -21,7 +21,8 @@ RUN set -ex \
&& apt-get update \
&& apt-get install --no-install-recommends -y procps git zip unzip mariadb-client tini \
php php-gd php-mbstring php-mysqli php-dom php-intl php-curl php-memcache \
openvpn netcat-openbsd; \
openvpn netcat-openbsd tcpdump vim.tiny libnet-pcap-perl libpoe-component-pcap-perl \
libdbi-perl libdbd-mysql libdbd-mysql-perl supervisor; \
cd /var/www/echoCTF.RED/${RED_APP}; \
chmod a+x /usr/local/bin/composer; \
git config --global url."https://".insteadOf "git://" ; \
Expand All @@ -37,5 +38,5 @@ RUN cd /var/www/echoCTF.RED/${RED_APP} && composer validate
EXPOSE 1194/udp
VOLUME /etc/openvpn
WORKDIR /var/www/echoCTF.RED
CMD ["tail -3f /var/log/openvpn/openvpn.log"]
CMD ["supervisord -c /var/www/echoCTF.RED/contrib/supervisord.conf"]
ENTRYPOINT ["tini","--", "/entrypoint.sh"]
13 changes: 8 additions & 5 deletions contrib/entrypoint-vpn.sh
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
#!/bin/bash
echo "<?php return [ 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=${MYSQL_HOST};dbname=${MYSQL_DATABASE}', 'username' => '${MYSQL_USER}', 'password' => '${MYSQL_PASSWORD}', 'charset' => 'utf8mb4', ];">/var/www/echoCTF.RED/backend/config/db.php
cp /var/www/echoCTF.RED/backend/config/cache-local.php /var/www/echoCTF.RED/backend/config/cache.php
sed -ie "s/127.0.0.1/${MYSQL_HOST}/g" /var/www/echoCTF.RED/backend/config/cache.php

if [ ! -f /etc/openvpn/.configured ]; then
echo "OpenVPN not configured, sleeping 30 seconds for mysql to come up"
sleep 30
echo "OpenVPN not configured"
openssl dhparam -out /etc/openvpn/dh.pem 2048
echo "Sleeping 30 seconds" && sleep 30
mkdir -p /etc/openvpn/certs /etc/openvpn/client_confs /var/log/openvpn /etc/openvpn/crl /etc/openvpn/ccd
install -d -m 700 /etc/openvpn/private
cp contrib/openvpn_tun0.conf /etc/openvpn
echo "<?php return [ 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=${MYSQL_HOST};dbname=${MYSQL_DATABASE}', 'username' => '${MYSQL_USER}', 'password' => '${MYSQL_PASSWORD}', 'charset' => 'utf8mb4', ];">backend/config/db.php
sed -e "s#{{db.host}}#${MYSQL_HOST}#g" contrib/echoctf_updown_mysql.sh > /etc/openvpn/echoctf_updown_mysql.sh
sed -e "s#ksh#bash#" -e "s#127.0.0.1#${MYSQL_HOST}#g" -e "s#{{db.user}}#${MYSQL_USER}#g" -e "s#{{db.pass}}#${MYSQL_PASSWORD}#g" -i /etc/openvpn/echoctf_updown_mysql.sh
chmod 555 /etc/openvpn/echoctf_updown_mysql.sh
cp contrib/crl_openssl.conf /etc/openvpn/crl/
touch /etc/openvpn/crl/index.txt
echo "00" > /etc/openvpn/crl/number
echo "OPENVPN_ADMIN_PASSWORD">/etc/openvpn/private/mgmt.pwd
openssl dhparam -out /etc/openvpn/dh.pem 2048
echo "${OPENVPN_ADMIN_PASSWORD}">/etc/openvpn/private/mgmt.pwd
openvpn --genkey secret /etc/openvpn/private/vpn-ta.key
/var/www/echoCTF.RED/backend/yii migrate --interactive=0
/var/www/echoCTF.RED/backend/yii migrate-sales/up --interactive=0
Expand Down
126 changes: 126 additions & 0 deletions contrib/findingsd.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/usr/bin/perl
use Net::Pcap;
use NetPacket::Ethernet;
use NetPacket::IP;
use NetPacket::TCP;
use NetPacket::UDP;
use NetPacket::ICMP;
use Socket;
use DBI;
use strict;
$|++;
my $err;
#my $filter_str='( tcp or udp or icmp ) and ( dst net 10.0.0.0/16 )';
my $filter_str='( tcp or udp or icmp ) and ( src net 10.10.0.0/24 and dst net 10.0.160.0/24 ) and not ( src host 10.10.0.1 )';
# Use network device passed in program arguments or if no
# argument is passed, determine an appropriate network
# device for packet sniffing using the
# Net::Pcap::lookupdev method

my $dev = $ARGV[0];
my $out=$ARGV[1];
unless (defined $dev) {
$dev = Net::Pcap::lookupdev(\$err);
if (defined $err) {
die 'Unable to determine network device for monitoring - ', $err;
}
}
my $dsn = "DBI:mysql:database=echoCTF;host=172.24.0.253;port=3306";
my $username = "vpnuser";
my $password = 'vpnuserpass';

# connect to MySQL database
my %attr = ( PrintError=>0, # turn off error reporting via warn()
RaiseError=>1 # report error via die()
);
my $dbh = DBI->connect($dsn,$username,$password,\%attr);
my $sql = "INSERT INTO findingsd ( srcip, dstip,dstport, proto) VALUES (INET_ATON(?),INET_ATON(?),?,?)";
my $sth = $dbh->prepare($sql);

my ($address, $netmask);
my $object;
# pcap_open_live($dev, $snaplen, $promisc, $to_ms, \$err)
# Returns a packet capture descriptor for looking at packets on the network.
# The $dev parameter specifies which network interface to capture packets from.
# The $snaplen and $promisc parameters specify the maximum number of bytes to
# capture from each packet, and whether to put the interface into promiscuous
# mode, respectively. The $to_ms parameter specifies a read timeout in
# milliseconds. The packet descriptor will be undefined if an error occurs, and
# the $err parameter will be set with an appropriate error message.
$object = Net::Pcap::pcap_open_live($dev, 1024, 0, 1, \$err);

unless (defined $object) {
die 'Unable to create packet capture on device ', $dev, ' - ', $err;
}


my $filter;
Net::Pcap::compile(
$object,
\$filter,
$filter_str,
0,
0
) && die 'Unable to compile packet capture filter';
Net::Pcap::setfilter($object, $filter) && die 'Unable to set packet capture filter';

Net::Pcap::loop($object, -1, \&syn_packets, '') ||
die 'Unable to perform packet capture';

Net::Pcap::close($object);

sub logPacket {
my ($srcip, $mtype, $dstip, $dstport, $prt, $color) = @_;
my $TIMESTAMP=time();
print "$srcip => $dstip:$dstport/$prt\n";
$sth->execute($srcip,$dstip,$dstport,$prt);
}

sub syn_packets {
my ($user_data, $header, $packet) = @_;

# Strip ethernet encapsulation of captured packet
my $eth = NetPacket::Ethernet->decode($packet);
my $ether_data = NetPacket::Ethernet::strip($packet);
# Decode contents of TCP/IP packet contained within
# captured ethernet packet
my $ip = NetPacket::IP->decode($ether_data);
my $srcport = 0;
my $dstport = 0;
my $size = $ip->{'len'};
my $prt="";
my $color="";
my $mtype="";

if ($ip->{'proto'}==6) {
my $decoded_packet = NetPacket::TCP->decode($ip->{'data'});
$prt = "tcp";
$color="#8E44AD";
$mtype="A";
$srcport=$decoded_packet->{'src_port'};
$dstport=$decoded_packet->{'dest_port'};
}
elsif($ip->{'proto'}==1) {
$color="#2E86C1";
$prt = "icmp";
$mtype="A";
$dstport=0;
}
elsif($ip->{'proto'}==17) {
my $decoded_packet = NetPacket::UDP->decode($ip->{'data'});
$prt = "udp";
$color="#FF5733";
$mtype="M";
$srcport=$decoded_packet->{'src_port'};
$dstport=$decoded_packet->{'dest_port'};
}

my $srchw = $eth->{src_mac};
my $dsthw = $eth->{dest_mac};
my $srcip = $ip->{'src_ip'};
my $dstip = $ip->{'dest_ip'};
$srchw=~ s/..\K\B/:/g;
$dsthw=~ s/..\K\B/:/g;
my $TIMESTAMP=time();
logPacket $srcip,$mtype,$dstip,$dstport,$prt,$color;
}
36 changes: 9 additions & 27 deletions contrib/findingsd.sql
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,20 @@ BEGIN

IF teams IS NOT NULL AND teams=1 THEN
SELECT memc_get(CONCAT('team_player:',_PLAYER_ID)) INTO _TEAM_ID;
SELECT memc_get(CONCAT('team_finding:',_TEAM_ID, ':', _FINDING_ID)) INTO CLAIMED_BEFORE;
ELSE
SELECT memc_get(CONCAT('player_finding:',_PLAYER_ID, ':', _FINDING_ID)) INTO CLAIMED_BEFORE;
-- SELECT memc_get(CONCAT('team_finding:',_TEAM_ID, ':', _FINDING_ID)) INTO CLAIMED_BEFORE;
END IF;
SELECT memc_get(CONCAT('player_finding:',_PLAYER_ID, ':', _FINDING_ID)) INTO CLAIMED_BEFORE;

IF @debug IS NOT NULL AND @debug=1 THEN
INSERT DELAYED into debuglogs (msg) VALUES (CONCAT('[BEFORE FINDING] _TARGET_ID:',ifnull(_TARGET_ID,0),' _PLAYER_ID:',ifnull(_PLAYER_ID,0),' _FINDING_ID:',ifnull(_FINDING_ID,0),' _TEAM_ID:',ifnull(_TEAM_ID,'-'),' CLAIMED BEFORE ID:', ifnull(CLAIMED_BEFORE,0)));
END IF;

IF _PLAYER_ID IS NOT NULL AND _FINDING_ID IS NOT NULL AND _FINDING_ID>0 THEN
UPDATE target_ondemand SET heartbeat=NOW() WHERE target_id=_TARGET_ID AND state>0;
END IF;

-- IF _PLAYER_ID IS NOT NULL AND _FINDING_ID IS NOT NULL AND _FINDING_ID>0 AND memc_get(CONCAT('target_ondemand_heartbeat:',_TARGET_ID)) IS NULL THEN
-- -- we set it before the insert to reduce the number of queries
-- DO memc_set(CONCAT('target_ondemand_heartbeat:',_TARGET_ID),UNIX_TIMESTAMP(now()),60);
-- UPDATE target_ondemand SET heartbeat=NOW() WHERE target_id=_TARGET_ID AND state>0;
-- END IF;
IF _PLAYER_ID IS NOT NULL AND _FINDING_ID IS NOT NULL AND _FINDING_ID>0 AND CLAIMED_BEFORE IS NULL THEN
-- we set it before the insert to reduce the number of queries
INSERT IGNORE INTO player_finding (finding_id,player_id) VALUES(_FINDING_ID,_PLAYER_ID) on duplicate key update finding_id=values(finding_id);
IF @debug IS NOT NULL AND @debug=1 THEN
INSERT DELAYED into debuglogs (msg) VALUES (CONCAT('[AFTER FINDING] _TARGET_ID:',ifnull(_TARGET_ID,0),' _PLAYER_ID:',ifnull(_PLAYER_ID,0),' _FINDING_ID:',ifnull(_FINDING_ID,0),' _TEAM_ID:',ifnull(_TEAM_ID,'-'),' CLAIMED BEFORE ID:', ifnull(CLAIMED_BEFORE,0)));
Expand All @@ -79,14 +80,7 @@ END
DROP PROCEDURE IF EXISTS `VPN_LOGIN` //
CREATE PROCEDURE `VPN_LOGIN`(IN usid BIGINT, IN assignedIP INT UNSIGNED, IN remoteIP INT UNSIGNED)
BEGIN
IF (select memc_server_count()<1) THEN
select memc_servers_set('127.0.0.1') INTO @memc_server_set_status;
END IF;

IF (SELECT COUNT(*) FROM player WHERE id=usid AND status=10)>0 THEN
SELECT memc_set(CONCAT('ovpn:',usid),INET_NTOA(assignedIP)) into @devnull;
SELECT memc_set(CONCAT('ovpn:',INET_NTOA(assignedIP)),usid) into @devnull;
SELECT memc_set(CONCAT('ovpn_remote:',usid),INET_NTOA(remoteIP)) into @devnull;
UPDATE `player_last` SET `on_vpn`=NOW(), `vpn_local_address`=assignedIP, `vpn_remote_address`=remoteIP WHERE `id`=usid;
END IF;
END
Expand All @@ -95,26 +89,14 @@ END
DROP PROCEDURE IF EXISTS `VPN_LOGOUT_STALLED` //
CREATE PROCEDURE `VPN_LOGOUT_STALLED`(IN vpn_server CHAR(15))
BEGIN
IF (select memc_server_count()<1) THEN
select memc_servers_set('127.0.0.1') INTO @memc_server_set_status;
END IF;

SELECT memc_delete(CONCAT('ovpn:',id)), memc_delete(CONCAT('ovpn_remote:',id)) from player_last where vpn_remote_address is not null or vpn_local_address is not null;
UPDATE player_last SET vpn_remote_address=null, vpn_local_address=null where vpn_remote_address is not null or vpn_local_address is not null;
END
//

DROP PROCEDURE IF EXISTS `VPN_LOGOUT` //
CREATE PROCEDURE `VPN_LOGOUT`(IN usid BIGINT, IN assignedIP INT UNSIGNED, IN remoteIP INT UNSIGNED)
BEGIN
IF (select memc_server_count()<1) THEN
select memc_servers_set('127.0.0.1') INTO @memc_server_set_status;
END IF;

IF (SELECT COUNT(*) FROM player WHERE id=usid AND status=10)>0 THEN
SELECT memc_delete(CONCAT('ovpn:',usid)) into @devnull;
SELECT memc_delete(CONCAT('ovpn_remote:',usid)) into @devnull;
SELECT memc_delete(CONCAT('ovpn:',INET_NTOA(assignedIP))) into @devnull;
UPDATE `player_last` SET vpn_local_address=NULL, vpn_remote_address=NULL WHERE `id`=usid;
END IF;
END
Expand Down
36 changes: 36 additions & 0 deletions contrib/supervisord.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[supervisord]
nodaemon=true
pidfile=/run/supervisord.pid
logfile=/var/log/supervisord.log
user=root
logfile_maxbytes=0
[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
chmod=0700 ; sockef file mode (default 0700)

[supervisorctl]
serverurl=unix:///run/supervisord.sock

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket

[program:findingsd]
priority = 100
user = root
command=perl /var/www/echoCTF.RED/contrib/findingsd.pl eth2
autostart=true
autorestart=true
stdout_logfile = /dev/null
stdout_logfile_maxbytes = 0
stderr_logfile = /dev/null
stderr_logfile_maxbytes = 0

[program:tail]
user = root
command = tail -3f /var/log/openvpn/openvpn.log
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true

0 comments on commit 15cf4a0

Please sign in to comment.