Netcat

Netcat是一种网络工具,也称为“nc”,可用于在计算机网络之间进行TCP/IP或UDP连接。它可以用于连接到其他计算机上的端口,发送和接收数据,扫描端口以及创建服务器等。

使用Python实现简易版

整体功能规划

if __name__ == "__main__":
# argparse库是python标准库里面用来处理命令行参数的库
# 传递不同的参数,就能控制这个程序执行不同的操作
parser = argparse.ArgumentParser( # 创建一个解析对象
description="ReverseShell",
formatter_class=argparse.RawDescriptionHelpFormatter,
# 帮助信息,程序启动的时候如果使用--help参数,就会显示这段信息
epilog=textwrap.dedent(
"""
python Simple_Netcat.py -t <IP> -p 5555 -l -c # command shell
python Simple_Netcat.py -t <IP> -p 5555 # connect to server
get <file> # download file
upload <file> # upload file
"""
),
) # -c参数,打开一个交互式的命令行shell;
parser.add_argument("-c", "--command", action="store_true", help="command shell")
# -l参数,创建一个监听器
parser.add_argument("-l", "--listen", action="store_true", help="listen ")
# -p参数,指定要通信的端口
parser.add_argument("-p", "--port", type=int, default=5555, help="specified port ")
# -t参数,指定要通信的目标IP地址
parser.add_argument("-t", "--target", default="127.0.0.1", help="specified IP") args = parser.parse_args() nc = SimpleNetcat(args)
nc.run()

创建NetCat类:

class SimpleNetcat:
def __init__(self, args):
# 我们用main代码块传进来的命令行参数,初始化一个NetCat对象,然后创建一个socket对象
self.args = args
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 如果NetCat对象是接收方,run就执行listen函数
# 如果是发送方,run就执行send函数
def run(self):
if self.args.listen:
self.listen()
else:
# 用于启动时输出
print('Enter the first command >',end='')
self.send()

实现listen功能:

# 监听数据
def listen(self):
self.socket.bind((self.args.target, self.args.port))
# listen(n)传入的值, n表示的是服务器拒绝(超过限制数量的)连接之前,操作系统可以挂起的最大连接数量。
self.socket.listen(5) # 用一个循环监听新连接,并把已连接的socket对象传递给handle函数执行任务
while True:
# accept()等待传入连接。,返回代表连接的新套接字以及客户端的地址。
client_socket, _ = self.socket.accept()
# 给每个客户端创建一个独立的线程进行管理
client_thread = threading.Thread(target=self.handle, args=(client_socket,))
client_thread.start()

当程序监听到指令之后,就可以执行相应的任务:

# 执行传入的任务
def handle(self, client_socket):
# 如果要执行命令,handle函数就会把该命令传递给execute函数
# 然后把输出结果通过socket发回去
if self.args.command:
# 创建shell,先创建一个循环,向发送方发一个提示符,
# 然后等待其发回命令。每收到一条命令,就用execute函数执行它,然后把结果发回发送方
while True:
try:
cmd_buffer = b''
# 循环接收发送端命令
while '\n' not in cmd_buffer.decode():
cmd_buffer += client_socket.recv(64)
cmd = cmd_buffer.strip().decode()
if cmd.startswith("get"):
send_file(cmd, client_socket)
elif cmd.startswith("upload"):
get_file(cmd, client_socket)
else:
response = execute(cmd_buffer.decode())
if response:
client_socket.send(response.encode())
except Exception as e:
print(f'Server killed {e}')
self.socket.close()
sys.exit()

实现execute函数

# execute函数用于接受一条命令并执行,然后将结果作为一段字符串返回
def execute(cmd):
if cmd.startswith('cd '):
# 切换目录
os.chdir(cmd[3:].strip())
return os.getcwd() + '>'
else:
cmd = cmd.strip()
if not cmd:
return
# subprocess库提供了一组强大的进程创建接口,可以通过多种方式调用其他程序。
# check_output函数会在本机运行一条命令,并返回该命令的输出
output = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT)
return output.decode() + os.getcwd() + '>'

