Capturing all traffic in Wireshark from a specific MAC OUI? - wireshark

I would like to capture all wifi traffic from a specific device manufacturer using Wireshark/Tshark/TCPDump/etc. I want to use a CAPTURE filter, not a display filter. Basically, I want to capture all packets from the MAC address 11:22:33:xx:xx:xx and nothing else. Or, put another way, the first 3 octets or OUI of the MAC address using Berkeley Packet Filtering Syntax. Anyone have a preferred method?

Per this post, use syntax like ether[A:B] in your capture filter where
A = start byte location in ethernet frame, starting at 0
B = number of bytes, must be 1, 2, or 4
So to match 3 bytes, you have to have 2 comparisons: Match 2 bytes and 1 byte separately.
If you only want about packets coming from this OUI (per question):
tcpdump 'ether[0:2] == 0x1122 && ether[2:1] == 0x33'
If you want all packets going to/from this OUI:
tcpdump 'ether[0:2] == 0x1122 && ether[2:1] == 0x33 \
|| ether[6:2] == 0x1122 && ether[8:1] == 0x33'
The first 12 bytes (0-11) of the ethernet header consist of the destination and then source mac addresses. So to select both sets of 3 bytes 0-2 and 6-8, select 2 bytes at 0, 1 byte at 2, 2 bytes at 6 and 1 byte at 8.
You should also be able to use this with tshark as long as you preface this with the -f capture filter flag.

Related

How can I capture Gre or Vxlan inner network traffic?

I want to capture some network traffic with the filter like "src x.x.x.x and dst x.x.x.x".
Ususally it works, but it doesn't work when the network traffic is encapsulated by protocls like Gre or Vxlan.
For example, the Gre encapsulate a message like this:
Ethernet II, Src: VMware_91:f6:ad (00:0c:29:91:f6:ad), Dst: VMware_dc:c7:71 (00:0c:29:dc:c7:71)
Internet Protocol Version 4, Src: 10.75.2.161, Dst: 10.75.2.140
Generic Routing Encapsulation (Transparent Ethernet bridging)
Ethernet II, Src: Micro-St_e3:51:57 (4c:cc:6a:e3:51:57), Dst: VMware_91:f6:ad (00:0c:29:91:f6:ad)
Internet Protocol Version 4, Src: 10.75.2.11, Dst: 10.75.2.160
So what should I do to capture those inner traffic?
I use "src 10.75.2.160" to capture but it tcpdump captured nothing.
tcpdump -i eth0 "src 10.75.2.11"
It doesn't work.
I use "ip[54:4]" to capture, it works, but my leader tell me it's not accurate.
So what else can I try?
I don't know how accurate your leader wants the filter, but if we can make a few assumptions about the outer IP and GRE headers, then the filter isn't too complicated. So here are the 2 assumptions:
The outer IP header is a standard 20 bytes. If this isn't the case or can't be relied upon, then everywhere I use 20 in the filter will need to be replaced with the IP header length calculation, which is (ip[0] & 0x0f) * 4.
The GRE header is a standard size of 4 bytes. If options are present and you can guarantee that all GRE headers are exactly the same size, then you can substitute 4 for the actual GRE header length, but if GRE options could vary, then it should still be possible to specify a capture filter that works with any size GRE header, but it will be much more complicated and hard to follow. I leave that as an exercise for the reader.
With those assumptions out of the way, here's a filter that would be the equivalent of "src 10.75.2.11" but for the inner source IP address of a IP/GRE/IP packet:
(ip proto 47) && (ip[20 + 2:2] = 0x0800) && (ip[20 + 4 + 12:4] = 0x0a4b0x0b)
Explanation:
ip proto 47: This captures only IP/GRE packets as GRE is assigned protocol number 47.
ip[20 + 2:2] = 0x0800: Since 0x0800 is the assigned Ethertype for IPv4, this captures only GRE packets where the Protocol Type field is IP, so only IP/GRE/IP packets. (NOTE: RFC 1701 states, "The Protocol Type field contains the protocol type of the payload packet. In general, the value will be the Ethernet protocol type field for the packet.")
ip[20 + 4 + 12:4] = 0x0a4b020b: This captures only the IP/GRE/IP packets where the source IP address field of the inner IP header is 10.75.2.11. (NOTE: To get 0x0a4b020b from 10.75.2.11, you just need to convert each decimal octet to hexadecimal and combine them into a single 4 byte value.)
To verify the resulting BPF code, you can run tcpdump with the -d option to check that the filter meets your expectations, for example:
tcpdump -i eth0 "(ip proto 47) && (ip[20 + 2:2] = 0x0800) && (ip[20 + 4 + 12:4] = 0x0a4b020b)"
You should see output of the following form:
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 9
(002) ldb [23]
(003) jeq #0x2f jt 4 jf 9
(004) ldh [36]
(005) jeq #0x800 jt 6 jf 9
(006) ld [50]
(007) jeq #0xa4b020b jt 8 jf 9
(008) ret #262144
(009) ret #0
If you're not familiar with BPF code, then I would suggest further reading elsewhere, as providing a BPF tutorial here is beyond the scope of this answer.
Finally, if you need to filter for the source IP address whether it's in the outer IP header or the inner IP header, then you can basically just combine the 2 filters, i.e.:
"(ip src 10.75.2.11) || ((ip proto 47) && (ip[20 + 2:2] = 0x0800) && (ip[20 + 4 + 12:4] = 0x0a4b020b))"

