i need your help guys, well my idea is, after we press the enter v
button to search for a site, i have to capture this packet and check it, i already did the "check part", the packet i am looking for is 'get' requests, i guess? so here is the code where i need help
from __future__ import print_function
def process_tcp_packet(packet):
#here i should stop the packet
#after i captured the packet i am checking it(already have this part)
#decide if i should delete the request packet or send it as i wished
return
def main():
#sniff(filter=, prn=process_tcp_packet)
pass
after i sniff the packet how i am stopping the sending, like i need to stop the packet check it and then decide to send it as i wanted or delete the packet, can i do it?
It is not possible to "stop" a packet using scapy:
Scapy only sniffs packets, which means get a copy of them as they are beeing sent. It is using some libraries to do so, and cannot force your OS to cancel the sending.
Related
I'm trying to write a server-client(s) program in python using the socket and the threading module. I would like to send and receive to and from the client a confirmation data packet to check if it is still connected to the server and, simultaneously, I would like to be able to ask for input from the server user and then send it whenever the server user presses enter.
I think a possible way to achieve that is just using two simultaneous threads, one that sends a validation data packet and the other that sands server user input. The syntax would look like the following:
import threading
import socket
def confirmation():
# do confirmation
def send_server_input():
# send the user server input
confirmation_thread = threading.Thread(target=confirmation)
confirmation_thread.start()
send_server_input_thread = threading.Thread(target=send_server_input)
send_server_input_thread.start
But I'm afraid that this way won't work, because the data packets may "get confused" or "collapse" one into the other. And if that doesn't happen, how can I distinguish one from the other from the client side this to data packets?
Thank you very much for your time and excuse my English, I'm still practising it!
I am communicating with an instrument via TCP/IP using the Python socket package.
The program sends a command to the instrument to perform an action, and then repetitively sends another "check" command until it receives a "done" reply. However, after many loops, the program hangs while waiting for a "done" reply.
I have circumvented this problem by using the recv_timeout() function below, which returns no data if the socket is hanging, then I close the connection with socket.close() and reconnect.
Is there a more elegant solution without having to reboot anything?
import socket
import time
def recv_timeout(self,timeout=0.5):
'''
code from http://code.activestate.com/recipes/408859/
'''
self.s.setblocking(0)
total_data=[];data='';begin=time.time()
while 1:There must be a way I can reboot to carry on communicating with the instrument, without having to restart.
#if you got some data, then break after wait sec
if total_data and time.time()-begin>timeout:
break
#if you got no data at all, wait a little longer
elif time.time()-begin>timeout*2:
break
try:
data=self.s.recv(8192)
if data:
total_data.append(data)
begin=time.time()
else:
time.sleep(0.1)
except:
pass
return ''.join(total_data)
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect(('555.555.55.555',23))
for action_num in range(0,1000):
socket.sendall(('performaction %s \r'%action_num).encode())
while True:
time.sleep(0.2)
socket.sendall(('checkdone \r').encode())
done = socket.recv_timeout()
if not done:
print 'communication broken...what should I do?'
socket.close()
time.sleep(60)
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect(('555.555.55.555',23))
elif done == '1':
print 'done performing action'
break
socket.close()
I have circumvented this problem by using the recv_timeout() function
below, which returns no data if the socket is hanging
Are you certain that the socket will hang forever? What about the possibility that the instrument just sometimes takes more than half a second to respond? (Note that even if the instrument's software is good at responding in a timely manner, that is no guarantee that the response data will actually get to your Python program in a timely manner. For example, if the TCP packets containing the response get dropped by the network and have to be resent, that could cause them to take more than .5 seconds to return to your program. You can force that scenario to occur by pulling the Ethernet cable out of your PC for a second or two, and then plugging it back in... you'll see that the response bytes still make it through, just a second or two later on (after the dropped packets get resent); that is, if your Python program hasn't given up on them and closed the socket already.
Is there a more elegant solution without having to reboot anything?
The elegant solution is to figure out what is happening to the reply bytes in the fault scenario, and fixing the underlying bug so that the reply bytes no longer get lost. WireShark can be very helpful in diagnosing where the fault is; for example if WireShark shows that the response bytes did enter your computer's Ethernet port, then that is a pretty good clue that the bug is in your Python program's handling of the incoming bytes(*). On the other hand if the response bytes never show up in WireShark, then there might be a bug in the instrument itself that causes it to fail to respond sometimes. Wireshark would also show you if the problem is that your Python script failed to send out the "check" command for some reason.
That said, if you really can't fix the underlying bug (e.g. because it's a bug in the instrument and you don't have the ability to upgrade the source code of the software running on the instrument) then the only thing you can do is what you are doing -- close the socket connection and reconnect. If the instrument doesn't want to respond for some reason, you can't force it to respond.
(*) One thing to do is print out the contents of the string returned by recv_timeout(). You may find that you did get a reply, but it just wasn't the '1' string you were expecting.
I am currently working on a project where I need to send packets to a particular networking hardware, receive responses back, and generate packets based on the response in real time.
I came across Scapy, and to my understanding it is capable of doing the first two parts: sending and receiving. Is it possible through Python to retrieve the necessary fields in a response and respond back?
Thanks!
If I understand what you mean, you have (at least) two options with Scapy:
The clean one is to create an AnsweringMachine that matches your needs (you have several examples in Scapy's code).
The dirty (but maybe quicker if that's what you need) one is to give as prn parameter to sniff() a function that will receive the packet, craft an answer (or anything you like) and send() it on the network.
As an example, this code will send RST-ACK packets to any TCP packet seen with SYN flag on:
def rst(p):
ans = IP(src=p[IP].dst, dst=p[IP].src)/TCP(
flags='RA',
sport=p[TCP].dport,
dport=p[TCP].sport,
seq = 0,
ack = p[TCP].seq + 1,
)
send(ans, verbose=False)
return "%s\n => %s" % (p[IP].summary(), ans.summary())
sniff(iface="eth0", filter="tcp and tcp[tcpflags] & tcp-syn == tcp-syn",
prn=rst)
In order to perform a HTTP GET, I need to send a packet (the GET / HTTP/1.0\n\n) and wait for 3 packets:
The ACK of my GET
The GET answer: HTTP/1.0 200 OK
and the FIN ACK of the transmission
I found 2 ways:
=> use sr() with multi option
=> use sniff just after sending my GET request
For sr() function, the problem is to stop the sniffing, the only option is to set a timeout, but my script will test many different sites, so many different of time's answer, it could be hard to choose a static timeout value where I'm sure that no site exceed it anytime.
For sniff, there is no the same problem because I can set "count" argument to take only the 3 packets. But it's hard to make a filter good enough to be sure the 3 packets recorded are the 3 that I want (and no ARP, DNS or anything else).
But the main problem is sometimes the fist answer packet come before "sniff" is launched (between send(GET_PACKET) and answers=sniff(...)). In this case, I lost some information and all my post-treatment is corrupted.
The perfect way would be to use sr() function with "count=3" option to only get 3 packets, but that option doesn't exist with sr().
Anynone have an idea?
Thanks a lot
Sorry for my language, I'm French
Use Sniff and set the filter to TCP port 80
and for delay problem you can use a thread, first start your sniffer in thread then send the packets :
def sniffer():
packets=sniff(filter="tcp port 80" , count=5)
wrcap("test.cap" , packets) #save packets in .cap file
t = threading.Thread(target=sniffer)
t.start()
But you can use a better way that explained HERE. send your packets manually.
This is more of a hint than an answer, but the problem might be that you want to inspect transport layer packets for a application layer request. You could split up your HTTP GET down to transport layer by sending SYN, waiting for and answer and then send ACK, GET. Here is a link describing what you might want.
I am trying to use scapy to run a complete HTTP session. That is to say, I want to manually perform the three way handshake, GET request, acknowledgements as necessary to receive the HTML file, and terminating the connection. Using [1] I have completed the three way handshake and the GET request, but I can't seem to capture the raw HTML packets sent from the server, and I obviously can't send an ack packet back for more. Any ideas?
Additionally, I'd ultimately like to be able to parse the raw packet for HTML. If anyone knows how to do that from a scapy packet I'd appreciate it.
[1] http://www.thice.nl/creating-ack-get-packets-with-scapy/
Gimbi,
I am at work and can only parse and not initiate connections in scapy right now. So i will address your second request. We are looking at something like I have provided here. The layer that contains the html as well as the http requests is (Raw).load if the packet contains html or an http request I would first test to see if the layer exists (haslayer) and then if the packet is a 'http packet" here is just check for 80 in the IF statement, however you could potentially just use the port in the sniff netfilter. I have included the option to sniff directly off the wire or pull in a pcap here in this snippet. (adjust ports etc if you are using non standards)
#!/usr/bin/python -tt
from scapy import *
import sys
def parse(pkt):
if pkt.haslayer(TCP) and pkt.getlayer(TCP).dport == 80 and pkt.haslayer(Raw):
print pkt.getlayer(Raw).load
if '-l' in sys.argv:
sniff(prn=parse)
else:
pkts = rdpcap(sys.argv[1])
for pkt in pkts:
parse(pkt)
Of course use this as a start you can adjust line 8 to pick up not just dport but also sport for example. Let me know if this helps at all and good luck!
P.S. change the following
from scapy import *
to
from scapy.all import *
depending on your version..