I have a very basic question, I suppose. I am using pyOSC library to receive OSC messages with Python.
The code I use is this:
import OSC
import time, threading
receive_address = '127.0.0.1', 9000
def printing_handler(addr, tags, stuff, source):
print "---"
print "received new osc msg from %s" % OSC.getUrlStr(source)
print "with addr : %s" % addr
print "typetags %s" % tags
print "data %s" % stuff
print "---"
s = OSC.OSCServer(receive_address)
s.addMsgHandler("/valueToNetwork", printing_handler)
st = threading.Thread( target = s.serve_forever )
st.start()
I then want to use the values in stuff as variables OUTSIDE the function, so I put return stuff; as last line but got a message when doing print printing_handler.
The message I get is: <function printing_handler at 0x76a78e70> in the sh window.
Related
I recently bought the book Black Hat Python, 2nd Edition, by Justin Seitz, which seems to be a very good book about networking and all that (i am writing my code on Kali Linux)
I have a problem on the TCP Proxy Tool on chapter 2 :
Here is the code :
import sys
import socket
import threading
HEX_FILTER = ''.join(
[(len(repr(chr(i))) == 3) and chr(i) or '.' for i in range(256)])
def hexdump(src, length = 16, show = True):
# basically translates hexadecimal characters to readable ones
if isinstance(src, bytes):
src = src.decode()
results = list()
for i in range(0, len(src), length):
word = str(src[i:i+length])
printable = word.translate(HEX_FILTER)
hexa = ' '.join(['{ord(c):02X}' for c in word])
hexwidth = length*3
results.append('{i:04x} {hexa:<{hexwidth}} {printable}')
if show :
for line in results :
print(line)
else :
return results
def receive_from(connection):
buffer = b""
connection.settimeout(10)
try :
while True :
data = connection.recvfrom(4096)
if not data :
break
buffer += data
except Exception as e:
pass
return buffer
def request_handler(buffer):
# perform packet modifications
return buffer
def response_handler(buffer):
# perform packet modifications
return buffer
def proxy_handler(client_socket, remote_host, remote_port, receive_first):
remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote_socket.connect((remote_host, remote_port))
if receive_first :
# Check for any data to receive before
going into the main loop (i guess)
remote_buffer = receive_from(remote_socket)
hexdump(remote_buffer)
remote_buffer = response_handler(remote_buffer)
if len(remote_buffer):
print("[<==] Sending %d bytes to localhost." % len(remote_buffer))
client_socket.send(remote_buffer)
while True : # Start the loop
local_buffer = receive_from(client_socket)
if len(local_buffer):
line = "[==>] Received %d bytes from localhost." % len(local_buffer)
print(line)
hexdump(local_buffer)
local_buffer = request_handler(local_buffer)
remote_socket.send(local_buffer)
print("[==>] Sent to remote.")
remote_buffer = receive_from(remote_socket)
if len(remote_buffer):
print("[==>] Received %d bytes from remote." % len(remote_buffer))
hexdump(remote_buffer)
remote_buffer=response_handler(remote_buffer)
client_socket.send(remote_buffer)
print("[<==] Sent to localhost.")
if not len(local_buffer) or not len(remote_buffer):
# If no data is passed, close the sockets and breaks the loop
client_socket.close()
remote_socket.close()
print("[*] No more data. Closing connections. See you later !")
break
def server_loop(local_host, local_port, remote_host, remote_port, receive_first):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try :
server.bind((local_host, local_port)) # Bind the local host and the local port
except Exception as e:
print('Problem on bind : %r' %e)
# If an error occurs, prints a
print("[!] Failed to listen on %s:%d" % (local_host, local_port))
print("[!] Check for other listening sockets or correct permissions.")
sys.exit(0)
print("[*] Listening on %s:%d" % (local_host, local_port))
server.listen(5)
while True :
client_socket, addr = server.accept()
# print out the local connection information
line = "> Received incoming connection from %s:%d" % (addr[0], addr[1])
print(line)
# start a thread to talk to the remote host
proxy_thread = threading.Thread(
target = proxy_handler,
args=(client_socket,remote_host,
remote_port, receive_first))
proxy_thread.start()
def main():
if len(sys.argv[1:]) != 5:
print("Usage: ./proxy.py [localhost] [localport]")
print("[remotehost] [remoteport] [receive_first]")
print("Example : ./proxy.py 127.0.0.1 9000 192.168.56.1 9000 True")
sys.exit(0)
loca l_host = sys.argv[1]
local_port = int(sys.argv[2])
remote_host = sys.argv[3]
remote_port = int(sys.argv[4])
receive_first = sys.argv[5]
if "True" in receive_first:
receive_first = True
else :
receive_first = False
server_loop(local_host, local_port,
remote_host, remote_port, receive_first)
if __name__ == '__main__':
main()
(sorry, i had a bit of a trouble formatting it and it's quite long)
Now, normally, i just need to open 2 terminals and run the code with the command line :
sudo python proxy.py 127.0.0.1 21 ftp.dlptest.com 21 True
in one terminal, and :
ftp 127.0.0.1 21
in the other one.
My code seems to be working fine, except that... I receive no data. I tried different ftp servers (notice that i don't use the one quoted in the book), but it still doesn't work. It just says :
[*] Listening on 127.0.0.1
> Received incoming connection from 127.0.0.1:55856
but it doesn't actually displays anything until the connexion times out or that i stop the command with Ctrl + C.
I know this question has already been asked, but they don't resolve my problem.
Please tell me if i forgot a line of code (for example the one that prints the data on the screen lol) or did anything wrong :)
one the hexa variable you need to put and f'{ord(c):02x}' because you just have a string and not using the 'c' variable from the list comprehension. That's a small typo you missed fix that and try the whole process again.
hexa = ' '.join([f'{ord(c):02X}' for c in word])
The f should be here ^
this is my first entry #stackoverflow;-))
I need a Python3 TCP server, which sends all inputs of the clients to the other participants. The server works, but unfortunately the message is only returned to the sending client. As soon as the second client sends something, it gets all entries.The entries are therefore available in the output queue.
Why are the entries not recognized by select ()?
Thx for the support.
`
import select
import socket
import sys
import queue
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(0)
server_address = ('192.168.100.28', 8888)
print ("starting up on %s port %s" % server_address)
server.bind(server_address)
server.listen(5)
inputs = [ server ]
outputs = [ ]
message_queues = {}
while inputs:
print ("\nwaiting for the next event")
readable, writable, exceptional = select.select(inputs, outputs, inputs)
Handle inputs
for s in readable:
if s is server:
# A "readable" server socket is ready to accept a connection
connection, client_address = s.accept()
print ("new connection from", client_address)
connection.setblocking(0)
inputs.append(connection)
# Give the connection a queue for data we want to send
message_queues[connection] = queue.Queue()
else:
data = s.recv(1024)
if data:
# A readable client socket has data
print ('received "%s" from %s' % (data, s.getpeername()))
# Add output channel for response
#message_queues[s].put(data)
if s not in outputs:
outputs.append(s)
for aQueue in message_queues:
message_queues[aQueue].put(data)
# AQueue.send ("Test".encode())
else:
# Interpret empty result as closed connection
print ("closing", client_address, "after reading no data")
# Stop listening for input on the connection
if s in outputs:
outputs.remove(s)
inputs.remove(s)
s.close()
# Remove message queue
del message_queues[s]
Handle outputs
for s in writable:
try:
next_msg = message_queues[s].get_nowait()
except queue.Empty:
# No messages waiting so stop checking for writability.
print ("output queue for", s.getpeername(), "is empty")
outputs.remove(s)
else:
print ('sending "%s" to %s' % (next_msg, s.getpeername()))
s.send(next_msg)
Handle "exceptional conditions"
for s in exceptional:
print ("handling exceptional condition for", s.getpeername())
# Stop listening for input on the connection
inputs.remove(s)
if s in outputs:
outputs.remove(s)
s.close()
# Remove message queue
del message_queues[s]
`
Your problem is that you only add a peer to the output list when you read something from it. You should instead do it when you write somthing to its message queue.
The receiving part should become:
...
data = s.recv(1024)
if data:
# A readable client socket has data
print ('received "%s" from %s' % (data, s.getpeername()))
# Add output channel for response
#message_queues[s].put(data)
# if s not in outputs:
# outputs.append(s)
for aQueue in message_queues:
message_queues[aQueue].put(data)
if aQueue not in outputs: # enqueue the msg
outputs.append(aQueue) # and ask select to warn when it can be sent
# AQueue.send ("Test".encode())
else:
...
According to your own requirements, you should only enqueue messages for other participants:
for aQueue in message_queues:
if aQueue != s: # only send to other participants
...
Finally, you often test existence of a socket in outputs. That let think that a set would be more appropriate than a list.
My script is monitoring changes to the state of my remote xbee. To do this I need to send the destination long address to the router which I get from the coordinator. It all works well if I explicitly type in the destination long address like this:
addr = '\x00\x13\xA2\x00#\n!\x1C'
xbee.remote_at(dest_addr_long=addr, command=mycommand, frame_id='\x01')
and it gives me the desired data output which is
{'status': '\x00', 'source_addr': '\x7fD', 'source_addr_long': '\x00\x13\xa2\x00#\n!\x1c', 'frame_id': '\x01', 'command': 'D0', 'parameter': '\x05', 'id': 'remote_at_response'}
from which I can read the parameter to determine the state of the xbee.
The problem I am having is that I don't know the addr up front. I get it when I run this command
mysourceaddrlong = repr(data['source_addr_long'])[1:-1]
addr = "\\".join([(i[0]+i[1:].upper()) for i in mysourceaddrlong.split('\\') if i])
addr = addr[1:] #remove the x in front
addr = r"\x"+addr #add \x to the front and save it as a raw string
print "Formatted addr: %s" % addr
Which outputs:
Formatted addr: \x00\x13\xA2\x00#\n!\x1C
This formatted addr appears to me to be exactly the same, but it does not work when I run my at command like this:
xbee.remote_at(dest_addr_long=addr, command=mycommand, frame_id='\x01')
I get an error saying
ValueError: The data provided for 'dest_addr_long' was not 8 bytes long
I've included the entire script below:
#! /usr/bin/python
import serial
import time
from xbee import XBee
ser = serial.Serial('/dev/ttyUSB0', 9600)
xbee = XBee(ser)
def print_data(data):
print data
mycommand = data['command']
mysourceaddrlong = repr(data['source_addr_long'])[1:-1]
addr = "\\".join([(i[0]+i[1:].upper()) for i in mysourceaddrlong.split('\\') if i])
print "incorrectly formatted addr: %s" % addr
addr = addr[1:] #remove the x in front
addr = r"\x"+addr #add \x to the front and save it as a raw string
print "formatted addr: %s" % addr
try:
xbee.remote_at(dest_addr_long=addr, command=mycommand, frame_id='\x01')
response = xbee.wait_read_frame()
myhexparameter = response['parameter']
myparameter = ord (myhexparameter)
if myparameter == 4:
print "Which means pin %s is OFF" % mycommand
if myparameter == 5:
print "Which means pin %s is ON" % mycommand
except KeyboardInterrupt:
pass
xbee = XBee(ser, callback=print_data)
while True:
try:
time.sleep(0.001)
except KeyboardInterrupt:
break
xbee.halt()
ser.close()
formatted_addr (my name for the addr you compute in your second snippet) only appears to be the same as addr (as you set it in the first snippet) because you're passing both through the wringer of __str__ (indirectly via print) which strives for aesthetically nice output at the cost of possible ambiguity. Try instead:
print(repr(addr))
vs
print(repr(formatted_addr))
and you'll see the differences -- all those backslash characters are actually in the formatted_addr string (and get doubled in repr) while they aren't in addr (they're only displayed as part of escape sequences).
I can't repro the issue myself as I don't have access to your setup, but I suspect
actual_addr = data['source_addr_long']
is actually what you want, without all the string processing gyrations around it. Try
print(repr(actual_addr))
and unless the problem is fixed tell us what exactly you see from these three print(repr(...)) and I bet it will be easy to fix any discrepancy that might remain.
How can I find with scapy wireless networks around? If I do sniff() and if pkt.haslayer(Dot11) and then if pkt.info then I collect them but very slow, for example my Android phone do it in seconds and this script in minutes or even more...
The reason for the difference is that your phone is actively looking for WiFi points by sending out requests to any access points nearby - sniff is listening for any passing traffic.
You might find is a lot quicker to:
Specifically select your network adapter - so you are not sniffing all adapters.
Do some digging to find out how to actively query for wifi networks and use sr with such packets, read the IEEE 802.11 specification to find out more, I would especially look for "Probe request frame".
The example on how to send WiFi packets from packet header may well help, (not my code and not tested by me):
#!/usr/bin/env python
"""
802.11 Scapy Packet Example
Author: Joff Thyer, 2014
"""
# if we set logging to ERROR level, it supresses the warning message
# from Scapy about ipv6 routing
# WARNING: No route found for IPv6 destination :: (no default route?)
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
class Scapy80211():
def __init__(self,intf='wlan0',ssid='test',\
source='00:00:de:ad:be:ef',\
bssid='00:11:22:33:44:55',srcip='10.10.10.10'):
self.rates = "\x03\x12\x96\x18\x24\x30\x48\x60"
self.ssid = ssid
self.source = source
self.srcip = srcip
self.bssid = bssid
self.intf = intf
self.intfmon = intf + 'mon'
# set Scapy conf.iface
conf.iface = self.intfmon
# create monitor interface using iw
cmd = '/sbin/iw dev %s interface add %s type monitor >/dev/null 2>&1' \
% (self.intf, self.intfmon)
try:
os.system(cmd)
except:
raise
def Beacon(self,count=10,ssid='',dst='ff:ff:ff:ff:ff:ff'):
if not ssid: ssid=self.ssid
beacon = Dot11Beacon(cap=0x2104)
essid = Dot11Elt(ID='SSID',info=ssid)
rates = Dot11Elt(ID='Rates',info=self.rates)
dsset = Dot11Elt(ID='DSset',info='\x01')
tim = Dot11Elt(ID='TIM',info='\x00\x01\x00\x00')
pkt = RadioTap()\
/Dot11(type=0,subtype=8,addr1=dst,addr2=self.source,addr3=self.bssid)\
/beacon/essid/rates/dsset/tim
print '[*] 802.11 Beacon: SSID=[%s], count=%d' % (ssid,count)
try:
sendp(pkt,iface=self.intfmon,count=count,inter=0.1,verbose=0)
except:
raise
def ProbeReq(self,count=10,ssid='',dst='ff:ff:ff:ff:ff:ff'):
if not ssid: ssid=self.ssid
param = Dot11ProbeReq()
essid = Dot11Elt(ID='SSID',info=ssid)
rates = Dot11Elt(ID='Rates',info=self.rates)
dsset = Dot11Elt(ID='DSset',info='\x01')
pkt = RadioTap()\
/Dot11(type=0,subtype=4,addr1=dst,addr2=self.source,addr3=self.bssid)\
/param/essid/rates/dsset
print '[*] 802.11 Probe Request: SSID=[%s], count=%d' % (ssid,count)
try:
sendp(pkt,count=count,inter=0.1,verbose=0)
except:
raise
def ARP(self,targetip,count=1,toDS=False):
if not targetip: return
arp = LLC()/SNAP()/ARP(op='who-has',psrc=self.srcip,pdst=targetip,hwsrc=self.source)
if toDS:
pkt = RadioTap()\
/Dot11(type=2,subtype=32,FCfield='to-DS',\
addr1=self.bssid,addr2=self.source,addr3='ff:ff:ff:ff:ff:ff')\
/arp
else:
pkt = RadioTap()\
/Dot11(type=2,subtype=32,\
addr1='ff:ff:ff:ff:ff:ff',addr2=self.source,addr3=self.bssid)\
/arp
print '[*] ARP Req: who-has %s' % (targetip)
try:
sendp(pkt,inter=0.1,verbose=0,count=count)
except:
raise
ans = sniff(lfilter = lambda x: x.haslayer(ARP) and x.op == 2,
store=1,count=1,timeout=1)
if len(ans) > 0:
return ans[0][ARP].hwsrc
else:
return None
def DNSQuery(self,query='www.google.com',qtype='A',ns=None,count=1,toDS=False):
if ns == None: return
dstmac = self.ARP(ns)
dns = LLC()/SNAP()/IP(src=self.srcip,dst=ns)/\
UDP(sport=random.randint(49152,65535),dport=53)/\
DNS(qd=DNSQR(qname=query,qtype=qtype))
if toDS:
pkt = RadioTap()\
/Dot11(type=2,subtype=32,FCfield='to-DS',\
addr1=self.bssid,addr2=self.source,addr3=dstmac)/dns
else:
pkt = RadioTap()\
/Dot11(type=2,subtype=32,\
addr1=dstmac,addr2=self.source,addr3=self.bssid)/dns
print '[*] DNS query %s (%s) -> %s?' % (query,qtype,ns)
try:
sendp(pkt,count=count,verbose=0)
except:
raise
# main routine
if __name__ == "__main__":
print """
[*] 802.11 Scapy Packet Crafting Example
[*] Assumes 'wlan0' is your wireless NIC!
[*] Author: Joff Thyer, 2014
"""
sdot11 = Scapy80211(intf='wlan0')
sdot11.Beacon()
sdot11.ProbeReq()
sdot11.DNSQuery(ns='10.10.10.2')
I once wrote a script that could scan wireless network .
Its simple to use :
python rs.py mon0
Here mon0 is our interface. There are comments in the code to understand it properly.
#Implementation of a wireless scanner using Scapy library
#!/usr/bin/env python
# rs.py - Wireless AP scanner
#author rahil sharma
# date 15/3/2013 #rs
#usage python rs.py mon0
#where mon0 is your monitoring interface
#used this using my alfa card in bactrack
import sys, os, signal
from multiprocessing import Process
from scapy.all import *
interface='' # monitor interface
aps = {} # dictionary to store unique APs
# process unique sniffed Beacons and ProbeResponses.
#haslayer packet has Dot11 layer present
#ord() string to integer ex ord('a) will give 97
def sniffAP(p):
if ( (p.haslayer(Dot11Beacon))):
ssid = p[Dot11Elt].info
bssid = p[Dot11].addr3
channel = int( ord(p[Dot11Elt:3].info))
capability = p.sprintf("{Dot11Beacon:%Dot11Beacon.cap%}\
{Dot11ProbeResp:%Dot11ProbeResp.cap%}")
# Check for encrypted networks
#now we put Dot11Beacon.cap info in capability and using regular expression search inbuilt function in python we search for privacy if it is present then the network is encrypted
#output of the above cap file is somewhat like this short-slot+DSSS-OFDM+res15+ESS
if re.search("privacy", capability): enc = 'Y'
else: enc = 'N'
# Save discovered AP
aps[p[Dot11].addr3] = enc
# Display discovered AP
print "%02d %s %s %s" % (int(channel), enc, bssid, ssid)
# Channel hopper - we are making a channel hopper because we want to scan the whole wireless spectrum.
#first choose a random channel using randrange function
#use system to run the shell command iw dev wlan0 set channel 1
#exit when a keyboard interrupt is given CTrl+c
def channel_hopper():
while True:
try:
channel = random.randrange(1,15)
os.system("iw dev %s set channel %d" % (interface, channel))
time.sleep(1)
except KeyboardInterrupt:
break
# Capture interrupt signal and cleanup before exiting
#terminate is used to end the child process
#before exiting the program we will be displaying number of aps found etc.
#here Cntrl+c is used to
#signal_handler used to do clean up before the program exits
def signal_handler(signal, frame):
p.terminate()
p.join()
print "\n-=-=-=-=-= STATISTICS =-=-=-=-=-=-"
print "Total APs found: %d" % len(aps)
print "Encrypted APs : %d" % len([ap for ap in aps if aps[ap] =='Y'])
print "Unencrypted APs: %d" % len([ap for ap in aps if aps[ap] =='N'])
sys.exit(0)
#use this for command line variables
#for checking the number of command line variables and if they are in right order
if __name__ == "__main__":
if len(sys.argv) != 2:
print "Usage %s monitor_interface" % sys.argv[0]
sys.exit(1)
interface = sys.argv[1]
#take mon0 as interface given in the fist command line variable
# Print the program header
print "-=-=-=-=-=-= rs_scan.py =-=-=-=-=-=-"
print "CH ENC BSSID SSID"
# Start the channel hopper
#In multiprocessing, processes are spawned by creating a Process object and then calling its start() method
p = Process(target = channel_hopper)
p.start()
# Capture CTRL-C
#this will call the signal handler CTRL+C comes under the SIGINT
signal.signal(signal.SIGINT, signal_handler)
# Start the sniffer
sniff(iface=interface,prn=sniffAP)
#inbuit scapy function to start sniffing calls a function which defines the criteria and we need to give the interface`enter code here`
I'm making an IRC bot for my network. To make the code cleaner, I am defining functions in modules. All these modules are in a folder called "plugins". One module say calls the function sendMsg and fails because it's trying to run a function defined in the main program. I also want to have this module to be able to access variables defined in the main program after the program has started.
import socket
import time
import re
from plugins.say import *
host = "irc.somenetwork.net"
port = 6667
nick = "ircbot"
channels = "##bottesting"
s = socket.socket()
def connect():
s.connect((host, port))
s.send("NICK %s\r\n" % nick)
s.send("USER %s %s nul :%s\r\n" % (nick, nick, nick))
time.sleep(3)
s.send("JOIN %s\r\n" % channels)
time.sleep(3)
def sendMsg(chan, msgSend):
s.send("PRIVMSG %s :%s\r\n" % (chan,msgSend))
# print "Sending message \"%s\" to channel/user \"%s\"" % (msgSend, chan)
def quitServ(quitMsg="m8bot"):
s.send("QUIT %s\r\n" % quitMsg)
connect()
while 1:
msgRaw = s.recv(1024)
print msgRaw
if msgRaw == "":
break
if "PING" in msgRaw:
print "Pong!"
PONG = msgRaw.split(' ')
PONG[0] = PONG[0].replace('PING','PONG')
PONG = ' '.join(PONG)
s.send("%s\r\n" % PONG)
if "PRIVMSG" in msgRaw:
# print "PRIVMSG detected"
user = ''.join(re.compile("(?<=:).{0,}(?=.{0,}!)").findall(msgRaw.split(' ')[0]))
channel = msgRaw.split(' ')[2]
command = (' '.join(msgRaw.split(' ')[3:]).replace(":","",1)).split(' ')[0]
msg = ''.join((' '.join(msgRaw.split(' ')[3:]).replace(":","",1)).split(' ')[1:]).replace("\r\n","")
if not "#" in channel:
channel = user
print "Nick: %s\nChannel: %s\nCommand: %s\nMsg: %s" % (user,channel,command,msg)
if ".quit" in command:
if msg:
quitServ(str(msg))
else:
quitServ()
if ".hello" in command:
# print "Attempting to send Hello World message."
sendMsg(channel, "Hello World!")
if ".say" in command:
say(msg)
quitServ()
This is my program. function say() is as follows:
def say(msg):
sendMsg(channel, "You said: %s" % msg)
I can see what the problem is, but I don't know how I would fix this. Feedback appreciated :)
-Nia
Try import __main__ in your say.py.
And then your say function should look something like this:
def say():
__main__.sendMsg(channel, "You said: %s" % msg)
But this is not a best solution. Just solution with less code changes.