Python编写渗透工具学习笔记一 | 0x02实现一个反弹shell

0x02实现一个反弹shell

这个比较简单,就是用套接字,tcp三次握手,然后用subprocess模块实现命令执行

注意客户端和服务端脚本中的端口要一致,不然会连接失败,而且端口号一定要为数值型

脚本利用演示

把server_shell.py脚本放进靶机kali64,并执行就可以了(攻击了靶机之后可以把这个脚本设置为开机自动启用)--进入等待连接攻击机状态

在攻击机win7上执行客户端脚本client.py后

靶机上的脚本server_shell.py会接收到连接信息,就会输出一条被连接的信息(这个信息其实是可以被隐去的,这里是为了帮助我们更好的分析脚本的执行流程而写进去的)

这时候我们把靶机的终端关闭,然后在攻击机上输入一条命令 ls,可以收到回显,并且靶机上并没有显示有任何的异常,这个得到反弹shell的方式还是非常隐秘的

脚本代码的实现和分析

Client.py

客户端:创建socket 连接 通信循环

Server_shell.py

服务端:创建socket 绑定 监听 两循环(等待客户端连接循环 和 通信循环)

拓:

简单实现netcat功能的脚本

简单说说脚本里的模块和函数

Sys在这里的话主要是用到sys.argv--接收命令行参数,sys.stdin.read()--读取标准输入端中的数据,有点类似raw_input()但是又有区别,raw_input()遇到回车就会返回读取的数据,但是sys.stdin.read()会等到用户输入EOF符(即ctrl+d)才会开始读取数据

Threading主要是用于多线程编程的,提高运行速度和效率等等

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)--子进程执行args中的命令,并将其输出形成字符串返回

Socket的话就是跟套接字有关的模块,创建套接字对象,连接,绑定,监听,发送数据,接收数据这些等等(这个应该大家都比较熟悉,不多说)

Getopt主要是用来定义一些使用说明和使用方法的,同时处理和接收一下命令行传进来的参数

Getopt.getopt(args,options[,long_options])

用于解析命令行选项和参数列表,args是要解析的参数列表。

Options前缀为一个连字符(-),用来做剪短的选项(如”-x”)

Long_options前缀为两个连字符(--) 用来做长选项,是个列表

opts, args = getopt.getopt(sys.argv[1:], "hle:t:p:cu:",["help", "listen", "execute", "target", "port", "command", "upload"])

对于这一句,可以再举一个例子,例如这里如果在命令行执行这一句

python replaceNetcat.py -t 192.168.0.1 -p 5555 -l -e=\”cat/etc/passwd\”

那么得到的opts和args参数分别是

opts=[(‘-t’,’192.168.0.1’),(‘-p’,’5555’),(‘-l’,’’),(‘-e’,’\”cat/etc/passwd\”’)]

args=[‘replaceNetcat.py’,’192.168.0.1’,’5555’]

这个概念如果没接触过可能一时半会也还不能理解,这里我就不再深入说下去了,还不理解的话大家可以自行百度一下吧~~

通过脚本的利用分析一下这个脚本的代码设计流程

(因为这里的socket通信是很多脚本的基础中的基础,所以我这里说的有点详细,如果已经能熟练使用了的话可以不用去看这一部分)

(下面的分析过程建议大家对着脚本来看)

靶机 kali 10.10.10.128

攻击机kali 10.10.10.134

先在靶机上执行

其实这个脚本是一个服务端和客户端合并起来的脚本

先说下这个脚本中服务端的实现,主要是server_loop()和 client_sender()这两个函数

其中server_loop()函数就相当于上面提到的server_shell.py脚本,就是进行端口连接的监听

然后等待客户端连接,一旦有客户端连接上了,就会创建一个新的线程,执行client_sender()函数,client_sender()函数的作用其实就是实现跟客户端的通信。

这里执行python replaceNetcat.py -l -p 9999 -c

会先执行main函数,然后由于参数-l -p 9999 -c会把listen设置为true,port=9999,command = True,然后会进入if listen:执行server_loop()函数进入监听状态

此时在攻击机上执行python replaceNetcat.py -t 10.10.10.128 -p 9999

这是脚本运行会进行一些设置target=10.10.10.128 port=9999 然后进入if not listen and len(target) and port > 0:

# 从命令行读取内存数据

# 这里将阻塞,所以不再向标准输入发送数据时发送CTRL-D

buffer = sys.stdin.read()

client_sender(buffer)

注意!!此时脚本停留在了if里面阻塞住了,这个时候客户端(也就是攻击机)还没有跟服务端(靶机)连接上(因为我的分享是编程方面的知识而不是脚本的利用,所以这里我们一定要重点分析好进行每一步操作的时候脚本到底干了些什么,一定要弄清楚脚本到底具体执行到哪里,不能含糊)

所以这时候我们按下CTRL+D它就会返回一个shell

演示一下 在攻击机上按下CTRL+D 返回了一个shell并且有提示符<BHP:#>输出

有提示符<BHP:#>输出这是因为按下CTRL+D 后脚本将继续执行进入client_sender(buffer)函数,注意client.connect((target, port))当客户端执行到这里的时候就要等待服务端的响应才会继续执行下去了

