How to send raw data in tls in scapy? - security

There were packets captured by Wireshark sent by a fuzzing tool, and I'd like to craft to resend the packets in tls by scapy.
Here is the malformed packet captured. The pattern is \x18\x03\x01\x00\x01\x7f.
The structure of the packet disassembled by scapy is as follows:
>>> rdpcap("659726.pcap")[146].show()
###[ Ethernet ]###
dst= aa:aa:aa:aa:aa:aa
src= 00:50:56:bb:64:01
type= 0x800
###[ IP ]###
version= 4
ihl= 5
tos= 0x0
len= 46
id= 4211
flags= DF
frag= 0
ttl= 128
proto= tcp
chksum= 0x0
src= 192.168.40.214
dst= 192.168.40.32
\options\
###[ TCP ]###
sport= 61385
dport= https
seq= 351671141
ack= 2538369473
dataofs= 5
reserved= 0
flags= PA
window= 508
chksum= 0xd267
urgptr= 0
options= []
###[ Raw ]###
load= '\x18\x03\x01\x00\x01\x7f'
The following script, which I modified from /examples/full_rsa_connection_with_application_data.py is to resend the packets. It contains 2 steps: SSL Handshake and a malformed packet.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import with_statement
from __future__ import print_function
from scapy.all import *
try:
# This import works from the project directory
from scapy_ssl_tls.ssl_tls import *
except ImportError:
# If you installed this package via pip, you just need to execute this
from scapy.layers.ssl_tls import *
tls_version = TLSVersion.TLS_1_0
ciphers = [TLSCipherSuite.ECDHE_RSA_WITH_AES_128_GCM_SHA256]
# ciphers = [TLSCipherSuite.ECDHE_RSA_WITH_AES_256_CBC_SHA384]
# ciphers = [TLSCipherSuite.RSA_WITH_AES_128_CBC_SHA]
ciphers = [TLSCipherSuite.RSA_WITH_RC4_128_SHA]
# ciphers = [TLSCipherSuite.DHE_RSA_WITH_AES_128_CBC_SHA]
# ciphers = [TLSCipherSuite.DHE_DSS_WITH_AES_128_CBC_SHA]
extensions = [TLSExtension() / TLSExtECPointsFormat(),
TLSExtension() / TLSExtSupportedGroups()]
def tls_client(ip):
with TLSSocket(client=True) as tls_socket:
try:
tls_socket.connect(ip)
print("Connected to server: %s" % (ip,))
except socket.timeout:
print("Failed to open connection to server: %s" % (ip,), file=sys.stderr)
else:
try:
server_hello, server_kex = tls_socket.do_handshake(tls_version, ciphers, extensions)
server_hello.show()
malformedPacket = Raw('\x18\x03\x01\x00\x01\x7f') #or malformedPacket = IP(dst="192.168.40.32")/TCP(dport=443)/raw('\x18\x03\x01\x00\x01\x7f')
respMalformedPacket = tls_socket.do_round_trip(malformedPacket)
print("response from malformed packet: ==========================================")
respMalformedPacket.show()
print("end of response from malformed packet: ==========================================")
except TLSProtocolError as tpe:
print("Got TLS error: %s" % tpe, file=sys.stderr)
tpe.response.show()
else:
resp = tls_socket.do_round_trip(TLSPlaintext(data="GET / HTTP/1.1\r\nHOST: localhost\r\n\r\n"))
print("Got response from server")
resp.show()
finally:
print(tls_socket.tls_ctx)
if __name__ == "__main__":
if len(sys.argv) > 2:
server = (sys.argv[1], int(sys.argv[2]))
else:
server = ("127.0.0.1", 8443)
tls_client(server)
I just want to send the pattern'\x18\x03\x01\x00\x01\x7f' to the target after SSL Handshake. SSL Handshake is done by tls_socket.do_handshake(). Then I want to send the malformed packet I crafted by adding tls_socket.do_round_trip(malformedPacket) after ChangeCipherSpec as the original packet captured. However, it failed to send successfully, and here is the result. I have no idea of how to send the raw data in tls correctly. I need some suggestion. Thanks.

Related

A program that can sniff and spoof ICMP packets using the Scapy library in Python:

