Re-evaluating how some actions are performed can sometimes lead to new insights, which is exactly the reason for this blog post. Be aware that I’ve only tested this on two ‘test’ networks, so I cannot guarantee this will always work. Worst scenario you’ll read an (hopefully) out-of-the-box blog entry about an alternative port scan method that maybe only works in weird corner cases. The source for the script can be found on my gist, if you prefer to skip my ramblings and jump directly to the source.
One of the things I usually do is sniff traffic on the network that I am connected to with either my laptop or a drop device. At that point the output of the ifconfig command usually looks similar to this:
eth0 Link encap:Ethernet HWaddr 00:0c:29:4b:e7:35 inet6 addr: fe80::20c:29ff:fe4b:e735/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:386316 errors:0 dropped:0 overruns:0 frame:0 TX packets:25286 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:390745367 (390.7 MB) TX bytes:4178071 (4.1 MB)
Like you will notice the interface has no IPv4 IP address assigned, you can ignore the IPv6 address for now. Normally I determine which IP address or MAC address to clone based on the traffic that I captured and analysed previously. Then I’m all set to start port scanning or performing other type of attacks.
This time however I wondered what type of activities I could perform without an IP address. I mean it would be pretty interesting to talk IP to devices, somehow see a response and not be traceable, right? So I decided to see if it would for example be possible to perform a port scan on the network without having an IP address configured on my network interface.
Since usually when you want to perform non-standard, weird or nifty tricks with TCP/IP you have to resort to raw sockets I decided to directly jump to scapy to build a POC. My working theory was as follow:
Normally when I am just sniffing traffic I see all kind of traffic that gets send to the broadcast address, so what if we perform a port scan and we specify the broadcast address as the source?
I decided to test this using two virtual machine (ubuntu & Windows 10) with the network settings on ‘NAT’ and also tested with the same virtual machines while bridged to a physical network. The following oneliners can be used to transmit the raw packet:
pkt = Ether(dst='00:0c:29:f6:a5:65',src='00:08:19:2c:e0:15') / IP(dst='172.16.218.178',src='172.16.218.255') / TCP(dport=445,flags='S') sendp(pkt,iface='eth0')
Running tcpdump will confirm if this works or not, moment of truth:
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 23:27:21.903583 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto TCP (6), length 40) 172.16.218.255.20 > 172.16.218.178.445: Flags [S], cksum 0x803e (correct), seq 0, win 8192, length 0 23:27:21.904440 IP (tos 0x0, ttl 128, id 31823, offset 0, flags [DF], proto TCP (6), length 44) 172.16.218.178.445 > 172.16.218.255.20: Flags [S.], cksum 0x03be (correct), seq 3699222724, ack 1, win 65392, options [mss 1460], length 0 23:27:24.910050 IP (tos 0x0, ttl 128, id 31824, offset 0, flags [DF], proto TCP (6), length 44) 172.16.218.178.445 > 172.16.218.255.20: Flags [S.], cksum 0x03be (correct), seq 3699222724, ack 1, win 65392, options [mss 1460], length 0 23:27:30.911092 IP (tos 0x0, ttl 128, id 31825, offset 0, flags [DF], proto TCP (6), length 44) 172.16.218.178.445 > 172.16.218.255.20: Flags [S.], cksum 0x03be (correct), seq 3699222724, ack 1, win 65392, options [mss 1460], length 0 23:27:42.911498 IP (tos 0x0, ttl 128, id 31829, offset 0, flags [DF], proto TCP (6), length 40) 172.16.218.178.445 > 172.16.218.255.20: Flags [R], cksum 0x1af8 (correct), seq 3699222725, win 0, length 0
wOOOOOOOt!! It seems to work. We can clearly see the packet being sent to the ‘.178’ IP address from the broadcast (.255) source address and then we see the response flowing back to the broadcast address.
Now that’s pretty interesting right? Essentially we can now perform port scans without being really traceable on the network. Somehow this still feels ‘weirdish’ because it just works on first try…so still thinking I missed something :/
sudo ./ipless-scan.py 172.16.218.178 00:0c:29:f6:a5:65 -p 445 3389 5000 -i eth0 2017-10-26 23:13:33,559 - INFO - Started ipless port scan 2017-10-26 23:13:33,559 - INFO - Started sniffer and waiting 10s 2017-10-26 23:13:43,568 - INFO - Starting port scan 2017-10-26 23:13:43,604 - INFO - Found open port - 445 2017-10-26 23:13:43,628 - INFO - Found open port - 3389 2017-10-26 23:13:43,645 - INFO - Found closed port - 5000 2017-10-26 23:13:43,654 - INFO - Finished port scan, waiting 5s for packets 2017-10-26 23:13:52,626 - INFO - Stopped sniffer