实现send函数

def send(self):
# 连接到target:port
self.socket.connect((self.args.target, self.args.port))
# 创建个try/catch块,这样就能直接用Ctrl+C组合键手动关闭连接
try:
# 创建一个大循环,接收target返回的数据
while True:
# 等待用户输入新的内容,再把新的内容发给target
buffer = input() + '\n'
self.socket.send(buffer.encode())
if buffer.startswith("get"):
get_file(buffer, self.socket)
elif buffer.startswith("upload"):
send_file(buffer, self.socket)
else:
recv_len = 4096
response = ''
# 读取socket本轮返回的数据,如果socket里的数据目前已经读到头,就退出小循环
while recv_len:
data = self.socket.recv(4096)
recv_len = len(data)
response += data.decode('utf-8', errors='ignore')
if recv_len < 4096:
break
# 检查刚才有没有实际读出什么东西来,如果读出了什么,就输出到屏幕上
if response:
print(response, end='')
except KeyboardInterrupt:
print("User Terminated.")
self.socket.close()
sys.exit()

实现文件上传功能

def send_file(cmd, client_socket):
filename = cmd.split()[1]
if os.path.isfile(filename): # 判断文件是否存在
size = os.path.getsize(filename) # 获取文件大小
client_socket.send(str(size).encode() + b'\n') # 发送数据长度 with open(filename, "rb") as f:
client_socket.send(f.read())
else:
client_socket.send("File Not Exist".encode())

实现文件下载功能

def get_file(buffer, socket):
cmd, filename = buffer.split(" ")
filename = filename.replace("\n", "")
file_size = int(socket.recv(64).decode().strip('\n'))
print("File Size:%s" % (file_size)) with open(filename, "wb") as f:
received_size = 0
while received_size < file_size:
size = min(4096, file_size - received_size)
data = socket.recv(size)
f.write(data)
received_size += len(data)
print("Download: {:.2f}%".format(received_size / file_size * 100))
print("File '{}' downloaded successfully.".format(filename))
print('Enter Command >', end="")

整体代码

完整代码可以参考我的Github仓库:Github

代码测试

shell:

上传文件:

下载文件:

Python实现简易版Netcat的更多相关文章

  1. Python模拟简易版淘宝客服机器人

    对于用Python制作一个简易版的淘宝客服机器人,大概思路是:首先从数据库中用sql语句获取相关数据信息并将其封装成函数,然后定义机器问答的主体函数,对于问题的识别可以利用正则表达式来进行分析,结合现 ...

  2. Python写地铁的到站的原理简易版

    Python地铁的到站流程及原理(个人理解) 今天坐地铁看着站牌就莫名的想如果用Python写其工作原理 是不是很简单就小试牛刀了下大佬们勿喷纯属小弟个人理解 首先来看看地铁上显示的站牌如下: 就想这 ...

  3. python简易版微信或QQ轰炸

    ​ 在讲解代码之前我们先来回忆一下,平时我们发送消息时,先打开微信或QQ的界面,在信息栏中输入你要发送的内容在点击发送或通过快捷键发送.如果要发送表情时,先打开微信或QQ的界面,在点击表情包中你要发送 ...

  4. 简易版的TimSort排序算法

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处http://www.cnblogs.com/nullzx/ 1. 简易版本TimSort排序算法原理与实现 TimSort排序算法是Python和Ja ...

  5. django框架简介及自定义简易版框架

    web应用与web框架本质 概念 什么是web应用程序呢? Web应用程序就一种可以通过互联网来访问资源的应用程序, 用户可以只需要用一个浏览器而不需要安装其他程序就可以访问自己需要的资源. 应用软件 ...

  6. 第十八篇:简易版web服务器开发

    在上篇有实现了一个静态的web服务器,可以接收web浏览器的请求,随后对请求消息进行解析,获取客户想要文件的文件名,随后根据文件名返回响应消息:那么这篇我们对该web服务器进行改善,通过多任务.非阻塞 ...

  7. 简易版cnlog

    目录 简易版cnlog html文件 mycess.cess 页面效果 简易版cnlog 注意的点 1.一定先分好块标签,再基于一个个块标签进行装饰(相当于给一个个人化妆) 2.浮动: 我的理解是从一 ...

  8. Python编写简易木马程序(转载乌云)

    Python编写简易木马程序 light · 2015/01/26 10:07 0x00 准备 文章内容仅供学习研究.切勿用于非法用途! 这次我们使用Python编写一个具有键盘记录.截屏以及通信功能 ...

  9. .NET Core的文件系统[5]:扩展文件系统构建一个简易版“云盘”

    FileProvider构建了一个抽象文件系统,作为它的两个具体实现,PhysicalFileProvider和EmbeddedFileProvider则分别为我们构建了一个物理文件系统和程序集内嵌文 ...

  10. MVC 验证码实现( 简易版)

    现在网站上越来越多的验证码,使用场景也是越来越多,登陆.注册.上传.下载...等等地方,都有可能大量使用到验证码,那么制作验证码到底有多简单呢?我们一起来看下最简易版的验证码实现过程- 验证码的基本步 ...

