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..
Related
I'm building a network scanner with Python using Scapy. I've been trying to send ARP packets but for some reason they don't get responded to.
#!/usr/bin/env python3
from scapy.all import *
def scan(ip):
arp_request = ARP(pdst=ip)
broadcast = Ether(dst="ff:ff:ff:ff:ff:ff")
arp_request_broadcast = arp_request/broadcast
answered_list = srp(arp_request_broadcast, timeout=2)[0]
for element in answered_list:
print(element[1].show())
scan("192.168.1.0/24")
Running it results in the following:
[void#Void Network Scanner]$ sudo python3 tutorial_netscanner.py
[sudo] password for void:
Begin emission:
Finished sending 256 packets.
............................................................
Received 60 packets, got 0 answers, remaining 256 packets
The strange part is that if I run this from the scapy interactive shell it works and the arp packets do get answered.
arping("192.168.1.0/24")
Super confused as to why this isn't working, the code seems perfectly fine to me, if anyone could help me out that would be great. Thank you.
arp_request/broadcast is incorrect. The outer-most protocols go on the left. If you use Wireshark to see what's going on (the first thing you should do when something like this happens), you can see that it's not what you'd expect it to be:
It's essentially a malformed packet. You need broadcast / arp_request; although specifying the Ether layer is optional. You can use simply ARP (and sr).
Use Wireshark. It's an invaluable tool. You should only run it on networks that you have control over/permission to snoop, but it really is indispensable.
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.
I want to send a packet with scapy to another interface.
I have the wlan2 interface and i want my packet (that i generate) to be send there.
I've tried using send with iface but it has no effect.
I also tried using srp and just sendp but i am getting this strange result:
answer = srp(pkt[Ether]/ip/new_pkt/html1, iface="wlan2")
pkt[Ether] is a valid pkt that comes from the wlan2 interface and i can sniff it.
i am trying to generate an http response packet using its Ethernet layer.
But my response is always going to another interface and i think this is the problem.
Wireshark Ethernet II
The packets are grey...
The question is how to fix this? how do i send a legit packet to the wlan2 interface.
I have a program (.exe) that gets certain info from a server, and I wanted to be able to get that info from the command line too. I started netcat and listened on the port the program uses to communicate with its target, because I wanted to know what "requests" to make from a script, and I received this over netcat, plain text:
net.tcp://[my ip address]:41012/Lapis.Btouch/ServerInfo
I tried sending exactly that to the target (replacing my IP for its IP) using socket.send() but it wouldn't return anything. What does that mean and how can I get the data?
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('[server ip address]',41012))
while True:
s.send('net.tcp://[server ip address]:41012/Lapis.Btouch/ServerInfo')
response = s.recv(1024)
print response
s.close()
That's the code I'm using to send the request to the target server. It won't return anything, so I think I'm not making the request in the right way. Thanks for any help.
Try capture your network packet on port 41012, via tcpdump or wireshark or ...
Then check:
does your code send the request?
does the response returned to you?
If the answer for question (1) is False, problem is side of you and your machine. so go and solve it (review your code, check your firewall and ...)
If the answer of question (1) is True, but server doesn't send any response (this case often not happened) review your request format (check you URL or test it via browser or ...). also based on the server you connect to, maybe needed to your machine's IP recognized for server (I mean some server only give response to requests, that come from known IP addresses, in this case you need introduce yourself to server (e.g. add your IP to trusted list on server), before sending request)
Last case, if answer of both questions are correct (I guess it's your problem), you most correct your code (response = s.recv(1024)) why do you used 1024 for your response length?. Use correct and accurate parameters.
In python exist several methods for receiving response via socket (from server), search stackoverflow and you can find useful tips and commands. commands like use non-blocking ways, ascync ways and ...
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.