Multiple Ways to Persistence on Windows 10 with Metasploit

In this article, you will learn the multiple ways to maintain access or create a persistent backdoor with the help of the Metasploit Framework on the host machine which you have compromised.

Table of Content

Persistence Backdoor


Methods for Generating persistence using Metasploit

  • Persistence_service
  • Mitigation method for persistence_service exploit.
  • Persistence_exe
  • Mitigation method for persistence_exe exploit.
  • Registry_persistence
  • Mitigation method for Registry_persistence exploit.
  • Persistence through Netcat.
  • Persistence through Remote Desktop Protocol.


Persistence Backdoor

The word Persistence is simply known as permanent hence in this post, we are sharing the multiple methods to generate a permanent backdoor within the victim machine.

As there is a lot of hard work required to exploit any system and once the system is exploited successfully you need more time for further examine or penetrate the victim’s system but at that time if victim shut down his system or changed the credentials then all your hard work will be spoiled. That’s why maintaining access is an important phase of penetration testing. Persistence consists of techniques that adversaries use to keep access to systems across restarts, changed credentials and other interruptions that could cut off their access.


Window 10 -Victim System

Kali Linux – Attacker (Metasploit Framework)

Note: For creating a persistence backdoor, you should have a compromised machine of the victim with meterpreter session to continue all practices that are taught in this post.

Methods for Generating persistence using Metasploit

Let’s start, we already have compromised the window 10 (victim’s PC) and have meterpreter session along with the admin rights. To know how to get admin access click here. Now, we want to leave a permanent backdoor in the victim system that will provide a reverse connection for the next time.

Service Persistence

This Module will generate and upload an executable to a remote host, next will make it a persistent service. It will create a new service which will start the payload whenever the service is running. Admin or system privilege is required.

Thus, we will run the following commands on Kali Linux to run the above-listed module:

Above said module which will generate and upload an executable on the victim’s system under the /temp directory as  “lVFC.exe” and will make it a persistence service.

If the victim reboots the system, the previous meterpreter session will be closed. Only we need to set up the multi handler to run the payload by using the following commands:

Once the victim system starts, automatically we will gain the meterpreter session again.

When the PC is started automatically some of its services starts by default so persistence_service exploit creates a new service that will start the payload whenever the service is running. In the below image you can see the executable file IVFC.exe is running under username System and we can verify its path.


Mitigation method for persistence_service exploit

First of all, identify the unfamiliar files which are running and then stop the running executable format file i.e. IVFC.exe and delete it from the temp directory.


This is the second method to maintain access to the victim’s PC. Under this scenario, we already have meterpreter session of the victim’s PC and it has user access.

This module will upload an executable to the victim’s system and make it persistent. It can be installed as a user, system or service. We will use this module by using the session 1(already compromised system’session) and set the rexpath (remote executable path), through this payload file will create on victim’s PC but due to persistence script, it will save under temp directory with default.exe name(change the name under rexname option ) and will set it to autorun under the registry path mentioned in below image.

 To run this module, type the following commands:

After, successful execution of the above module, now we have to set up the multi handle by using the following command:

Once the victim reboots its PC and the login into it, automatically we will get the meterpreter session.

In the below image you can see the function of persistence_exe, which will create the autorun service under the registry editor path:

due to which service will start running as soon as the victim’s PC starts. Its default file creates under the temp directory.

Mitigation Method for Persistence_exe

First, remove the entry from the registry editor under the path:

And then delete the executable payload file under the temp directory and reboot the system.

Registry Persistence

A registry is the core part of the window and contains a surplus of raw data. Attackers love to choose windows registry locations to hook their codes so that files or codes cannot be detected by scans for suspicious activities.

This module will install a payload that is executed during boot. It will be executed either at user logon or system startup via the registry value in “CurrentVersion\Run” (depending on privilege and selected method). The payload will be installed completely in the registry.

Since we already have compromised the victim’s Pc and have the meterpreter session along with the user privileges. Use the following command to execute the registry persistence.

Once the exploit executed, it will create a registry key under HKCU\software\wl4cN9w and installed key as highlighted in the image.

If the victim reboots the system, meterpreter session will dead get the session again just set up the multi handler payload and execute it.

Once the victim’s machine will start and as the victim will log in into the system, automatically we will get the meterpreter session again due to the autorun script under the registry which is installed by the attacker. Successfully registry _persistence is executed.

Through the below image you can verify the path of registry key created by registry_persistence exploit.

Persistence through Netcat

Netcat or nc is a utility tool that uses TCP and UDP connections to read and write in a network. It can be used for both attack and security. In the case of attack, it can be driven by scripts which makes it quite dependable back-end and if we talk about security, it helps us to debug the network along with investing it. To read more about netcat please refer

