Wireshark packet details pane info with tshark or scapy? - python-3.x

The information I'd like to automate retrieval of via Bash or Python is what's contained in the Packet Details pane for the last layer, when viewing DIS protocol captured packets.
So far I've gotten to the point where I can read the Packet Bytes pane information with the Scapy library in Python, but this is much harder for me to interpret/work with.
from scapy.all import sniff
capture = sniff(filter="dst 10.6.255.255 and port 3000", count=5)
packet = capture[0]
print(packet.show())
raw = packet.lastlayer()
from scapy.utils import hexdump
hexdump(raw)
Is there any way that I can get the Packet Details pane information instead with Python or Bash?

Have you tried things like:
tshark -r file.pcap -O dis
or even
tshark -r file.pcap -Y dis -T pdml > file.pdml
Refer to the tshark man page for more information on these options and to the Wireshark PDML wiki page for more information about the "Packet Description Markup Language".

Hope I don’t get the question wrong :/
You have a pretty cool packet.show() function which looks somewhat similar to wireshark
You can also try pdf-dumping packet.pdfdump() (or svg-dumping with github version)

Related

I have a pcap with two MPLS headers . i observe the match criteria for every field in both the MPLS headers are similar . How do I differentiate? [closed]

Closed. This question is not about programming or software development. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 3 months ago.
The community reviewed whether to reopen this question 3 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I have a pcap with two MPLS headers . i observe the match criteria for every field in both the MPLS headers are similar . How do I differentiate between the two MPLS headers ? Is it possible to achieve this via Wireshark or tshark ? If it is possible to achieve via tshark , please share the linux cmd.
For example , i am trying to filter using -
mpls.exp==7 && mpls.bottom == 0
but with the above match filter criteria , even those packets where mpls.exp==7 (in header1) and mpls.bottom==0 (in header 2) are matched. Attaching pcap snip for your reference.
above match criteria matching exp from header 1 and bottom of stack from header 1
above match criteria matching exp from header 2 and bottom of stack from header 1
TIA.
Tried to filter this using tsahrk in linux . Still not able to get the desired result -
Expected result - only the first 8 packets only should be matched
Observed result - 16 packets are matched
Tshark cmd :
tshark -r capture2_11-17-2022_11-15-15.pcap -T fields -E header=y -e mpls.exp -e mpls.bottom mpls.bottom==0 and mpls.exp==7
tshark output table
2nd EDIT: I thought of an alternative solution, which I'll now describe here. (Note that I would have provided this alternative solution, which involves programming in the form of a Lua script, as a separate answer, but it seems folks were a little trigger-happy in closing this question, so I have no choice but to supply it here. If the question is reopened, which I've voted to do, I can make this a separate answer.)
What you can do is create an MPLS Lua postdissector that adds new mpls_post.exp and mpls_post.bottom fields to an MPLS postdissector tree. You can then use those new fields in your filter to accomplish your goal. As an example, consider the following Lua postdissector:
local mpls_post = Proto("MPLSPost", "MPLS Postdissector")
local pf = {
expbits = ProtoField.uint8("mpls_post.exp", "MPLS Experimental Bits", base.DEC),
bottom = ProtoField.uint8("mpls_post.bottom", "MPLS Bottom of Label Stack", base.DEC)
}
mpls_post.fields = pf
local mpls_exp = Field.new("mpls.exp")
local mpls_bottom = Field.new("mpls.bottom")
function mpls_post.dissector(tvbuf, pinfo, tree)
local mpls_exp_ex = {mpls_exp()}
local mpls_bottom_ex = {mpls_bottom()}
if mpls_exp_ex == nil or mpls_bottom_ex == nil then
return
end
local mpls_post_tree = tree:add(mpls_post)
mpls_post_tree:add(pf.expbits, mpls_exp_ex[1].range, mpls_exp_ex[1].value)
mpls_post_tree:add(pf.bottom, mpls_bottom_ex[1].range, mpls_bottom_ex[1].value)
end
register_postdissector(mpls_post)
If you save this to a file, e.g. mpls_post.lua and place that file in your Wireshark Personal Lua Plugins directory, which you can find from "Help -> About Wireshark -> Folders" or from tshark -G folders, then [re]start Wireshark, you will be able to apply a filter such as follows:
mpls_post.exp==7 && mpls_post.bottom == 0
You can also use tshark to do the same, e.g.:
tshark -r capture2_11-17-2022_11-15-15.pcap -Y "mpls_post.exp==7 && mpls_post.bottom==0" -T fields -E header=y -e mpls_post.exp -e mpls_post.bottom
(NOTE: The tshark command, as written, will simply print out what you already know, namely 7 and 0, so presumably you want to print more than just that, but this is the idea.)
I think this is probably the best that can be done for now until the Wireshark MPLS dissector is modified so that layer operators work as expected for this protocol, but there are no guarantees that any changes to the MPLS dissector will ever be made in this regard.
EDIT: I'm sorry to say that the answer I provided doesn't actually work for MPLS. It doesn't work because the MPLS dissector is only called once and it then loops through all labels as long as bottom of stack isn't true, but it doesn't call itself recursively, which is what would be needed in this case in order for the second label to be considered another layer. The layer syntax does work for other protocols such as IP (in the case of tunneled traffic or ICMP error packets) and others though, so it's a good thing to keep in mind, but unfortunately it won't be of much use for MPLS, at least not in the Wireshark MPLS dissector's current state. I suppose I'll leave the answer up [for now] in case the dissector is ever changed in the future to allow for the layer syntax to work as one might intuitively expect it to work. And unfortunately, I can't think of an alternative solution to this problem at this time.
With Wireshark >= version 4.0, you can use the newly introduced syntax for matching fields from specific layers. So, rather than specifying mpls.exp==7 && mpls.bottom == 0 as the filter, which matches fields from any layer, use the following syntax instead, which will only match against fields from the first layer:
mpls.exp#1 == 7 && mpls.bottom#1 == 0
Refer to the Wireshark 4.0.0 Release Notes for more details about this new syntax as well as for other display filter changes, and/or to the wireshark-filter man page.
NOTE: You can also achieve this with tshark, although you can't [yet] selectively choose which field is displayed. For example:
tshark -r capture2_11-17-2022_11-15-15.pcap -Y "mpls.exp#1 == 7 && mpls.bottom#1 == 0" -T fields -E header=y -e mpls.exp -e mpls.bottom
To be clear, you can't [yet] specify -e mpls.exp#1 and -e mpls.bottom#1.