随机推荐

  1. .NET Core开发实战(第22课:异常处理中间件:区分真异常与逻辑异常)--学习笔记(下)

    接下来介绍使用代理方法的方式,也就是说把 ErrorController 整段逻辑直接定义在注册的地方,使用一个匿名委托来处理,这里的逻辑与之前的逻辑是相同的 app.UseExceptionHand ...

  2. spring前导知识-Tomcat、Maven等配置

    spring前导知识: 版本注意: 该博客所用的版本: tomcat version 9 (注意10有未知错误(个人测试)) Maven version3.6.3 (注意3.6.2未知错误) serv ...

  3. NC16466 [NOIP2015]信息传递

    题目链接 题目 题目描述 有 n 个同学(编号为 1 到 n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为 i 的同学的信息传递对象是编号为Ti的同学. 游戏开始时, ...

  4. NC50493 石子合并

    题目链接 题目 题目描述 将n堆石子绕圆形操场排放,现要将石子有序地合并成一堆.规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆的石子数记做该次合并的得分. 请编写一个程序,读入堆数n及每堆的石子 ...

  5. 面试官:谈一谈你对 redis 分布式锁的理解

    ​为什么需要分布式锁 在 jdk 中为我们提供了多种加锁的方式: (1)synchronized 关键字 (2)volatile + CAS 实现的乐观锁 (3)ReadWriteLock 读写锁 ( ...

  6. 【Unity3D】UGUI之Button

    1 Button属性面板 ​ 在 Hierarchy 窗口右键,选择 UI 列表里的 Button 控件,即可创建 Button 控件,选中创建的 Button 控件,按键盘[T]键,可以调整 But ...

  7. 【OpenGL ES】基于ValueAnimator的旋转、平移、缩放动效

    1 前言 ​ ValueAnimator 基于 Choreographer 的 frame callback 机制,周期性(约16.7ms,与屏幕帧率相关)执行其 doAnimationFrame() ...

  8. 突破Windows的极限

    偶然碰到这类技术博客,甚感欣慰,但奈何技术水平达不到,很多都难以理解,故记录在此,用作日后学习. 国内有类似的中文翻译,比如:突破Windows极限:物理内存 但是外文链接已经失效,看不到原汁原味的英 ...

  9. 【系统选型】OA需求分析,OA系统选型及各供应商对比。

    去年公司内部做OA信息化升级,需要更新换代一下OA系统,当时OA选型整理下来的资料分享一下. 需求调研整理后如下: 一共四个模块需要更新&升级 :  OA模块(包括行政) + 合同模块 + 费 ...

  10. 【LeetCode链表#11】环形链表II(双指针)

    环形链表II 力扣题目链接(opens new window) 题意: 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,使用整数 pos 来表示 ...