Now we are going to make a persistence Netcat backdoor on the compromised system. As we already have meterpreter session, upload netcat.exe into system32 file of victim’s pc by using the following command:

The next step is to set the netcat to listen on the random port i.e.4445, open the port on startup and make the connection.

Use the following command:

On successful netcat connection, we get the shell of the victim’s PC.

We will add the new rule in the firewall named as ‘netcat’ in which inbound connection will allow for port 4445 by using the interactive cmd prompt running a command called netsh. Type the following command:

To check the operational mode and port status run the command:

When the victim reboots the system again, we will get the netcat shell. On Kali Linux(attacker system) run the following command to connect our netcat backdoor via port 4445.

Persistence through RDP

After having the meterpreter session of the already compromised targeted system. We will utilize Carlos Perez’s getgui script which enables Remote Desktop and creates a user account to login to it.

Username: Nisha

Password: 123

Run the following command:

With the help of the following module, it is possible to apply the ‘sticky keys’ hack to a session with appropriate rights. The hack provides a means to get a SYSTEM shell using UI-level interaction at an RDP login screen or via a UAC confirmation dialog.

As you can see here that we sticky is added successfully, now to launch the exploit at an RDP or UAC by press shift key 5 times.

Now we will check the connection using rdesktop and review the certificate and type Yes. By using the following command

Congrats !!! finally we get the Gui mode of the victim’s system.


Persistence does not require any authentication to connect with the victim’s system. To complete the penetration testing, always remember to clean up the processes and the backdoor services on the victim’s host.

Author: Nisha Sharma is trained in Certified Ethical hacking and Bug Bounty Hunter. Connect with her here

Forensics Investigation of Ping Command


When we say “ping,” we often are just limiting its definition to checking whether a host is alive or not. In my opinion, while this purpose is correct, its technical details are often ignored. Many network administrators are unable to answer what ping is in details; or how it works. So in this research-based article, I am going to present some points that I didn’t know before starting to read about the topic.

Tools used: Wireshark, command prompt/terminal,

In this article, practicals are based on a Windows 10 x64 system to ping a Debian Linux x64 bit architecture. While this shouldn’t matter in many cases, it matters for a certain part where we calculate TTL and an anomaly case as well. More of that later though. While reading about this topic I learnt tons of new stuff that for me, as a penetration tester, would definitely be useful to understand in-depth how those exploits are working.

Let’s get to the good stuff now.

Table of Content:

  • OSI Model
  • Ethernet, IP and ICMP protocols
  • Ping command and ping packet
  • Wireshark and basic filters
  • How is a datagram sent to destination host (understanding layers involved using Wireshark)
  • Understanding data size in ping
  • MTU in IEEE 802.3i
  • Fragmentation in ping
  • Anomaly in ping

OSI Model:

OSI stands for Open System Interconnection is a reference model that describes how information from a software application in one computer moves through a physical medium to the software application in another computer.

It has seven layers and each layer performs a special network task. They are as follows:

Each layer has a specific task to do and we’re not going into depth with each and every one of them. Let’s save that for another day. Let’s focus on layers 1, 2 and 3 for now.

Layer 1, 2 and layer 3 combined are responsible for the effective transmission of ICMP packets.

Ethernet, IP and ICMP Protocols

While “pinging” a system, layers 1, 2 and 3 are in action. Each layer defines its own “format of protocol options” known as a header. It precedes the actual data to be sent and has information such as the source IP, destination IP, checksum, type of protocol etc. And when it is attached with the actual data to be sent, it forms a protocol data unit which is renamed as per the layer.

Default protocol data units (PDU) in these layers are:

  • Layer 1: bits
  • Layer 2: frame
  • Layer 3: packet
  • Layer 4: datagram

We’ll be using these terms quite often and it is important to be clear what these terms mean. While the data is travelling through these layers, it is converted virtually into its own PDU.


IEEE 802.3 is a set of standards and protocols that define Ethernet-based networks. Ethernet technologies are primarily used in LANs. There are a number of versions in IEEE 802.3 such as the 802.3a, 802.3i etc. When we ping, there is some data sent to the destination host and in a specific format.

Ethernet header:

IP (Internet Protocol)

It is the principal communications protocol for relaying datagrams across network boundaries. IP has the task of delivering packets from the source to the host solely based on the IP address in the packet headers. IP defines packet structures that encapsulate the data and headers.

ICMP (Internet Control Message Protocol)

Since IP does not have an inbuilt mechanism for error control and sending control messages, ICMP is here to provide that functionality. It is a supporting protocol used by network devices like routers for sending error messages.


