File Name Too long error while reading a pcap file using subprocess.call - subprocess

I am new to using subprocess calls. Please help me in figuring out the issue in following script..
I am trying to write a new PCAP file (filter1.pcap) that would contain only packets from a specific IP address (ipadd) from a big set of packets from various IP addresses contained in a larger PCAP file(superset.pcap)
The error is: OSError: [Errno 36] File name too long
The code is as follows:
from subprocess import *
pcapfile = rdpcap("superset.pcap")
ipadd = "192.168.1.1"
fileout = "filter1.pcap"
command = "sudo tcpdump -w %s -r %s src %s" %(fileout,pcapfile,ipadd)
subprocess.call( [command] )
BTW the below command in Linux works perfectly fine:
sudo tcpdump -w filter1.pcap -r superset.pcap src 192.168.1.1
Any help would be great !!
Thank you,
cks

This is resolved.. There was a logical error here. I was reading the complete PCAP file using rdpcap and passing the value to tcpdump. So tcpdump was reading the complete file itself as the file name.
I changed the code as below and it's working now !
import os.path
pcapfile = "superset.pcap"
ipadd = "192.168.1.1"
fileout = "filter1.pcap"
command = "sudo tcpdump -w %s -r %s src %s" %(fileout,pcapfile,ipadd)
os.system(command)

Related

pySerial running command to list ports

I am using pySerial and I am running this command using CMD to list available COM ports and displays a COM port number when found:
python -m serial.tools.list_ports
I know that the command line will import the serial module when I use the python -m flag and I can access the objects inside it so it should show the output. However, the same command however does not work when run using the IDLE shell:
import serial
print(serial.tools.list_ports_common)
This returns an error AttributeError: module 'serial' has no attribute 'tools'
Why is it not working at IDLE?
You need to import it first:
from serial.tools import list_ports
list_ports.main() # Same result as python -m serial.tools.list_ports
You can check out the source here
You can simply try connecting to each possible port (COM0...COM255). Then add the ports with successful connections to a list. Here is my example:
import serial
def connectedCOMports ():
allPorts = [] #list of all possible COM ports
for i in range(256):
allPorts.append("COM" + str(i))
ports = [] #a list of COM ports with devices connected
for port in allPorts:
try:
s = serial.Serial(port) #attempt to connect to the device
s.close()
ports.append(port) #if it can connect, add it the the list
except:
pass #if it can't connect, don't add it to the list
return(ports)
print(connectedCOMports())
When I ran this program, it printed ['COM7'] to the console. This represents the ESP32 microcontroller that I connected to my USB port.

Error trying to send message to serve Ubuntu 18.04 LTS

