手写netcat教程(详细)

1.1什么是 Socket?

Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。

socket的使用:

socket()
socket.socket([family[, type[, proto]]])

family: 套接字家族可以是 AF_UNIX 或者 AF_INET

type: 套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAM或SOCK_DGRAM

proto: 一般不填默认为0.

常用方法

s.bind()
绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。

s.listen()
开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。

s.recv()
接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。

s.send()
发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。

s.close()
关闭套接字

1.2什么是tcp?

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

1.3什么是udp?

“UDP 是User Datagram Protocol的简称, 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务

1.4tcp和udp有什么区别?

简单来说udp是一个无连接协议,具体体现在python代码上,我们的udp是无需先发送连接

代码对比:

1.定义socket对象
tcp socket.SOCK_STREAM
udp socket.SOCK_DGRAM

2.是否需要连接客户端?
TCP client.connect((host,port))
udp 否

3.发送请求
tcp send()
udp tosend()

1.4什么是多线程

举个通俗易懂的例子哈!

要考试了你和你同桌作弊,它抄前一部分,你抄一部分,最后你们顺利的通过考试。这里有个细节,就是无论你们谁先抄完都要等对方,不等就交卷两个都凉了。

两只手同时画圆和正方形,你会发现怎么画都基本上难同时画出来,除非训练得很多,大脑响应得快,(cpu交替运行得快)

当然了有的怪胎是天生就可以,经典的双核CPU。

1.5说一说python的多线程

python的多线程我感觉不咋地,为什么有这种感觉,学过go,c就。。。。。不过对于写点工具要得是生产力,不要管那些运行速度了。

线程的分类:

内核线程:由操作系统内核创建和撤销。

用户线程:不需要内核支持而在用户程序中实现的线程。(用的多)

Python3 线程中常用的两个模块为:

_thread
threading(推荐使用)

thread 模块已被废弃。用户可以使用 threading 模块代替。所以,在 Python3 中不能再使用"thread" 模块。为了兼容性,Python3 将 thread 重命名为 "_thread"。

Thread类提供了以下方法:

run(): 用以表示线程活动的方法。
start():启动线程活动。
join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
isAlive(): 返回线程是否活动的。
getName(): 返回线程名。
setName(): 设置线程名。

1.6编写一个netcat(实战)

难度:⭐⭐(5⭐标准)

难点:面向对象,网络编程基础

重点:应用网络编程基础,掌握工具开发基本结构

为什么要写netcat?

用过netcat的小伙伴有没有这样的经历?打开杀毒软件,咱才下载的netcat就被杀了。。。。为什么会这样呢?

精明的网络管理员总是会把系统里面netcat移除,防止被黑客利用。。。。。不过大部分服务器却会安装python,用python搓一个netcat是相对容易的。同时也是一次很好的编程练习。当然了,我们要使用内置包这里是个细节。

补充一下,为什么大部分服务器会装python?

第一,Python是一门后端语言,可以用来web编程,例如:django flask fastapi 等web框架。部署python应用,肯定要安装python环境;

第二,python是一门脚本语言,很多运维工程师在产品上线的时候,不是用shell就是用python批量配置环境。而且产品时不时更新啥的,为了方便直接安装后就不卸载python环境。

写这个项目有什么好处?

1.实践socket编程,socket面试会问的。。。。
2.其它好处不在这里说了,哈哈

知识点:

1.命令行工具设计

2.认识使用到的内置库

argparse

当一个项目的输入参数较多,且要进行修改和调试时,经常涉及到参数的格式和路径问题。
如果一行一行去进行修改代码,会非常繁琐且错误率很高。

shlex
subprocess

shlex 模块最常用的是 split() 函数,用来分割字符串,通常与 subprocess 结合使用

sys是Python提供的程序与解释器交互的标准库

textwrap库:Python格式化文本段落

3.面向对象程序设计

在netcat项目中我们使用了面向对象的思想,设计了netcat对象,并且根据需求对对象增加的方法。

项目的结构分析

我们只是开发简单的工具,所以以简洁为主。程序都写在了一个文件中方便使用,项目中,可以分为4个部分:

1.包

2.命令执行函数

3.netcat对象

4.主函数入口+help

项目详细讲解过程

1)导入

大家好,本节课我们将使用python3来写一个netcat。什么是netcat呢?netcat的中文翻译就是“瑞士军刀”(出示瑞士军刀图片)。netcat是一个功能丰富的网络工具,它经常会被黑客使用。精明的管理员会把它移除,不过我们可以用python快速编写,因为管理员不会随便把python卸载。接下来就和我一起来实战吧!

我们打开pycharm,无需创建虚拟环境,无需下载内置包。新建一个netcat.py文件,文件头导入一下包:

import argparse
import socket
import shlex
import subprocess
import sys
import textwrap
import threading

我们编写一个命令执行函数,输入 => exe函数接受命令并执行 =>输出

def execute(cmd):
cmd=cmd.strip() #@1
if not cmd:
return
output=subprocess.check_output(shlex.split(cmd),stderr=subprocess.STDOUT)#@2

return output.decode()

@1整理开头和结尾的字符串

@2这个函数是在 Python 2.7 中引入的。我们可以使用它在命令提示符下运行带有 Python 参数的命令。

subprocess.check_output() 函数将以字节形式返回给定命令的输出。如果函数返回非零代码,则会引发 CalledProcessError 对象。

CalledProcessError 对象有两个属性。这些是 returncode 和 output 属性。

我们为项目编写入口:

if name == 'main':
parser=argparse.ArgumentParser(

    # 工具描述信息
    description='jiang net tool',
    #工具命令
    formatter_class=argparse.RawDescriptionHelpFormatter,
    epilog=textwrap.dedent(
    '''example:
    netcat.py -t host -p port -l -c # command shell
    netcat.py -t host -p port -l -u=text.txt #upload to file
    netcat.py -t host -p port -l -e=\"cat/etc/password\"#execute command
    echo 'abc' | ./netcat.py -t host -p 135 # echo text to server port 135
    netcat.py -t host -p port #connect server
    '''
    ))
    #注册命令
parser.add_argument('-c','--command',action='store_true',help='command shell')
parser.add_argument('-e','--execute',help='execute specified command ')
parser.add_argument('-l','--listen',action='store_true',help='listen')
parser.add_argument('-p','--port',type=int,help='specified port',default=5555)
parser.add_argument('-t','--target',default='192.168.1.203',help='specified ip')
parser.add_argument('-u','--upload',help='upload file')

最后实现netcat对象

对象初始化

class NetCat:
def init(self,args,buffer= None) :
self.args=args
self.buffer=buffer
self.socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

run方法

def run(self):
if self.args.listen:
self.listen()
else:
self.send()

send 方法

def send(self):
self.socket.connect((self.args.target,self.args.port))
if self.buffer:
self.socket.send(self.buffer)
try:
while True:
recv_len=1
response=''
while recv_len:
data=self.socket.recv(4096)
recv_len=len(data)
response+=data.decode
if recv_len<4096:
break
if response:
print(response)
buffer=input('>')
buffer+='\n'
self.socket.send(buffer.encode)
except KeyboardInterrupt:
print('user terminated')
self.socket.close()
sys.exit()

listen 方法

def listen(self):
self.socket.bind((self.args.target,self.args.port))
self.socket.listen(5)
while True:
client_socket,_=self.socket.accept()
client_thread=threading.Thread(
target=self.handle,args=(client_socket,)
)
client_thread.start()

handle 方法

def handle(self,client_socket):
if self.args.execute:
output=execute(self.args.execute)
client_socket.send(output.encode)
elif self.args.upload:
file_buffer='b'
while True:
data=client_socket.recv(4096)
if data:
file_buffer+=data
else:
break
with open(self.args.upload,'wb') as f:
f.write(file_buffer)
message=f'Save file {self.args.upload}'
client_socket.send(message.encode)
elif self.args.command:
cmd_buffer='b'
while True:
try:
client_socket.send(b'BHP: #>')
while '\n'not in cmd_buffer.decode():
cmd_buffer+=client_socket.recv(64)
response=execute(cmd_buffer.decode())
if response:
client_socket.send(response.encode())
cmd_buffer='b'
except Exception as e:
print(f'server killed{e}')
self.socket.close()
sys.exit()

实战netcat总结

1.开发工具的选取。尽量使用pycharm,效率高,vscode插件装多难免会有bug。vim系列也不是不可以,前提你得配置好。

2.实战不要只会抄代码,要想一下为什么要这么写,遇到不会的马上补充知识点。学习模式就是:从知识走进实战,在实战中学习经验。

3.面向对象是一种编程思想,划分一下就是内功修炼,得慢慢来。

4.肯定有你不会的,肯定有bug。很喜欢某人说过的一句话:你从来没得过芒果确实悲哀,但回回是你得到,更悲哀!

1.7开发一个tcp代理

用途:

主机流量转发

检测网络软件

无法使用抓包的时候开代理

项目结构:

1.本地设备和远程设备通信过程显示

2.本地设备或远程设备入口

3.控制本地设备和远程设备的流量方向

4.监听socket......

posted @ 2023-03-10 13:22  像素飞行员  阅读(251)  评论(0)    收藏  举报