`#!/usr/bin/env python
from scapy.all import *
from threading import Thread
def icmp_spoof(pkt):
if pkt.haslayer(ICMP) and pkt[IP].src == "10.9.0.1":
src_ip = pkt[IP].dst
dst_ip = pkt[IP].src
seq_num = pkt[ICMP].seq
id_num = pkt[ICMP].id
icmp_reply = IP(src=src_ip, dst=dst_ip)/ICMP(type='echo-reply', id=id_num, seq=seq_num)/Raw(load=pkt[Raw].load)
send(icmp_reply, verbose=0)
def sniff_icmp():
sniff(filter="icmp and src host 10.9.0.1", prn=icmp_spoof)
if __name__ == '__main__':
t = Thread(target=sniff_icmp)
t.start()`
this program is spoofing the packets but it is not printing the sniffed packets what chan could be made in order to print the sniffed packets
This image shows the ICMP packets spoofed
This is how I want this packet info printed

send DNS queries over UDP to a DNS server using the Python

I am going to send DNS queries over UDP to a DNS server using the Python3 programming language. This is a description:
Your program must send requests for either IPv4 ("A) or IPv6 ("AAAA") addresses
Your program must take 3 command-line arguments:
The type of of address requested (denoted with the --type flag), which can have the value 'A' or 'AAAA'
The host name being queried (denoted with the --name flag)
The IP address of the DNS server to query (denoted with the --server flag)
why when I print(raw_bytes2), I received nothing
#!/usr/bin/env python3
# Python DNS query client
#
# Example usage:
# ./dns.py --type=AAAA --name=www.google.com --server=8.8.8.8
# Should provide equivalent results to:
# dig www.google.com AAAA #8.8.8.8 +noedns
# (note that the +noedns option is used to disable the pseduo-OPT
# header that dig adds. Our Python DNS client does not need
# to produce that optional, more modern header)
import argparse
import ctypes
import random
import socket
import struct
import sys
def main():
# Setup configuration
parser = argparse.ArgumentParser(description='DNS client for ECPE 170')
parser.add_argument('--type', action='store', dest='qtype',
required=True, help='Query Type (A or AAAA)')
parser.add_argument('--name', action='store', dest='qname',
required=True, help='Query Name')
parser.add_argument('--server', action='store', dest='server_ip',
required=True, help='DNS Server IP')
args = parser.parse_args()
qtype = args.qtype
qname = args.qname
server_ip = args.server_ip
port = 53
server_address = (server_ip, port)
if qtype not in ("A", "AAAA"):
print("Error: Query Type must be 'A' (IPv4) or 'AAAA' (IPv6)")
sys.exit()
# Create UDP socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((server_ip, port))
# Generate DNS request message
# type
raw_bytes = bytearray()
if qtype == "A":
raw_bytes.append(0x00)
raw_bytes.append(0x01)
elif qtype == "AAAA":
raw_bytes.append(0x00)
raw_bytes.append(0x1c)
#qname
split = qname.split(".")
string = ""
for i in split:
hexs = hex(len(i))
string += str(hexs)+i
#string += "0x00"
raw_bytes +=bytes(string,'ascii')
#sever 8.8.8.8
raw_bytes.append(0x08)
raw_bytes.append(0x08)
raw_bytes.append(0x08)
raw_bytes.append(0x08)
# Send request message to server
# print(raw_bytes)
bytes_send = s.sendto(raw_bytes,server_address)
# Receive message from server
max_bytes = 4096
(raw_bytes2,src_addr) = s.recvfrom(max_bytes)
print(raw_bytes2)
# Close socket
# ---------
s.close()
# Decode DNS message and display to screen
print(bytes_send)
# dns.decode_dns(raw_bytes)
if __name__ == "__main__":
sys.exit(main())

How to write a pcap file with input data given [duplicate]

I'm trying to create a very simple PCAP file (1 UDP message).
Tried using dpkt (pcap.Writer), no luck, and the documentation is scarce.
Can anyone post a working example?
(or any other alternative - I'm not bound to dpkt)
You may use Scapy.
https://scapy.readthedocs.io/en/latest/installation.html
If using Python 3:
pip3 install scapy
Then in Python:
from scapy.all import wrpcap, Ether, IP, UDP
packet = Ether() / IP(dst="1.2.3.4") / UDP(dport=123)
wrpcap('foo.pcap', [packet])
you need to write the packet into a libpcap format
Global Header + Packet Header + Packet Data + Packet Header + Packet Data
this link should help you
http://www.codeproject.com/Tips/612847/Generate-a-quick-and-easy-custom-pcap-file-using-P
construct's cap (broken link) shows how to use construct for this. Construct also has a rudimentary ip stack (broken link) example. The nice thing about Construct is that it is symmetrical, i.e. you can put data into it, convert it to a set of Python objects and you can then dump out the objects to create the original data blob again.
You can try the code below :
#!/usr/bin/env python3
import sys
import struct
import os
import argparse
from scapy.all import sniff, sendp, hexdump, linehexdump, get_if_list, get_if_hwaddr
from scapy.all import Packet, IPOption
from scapy.all import ShortField, IntField, LongField, BitField, FieldListField, FieldLenField
from scapy.all import IP, TCP, UDP, Raw
from scapy.layers.inet import _IPOption_HDR
from scapy.all import raw
from scapy.all import bytes_hex
import hashlib
import pcapng.blocks as blocks
from pcapng import FileWriter
counter = 1
def get_if():
ifs=get_if_list()
iface=None
for i in get_if_list():
if "enp1s0f1" in i:
iface=i
break;
if not iface:
print("Cannot find eth0 interface")
exit(1)
return iface
def main():
global counter
ifaces = [i for i in os.listdir('/sys/class/net/') ]
iface = get_if()
print(("sniffing on %s" % iface))
sys.stdout.flush()
writer = FileWriter(args.outfile, shb)
orig_packets = sniff(filter='tcp and port 5201',iface = iface)
for packet in orig_packets:
spb = shb.new_member(blocks.SimplePacket)
spb.packet_data = bytes(packet)
writer.write_block(spb)
print("C=",counter)
counter=counter+1
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("outfile", type=argparse.FileType("wb"))
args = parser.parse_args()
shb = blocks.SectionHeader(
options={
"shb_hardware": "artificial",
"shb_os": "python",
"shb_userappl": "python-pcapng",
})
idb = shb.new_member(
blocks.InterfaceDescription,
link_type=1,
options={
"if_description": "Hand-rolled",
"if_os": "Python",
"if_filter": [(0, b"tcp port 5201 and host 192.168.1.3")],
},)
main()

Python3 x Socket - ICMP Echo request - Why my socket is hang up on recv?

I want to send echo request with ICMP and python's socket. I was sending packet. But my program is hang up on recv from socket. Why my socket is hang up?
OS is Windows10.
Launch terminal is admin mode.
# -*- coding: utf-8 -*-
import socket
import struct
def ping(host, port):
with socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) as sock:
sock.connect((host, port))
sock.settimeout(30)
icmp_message = struct.pack('!BBHHH', 8, 0, 8, 0, 0)
packet = icmp_message
print('send packet...')
sock.sendall(packet)
print('recv...')
data = sock.recv(1024)
def main():
ping('192.168.0.1', 80)
if __name__ == '__main__':
main()

dns scapy server doesnt get the packet

i need to send a packet using scapy to a dns server i made, and for some reason the server doesnt get the packet
this is the dns server
-- coding: utf-8 --
from scapy.all import *
def le_check(p):
return (DNS in p and p[0][DNSQR].qtype == 1 and p[0][UDP].dport==53)
def main():
data_base = {'www.google.com': ('172.217.23.164','173.194.79.104','173.194.79.99')}
p1=sniff(count=1, lfilter=le_check)
x=p1[0][DNSQR].qname
if x in data_base:
list=data_base[x]
else:
list= "no such name"
print p1[0][DNSQR].qname
print list
send(IP(dst=p1[0][IP].src)/UDP(sport=53, dport=53)/Raw(list))
if __name__ == '__main__':
main()
code from scapy
sendp(IP(dst=MY_IP)/UDP(sport=24601,dport=53)/DNS(qdcount=1,rd=1)/DNSQR(qname="www.google.com",qtype=1))

Resources