Ping is a computer networking utility used to test the reachability of a host on IP network. Ping operates by sending ICMP Echo request packets and waits for ICMP Echo replies. This reports error, TTL, packet loss etc. One ping request is a combination of Ethernet, IP and ICMP headers and data.

Useful ping options in windows and Linux are:


Options Functionalities
-t To see statistics and continue – type Control-Break; To stop – type Control-C.

Ping the specified host until stopped.

-a Resolve addresses to hostnames.
-n count The number of echo requests to send.
-l size Send buffer size.
-f Set Don’t Fragment flag in packet (IPv4-only).
-i TTL Time To Live.
-v TOS Type Of Service (IPv4-only. This setting has been deprecated and has no effect on the type of service field in the IP Header).
-r count Record route for count hops (IPv4-only).
-s count Timestamp for count hops (IPv4-only).
-j host-list Loose source route along host-list (IPv4-only).
-k host-list Strict source route along host-list (IPv4-only).
-w timeout Timeout in milliseconds to wait for each reply.
-R Use the routing header to test reverse route also (IPv6-only). Per RFC 5095 the use of this routing header has been deprecated. Some systems may drop echo requests if this header is used.
-S srcaddr Source address to use.
-c Compartment Routing compartment identifier.


Ping a Hyper-V Network Virtualization provider address.
-4 Force using IPv4.
-6 Force using IPv6.


Options Functionalities
-a use audible ping
-A use adaptive ping
-B sticky source address
-c <count> stop after <count> replies
-D print timestamps
-d use SO_DEBUG socket option
-f flood ping
-h print help and exit
-I <interface> either interface name or address
-i <interval> seconds between sending each packet
-L suppress loopback of multicast packets
-l <preload> send <preload> number of packages while waiting replies
-m <mark> tag the packets going out
-M <pmtud opt> define mtu discovery, can be one of <do|dont|want>
-n no dns name resolution


-O report outstanding replies
-p <pattern> contents of padding byte
-q quiet output
-Q <tclass> use quality of service <tclass> bits
-s <size> use <size> as number of data bytes to be sent
-S <size> use <size> as SO_SNDBUF socket option value
-t <ttl> define time to live
-U print user-to-user latency
-v verbose output
-V print version and exit
-w <deadline> reply wait <deadline> in seconds
-W <timeout> time to wait for response

IPv4 options:

Options Functionalities
-4 use IPv4
-b allow pinging broadcast
-R record route
-T <timestamp> define timestamp, can be one of <tsonly|tsandaddr|tsprespec>

IPv6 options:

Options Functionalities
-6                 use IPv6
    -F <flowlabel>     define flow label, default is random
  -N <nodeinfo opt> use icmp6 node info query, try <help> as argument

Ping sends out IP packets with ICMP_Echo_Request to the destination and waits for its reply (IP packet with ICMP_Echo_Reply).

The ICMP packet is encapsulated in an IPv4 packet. The general composition of the IP datagram is as follows:

When a ping command is sent to the host, the datagram is encapsulating Ethernet header, IP header, ICMP header and payload too. The minimum size of an IPv4 header is 20 bytes and the maximum size is 60 bytes.

The default size of payload data in ping in windows is 32 bytes. Let’s add 20 bytes of IP header in it and 8 bytes of ICMP header. 32+20+8, it comes out to be 60 bytes.

But, when we analyse ping in Wireshark, the size of the frame written in the log is 74 bytes. This is because while pinging, we would need the destination and source MAC address as well, which is available in the Ethernet header.

So, 14 + 20 + 8 + 32 = 74 bytes.

So, ping sends an encapsulated IP packet which is a combination of:

Ethernet header + IP header + ICMP header + ICMP payload

But, keep on reading for very interesting cases that made me write this article.

Wireshark and Basic Filters

Wireshark is a freely available network monitoring tool that is able to log all the traffic incoming and outgoing from a single NIC card. I won’t be telling how to set up Wireshark and start logging, please use this tutorial for it.
In the above case, when we ping a Linux system from a windows system, we see something like:

Let’s go step by step and see what just happened.

  1. I’ve pinged IP address from my source IP and captured just one packet to see clearly the action.
  2. On the top, there is a Wireshark filter applied for the IP address that goes like addr ==
  3. Some other useful Wireshark filters are:
    http or dns

  1. Next, you can see the total length of the datagram sent, that is, 74 bytes, as already explained above.
  2. Then you can see, in yellow, Ethernet frame. Here, you’ll find the Ethernet header.
  3. After that is the IPv4 packet. IP is used to deliver packets from source to destination based on the IP addresses.
  4. Finally, we see the ICMP header and payload data.
  5. All these layers are involved in a simple ping over IEEE 802.3. In the next section, we’ll learn how to analyse a packet data using Wireshark to get an in-depth view of packet forensics.