How does only numbers in URL resolve to a domain?

I've been seeing some examples such as http://38263628 that resolves to a legitimate website https://example.com
When doing dig or nslookup on 38263628, it returns me NXDOMAIN.
How does the redirection or resolution work?
For data protection reasons, I can't give the actual numbers and domain it resolves to.
Thanks!
We usually write IP addresses as four dot-separated numbers like 12.34.56.78 but the address is just a number and it can be written in other ways. For example, 12.34.56.78 can also be written as 12.34.14414 or 12.2242638 or 203569230 or 0xc22384e or 0xc.0x22.0x38.0x4e.
The four-dot-separated form is effectively a base-256 representation of the number, so to convert from a single large number N into the four-dot-separated form A.B.C.D you would calculate these four values:
A = N / 256 / 256 / 256
B = N / 256 / 256 % 256
C = N / 256 % 256
D = N % 256
So your 38263628 is equivalent to 2.71.219.76
dig and nslookup don't work with plain numbers because they treat their arguments as strings, even when the arguments are known to represent IP addresses. (For instance, man dig says that the -x option requires an address in the four-dot form. That's because dig just wants to treat it as a string that can be split on the dots and rearranged into a in-addr.arpa query.)
However, most commands that convert their arguments into actual IP address numbers will accept any of the number formats. Try it with ping (which will helpfully show the address in four-dot format when it shows its results):
$ ping 203569230
PING 203569230 (12.34.56.78): 56 data bytes
...
That also gives you an easy way to convert any number into four-dot form -- just give the number as an argument to ping and let it do the conversion for you.

How to read a byte of the Serial Presence Detect (SPD) data from the DIMM after 255(FF) bytes?

I have got SMBus Base Address Register,
and program the SMBus Transmit Slave Address Register with the DIMM SMBus address, SMBBASE 04h.
Then program the SMBus Host Command Register with the DIMM’s SPD data offset to be read, SMBBASE 03h.
But the Host Command Register (HCMD)—Offset 3h is Size: 8 bits(255/FF),
So How can I read the after 255 bytes?
For example:
DDR4 Serial Presence Detect (SPD) Table:
Byte 320 : Module Manufacturer ID Code
I need to read Byte 320.
My code like this
unsigned ReadByte(unsigned SMBase_addr,unsigned i)
{
unsigned val;
outportb(SMBase_addr,0x1e);
outportb(SMBase_addr 0x04,0xa7);
outportb(SMBase_addr 0x03,i);
outportb(SMBase_addr 0x02,0x48);
while((inportb(SMBase_addr))&0x01){
delay(10);
}
val=inportb(SMBase_addr 0x05);
return val;
}
for(i=0;i<383;i )
{
data=ReadByte(SMBase_addr,i);
printf("%4x",data);
}
and I change
outportb(SMBase_addr 0x03,i);
to
outportw(SMBase_addr 0x03,i);
Host Status Register return 0x44, Device Error (DERR).
At least in Linux PC,
You need to write SMBus address 0x37 first to reach page 1. (Let write 0 to SMbus addr 32)
Than ALL of your DDR4 RAM SPD switches to Page 1.
Just use regular functions for writing & reading required addresses.
Than switch to page 0 by writing SMBus address 0x36 after.
Trying to read DDR4 SPD?
They have 2 pages of 256 bytes each, and you need a dummy write to a special predefined address 0x6E to switch all SPD chips to page 1 (where your byte 320 is located), and than write to 0x6C switch them back to page 0 (to prevent an SPD read failure during next boot).
Read this datasheet on page 12 for more info.

Why is my program reporting more captured packets than Wireshark?