我们分析一下此时服务端都干了些什么,先放出部分代码

while True:

client_socket, addr = server.accept()

# 分拆一个线程处理新的客户端

client_thread = threading.Thread(target=client_handler, args=(client_socket,))

client_thread.start()

此时服务端会处理客户端的连接请求,执行client_socket, addr = server.accept()接收客户端的连接并且返回一个client_socket和 addr(tips:accept()方法返回连接的客户端套接字以及其IP地址和端口的元组 addr )然后服务端就创建一个新的线程执行client_handler函数,在client_handler函数中进入了if command:然后执行client_socket.send("<BHP:#>"),服务端在这里向客户端发送了一个字符串"<BHP:#>"然后服务端会继续执行下去,直到停留在这一句了cmd_buffer += client_socket.recv(1024),等待客户端的输入然后接收客户端的输入

在服务端执行client_socket.send("<BHP:#>")之后,客户端的client.connect((target, port))就执行完毕了,并且一直执行到了data = client.recv(4096)接收服务端传过来的"<BHP:#>",并且执行print response把得到的信息打印出来,这里就是攻击机的终端上有提示符<BHP:#>输出的原因了 此时已经完成了服务端和客户端的连接正式进入通信阶段

这时候又轮到客户端出场了,这时客户端执行ls -la并按下回车键,会得到服务端执行命令后返回的数据

在客户端执行执行print response把得到的信息"<BHP:#>"打印出来之后,客户端的脚本就停留在了buffer = raw_input(""),然后当服务端输入ls -la,并按下回车的时候,就会执行client.send(buffer)向服务端发送数据,

然后服务端处理

 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)

当客户端向服务端发送数据的时候,服务端的cmd_buffer += client_socket.recv(1024)这句会被激活,然后继续执行 run_command(cmd_buffer)和client_socket.send(response),执行客户端发送过来的命令并且把结果发回给客户端,然后客户端接收到结果之后又继续发送命令,就这样一直循环下去,知道按下ctrl+c结束脚本的运行

进一步浓缩一下

服务端:创建socket 绑定 监听 两循环(等待客户端连接循环 和 通信循环)

客户端:创建socket 连接 通信循环

除此之外这个脚本还有上传文件的功能,核心实现也是通过文件内容的读取和写入,显示在客户端读取文件的内容,然后把文件的内容像上面传递命令那样传递过去给服务端,然后服务端在把这些内容写到一个文件里面去,从而实现了文件的上传功能。

原文发布于微信公众号 - 安恒网络空间安全讲武堂(gh_fa1e45032807)

原文发表时间:2017-12-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java一日一条

理解Cookie和Session机制

会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确...

1921
来自专栏用户画像

3.1.1内存管理的概念

内存管理是操作系统设计中最重要和最复杂的内容之一,虽然 计算机硬件一直在飞速发展,内存 容量也在 不断增长,但是仍然不可能将用户进程所需要的全部程序和数据放入主...

811
来自专栏linux运维学习

linux学习第二十三篇:shell介绍,命令历史,命令补全和别名,通配符,输入输出重定向

shell介绍 什么是shell, shell是一个命令解释器,提供用户和机器之间的交互。支持特定语法,比如逻辑判断、循环。每个用户都可以有自己特定的shel...

2109
来自专栏SDNLAB

ONOS编程系列(一)之简单应用开发

一个ONOS application是使用maven做管理的OSGi bundle。 因此,ONOS application 可以归结为Java类和POM文件的...

3845
来自专栏C/C++基础

Linux命令(30)——scp命令

scp(secure copy)命令是一个基于SSH安全的进行远程文件拷贝命令,用于在Linux下进行远程拷贝文件,和它类似的命令有cp,不过cp只是在本机进行...

1142
来自专栏IT可乐

Linux系列教程(四)——Linux常用命令之文件和目录处理命令

  这个系列教程的前面我们讲解了如何安装Linux系统,以及学习Linux系统的一些方法。那么从这篇博客开始,我们就正式进入Linux命令的学习。学习命令,首先...

2119
来自专栏琦小虾的Binary

Linux平台下安装boost库

Linux平台下安装boost库 今天在给师弟们设计新一代软件框架的时候,需要实现一种功能:存在一种容器,里面存放着不同的数据类型,例如int, double,...

2649
来自专栏企鹅号快讯

py3.6+xadmin的自学网站搭建

xadmin安装 由于安装时需要依赖包并且暂时不支持py3等原因,直接pip install的方法很容易就狗带了。 说一下我在网上找到的安装方式,在GitHub...

29310
来自专栏Java帮帮-微信公众号-技术文章全总结

Java面试系列18-servlet

Servlet方面 01 说一说Servlet的生命周期? servlet有良好的生存期的定义,包括加载和实例化、初始化、处理请求以及服务结束。这个生存期...

3468
来自专栏达摩兵的技术空间

linux之文件基本操作学习笔记

通过本教程你将熟悉linux文件的基本操作以及其具体使用。本文目录结构摘抄自《鸟哥的LINUX私房菜》基础学习篇(第三版)。

921

扫码关注云+社区

领取腾讯云代金券