#natcat.py
import argparse
#from dataclasses import dataclass
#from fileinput import close
#from inspect import FullArgSpec
#from inspect import ArgSpec
#from inspect import FullArgSpec
import socket
import shlex
#from sqlite3 import connect
#from ssl import SOL_SOCKET
import subprocess
import sys
#from textwrap import wrap
import textwrap
import threading
def execute(cmd):
cmd=cmd.strip()
if not cmd:
return
output =subprocess.check_output(shlex.split(cmd),
stderr=subprocess.STDOUT)
return output.decode()
class NetCat:
def __init__(self,args,buffer=None):
#pass
self.args=args
self.buffer=buffer
self.socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
def run(self):
if self.args.listen:
self.listen()
else:
self.send()
def send(self):
self.socket.connect((self.args.target,self.args.port))
if self.buffer:
self.socket.send(self.buffer)
try:
while True:
recv_len =1
response=''
while recv_len:
data =self.socket.recv(4096)
recv_len=len(data)
response+=data.decode()
if recv_len<4096:
break
if response:
print(response)
buffer=input('> ')#gai
#buffer='> '
buffer+='\n'
self.socket.send(buffer.encode())
except KeyboardInterrupt:
print("user terminated.")
self.socket.close()
sys.exit()
def listen(self):
self.socket.bind((self.args.target,self.args.port))
self.socket.listen(5)
while True:
client_socket, _ =self.socket.accept()
client_thread=threading.Thread(
target=self.handle,args=(client_socket,)
)
client_thread.start()
def handle(self,client_socket):
if self.args.execute:
output =execute(self.args.execute)
client_socket.send(output.encode())
elif self.args.upload:
file_buffer =b''
while True:
data=client_socket.recv(4096)
#print(data.decode)#jia
if data:
file_buffer +=data
else:
break
with open(self.args.upload, 'wb') as f:
f.write(file_buffer)
message=f'Saved file {self.args.upload}'
client_socket.send(message.encode())
elif self.args.command:
cmd_buffer=b''
while True:
try:
client_socket.send(b'BHP: #>')
while '\n' not in cmd_buffer.decode():
cmd_buffer +=client_socket.recv(64)
response=execute(cmd_buffer.decode())
if response:
client_socket.send(response.encode())
cmd_buffer=b''
except Exception as e:
print(f'server killed {e}')
self.socket.close()
sys.exit()
if __name__=='__main__':
parser=argparse.ArgumentParser(
description="BHP net tool",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=textwrap.dedent('''Example:
netcat.py -t 192.168.0.1 -p 5555 -l -c #command shell
netcat.py -t 192.168.0.1 -p 5555 -l -u=mytest.txt #upload to file
netcat.py -t 192.168.0.1 -p 5555 -l -e=\"cat /etc/passwd\" # excute command
echo 'ABC' | ./netcat.py -t 192.168.0.1 -p 135 # echo text to server port 135
netcat.py -t 192.168.0.1 -p 5555 # connect tp server
''')
)
parser.add_argument('-c','--command',action= 'store_true',help='command shell')
parser.add_argument('-e','--execute',help='execute specified command')
parser.add_argument('-l','--listen',action='store_true',help='listen')
parser.add_argument('-p','--port',type=int,default=5555,help='specified port')
parser.add_argument('-t','--target',default='192.168.0.1',help='specified IP')
parser.add_argument('-u','--upload',help='upload file')
#parser.add_argument()
args= parser.parse_args()
if args.listen:
buffer =''
else:
buffer=sys.stdin.read()
nc=NetCat(args,buffer.encode())
nc.run()
第一个测试,第一窗口,在代码目录,运行服务端。
python3 netcat.py -t 10.0.2.15 -p 5555 -l -c (回车)
第二窗口,在代码目录,运行客户端
python3 netcat.py -t 10.0.2.15 -p 5555 (回车)
Ctrl+D
ls -la (回车)
Ctrl+c退出测试,开始进行第二个测试,第一窗口,输入命令
python3 netcat.py -t 10.0.2.15 -p 5555 -l -e="cat /etc/passwd"(回车)
测试二,在第二个窗口,输入,
python3 netcat.py -t 10.0.2.15 -p 5555
回车
Ctrl+D
测试二,第二个窗口操作方法二,先ctrl+c退出。使用nc。
退出
nc 10.0.2.15 5555 (回车)
在两个窗口,先使用ctrl+c退出,进行第三个测试,
有错误提示
查到说,改成buffer = ‘> ’
不过,会有影响,比如:(第一个测试,报错)
Ctrl+c,退出,进行第四个测试,第一个窗口
python3 netcat.py -t 10.0.2.15 -p 5555 -l -u=mytest.txt(回车)
注意!!!文件会自行在服务端目录下创建。(如果已经存在,则会覆盖原来的内容)
第二个窗口
nc 10.0.2.15 5555(回车)
然后随意输入一些字符,ctrl+C退出
第一个窗口,服务端也退出,cat
查看
回车
与在客户端随意输入的一样
(文件)输入