How is a datagram sent to the destination?

When a datagram is sent from source to destination, in our case, when we ping, the format of the datagram is as follows:

We’ll ping a destination with default options:

Let’s start analysing the traffic in Wireshark now.

I just captured a single datagram in Wireshark when I pinged a destination host and analysed it layer by layer.

Talking about Layer 2 here, we can see that Ethernet type 2 is being used.

As we talked in point 2, Ethernet frame sent with ping includes the source and destination MAC along with the type of protocol being used.

0000   00 0c 29 d7 b1 35 00 50 56 c0 00 08      08 00

           Destination MAC         Source MAC          EtherType

                (6 bytes)                      (6 bytes)             (2 bytes)

The most important field here is the EtherType field as on analysing these bytes we can find the protocol that was used in the communication. This is really essential for forensics point of view and some of the most important hex values are:

Ethernet Types Hex Value                       
ARP 08 06
IPv4 08 00
IPv6 86 dd
IEEE 802.1Q 81 00

Moving on to layer 3, we see an IP packet, since obviously ping is using IP protocol to check if a host is alive or not. Here is the observation of the hex dump of IP packet:

0000   ….45           00              00 3c da 40 00 00 80        01 2c ad c0 a8 d9 01

        Header    Type              Total                        TTL     Protocol        Source IP

        Length     of service     Length

        (1 byte)    (1 byte)       (2 bytes)                 (1 byte)  (1 byte)          (4 bytes)

0010   c0 a8 d9 80

           Destination IP

              (4 bytes)

From the analysis of this IP packet, we observe that IP header is then added to the Ethernet frame to make a packet that has the above-mentioned options specified. By analysing this data we can observe a lot of different things. Some of which are:


OS Hex Value TTL Decimal Value TTL
Windows 80 128
Linux 40 64
Mac 39 57

Type Of Protocol:

Protocol Hex Value Decimal Value
ICMP 1 1
TCP 6 6
EGP 8 8
UDP 11 11

One really interesting thing to note is the Header Length. We see that header length is written as 45 in hex which comes out to be 69 which is not possible. On further breaking down this byte, we see that the first nibble (half byte) tells the version of the protocol.

4 = hex value = 4 (version of protocol), that is IPv4

5 = hex value = IHL (Internet Header Length) = next for bits

And so on (total length = 00 3c = 60 bytes)

A datagram is completed and transported when ICMP header is added in Layer 3. We know that IP lacks error control mechanism, so ping uses ICMP to serve that purpose. ICMP protocol is specified in IP header as we saw above and hence, it is important to analyse ICMP header to better understand the underlying mechanism of ping.

0000     08            00              4d 53 00 01 00 08 61 62 63 64 65 66 67 68

           Type        Code           Checksum                         Data

           (1 byte)    (1 byte)       (2 bytes)                         (32 bytes)

0010   69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 61

0020   62 63 64 65 66 67 68 69

Type: It is the type of request of ICMP request sent. According to IANA, there are 45 assigned requests.

We can see, 08 as the Type of request which symbolises Echo request. When one system pings another system, it sends a Type 8 request and if the host is alive, the host sends back Type 0 (Echo Reply) request.

Code: It is simply the hex value of the type of ICMP request message. It ranges from 0 to 15 for each of the types. This reference is taken from Wikipedia:

Checksum: “The checksum is the 16-bit one’s complement of the one’s complement sum of the ICMP message starting with the ICMP Type. For computing the checksum, the checksum field should be zero. If the total length is odd, the received data is padded with one octet of zeros for computing the checksum. This checksum may be replaced in the future.” – RFC 792

So, to calculate the checksum, we have to split the ICMP header and payload data into multiple pairs of 2 bytes each, calculate the one’s complement of first two bytes, add with the next one and repeat it till all the bytes are exhausted.

Here, checksum status is shown as good and correct, so we need not look any further.

Data: Contains other essential data like timestamp, sequence number, magic number etc.

Data size in ping

According to RFC 791, an IP can handle a datagram of maximum size 65,535 bytes. However, by default, the data in ping is 32 bytes and the whole datagram is by default 60 bytes in case of windows. Adding 14 extra bytes of Ethernet header, it comes out to be 74 bytes which we see in Wireshark. Focus on the colour codes here:

Red= ICMP payload data size

Green= Total length of the IPv4 packet

Maroon= Total length of the datagram

Let’s talk about Linux now. The default IP packet size in Linux’s case is 56 bytes. Adding extra 28 bytes of IP and ICMP header makes it 84 bytes. Adding more 14 Ethernet frame header bytes makes it 98 bytes.