I am writing a packet sniffer using pcap and visual studio. I've taken sample code for offline capturing and combined it with code that looks for an interface and captures packets live. This is what I have to display the packets information gotten from 1.
while (int returnValue = pcap_next_ex(pcap, &header, &data) >= 0)
{
// Print using printf. See printf reference:
// http://www.cplusplus.com/reference/clibrary/cstdio/printf/
// Show the packet number
printf("Packet # %i\n", ++packetCount);
// Show the size in bytes of the packet
printf("Packet size: %d bytes\n", header->len);
// Show a warning if the length captured is different
if (header->len != header->caplen)
printf("Warning! Capture size different than packet size: %ld bytes\n", header->len);
// Show Epoch Time
printf("Epoch Time: %d:%d seconds\n", header->ts.tv_sec, header->ts.tv_usec);
// loop through the packet and print it as hexidecimal representations of octets
// We also have a function that does this similarly below: PrintData()
for (u_int i=0; (i < header->caplen ) ; i++)
{
// Start printing on the next after every 16 octets
if ( (i % 16) == 0) printf("\n");
// Print each octet as hex (x), make sure there is always two characters (.2).
printf("%.2x ", data[i]);
}
// Add two lines between packets
printf("\n\n");
}
The problem I'm having is that if I run a WireShark live capture and also run my program, both capture packets live, but WireShark will show that it's capturing packet 20 and VS will show packetCount = 200.(Note: arbitrary numbers chosen to show Wireshark hasn't captured many packets, but VS is counting extremely fast.)
From what I understand, it seems the while loop is just running much faster than the packets are coming in and so it's just printing information from the last packet it received over and over again until a new one comes in.
How can I get VS to only capture packets as they come in?
I was unaware that Visual Studio included a packet sniffer; did you mean "how can I get my application, which I'm building with Visual Studio, to only capture packets as they come in?"
If that's what you meant, then that's what your code is doing.
Unfortunately, what it's not doing is "checking whether a packet has actually come in".
To quote the man page for pcap_next_ex() (yeah, UN*X, but this applies to Windows and WinPcap as well):
pcap_next_ex() returns 1 if the packet was read without problems,
0 if packets are being read from a live capture, and the timeout
expired, -1 if an error occurred while reading the packet, and -2
if packets are being read from a ``savefile'', and there are no
more packets to read from the savefile. If -1 is returned,
pcap_geterr() or pcap_perror() may be called with p as an argument
to fetch or display the error text.
Emphasis on "0 if packets are being read from a live capture, and the timeout expired"; 0 means that you did not get a packet.
Do not act as if a packet were captured if pcap_next_ex() returned 0, only do so if it returned 1:
while (int returnValue = pcap_next_ex(pcap, &header, &data) >= 0)
{
if (returnValue == 1) {
// Print using printf. See printf reference:
// http://www.cplusplus.com/reference/clibrary/cstdio/printf/
// Show the packet number
printf("Packet # %i\n", ++packetCount);
...
// Add two lines between packets
printf("\n\n");
}
}
SOLUTION: So apparently, adding parentheses around the argument fixes the issue.
while ( (( int returnValue = pcap_next_ex(pcap, &header, &data) ) >= 0 ) )

Reassembling packets in a Lua Wireshark Dissector

I'm trying to write a dissector for the Safari Remote Debug protocol which is based on bplists and have been reasonably successful (current code is here: https://github.com/andydavies/bplist-dissector).
I'm running into difficultly with reassembling packets though.
Normally the protocol sends a packet with 4 bytes containing the length of the next packet, then the packet with the bplist in.
Unfortunately some packets from the iOS simulator don't follow this convention and the four bytes are either tagged onto the front of the bplist packet, or onto the end of the previous bplist packet, or the data is multiple bplists.
I've tried reassembling them using desegment_len and desegment_offset as follows:
function p_bplist.dissector(buf, pkt, root)
-- length of data packet
local dataPacketLength = tonumber(buf(0, 4):uint())
local desiredPacketLength = dataPacketLength + 4
-- if not enough data indicate how much more we need
if desiredPacketLen > buf:len() then
pkt.desegment_len = dataPacketLength
pkt.desegment_offset = 0
return
end
-- have more than needed so set offset for next dissection
if buf:len() > desiredPacketLength then
pkt.desegment_len = DESEGMENT_ONE_MORE_SEGMENT
pkt.desegment_offset = desiredPacketLength
end
-- copy data needed
buffer = buf:range(4, dataPacketLen)
...
What I'm attempting to do here is always force the size bytes to be the first four bytes of a packet to be dissected but it doesn't work I still see a 4 bytes packet, followed by a x byte packet.
I can think of other ways of managing the extra four bytes on the front, but the protocol contains a lookup table thats 32 bytes from the end of the packet so need a way of accurately splicing the packet into bplists.
Here's an example cap: http://www.cloudshark.org/captures/2a826ee6045b #338 is an example of a packet where the bplist size is at the start of the data and there are multiple plists in the data.
Am I doing this right (looking other questions on SO, and examples around the web I seem to be) or is there a better way?
TCP Dissector packet-tcp.c has tcp_dissect_pdus(), which
Loop for dissecting PDUs within a TCP stream; assumes that a PDU
consists of a fixed-length chunk of data that contains enough information
to determine the length of the PDU, followed by rest of the PDU.
There is no such function in lua api, but it is a good example how to do it.
One more example. I used this a year ago for tests:
local slicer = Proto("slicer","Slicer")
function slicer.dissector(tvb, pinfo, tree)
local offset = pinfo.desegment_offset or 0
local len = get_len() -- for tests i used a constant, but can be taken from tvb
while true do
local nxtpdu = offset + len
if nxtpdu > tvb:len() then
pinfo.desegment_len = nxtpdu - tvb:len()
pinfo.desegment_offset = offset
return
end
tree:add(slicer, tvb(offset, len))
offset = nxtpdu
if nxtpdu == tvb:len() then
return
end
end
end
local tcp_table = DissectorTable.get("tcp.port")
tcp_table:add(2506, slicer)

Resources