When I try to send a quoted string from client to server, it works. However, when i try to send a variable storing the input of the user to the server, it does not. Anybody knows why?
server_file
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind( ("0.0.0.0", 1234) )
buff, addr = s.recvfrom(100)
print buff, addr
client_file
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
nume_user = input()
# s.sendto( nume_user, ("127.0.0.1", 1234) ) # this does not work
s.sendto("john", ("127.0.0.1", 1234) ) # this works
buff, addr = s.recvfrom(100)
print buff
This is the error that I am getting ( Ubuntu 18.04 LTS )
Traceback (most recent call last:
File "c4-1.py", line 5, in <module>
nume_user = input()
File "<string>", line 1, in <module>
NameError: name 'ionut' is not defined
From the documentation:
input([prompt])
Equivalent to eval(raw_input(prompt)).
Thus it will read the string you enter (in this case ionut) and then eval it. Since ionut is not a declared variable or otherwise valid Python statement it will throw the error shown.
Also from the documentation:
Consider using the raw_input() function for general input from users.
This is what you should use instead and then you don't get the error.
Apart from that consider using Python3 instead of Python2 which you currently use. Python2 is end of life and also the input function in Python3 is more what you seem to expect - see this documentation.

Opening a DGRAM socket from within a docker container fails (permission denied)

I'm running an application which builds and sends ICMP ECHO requests to a few different ip addresses. The application is written in Crystal. When attempting to open a socket from within the crystal docker container, Crystal raises an exception: Permission Denied.
From within the container, I have no problem running ping 8.8.8.8.
Running the application on macos, I have no problem.
Reading the https://docs.docker.com/engine/security/apparmor/ and https://docs.docker.com/engine/security/seccomp/ pages on apparmor and seccomp I was sure I'd found the solution, but the problem remains unresolved, even when running as docker run --rm --security-opt seccomp=unconfined --security-opt apparmor=unconfined socket_permission
update/edit: After digging into capabilities(7), I added the following line to my dockerfile: RUN setcap cap_net_raw+ep bin/ping trying to let the socket get opened but without change.
Thanks!
Relevant crystal socket code, full working code sample below:
# send request
address = Socket::IPAddress.new host, 0
socket = IPSocket.new Socket::Family::INET, Socket::Type::DGRAM, Socket::Protocol::ICMP
socket.send slice, to: address
Dockerfile:
FROM crystallang/crystal:0.23.1
WORKDIR /opt
COPY src/ping.cr src/
RUN mkdir bin
RUN crystal -v
RUN crystal build -o bin/ping src/ping.cr
ENTRYPOINT ["/bin/sh","-c"]
CMD ["/opt/bin/ping"]
Running the code, first native, then via docker:
#!/bin/bash
crystal run src/ping.cr
docker build -t socket_permission .
docker run --rm --security-opt seccomp=unconfined --security-opt apparmor=unconfined socket_permission
And finally, a 50 line crystal script which fails to open a socket in docker:
require "socket"
TYPE = 8_u16
IP_HEADER_SIZE_8 = 20
PACKET_LENGTH_8 = 16
PACKET_LENGTH_16 = 8
MESSAGE = " ICMP"
def ping
sequence = 0_u16
sender_id = 0_u16
host = "8.8.8.8"
# initialize packet with MESSAGE
packet = Array(UInt16).new PACKET_LENGTH_16 do |i|
MESSAGE[ i % MESSAGE.size ].ord.to_u16
end
# build out ICMP header
packet[0] = (TYPE.to_u16 << 8)
packet[1] = 0_u16
packet[2] = sender_id
packet[3] = sequence
# calculate checksum
checksum = 0_u32
packet.each do |byte|
checksum += byte
end
checksum += checksum >> 16
checksum = checksum ^ 0xffff_ffff_u32
packet[1] = checksum.to_u16
# convert packet to 8 bit words
slice = Bytes.new(PACKET_LENGTH_8)
eight_bit_packet = packet.map do |word|
[(word >> 8), (word & 0xff)]
end.flatten.map(&.to_u8)
eight_bit_packet.each_with_index do |chr, i|
slice[i] = chr
end
# send request
address = Socket::IPAddress.new host, 0
socket = IPSocket.new Socket::Family::INET, Socket::Type::DGRAM, Socket::Protocol::ICMP
socket.send slice, to: address
# receive response
buffer = Bytes.new(PACKET_LENGTH_8 + IP_HEADER_SIZE_8)
count, address = socket.receive buffer
length = buffer.size
icmp_data = buffer[IP_HEADER_SIZE_8, length-IP_HEADER_SIZE_8]
end
ping
It turns out the answer is that Linux (and by extension docker) does not give the same permissions that macOS does for DGRAM sockets. Changing the socket declaration to socket = IPSocket.new Socket::Family::INET, Socket::Type::RAW, Socket::Protocol::ICMP allows the socket to connect under docker.
A little more still is required to run the program in a non-root context. Because raw sockets are restricted to root, the binary must also be issued the correct capability for access to a raw socket, CAP_NET_RAW. However, in docker, this isn't necessary. I was able to get the program to run outside of super-user context by running sudo setcap cap_net_raw+ep bin/ping. This is a decent primer on capabilities and the setpcap command
MacOS doesn't use the same system of permissions, so setcap is just an unrecognized command. As a result, to get the above code to compile and run successfully on macOS without super-user context, I changed the socket creation code to:
socket_type = Socket::Type::RAW
{% if flag?(:darwin) %}
socket_type = Socket::Type::DGRAM
{% end %}
socket = IPSocket.new Socket::Family::INET, socket_type, Socket::Protocol::ICMP
Applying the CAP_NET_RAW capability for use in linux happens elsewhere in the build process if needed.
With those changes, I'm not seeing any requirement for changes to seccomp or apparmor from the default shipped with Docker in order to run the program.

Filtering an argus file

I'm utilizing argus against a pcap file and need to filter by datetime, source and destination IP, and port. Currently, I can take a pcap file and convert to argus:
argus -r packet.pcap -w packet.argus
Then, to read and display argus data:
ra -r packet.argus
At this point, it seems that one can filter the argus data by my aforementioned parameters by using the ra command but I can't seem to find the correct syntax. Any ideas?
info in
https://www.systutorials.com/docs/linux/man/1-ra/
so an example from a batch file I used...
ra -s {column names} -r $l.ra > $l.txt
also suggest adding state and flags, giving;
ra -s stime proto saddr sport daddr dport state -nzr $l.ra > $l.txt

Supervisorctl not respecting my configuration

I have set the following in /home/david/conf/supervisor.conf:
[unix_http_server]
file=/home/david/tmp/supervisor.sock
[supervisord]
logfile=/home/david/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
loglevel=info ; (log level;default info; others: debug,warn,trace)
pidfile=/home/david/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024)
minprocs=200
childlogdir=/home/david/tmp
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///home/david/tmp/supervisor.sock
And started supervisord:
$ supervisord -c /home/david/conf/supervisor.conf
However how come supervisorctl still uses the default http://localhost:9001 as the serverurl?
$ supervisorctl
http://localhost:9001 refused connection
supervisor>
I checked /home/david/tmp and the files supervisord.log and supervisord.pid do exist.
You should run supervisorctl with -c as well. From the documentation (my emphasis):
The Supervisor configuration file is conventionally named
supervisord.conf. It is used by both supervisord and supervisorctl. If
either application is started without the -c option (the option which
is used to tell the application the configuration filename
explicitly), the application will look for a file named
supervisord.conf within the following locations, in the specified
order. It will use the first file it finds.
$CWD/supervisord.conf
$CWD/etc/supervisord.conf
/etc/supervisord.conf
In MacOS, use brew to install
brew install supervisor
Then go to /usr/local/etc/supervisord.ini and comment these lines:
;[unix_http_server]
;file=/usr/local/var/run/supervisor.sock ; the path to the socket file
and uncomment these lines:
[inet_http_server] ; inet (TCP) server disabled by default
port=127.0.0.1:9001 ; ip_address:port specifier, *:port for all iface
Finally restart the daemon:
brew services restart supervisor
That's all you need.
To add to the valid answer above make sure you are putting your config files for the apps you want to monitor under supervisor's config folder as a subfolder called conf.d. This will depend of what method you use to install supervisor, the default package manager or easy_install.
As solution you can make symbolic link to the config file.
Like this for Mac OS:
sudo ln -sv /usr/local/etc/supervisord.ini /etc/supervisord.conf