However, we can add data as per our wish, as long as it remains under 65,535 bytes using the ping –l option in Windows. This also has some limitations. Let’s talk about them in the next section.

MTU in IEEE 802.3i

MTU stands for Maximum Transmission Unit and it is the size of the largest Protocol Data Unit that can be communicated in a single network-layer operation. IEEE 802.3 standards restrict the minimum to 48 bytes and the maximum to 1500 bytes. So, if I am to transfer more than 1500 bytes of data in a single datagram, it would be fragmented into multiple packets.

To understand MTU, we’ll take up four cases:

Data payload size=200 bytes, 1472 bytes, 2000 bytes, 65500 bytes

Payload size 200 bytes:

We see that the size of IPv4 datagram comes out to be 242 bytes. This is a result of 200 payload bytes + 8 bytes ICMP header + 20 bytes of IP header + 14 bytes of Ethernet header. The noticeable thing here is that still a single datagram is sent and no fragmentation is done. Let’s push the limit to MTU now.

Now let’s push the limits of ping packet to the MTU, that is, 1500 bytes in case of an IEEE 802.3.

Notice some things here. We have not set the data size as 1500 which is the MTU rather 1472 due to the fact that protocol has some bytes for the headers in reserve.

20 bytes of IP and 8 bytes of ICMP headers are automatically added in every transaction as we’ve seen. So, 1500-28=1472 is the maximum payload data size that we can specify in a ping command.

These 1500 bytes are then collated with ethernet header and finally, a datagram of 1514 bytes is transferred.

So, what will happen when this data size is increased from 1472? Let’s check out.

Fragmentation in ping

IP fragmentation or ping fragmentation is a process in which a packet exceeding the size of MTU is broken into multiple pieces and transacted to the destination host. RFC 791 has the procedure for IP fragmentation, transmission and reassembly of packets.

Let’s increase the size of the data payload to 2000 bytes and let’s see what happens.

Now, we can see that fragmentation is done and the datagram is split into two fragments of size 1480 and 520 bytes. Why?

The first fragment is 1500 bytes in total length but the data is only 1480 because 20 bytes are always in reserve for IP protocol header, and the second fragment is 520 bytes in payload data size.

First fragment= 1480 (data size) + 20 (IP header)

Second fragment= 520 (data size) + 20 (IP header) + 8 (ICMP header)

It is important to note that ICMP header is not added in the first fragment and it will only be added when the whole datagram is complete. It is because ICMP is responsible for error control and it calculates the checksum. For checksum to be calculated, whole data should be transmitted first and hence, ICMP header is not added in the initial fragments but only in the last fragment.

Now we push these limits to the maximum size.

Here, the datagram is split into multiple 44 fragments of 1480 bytes each and the last packet is 408 (minus 28= 380 bytes) bytes in size.

You must not get confused here. 65500 is the maximum size of a payload that we can specify in ping.

However, each of the 44 frames is of size 1500 bytes and the last frame is 388+20+8 bytes, which comes out to be 66416 bytes. Hence, the cumulative size of a packet datagram can be at max 66416 bytes.

Add on extra 14 bytes of Ethernet header, it comes out to be: 67,046 bytes.

Anomaly in Ping

Let’s focus on a case when the payload size is specified as 0. Let’s see what the protocols do with 0 bytes of data.

As expected, the request goes with 42 bytes (20 + 8 + 14) with 0 bytes of data but wait, why does the reply come back as 60 bytes?

On analysing the hex dump, we see that a Linux system is replying with 18 null bytes of data.

If we specify ping –s 0 in Linux machine, maybe we get some answer.

Okay, so in the terminal, we see “pinging with 0 (28) bytes of data” which means 28 bytes of IP plus ICMP header and 0-byte data. BUT, Wireshark shows us something size of 60 bytes and has again added an extra 18 bytes.

Turns out that these 18 bytes are Ethernet padding bytes and that’s why this anomaly has arisen. IEEE 802.3 adds extra bytes if data is less than 18 bytes in case of Linux known as padding bytes or pad bytes.

Let’s specify a data in the range: 1<x<18 for example, 10 bytes. Let’s see what happens.

In Wireshark, we see the size is still 60 bytes. And 10 bytes have been written by the hex values from 0 to 9, while rest of them are still null bytes.

It is safe to say the same anomaly will exist when we specify data in the multiples of 1480 since the last fragment will have 0 bytes of data to be sent and padding would be added.

This was an interesting anomaly and made us understood some details of the IEEE 802.3 standards difference in Windows and Linux.

Author: Harshit Rajpal is an InfoSec researcher and left and right brain thinker. contact here

Windows Persistence using Application Shimming