Linux bash script to get own internet IP address

I know I got quite rusty when it comes to bash coding, especially the more elaborate needed trickery handling awk or sed parts.
I do have a script that logs the IP address currently in use for the interwebs.
It gets that by either using wget -q0 URL or lynx -dump URL.
The most easy one was a site that only returned the IP address in plain text and nothing else. Unfortunately that site no longer exists.
The code was simple as can be:
IP=$(wget -qO - http://cfaj.freeshell.org/ipaddr.cgi)
But alas! using the code returns nothing cause the site is gone, as lynx can tell us:
$ lynx -dump http://cfaj.freeshell.org/ipaddr.cgi
Looking up cfaj.freeshell.org
Unable to locate remote host cfaj.freeshell.org.
Alert!: Unable to connect to remote host.
lynx: Can't access startfile http://cfaj.freeshell.org/ipaddr.cgi
Some other sites I used to retrieve for the same purpose no longer work either.
And the one I want to use is a German speaking one, not that I care one way or the other, it could be in Greek or Mandarin for all I care. I want only to have the IP address itself extracted, but like I said, my coding skills got rusty.
Here is the relevant area of what lynx -dump returns
[33]powered by
Ihre IP-Adresse lautet:
178.24.x.x
Ihre IPv6-Adresse lautet:
Ihre System-Informationen:
when running it as follows:
lynx -dump https://www.wieistmeineip.de/
Now, I need either awk or sed to find the 178.24.x.x part. (I know it can be done with python or Perl as well, but both are not part of a standard setting of my Linux, while awk and sed are.)
Since the script is there to extract the IP address, one needs to do the following either via sed or awk:
Search for "Ihre IP-Adresse lautet:"
Skip the next line.
Skip the whitespace at the beginning
Only return what is left of that line (without the lf at the end).
In the above example (that shows only the relevant part of the lynx dump, the whole dump is much larger but all above and below is irrelevant.) it would be "178.24.x.x" that should be returned.
Any help greatly appreciated to get my log-ip script back into working order.
Currently I have collected some other working URLs that report back the own internet IP. Any of these can also be used, but the area around the reported IP will differ from the above example. These are:
https://meineipinfo.de/
http://www.wie-ist-meine-ip.net/
https://www.dein-ip-check.de/
https://whatismyipaddress.com/
https://www.whatismyip.org/
https://www.whatismyip.net/
https://mxtoolbox.com/whatismyip/
https://www.whatismyip.org/my-ip-address
https://meineipadresse.de/
Even duckduckgo returns the IP address when e.g. asked this: https://duckduckgo.com/?q=ip+address&ia=answer
At least I know of no way of getting the own IP address when using the internet without retrieving an outside URL that reports that very IP address back to me.
You can do:
wget -O - v4.ident.me 2>/dev/null && echo
So, if you have a VM in some cloud provider you can solve this easily. I wrote some small Go app than echoes back an HTTP request. For instance :
$ curl 167.99.63.182:8888
Method ->
GET
Protocol ->
HTTP/1.1
Headers ->
User-Agent: [curl/7.54.0]
Accept: [*/*]
Content length (in Bytes) ->
0
Remote address ->
179.XXXXX
Payload
####################
####################
Where remote address is the address which the app received, hence, your IP.
And in case you are wondering, yes, 167.99.63.182 is the IP of the server and you can curl it right now and check it. I am disclosing the IP as anyway I get bombarded by brute force attacks for as long as I can remember and the machine does not have anything worth the break through.
Not exactly without relying on external services, but you could use dig to reach out to the resolver at opendns.com:
dig +short myip.opendns.com #resolver1.opendns.com
I think this is easier to integrate to a script.

what is netstat –nb and how to use it in python?

I have been tald that i need to send the progrem that sent or got the packet (packet in scapy) and that I need to use netstat –nb so i guess netstat –nb does that' but i can't find anywhere how to use it on packet, most of the code i fount was this:
import os
output_command = os.popen("netstat -nb").readlines()
but i can't understen, it not chacking one packet.
can someone help me to find how i use "netstat -nb " one a packet for finding the progrem that sent or got the packet? (in python)
I found something on Github hope it helps you. netstat.py written here
this is how netstat works.

Web service getting data from USB devices on Raspberry Pi

I have a question about getting data on the Raspberry Pi. I know that we can create RESTful services to get data from GPIO with the help of RPi.GPIO library. But what if I want to get data from traditional USB devices? Say I have a USB Bluetooth dongle and I can read data through operations in command line. But is it possible to perform the same through a web service? Any possible help is greatly appreciated!
Just an idea. I am not sure what data exactly you want to receive, but.. Since you can read data from your BT device via command-line tool (hcitool maybe), you can write cgi script to interact with it via web page. Here an example code in perl. This code generates html page with output of smartctl program. You can modify it to send certain parameters and parse an output lines right in perl script.
#!/usr/bin/perl
use CGI qw(:standard);
# header lines
print "Content-type: text/html\n\n";
print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n";
print "<html>\n";
print "<head>\n";
print " <title>S.M.A.R.T. data</title>\n";
print "</head>\n";
print "<body>\n";
print "S.M.A.R.T. output.\n";
my $cmd="/usr/bin/sudo /usr/sbin/smartctl -d sat -a /dev/sda";
my #list=`$cmd`;
foreach $ln (#list)
{
print "$ln<br>";
}
print "</body>\n";
print "</html>\n";
P.S. Code is not perfect, but it works in my RPi.

Is it possible to read only first N bytes from the HTTP server using Linux command?

Here is the question.
Given the url http://www.example.com, can we read the first N bytes out of the page?
using wget, we can download the whole page.
using curl, there is -r, 0-499 specifies the first 500 bytes. Seems solve the problem.
You should also be aware that many HTTP/1.1 servers do not have this feature enabled, so that when you attempt to get a range, you'll instead get the whole document.
using urlib in python. similar question here, but according to Konstantin's comment, is that really true?
Last time I tried this technique it failed because it was actually impossible to read from the HTTP server only specified amount of data, i.e. you implicitly read all HTTP response and only then read first N bytes out of it. So at the end you ended up downloading the whole 1Gb malicious response.
So the problem is that how can we read the first N bytes from the HTTP server in practice?
Regards & Thanks
You can do it natively by the following curl command (no need to download the whole document). According to the curl man page:
RANGES
HTTP 1.1 introduced byte-ranges. Using this, a client can request to get only one or more subparts of a specified document. curl
supports this with the -r flag.
Get the first 100 bytes of a document:
curl -r 0-99 http://www.get.this/
Get the last 500 bytes of a document:
curl -r -500 http://www.get.this/
`curl` also supports simple ranges for FTP files as well.
Then you can only specify start and stop position.
Get the first 100 bytes of a document using FTP:
curl -r 0-99 ftp://www.get.this/README
It works for me even with a Java web app deployed to GigaSpaces.
curl <url> | head -c 499
or
curl <url> | dd bs=1 count=499
should do
Also there are simpler utils with perhaps borader availability like
netcat host 80 <<"HERE" | dd count=499 of=output.fragment
GET /urlpath/query?string=more&bloddy=stuff
HERE
Or
GET /urlpath/query?string=more&bloddy=stuff
You should also be aware that many
HTTP/1.1 servers do not have this
feature enabled, so that when you
attempt to get a range, you'll instead
get the whole document.
You will have to get the whole web anyways, so you can get the web with curl and pipe it to head, for example.
head
c, --bytes=[-]N
print the first N bytes of each file; with the leading '-', print all
but the last N bytes of each file
I came here looking for a way to time the server's processing time, which I thought I could measure by telling curl to stop downloading after 1 byte or something.
For me, the better solution turned out to be to do a HEAD request, since this usually lets the server process the request as normal but does not return any response body:
time curl --head <URL>
Make a socket connection. Read the bytes you want. Close, and you're done.

Resources