In this article, we are going to describe the persistence of the Application Shimming and how vital it is in Windows Penetration Testing.


Application Shimming is a technique used on Windows OS that can be used to make the applications developed for the earlier versions of Windows OS still work on the latest version of Windows

Table of Content

  • Introduction
    • What is Application Shimming?
    • How does Application Shimming work?
  • Configurations used in Practical
  • Persistence using Application Shimming
    • Malicious DLL Creation
    • Injecting Malicious DLL
    • Installing Infected Executable
    • Gaining Persistent Shell
  • Detection
  • Mitigation
  • Conclusion


What is Application Shimming?

Ever since the early stages of Microsoft Windows, there have been some fundamental features that have been part of the Windows basic Functionalities. One of them is their “Backward Compatibility”. What it means is that if your Software was developed earlier like at the time of Windows XP. But now we have Windows 10 and you are worried that if the Windows will able to run that piece of software as it has updated. Here, the Backward Compatibility comes into play. It gives us the ability to run the software on the Windows OS that was not developed on that particular OS.

The “Shim Infrastructure” or how they like to call it at the big house “Microsoft Windows Application Compatibility Infrastructure” helped its user get that backward compatibility. Now the thing to keep in mind is that during all those years of development, Windows kept its basic Architecture the same. They developed around the same framework that they started to work in the early nineties. This means that there are still some bits of code in the Windows 10 that has been there since the times of Windows 95.

How does Application Shimming Work?

The Shim Infrastructure applies a method of Application Programming Interface (API) hooking. Explicitly, it forces the nature of linking to redirect API calls from Windows itself to alternative code – the shim itself. The Windows Portable Executable (PE) and Common Object Format (COFF) Specification includes several headers, and the data directories in this header provide a layer of indirection between the application and the linked file. Calls to external binary files take place through the Import Address Table (IAT). Consequently, a call into Windows looks like the image shown below to the system.

We can modify the address of the Windows function fixed in the import table, and then replace it with a pointer to a function into the alternate shim code, as shown in the image given below.

This indirection happens statically linked .dll files when the application is loaded. You can also shim dynamically linked .dll files by hooking it with an API.

Configurations used in Practical


OS: Kali Linux 2019.4

Tools: MSFVenom, Metasploit Framework


OS: Windows 10 (Build 1909)

Tools: Windows Assessment and Deployment Kit (Windows ADK), PuTTY.exe

You can download the Tools by clicking on Their Name.

Persistence using Application Shimming

Application Shimming can perform many functions but we will be focusing on gaining a persistence shell on the Target System for now. This practical was tested in a lab-controlled environment where we have the configurations set for minimum interference. The actual real-life scenario can differ.

Malicious DLL Creation

To begin the exploitation, we decided to create a payload using the MSFVenom tool. We used the reverse_tcp payload with the target to be Windows System and gaining a shell. We defined the LHOST for the IP Address for the Attacker Machine followed by the subsequent LPORT on which we will be receiving the session from the target machine. We created this payload in the form of a Dynamic Link Library or DLL and named it inject.dll

As discussed in the Configurations used section we need the Windows Assessment and Deployment Kit. After downloading and installing it, we have service inside it. Its called Compatibility Administrator. We are going to need it to proceed further.

Now in our Attacker Machine, we transferred the recently created DLL to the Target Machine. We use the python one-liner for it. There are lots of ways this can be done. We start a Multi/Handler on the Attacker Machine with the proper configuration to receive the session that will be generated soon.

Injecting Malicious DLL

Now we will divert our attention to the Target Machine. After browsing the IP Address of the Attacker Machine and downloading the Malicious DLL file, we open the Compatibility Administrator as shown in the image given below. Here we are using the 32-bit version as it is easier to bind the DLL to it. We also created a new custom Database.

Now we begin the process of binding the safe and original Executable without malicious DLL file. We right-clicked on our newly created Database and choose the First option in the Dropdown Menu called Create New. This leads to opening a sub-drop-down menu. We choose the Application Fix option as shown in the image given below. We can also use the Shortcut by pressing the Ctrl key and P key simultaneously.

As soon as we click on that Application Fix option, we have ourselves a Config Window Titled “Create New Application Fix”. We enter the name of the Program to be fixed as “putty”. And we provide the path of the executable to the program we want to inject our malicious DLL into. In this case, we provide the path of the PuTTY.exe and hit Next.

Now we are asked the compatibility modes. This would have been important if we were fixing a genuine executable. Or using the Shimming for genuine purposes. As we are not doing any of that, we will skip this step and straight-up hit the “Next” button and move on.

Now we are at an important step. We are asked the compatibility fix that we want to apply to the executable. We choose the “InjectDll” option from the list as shown in the image given below. After checking the box we hit the “Parameters” button to provide the path of out malicious DLL that we created at the start of the exploitation.

This opens up a new small window asking the Command-Line. Here we provide the path of our malicious DLL and click OK button.

Back to out config window, we click the Next Button and now we have the Matching Information panel in front of us. We click on “Unselect All” Button as we don’t want to add any more additional configurations to out payload. At last, we hit the Finish Button.

This closes the config window. We are back to our Compatibility Administrator window. We click the Save button as shown in the image below to inject our DLL in the PuTTY executable.

We are asked to name the database, we name it puttyshim. This can be whatever you want. In real life attacking situations choose the name that is less conspicuous.

After naming the database we are asked the location, where we want to save the AppCompat Database or the .sdb file of the complete configuration.

Installing Infected Executable

Now that this is done, we will now install the now infected Executable on the Target Machine. This can be done by right-clicking on the name of the database and choosing the Install option from the drop-down button.

This initiates an installation process that will installed our infected executable as a service. We can see that in the Programs and Features section inside the Control Panel as shown in the image below. If we had added the Publisher or Vendor Information at the earlier stage it would have appeared here.


Gaining Persistent Shell

Now when we execute the service that we just shimmed and installed. As soon as we have the program executed on the target machine, we will receive a shell on our attacker machine as shown in the image below. We can add the infected service in the startup service list to receive the shell every time the Target system reboots.

This concluded the exploitation. Now let’s talk defense mechanisms.


There are many tools available that can detect the applications that have been shimmed.

  • Shim-File-Scanner: Scans Files/Folders for non-default shims and checks registry for installed shims
  • Shim-Process-Scanner: Will search all process for shim flags and also check for the Shim App Helper

Other than that the process of shimming creates a bloody trail that leads right to the smoking gun aka the shimmed application. Shimming creates a trial inside the Registry at the following locations.

  • HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Custom
  • HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\InstalledSDB

Apart from the registry, we have some locations on the Drives where we can find evidence for the Application Shimming.

  • C:\Windows\AppPatch\Custom\
  • C:\Windows\AppPatch\Custom\Custom64\

We can also create custom Yara Rules and snort rules that could detect Application Shimming.


As always, the first line of defense against any kind of attack is keeping our infrastructure and devices updated. Microsoft released this patch for restricting the Shim Application to bypass the UAC.

Some tools like the one in the Detection section can be used for mitigating the Applications Shimming.

Shim-Guard: Detects and alert on newly installed shims

We can also implement strict UAC policies to notify when a user is getting elevated privileges.


This kind of attack is very much happening in real life. There have been multiple incidents targeted to different environments where the large scale compromise was done using the Applications Shimming.

Stay Tuned!


Black Hat USA


Author: Kavish Tyagi is a Cybersecurity enthusiast and Researcher in the field of WebApp Penetration testing. Contact here

Hack the Box Challenge: Bitlab Walkthrough

In this article, we are going to crack the Gitlab Boot to Root Challenge and present a detailed walkthrough. The machine depicted in this Walkthrough is hosted on HackTheBox Website. Credit for making this machine goes to Frey & thek. As the Machine is live, we don’t need to download it on our systems but we can take a look at the lab by clicking here.

Penetration Testing Methodology

  • Network Scanning
    • Nmap Scan
  • Enumeration
    • Directory Bruteforce using dirb
    • Browsing the HTTP Service in Browser
    • Decoding the JavaScript to extract credentials
  • Exploitation
    • Enumerating the Repositories
    • Finding the Database Query Script
    • Manipulating the script to get the credentials
    • Connecting to Machine using SSH
  • Post Exploitation
    • Reading the User Flag
    • Downloading the suspicious executable file
  • Privilege Escalation
    • Reverse Engineer the executable using the Debugger
    • Enumerating for the root credentials
    • Connecting to Target Machine using SSH with root credentials
  • Reading Root Flag


Network Scanning

From the Official HackTheBox Website,

Static IP Address:

Since we have the IP Address, the next step is to scan the target machine by using the Nmap tool. This is to find the open ports and services on the target machine and will help us to proceed further.

Here we performed an Aggressive scan coupled with the ping scan. After the scan, we saw that the port 22 and 80 are open. We have the SSH Service (22) as well as an HTTP Service (80) on the server.

This gave us a lay of the land. Now let’s get to enumeration.


We start the Enumeration with a Directory Brute Force. We will be using the dirb tool for this attack.

We see that the dirb helped us get some of the links that could be our potential entry points. We also see that we have the robots.txt file. It had a bunch of links in it. But since we have an HTTP Service, we decided to open the IP Address in the browser.

We find that the machine is running Gitlab on it. But as shown in the image given, there are some credentials that are required to get in. Back to the robots.txt, we see that we have the a /help/ link inside it. This was unusual so we decide to give it a look.

Here we found a page named bookmarks.html. Let’s check it out.

There are a couple of links in this bookmarks.html page. But one that drew our attention was the Git Lab login. Clicking on the link was useless. So, it occurred to us that like it a link on an HTML page, there must be a reference link behind it. We used the Inspect Element Tool of the Firefox Browser to look at that Reference link.  There is some JavaScript code involved. But we were pretty sure that the credentials are hiding inside it somewhere.     

We copied the code and looked for something that could decode these values for us.  We found this awesome Deobfuscator for JavaScript online. We pasted the script inside it and it gave us the decoded values. In those decoded values we have the Login Credentials. 


We went back to the login page that we found earlier. We enter the credentials that we just found and logged in the GitLab.

Username: clave

Password: 11des0081x

After the successful login, we enumerated the Projects and found 2 repositories: Profile and Deployer. We need to enumerate those repositories as well. Let’s Start with the Profile repo. 

We went inside the Profile Repo and then we saw that we have a Snippets Tab in the panel. So, we clicked on that to enumerate some snippets.

Here we have an interesting code snippet that contains a Postgresql file. We examined the file to see that it contains a code that could be useful. So, we took the note of that code.

We went back to the Profile Repository. It was kind-off empty so we went on to do some research on how to exploit the GitLab Repository. We tinkered with it and figured out a way. To do this, first, we need to create a new file in the repo as shown in the image given.

We name the file as “db.php” and paste the PostgreSQL code that we found earlier in the Code Snippet Section and because we want to fetch the credentials form the database, we added the lines at the end to do so.

After making the appropriate edits, we move all the way down to the “Commit changes” button and click on it to reflect the changes in the file.

After we have successfully saved the PHP file with the code, we need to merge the file that we just created in the current working repository. For this, we need to create a Merge Request. It can be done using the “Create merge request” button on the Repository. This will result in the opening of a page, we filled in the necessary details. After that, we drag to the bottom of the page where we find a “Submit merge request” button as shown in the image. 

After submitting the merge request, we need to merge the commit in the root branch. For that, we have a “Merge” button right below the request that we just submitted.

After clicking on that Merge button, we will now modify our URL to get to the PHP file that we just created. As shown in the image given below. Here we wrote the IP Address of the machine, followed by the name of the repository i.e., profile and lastly the name of the file that we created. Here we can see that we have the password of the user clave which was stored in the database. Cool!

Post Exploitation

Now that we had the credentials of the user clave. So, it’s time to connect to the Target Machine via the SSH service. Establishing a connection was a breeze. After connecting, we do some enumeration using the id command. We listed all the directories and found the user.txt. This is the user flag. Congratulations! The battle is half won.

When we were enumerating for the user flag, we saw an executable file named RemoteConnection.exe Let’s download the file to our system to have a better look at the executable. We used the SCP for transferring the RemoteConnection.exe to our system.

Now, that we have the executable we tired to run the file in out Windows Machine but as shown in the image we have the classic Access Denied!! Error.

Privilege Escalation

Now we decided to Reverse Engineer the exe to get some information or to bypass the Access Denied!! In actuality we just wanted to know as this exe makes a connection to the server then it must have a set of credentials hidden in it. We are going to use an x32dbg Debugger for our Reverse Engineering operations.

After opening the Debugger as shown in the image we locate the RemoteConnection.exe file in our Windows Explorer.

We open the executable inside the debugger and take a look around various text fields. In the search for some way to get through the Access Denied!! We click on the Run Button(Highlighted) to capture the response.

Here we take the instance and scan the Text Fields using the button (Highlighted) as shown in the image given below.

We see that we have the attempt for connecting to a server using the PuTTY Tools but then we got our Access Denied. This means that when it launches the PuTTY, it must have entered some set of credentials that are hiding from us. We need to find them.

We check the different breakpoints to see if we can get way in. But it was not looking too good.

So, what we did was set up multiple Breakpoints and tried to analyze the instances. And we see that we have some SSH commands. So, we selected an instance to take a better look at the instance as we see that we have the SSH Password displayed in cleartext. This is probably not a secure way to handle credentials. 

Now that we have the root credentials, all that’s left to do is just SSH our way in and grab that root flag that is waiting for us. We logged in using the credentials that we found and then we quickly located the root flag!

This concludes this awesome Capture the Flag challenge. We learned lots of new things and we were provided with a scenario that could very much possible in a Real Life.

Author: Kavish Tyagi is a Cybersecurity enthusiast and Researcher in the field of WebApp Penetration testing. Contact here