<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://ogmini.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://ogmini.github.io/" rel="alternate" type="text/html" /><updated>2026-07-15T19:02:26+00:00</updated><id>https://ogmini.github.io/feed.xml</id><title type="html">ogmini - Exploration of DFIR</title><subtitle>Having fun while learning about and pivoting into the world of DFIR.</subtitle><entry><title type="html">Tailscale Security Bulletin (TS-2026-009) and Detection</title><link href="https://ogmini.github.io/2026/07/15/Tailscale-Security-Bulletin-and-Detection.html" rel="alternate" type="text/html" title="Tailscale Security Bulletin (TS-2026-009) and Detection" /><published>2026-07-15T00:00:00+00:00</published><updated>2026-07-15T00:00:00+00:00</updated><id>https://ogmini.github.io/2026/07/15/Tailscale%20Security%20Bulletin%20and%20Detection</id><content type="html" xml:base="https://ogmini.github.io/2026/07/15/Tailscale-Security-Bulletin-and-Detection.html"><![CDATA[<p>A friend alerted me to a security bulletin <a href="https://tailscale.com/security-bulletins#ts-2026-009">https://tailscale.com/security-bulletins#ts-2026-009</a> released by Tailscale about a vulnerability related to Tailscale SSH. I was still running a vulnerable version in my testing environment and wanted to test this out and see what kind of artifacts it leaves behind. Would be useful for anyone wanting to check their logs for potential exploitation.</p>

<p>First, a quick video of exploitation. If you want a “detection rule” via grep or journalctl feel free to scroll down to the bottom.</p>

<video width="960" height="540" controls="">
 <source src="https://ogmini.github.io/images/ts-2026-009/Tailscale_(TS-2026-009)_Example.mp4" type="video/mp4" />
 Your browser does not support the video tag
</video>

<p><img src="/images/ts-2026-009/login-1.PNG" alt="Login 1" /></p>

<p><img src="/images/ts-2026-009/login-2.PNG" alt="Login 2" /></p>

<p>In the video, I’m using Putty on Windows to open an SSH session with my tailscale node. I login with the user <code class="language-plaintext highlighter-rouge">-i</code> which doesn’t exist. It immediately drops me a the root login and I verify that by running <code class="language-plaintext highlighter-rouge">whoami</code>.</p>

<p>The first question I asked myself is if can I see this login attempt in the tailscaled logs? They will not show up in the SSH server (Dropbear in this case) logs as the Tailscale client is handling all of this. I check the syslog file at <code class="language-plaintext highlighter-rouge">/var/log/syslog</code> and see the following:</p>

<pre><code class="language-syslog">2026-07-15T13:33:34.535160-04:00 DietPiHomeLab tailscaled[592]: magicsock: disco: node [/OSRQ] d:81766ca7a1b911d6 now using 192.168.0.205:41641 mtu=1360 tx=398c82f127ad
2026-07-15T13:33:34.685284-04:00 DietPiHomeLab tailscaled[592]: control: NetInfo: NetInfo{varies=true ipv6=false ipv6os=true udp=true icmpv4=false derp=#1 portmap=active-UMC link="" firewallmode="ipt-default"}
2026-07-15T13:33:34.685378-04:00 DietPiHomeLab tailscaled[592]: magicsock: endpoints changed: [REDACTED_IP]:41647 (portmap), [REDACTED_IP]:1720 (stun), [REDACTED_IP]:41641 (stun4localport), 192.168.0.212:41641 (local)
2026-07-15T13:33:34.733485-04:00 DietPiHomeLab tailscaled[592]: magicsock: disco: node [/OSRQ] d:81766ca7a1b911d6 now using 192.168.0.1:41641 mtu=1360 tx=f2dfd1d933fd
2026-07-15T13:33:35.371241-04:00 DietPiHomeLab tailscaled[592]: ssh-session(sess-20260715T172750-97360649bb): Session complete
2026-07-15T13:33:48.019352-04:00 DietPiHomeLab tailscaled[592]: ssh-conn-20260715T173345-1d65e5d9b8: handling conn: 100.85.179.88:50798-&gt;-i@100.105.171.109:22
2026-07-15T13:33:48.029603-04:00 DietPiHomeLab tailscaled[592]: ssh-conn-20260715T173345-1d65e5d9b8: starting session: sess-20260715T173348-860d5964ce
2026-07-15T13:33:48.029694-04:00 DietPiHomeLab tailscaled[592]: ssh-session(sess-20260715T173348-860d5964ce): handling new SSH connection from [REDACTED_USER_EMAIL] (100.85.179.88) to ssh-user "root"
2026-07-15T13:33:48.029784-04:00 DietPiHomeLab tailscaled[592]: ssh-session(sess-20260715T173348-860d5964ce): access granted to [REDACTED_USER_EMAIL] as ssh-user "root"
2026-07-15T13:33:48.029855-04:00 DietPiHomeLab tailscaled[592]: audit: SSH login: user=root uid=0 from=100.85.179.88 ts_user=[REDACTED_USER_EMAIL] node=outsider.[REDACTED_TAILNET].ts.net.
2026-07-15T13:33:48.030395-04:00 DietPiHomeLab tailscaled[592]: ssh-session(sess-20260715T173348-860d5964ce): starting pty command: [/usr/sbin/tailscaled be-child ssh --login-shell=/bin/bash
2026-07-15T13:33:48.030642-04:00 DietPiHomeLab tailscaled[592]: daemon --uid=0 --gid=0 --groups=0 --local-user=root --home-dir=/root --remote-user=[REDACTED_USER_EMAIL] --remote-ip=100.85.179.88 --has-tty=true --tty-name=pts/0 --force-v1-behavior --shell]
2026-07-15T13:33:55.537832-04:00 DietPiHomeLab tailscaled[592]: control: NetInfo: NetInfo{varies=false ipv6=false ipv6os=true udp=true icmpv4=false derp=#1 portmap=active-UMC link="" firewallmode="ipt-default"}
</code></pre>

<p>The following syslog entry in particular shows us the passing of the <code class="language-plaintext highlighter-rouge">-i</code> as the username called out by the security bulletin:</p>

<pre><code class="language-syslog">2026-07-15T13:33:48.019352-04:00 DietPiHomeLab tailscaled[592]: ssh-conn-20260715T173345-1d65e5d9b8: handling conn: 100.85.179.88:50798-&gt;-i@100.105.171.109:22
</code></pre>

<p><img src="/images/ts-2026-009/who_is_-i.png" alt="Who is -i?" /></p>

<p>Subsequently, I can see a login from root:</p>

<pre><code class="language-syslog">2026-07-15T13:33:48.029694-04:00 DietPiHomeLab tailscaled[592]: ssh-session(sess-20260715T173348-860d5964ce): handling new SSH connection from [REDACTED_USER_EMAIL] (100.85.179.88) to ssh-user "root"
</code></pre>

<p>Now that I know what to look for, I can write a simple grep/journalctl command to search for line that match the pattern. This could probably be converted to a Sigma rule or other detection rule; but, I don’t have a testing environment spun up to test and validate them.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">grep</span> <span class="nt">-E</span> <span class="s1">'tailscaled[[0-9]+]: ssh-conn-[^:]+: handling conn: .*-&gt;-i@'</span> /var/log/syslog
</code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>journalctl <span class="nt">-u</span> tailscaled | <span class="nb">grep</span> <span class="nt">-E</span> <span class="s1">'ssh-conn-[^:]+: handling conn: .*-&gt;-i@'</span>
</code></pre></div></div>

<p>As a quick sidenote, this will log the user -i as the first user listed in the passwd file. I verified this and was able to log in as a different user if I placed them at the top fo the passwd file.</p>]]></content><author><name>ogmini</name></author><category term="Tailscale" /><category term="Linux" /><summary type="html"><![CDATA[A friend alerted me to a security bulletin https://tailscale.com/security-bulletins#ts-2026-009 released by Tailscale about a vulnerability related to Tailscale SSH. I was still running a vulnerable version in my testing environment and wanted to test this out and see what kind of artifacts it leaves behind. Would be useful for anyone wanting to check their logs for potential exploitation.]]></summary></entry><entry><title type="html">Examining Tailscale Artifacts - Part 7</title><link href="https://ogmini.github.io/2026/07/13/Examining-Tailscale-Artifacts-Part-7.html" rel="alternate" type="text/html" title="Examining Tailscale Artifacts - Part 7" /><published>2026-07-13T00:00:00+00:00</published><updated>2026-07-13T00:00:00+00:00</updated><id>https://ogmini.github.io/2026/07/13/Examining%20Tailscale%20Artifacts%20-%20Part%207</id><content type="html" xml:base="https://ogmini.github.io/2026/07/13/Examining-Tailscale-Artifacts-Part-7.html"><![CDATA[<p>Continuing to look at Tailscale artifacts, this time on a Linux machine. Paths change but the artifacts are very similar to the Windows client.</p>

<table>
  <thead>
    <tr>
      <th>Windows</th>
      <th>Linux</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>%ProgramData%\Tailscale</td>
      <td>/var/lib/tailscale</td>
    </tr>
  </tbody>
</table>

<p>There appears to be one notable difference in that the <code class="language-plaintext highlighter-rouge">profile-data/*/netmap-cache</code> folder has files.</p>

<p><img src="/images/tailscale/netmap-cache1.png" alt="linux netmap-cache" /></p>

<p><img src="/images/tailscale/netmap-cache2.png" alt="windows netmap-cache" /></p>

<p>As the folder name suggests, these files do appear to be cached information about the network and the filenames appear to be hex-encoded ASCII. For example:</p>

<table>
  <thead>
    <tr>
      <th>Filename</th>
      <th>Decoded</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>646e73</td>
      <td>dns</td>
    </tr>
    <tr>
      <td>66696c746572</td>
      <td>filter</td>
    </tr>
    <tr>
      <td>706565722d6e4335626656733169323231434e54524c</td>
      <td>peer-nC5bfVs1i221CNTRL</td>
    </tr>
  </tbody>
</table>

<p>Not sure why the Windows client doesn’t leverage this or maybe my tests haven’t triggered the caching. I’d have to dig into their source code to see if it provides any hints. In my limited testing/research, the following file types exist:</p>

<table>
  <thead>
    <tr>
      <th>Prefix</th>
      <th>Filetype</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>757365722d</td>
      <td>user-</td>
      <td>Contains information about users that are a part of the tailnet. One file per user. Files also exist for tags.</td>
    </tr>
    <tr>
      <td>706565722d</td>
      <td>peer-</td>
      <td>Contains information about the peers/endpoints that are a part of the tailnet.</td>
    </tr>
    <tr>
      <td>646572706d6170</td>
      <td>derpmap</td>
      <td> </td>
    </tr>
    <tr>
      <td>737368</td>
      <td>ssh</td>
      <td> </td>
    </tr>
    <tr>
      <td>73656c66</td>
      <td>self</td>
      <td> </td>
    </tr>
    <tr>
      <td>66696c746572</td>
      <td>filter</td>
      <td> </td>
    </tr>
    <tr>
      <td>646e73</td>
      <td>dns</td>
      <td> </td>
    </tr>
    <tr>
      <td>6d736963</td>
      <td>msic</td>
      <td> </td>
    </tr>
  </tbody>
</table>

<p>There is definitely more to dig into here. From quick analysis, you could use this to easily rebuild the network map of the tailnet. This would include:</p>

<ul>
  <li>Users</li>
  <li>Endpoints</li>
  <li>Which user owns the endpoint</li>
  <li>Routing rules</li>
</ul>

<p>I am intrigued to see how similar/different the Android client is to the Linux client. This is a really useful digital artifact to have as you would need access to the owner’s Tailscale control panel to typically get all this information. More to come as there is a ton to dig into and test…</p>]]></content><author><name>ogmini</name></author><category term="Tailscale" /><category term="Linux" /><summary type="html"><![CDATA[Continuing to look at Tailscale artifacts, this time on a Linux machine. Paths change but the artifacts are very similar to the Windows client.]]></summary></entry><entry><title type="html">Examining Tailscale Artifacts - Part 6</title><link href="https://ogmini.github.io/2026/06/23/Examining-Tailscale-Artifacts-Part-6.html" rel="alternate" type="text/html" title="Examining Tailscale Artifacts - Part 6" /><published>2026-06-23T00:00:00+00:00</published><updated>2026-06-23T00:00:00+00:00</updated><id>https://ogmini.github.io/2026/06/23/Examining%20Tailscale%20Artifacts%20-%20Part%206</id><content type="html" xml:base="https://ogmini.github.io/2026/06/23/Examining-Tailscale-Artifacts-Part-6.html"><![CDATA[<p>This will sort of be a two for one post today as I’m still at training until the end of the week. Always fun how these sorts of things can get the mind churning and give you the motivation to start looking at stuff again. Today was mainly about Log Analytics workspaces and KQL. I had prior experience with what I would call doing “easy” queries. I’ve not had much need to play with functions like summarize, bin, or even search/find. I was very reliant on using the traditional where clause. So it was nice to be “forced” to use them.</p>

<p>Anyways, going back to Tailscale. Back in <a href="https://ogmini.github.io/2026/04/21/Examining-Tailscale-Artifacts.html">Part 1</a>, I had asked the question if partial downloads are kept forever or cleaned up periodically. I have an answer that is untested/unverified. It comes by way of looking at the Tailscale repository on GitHub specifically the <code class="language-plaintext highlighter-rouge">delete.go</code> file for Taildrop at <a href="https://github.com/tailscale/tailscale/blob/d4f2917c1bfd27529ec7997d08a8f1aa9ea903f2/feature/taildrop/delete.go">https://github.com/tailscale/tailscale/blob/d4f2917c1bfd27529ec7997d08a8f1aa9ea903f2/feature/taildrop/delete.go</a>. In the file we see the comment and const variable:</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">// deleteDelay is the amount of time to wait before we delete a file.</span>
<span class="c">// A shorter value ensures timely deletion of deleted and partial files, while</span>
<span class="c">// a longer value provides more opportunity for partial files to be resumed.</span>
<span class="k">const</span> <span class="n">deleteDelay</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">Hour</span>
</code></pre></div></div>

<p>So one hour before the partial file gets deleted.</p>

<p>Another interesting callout from reading the code. In the <code class="language-plaintext highlighter-rouge">ext.go</code> file for Taildrop at <a href="https://github.com/tailscale/tailscale/blob/d4f2917c1bfd27529ec7997d08a8f1aa9ea903f2/feature/taildrop/ext.go">https://github.com/tailscale/tailscale/blob/d4f2917c1bfd27529ec7997d08a8f1aa9ea903f2/feature/taildrop/ext.go</a> there is a comment about how MacOS and some other clients handle the location of in-progress downloads differently.</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">// directFileRoot, if non-empty, means to write received files</span>
	<span class="c">// directly to this directory, without staging them in an</span>
	<span class="c">// intermediate buffered directory for "pick-up" later. If</span>
	<span class="c">// empty, the files are received in a daemon-owned location</span>
	<span class="c">// and the localapi is used to enumerate, download, and delete</span>
	<span class="c">// them. This is used on macOS where the GUI lifetime is the</span>
	<span class="c">// same as the Network Extension lifetime and we can thus avoid</span>
	<span class="c">// double-copying files by writing them to the right location</span>
	<span class="c">// immediately.</span>
	<span class="c">// It's also used on several NAS platforms (Synology, TrueNAS, etc)</span>
	<span class="c">// but in that case DoFinalRename is also set true, which moves the</span>
	<span class="c">// *.partial file to its final name on completion.</span>
	<span class="n">directFileRoot</span> <span class="kt">string</span>
</code></pre></div></div>

<p>Again, I want to test this when I get the chance.</p>]]></content><author><name>ogmini</name></author><category term="Tailscale" /><category term="MacOS" /><summary type="html"><![CDATA[This will sort of be a two for one post today as I’m still at training until the end of the week. Always fun how these sorts of things can get the mind churning and give you the motivation to start looking at stuff again. Today was mainly about Log Analytics workspaces and KQL. I had prior experience with what I would call doing “easy” queries. I’ve not had much need to play with functions like summarize, bin, or even search/find. I was very reliant on using the traditional where clause. So it was nice to be “forced” to use them.]]></summary></entry><entry><title type="html">Examining Tailscale Artifacts - Part 5</title><link href="https://ogmini.github.io/2026/06/22/Examining-Tailscale-Artifacts-Part-5.html" rel="alternate" type="text/html" title="Examining Tailscale Artifacts - Part 5" /><published>2026-06-22T00:00:00+00:00</published><updated>2026-06-22T00:00:00+00:00</updated><id>https://ogmini.github.io/2026/06/22/Examining%20Tailscale%20Artifacts%20-%20Part%205</id><content type="html" xml:base="https://ogmini.github.io/2026/06/22/Examining-Tailscale-Artifacts-Part-5.html"><![CDATA[<p>It has been awhile since I’ve posted, currently attending IRC234 put on by Cybervance for CISA. Had a little time after the first day and decided to poke around Tailscale logs on MacOS. Just a warning, this post will be very light on details.</p>

<p>Going back to <a href="https://ogmini.github.io/2026/04/21/Examining-Tailscale-Artifacts.html">Part 1</a>, I looked at logs stored by the Windows client and focused a little on artifacts related to file transfers. MacOS stores them in the System Log and you can retrieve them using the sysdiagnose command. Instructions can also be found on Tailscale’s support page at <a href="https://tailscale.com/docs/features/logging?tab=macos">https://tailscale.com/docs/features/logging?tab=macos</a>.</p>

<p>On the Windows client we saw the following line:</p>

<pre><code class="language-txt">2026-04-21T15:02:44.495-04:00: localapi: [PUT] /localapi/v0/file-put/
</code></pre>

<p>On MacOS we see:</p>

<pre><code class="language-txt">default	2026-06-22 21:18:42.990417 -0400	IPNExtension	localapi: [PUT] /localapi/v0/file-put/
</code></pre>

<p>Similar lines with some information added to support the System Log format. Namely, the Type and Process. Later in the log, I see the public IP for the computer I am transferring the file to:</p>

<pre><code class="language-txt">default	2026-06-22 21:18:43.204547 -0400	IPNExtension	magicsock: disco: node [qZssQ] d:69d545be08f4adda now using [redacted]:41644 mtu=1360 tx=9f2ea8ed384c
</code></pre>

<p>This was a blind spot in my earlier testing since all the tailscale clients were on the same internal network. I’ll need to go back and take a look at this.</p>]]></content><author><name>ogmini</name></author><category term="Tailscale" /><category term="MacOS" /><summary type="html"><![CDATA[It has been awhile since I’ve posted, currently attending IRC234 put on by Cybervance for CISA. Had a little time after the first day and decided to poke around Tailscale logs on MacOS. Just a warning, this post will be very light on details.]]></summary></entry><entry><title type="html">Velociraptor - Tailscale Artifact</title><link href="https://ogmini.github.io/2026/05/06/Velociraptor-Tailscale-Artifact.html" rel="alternate" type="text/html" title="Velociraptor - Tailscale Artifact" /><published>2026-05-06T00:00:00+00:00</published><updated>2026-05-06T00:00:00+00:00</updated><id>https://ogmini.github.io/2026/05/06/Velociraptor%20-%20Tailscale%20Artifact</id><content type="html" xml:base="https://ogmini.github.io/2026/05/06/Velociraptor-Tailscale-Artifact.html"><![CDATA[<p>Submitted a Tailscale artifact to the Velociraptor <a href="https://docs.velociraptor.app/exchange/?query=">Artifact Exchange</a> that decodes and parses the configuration file, shows the logs, and grabs/uploads any partial file transfers to the machine. Tailscale has been used in the past in various attacks by threat actors such as:</p>

<ul>
  <li><a href="https://cyble.com/blog/new-malware-campaign-abusing-rdpwrapper-and-tailscale-to-target-cryptocurrency-users/">https://cyble.com/blog/new-malware-campaign-abusing-rdpwrapper-and-tailscale-to-target-cryptocurrency-users/</a></li>
  <li><a href="https://www.cisa.gov/news-events/cybersecurity-advisories/aa23-320a">https://www.cisa.gov/news-events/cybersecurity-advisories/aa23-320a</a></li>
</ul>

<p>The configuration file surfaces information about the Tailscale accounts, connected Tailnets, and unattended mode/account. These could help identify malicious Tailnet connections. Looking at the logs can potentially identify other machines on the Tailnet. There is also the possibility to recover partial file transfers that didn’t complete. I still need to write up the blog post about that.</p>]]></content><author><name>ogmini</name></author><category term="Tailscale" /><category term="Velociraptor" /><summary type="html"><![CDATA[Submitted a Tailscale artifact to the Velociraptor Artifact Exchange that decodes and parses the configuration file, shows the logs, and grabs/uploads any partial file transfers to the machine. Tailscale has been used in the past in various attacks by threat actors such as:]]></summary></entry><entry><title type="html">Examining Tailscale Artifacts - Part 4</title><link href="https://ogmini.github.io/2026/04/24/Examining-Tailscale-Artifacts-Part-4.html" rel="alternate" type="text/html" title="Examining Tailscale Artifacts - Part 4" /><published>2026-04-24T00:00:00+00:00</published><updated>2026-04-24T00:00:00+00:00</updated><id>https://ogmini.github.io/2026/04/24/Examining%20Tailscale%20Artifacts%20-%20Part%204</id><content type="html" xml:base="https://ogmini.github.io/2026/04/24/Examining-Tailscale-Artifacts-Part-4.html"><![CDATA[<p>Tailscale has the ability to run “unattended” on Windows based machines - <a href="https://tailscale.com/docs/how-to/run-unattended#windows">https://tailscale.com/docs/how-to/run-unattended#windows</a>.</p>

<blockquote>
  <p>On Windows, you can solve this by using “Run Unattended” mode. This configures Tailscale to run as the system instead of the currently logged in user. For example, a machine running Windows Server Edition might want to enable this to permit multiple users to connect using RDP at once.</p>
</blockquote>

<p>This could be very useful for a threat actor who wanted to maintain persistence or communications with a machine. I was interested how this configuration was stored and if I could I tell which account was set to be unattended. This information is found in the server-state.conf file that we’ve been looking at already.</p>

<p>Running a compare on the server-state.conf before and after setting unattended mode results in highlighting two lines where changes have been made.</p>

<p><img src="/images/tailscale/unattend-1.png" alt="compare" /></p>

<p>The key key here is “server-mode-start-key”. This is NULL if unattended mode is disabled and has the name of the relevant profile if it is turned on. With this information you can trace back to the relevant profile which should have “ForceDaemon” set to true. You can also link this back to the User SID. Below is a screenshot with snipped sections to highlight information related to unattended mode.</p>

<p><img src="/images/tailscale/unattend-2.png" alt="decoded" /></p>

<p>I think I’m going to write a simple python script to automatically parse the server-state.conf and decode the Base64. I’ve just been doing it manually for now using Cyberchef.</p>]]></content><author><name>ogmini</name></author><category term="Tailscale" /><summary type="html"><![CDATA[Tailscale has the ability to run “unattended” on Windows based machines - https://tailscale.com/docs/how-to/run-unattended#windows.]]></summary></entry><entry><title type="html">Examining Tailscale Artifacts - Part 3</title><link href="https://ogmini.github.io/2026/04/23/Examining-Tailscale-Artifacts-Part-3.html" rel="alternate" type="text/html" title="Examining Tailscale Artifacts - Part 3" /><published>2026-04-23T00:00:00+00:00</published><updated>2026-04-23T00:00:00+00:00</updated><id>https://ogmini.github.io/2026/04/23/Examining%20Tailscale%20Artifacts%20-%20Part%203</id><content type="html" xml:base="https://ogmini.github.io/2026/04/23/Examining-Tailscale-Artifacts-Part-3.html"><![CDATA[<p>Real short post today. I was able to verify that the LocalUserID is the SID on the computer for the user account Tailscale is being run under. This shows up in a few spots in the server-state.conf.</p>

<p><img src="/images/tailscale/sid.png" alt="whoami" /></p>

<p>We can see this SID in the following lines.</p>

<ul>
  <li>“_current/S-1-5-21-306847822-306330466-671967995-1000”: “profile-617d”,</li>
  <li>“LocalUserID”: “S-1-5-21-306847822-306330466-671967995-1000”,</li>
</ul>

<p>I created another local user on the computer and signed into Tailscale with another account. This results in more lines being added to the server-state.conf. There are now two “_current/[SID]: “profile-[ID]” lines for each local user. Each record under _profiles references the SID. With this information you can see which local accounts on the computer are using what tailscale accounts.</p>]]></content><author><name>ogmini</name></author><category term="Tailscale" /><summary type="html"><![CDATA[Real short post today. I was able to verify that the LocalUserID is the SID on the computer for the user account Tailscale is being run under. This shows up in a few spots in the server-state.conf.]]></summary></entry><entry><title type="html">Examining Tailscale Artifacts - Part 2</title><link href="https://ogmini.github.io/2026/04/22/Examining-Tailscale-Artifacts-Part-2.html" rel="alternate" type="text/html" title="Examining Tailscale Artifacts - Part 2" /><published>2026-04-22T00:00:00+00:00</published><updated>2026-04-22T00:00:00+00:00</updated><id>https://ogmini.github.io/2026/04/22/Examining%20Tailscale%20Artifacts%20-%20Part%202</id><content type="html" xml:base="https://ogmini.github.io/2026/04/22/Examining-Tailscale-Artifacts-Part-2.html"><![CDATA[<p>You can have multiple accounts associated with Tailscale and be able to switch between them. I logged in with a Google and Microsoft account. More testing is required for the other account types and options.</p>

<p>I had expected to see another avatar file created for the second account I logged into. This was not the case; but isn’t definitive. It is possible that the Microsoft account doesn’t provide an avatar to Tailscale. More testing is required. As a reminder the avatars are stored in %localappdata%\Tailscale\Avatars. You can refer to yesterday’s post for more details - <a href="https://ogmini.github.io/2026/04/21/Examining-Tailscale-Artifacts.html">https://ogmini.github.io/2026/04/21/Examining-Tailscale-Artifacts.html</a>.</p>

<p>The server-state.conf file located at %ProgramData%\Tailscale had some obvious changes. You can see a snippet/example below with some information redacted:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{
  "_current/S-1-5-21-306847822-[SNIP]-[SNIP]-1000": "cHJ[SNIP]",
  "_machinekey": "cHJpdm[SNIP]",
  "_profiles": "eyIwNTMz[SNIP]",
  "profile-0533": "ewoJIkNv[SNIP]",
  "profile-617d": "ewoJI[SNIP]",
  "server-mode-start-key": nullbox.c
}
</code></pre></div></div>

<p>The redacted information is actually Base64 encoded text. Which when decoded results in the following with some information redacted:</p>

<pre><code class="language-JSON">{
  "_current/S-1-5-21-306847822-[SNIP]-[SNIP]-1000": "profile-617d",
  "_machinekey": "privkey:[SNIP]",
  "_profiles":
    "{
      "0533": {
          "ID": "0533",
          "Name": "[SNIP]@gmail.com",
          "NetworkProfile": {
              "MagicDNSName": "tail[SNIP].ts.net",
              "DomainName": "[SNIP]@gmail.com",
              "DisplayName": "[SNIP]@gmail.com"
          },
          "Key": "profile-0533",
          "UserProfile": {
              "ID": [SNIP],
              "LoginName": "[SNIP]@gmail.com",
              "DisplayName": "ogmini",
              "ProfilePicURL": "https://lh3.googleusercontent.com/a/[SNIP]"
          },
          "NodeID": "[SNIP]",
          "LocalUserID": "S-1-5-21-306847822-[SNIP]-[SNIP]-1000",
          "ControlURL": "https://controlplane.tailscale.com"
      },
      "617d": {
          "ID": "617d",
          "Name": "[SNIP]@hotmail.com",
          "NetworkProfile": {
              "MagicDNSName": "tail[SNIP].ts.net",
              "DomainName": "[SNIP]@hotmail.com",
              "DisplayName": "[SNIP]@hotmail.com"
          },
          "Key": "profile-617d",
          "UserProfile": {
              "ID": [SNIP],
              "LoginName": "[SNIP]@hotmail.com",
              "DisplayName": "FirstName LastName"
          },
          "NodeID": "[SNIP]",
          "LocalUserID": "S-1-5-21-306847822-[SNIP]-[SNIP]-1000",
          "ControlURL": "https://controlplane.tailscale.com"
      }
    }",
  "profile-0533":
    "{
      "ControlURL": "https://controlplane.tailscale.com",
      "RouteAll": true,
      "ExitNodeID": "",
      "ExitNodeIP": "",
      "InternalExitNodePrior": "",
      "ExitNodeAllowLANAccess": false,
      "CorpDNS": true,
      "RunSSH": false,
      "RunWebClient": false,
      "WantRunning": true,
      "LoggedOut": false,
      "ShieldsUp": false,
      "AdvertiseTags": null,
      "Hostname": "",
      "NotepadURLs": false,
      "AdvertiseRoutes": null,
      "AdvertiseServices": null,
      "Sync": null,
      "NoSNAT": false,
      "NoStatefulFiltering": true,
      "NetfilterMode": 2,
      "AutoUpdate": {
        "Check": true,
        "Apply": true
      },
      "AppConnector": {
        "Advertise": false
      },
      "PostureChecking": false,
      "NetfilterKind": "",
      "DriveShares": null,
      "AllowSingleHosts": true,
      "Config": {
        "PrivateNodeKey": "privkey:[SNIP]",
        "OldPrivateNodeKey": "privkey:0000000000000000000000000000000000000000000000000000000000000000",
        "UserProfile": {
          "ID": [SNIP],
          "LoginName": "[SNIP]@gmail.com",
          "DisplayName": "ogmini",
          "ProfilePicURL": "https://lh3.googleusercontent.com/a/[SNIP]"
        },
        "NetworkLockKey": "nlpriv:[SNIP]",
        "NodeID": "[SNIP]"
      }
    }",
  "profile-617d":
    "{
      "ControlURL": "https://controlplane.tailscale.com",
      "RouteAll": true,
      "ExitNodeID": "",
      "ExitNodeIP": "",
      "InternalExitNodePrior": "",
      "ExitNodeAllowLANAccess": false,
      "CorpDNS": true,
      "RunSSH": false,
      "RunWebClient": false,
      "WantRunning": true,
      "LoggedOut": false,
      "ShieldsUp": false,
      "AdvertiseTags": null,
      "Hostname": "",
      "NotepadURLs": false,
      "AdvertiseRoutes": null,
      "AdvertiseServices": null,
      "Sync": null,
      "NoSNAT": false,
      "NoStatefulFiltering": true,
      "NetfilterMode": 2,
      "AutoUpdate": {
        "Check": true,
        "Apply": true
      },
      "AppConnector": {
        "Advertise": false
      },
      "PostureChecking": false,
      "NetfilterKind": "",
      "DriveShares": null,
      "AllowSingleHosts": true,
      "Config": {
        "PrivateNodeKey": "privkey:[SNIP]",
        "OldPrivateNodeKey": "privkey:0000000000000000000000000000000000000000000000000000000000000000",
        "UserProfile": {
          "ID": [SNIP],
          "LoginName": "[SNIP]@hotmail.com",
          "DisplayName": "FirstName LastName"
        },
        "NetworkLockKey": "nlpriv:[SNIP]",
        "NodeID": "[SNIP]"
      }
    }",
  "server-mode-start-key": null
}
</code></pre>

<p>Pretty easy to read and we can see the records for the two accounts that I connected. There is a profile 0533 and 617d which correlate to the two accounts I logged in with. The first line with _profile denotes which account is currently active on the computer.</p>

<p>You’ll also notice that only one account has a ProfilePicURL which sort of lines up with my theory above about there being no avatar for the Microsoft account. This needs to be tested.</p>

<p>Someething to call out for possible investigations is the DisplayName which pulled the Firstname and Lastname that I specified when creating the test accounts on Google and Microsoft. Potentially useful if you have a sloppy suspect.</p>

<p>A lot more to dive into later. I’m particularly interested in the NodeIDs, _machinekey, and LocalUserID. More than likely that LocalUserID is the SID on the computer for the user account Tailscale is being run under. The pattern matches but I didn’t actually verify that yet. This could be useful when someone sets up Tailscale to be run unattended.</p>]]></content><author><name>ogmini</name></author><category term="Tailscale" /><summary type="html"><![CDATA[You can have multiple accounts associated with Tailscale and be able to switch between them. I logged in with a Google and Microsoft account. More testing is required for the other account types and options.]]></summary></entry><entry><title type="html">Examining Tailscale Artifacts</title><link href="https://ogmini.github.io/2026/04/21/Examining-Tailscale-Artifacts.html" rel="alternate" type="text/html" title="Examining Tailscale Artifacts" /><published>2026-04-21T00:00:00+00:00</published><updated>2026-04-21T00:00:00+00:00</updated><id>https://ogmini.github.io/2026/04/21/Examining%20Tailscale%20Artifacts</id><content type="html" xml:base="https://ogmini.github.io/2026/04/21/Examining-Tailscale-Artifacts.html"><![CDATA[<p>I started looking at <a href="https://tailscale.com/">Tailscale</a> to see what sort of digital artifacts are left behind. It has clients for Windows/Linux/Android/iOS/macOS and I’m hoping to take a look at all of them except iOS. Tailscale is a networking tool that lets you securely connect your devices (laptop, phone, servers, cloud VMs, etc.) as if they were all on the same private network, no matter where they are. A very popular tool with Homelab people and I use it myself.</p>

<p>Today, I fired up a clean VM running Windows 11 25H2 and installed Tailscale 1.96.3. Authenticated with my account and started to poke around.</p>

<p>Locations of note:</p>

<ul>
  <li>%localappdata%\Tailscale
    <ul>
      <li>Avatars folder</li>
    </ul>
  </li>
  <li>%localappdata%\temp\Tailscale*.log
    <ul>
      <li>Installation log files</li>
    </ul>
  </li>
  <li>%ProgramData%\Tailscale
    <ul>
      <li>Logs folder</li>
      <li>files folder</li>
    </ul>
  </li>
</ul>

<p>The Avatars folder is interesting because it contains files with what appear to be HTTP/2 responses that have the avatar image embedded. I was able to extract them with a hex editor.</p>

<p>Tailscale also has support for secure file transfer between devices on a tailnet. You can read more at <a href="https://tailscale.com/docs/features/taildrop">https://tailscale.com/docs/features/taildrop</a>. In current versions, files are dropped into %userprofile%\Downloads AFTER they are temporarily stored at %ProgramData%\Tailscale\files[Account-uid-####]\ during transfer. This is to support the ability to resume interrupted tranfers. Possible to find interesting artifacts here… I wonder if they are kept forever or is this folder cleaned out periodically.</p>

<p>Additionally, I was able to find records in the local Tailscale logs about these transfers. Below are some examples:</p>

<p>Tiny transfer</p>

<pre><code class="language-log">2026-04-21T11:10:26.712-04:00: [v1] Accept: TCP{100.113.x.x:54099 &gt; 100.105.x.x:34718} 41 ok out
2026-04-21T11:10:26.713-04:00: [v1] v1.96.3-t3ffddb134-g460d8764a peers: 29500/767972
2026-04-21T11:10:26.713-04:00: [v1] Accept: TCP{100.105.x.x:34718 &gt; 100.113.x.x:54099} 40 tcp non-syn
2026-04-21T11:10:26.735-04:00: [v1] v1.96.3-t3ffddb134-g460d8764a peers: 29580/767972
2026-04-21T11:10:28.000-04:00: [v1] Accept: TCP{100.105.x.x:56010 &gt; 100.113.x.x:36843} 52 tcp ok
2026-04-21T11:10:28.033-04:00: peerapi: got put of &lt;=1MB in 0s from 100.105.x.x/0x7ff60151dc40
</code></pre>

<p>Moderate transfer</p>

<pre><code class="language-log">2026-04-21T11:22:08.273-04:00: [v1] Accept: TCP{100.105.x.x:56042 &gt; 100.113.x.x:36843} 52 tcp ok
2026-04-21T11:22:08.275-04:00: [v1] Accept: TCP{100.105.x.x:56042 &gt; 100.113.x.x:36843} 40 tcp non-syn
2026-04-21T11:22:08.275-04:00: [v1] Accept: TCP{100.105.x.x:56042 &gt; 100.113.x.x:36843} 172 tcp non-syn
2026-04-21T11:22:08.735-04:00: [v1] v1.96.3-t3ffddb134-g460d8764a peers: 36220492/1877892
2026-04-21T11:22:10.480-04:00: peerapi: got put of ~141MB in 2.2s from 100.105.x.x/0x7ff60151dc40
</code></pre>

<p>Cancelled transfer</p>

<pre><code class="language-log">2026-04-21T12:36:44.735-04:00: [v1] v1.96.3-t3ffddb134-g460d8764a peers: 283171412/9316908
2026-04-21T12:36:46.735-04:00: [v1] v1.96.3-t3ffddb134-g460d8764a peers: 434701012/13177516
2026-04-21T12:36:47.346-04:00: netmap: suggested exit node:  ()
2026-04-21T12:36:48.735-04:00: [v1] v1.96.3-t3ffddb134-g460d8764a peers: 563871396/16888732
2026-04-21T12:36:50.347-04:00: netmap: suggested exit node:  ()
2026-04-21T12:36:50.735-04:00: [v1] v1.96.3-t3ffddb134-g460d8764a peers: 704353732/20631252
2026-04-21T12:36:52.735-04:00: [v1] v1.96.3-t3ffddb134-g460d8764a peers: 834675908/24517588
2026-04-21T12:36:53.242-04:00: [v1] Accept: TCP{100.105.x.x:56073 &gt; 100.113.x.x:36843} 1280 tcp non-syn
2026-04-21T12:36:53.347-04:00: netmap: suggested exit node:  ()
2026-04-21T12:36:54.735-04:00: [v1] v1.96.3-t3ffddb134-g460d8764a peers: 985344324/28780612
2026-04-21T12:36:56.347-04:00: netmap: suggested exit node:  ()
2026-04-21T12:36:56.735-04:00: [v1] v1.96.3-t3ffddb134-g460d8764a peers: 1138328004/33788836
2026-04-21T12:36:58.735-04:00: [v1] v1.96.3-t3ffddb134-g460d8764a peers: 1286926196/38278692
2026-04-21T12:36:59.347-04:00: netmap: suggested exit node:  ()
2026-04-21T12:37:00.735-04:00: [v1] v1.96.3-t3ffddb134-g460d8764a peers: 1435116740/42726524
2026-04-21T12:37:02.348-04:00: netmap: suggested exit node:  ()
2026-04-21T12:37:02.735-04:00: [v1] v1.96.3-t3ffddb134-g460d8764a peers: 1583067284/46583196
2026-04-21T12:37:03.242-04:00: [v1] Accept: TCP{100.105.x.x:56073 &gt; 100.113.x.x:36843} 1280 tcp non-syn
</code></pre>

<p>Sent File</p>

<pre><code class="language-log">2026-04-21T15:02:42.720-04:00: [v1] Accept: TCP{100.105.x.x:53517 &gt; 100.104.x.x:58294} 41 ok out
2026-04-21T15:02:42.721-04:00: [v1] Accept: TCP{100.104.x.x:58294 &gt; 100.105.x.x:53517} 40 tcp non-syn
2026-04-21T15:02:42.721-04:00: [v1] v1.96.3-t3ffddb134-g460d8764a peers: 892/1220
2026-04-21T15:02:44.495-04:00: localapi: [PUT] /localapi/v0/file-put/
2026-04-21T15:02:44.496-04:00: [v1] Accept: TCP{100.105.x.x:53517 &gt; 100.104.x.x:58294} 165 ok out
2026-04-21T15:02:44.503-04:00: netmap: suggested exit node:  ()
2026-04-21T15:02:44.505-04:00: netmap: suggested exit node:  ()
2026-04-21T15:02:45.532-04:00: [v1] v1.96.3-t3ffddb134-g460d8764a peers: 1644/8036
</code></pre>

<p>Zeroing in on a few specific lines:</p>

<pre><code class="language-log">2026-04-21T11:10:28.033-04:00: peerapi: got put of &lt;=1MB in 0s from 100.105.38.14/0x7ff60151dc40
</code></pre>

<p>This is logged on the client that recieves a file. We can glean the approximate size of the file, the IP of the Tailscale device that sent the file, and when the file was received.</p>

<pre><code class="language-log">2026-04-21T15:02:44.495-04:00: localapi: [PUT] /localapi/v0/file-put/
</code></pre>

<p>This is logged on the client that sent the file. Previous and subsequent log records possibly point to the IP of the Tailscale device the file was sent to. But this requires far more testing. Those log records could just be showing communication between clients.</p>

<p>Many more things I want to test in future posts.</p>]]></content><author><name>ogmini</name></author><category term="Tailscale" /><summary type="html"><![CDATA[I started looking at Tailscale to see what sort of digital artifacts are left behind. It has clients for Windows/Linux/Android/iOS/macOS and I’m hoping to take a look at all of them except iOS. Tailscale is a networking tool that lets you securely connect your devices (laptop, phone, servers, cloud VMs, etc.) as if they were all on the same private network, no matter where they are. A very popular tool with Homelab people and I use it myself.]]></summary></entry><entry><title type="html">BSides South Jersey 2026</title><link href="https://ogmini.github.io/2026/04/19/BSides-South-Jersey-2026-Talk.html" rel="alternate" type="text/html" title="BSides South Jersey 2026" /><published>2026-04-19T00:00:00+00:00</published><updated>2026-04-19T00:00:00+00:00</updated><id>https://ogmini.github.io/2026/04/19/BSides%20South%20Jersey%202026%20Talk</id><content type="html" xml:base="https://ogmini.github.io/2026/04/19/BSides-South-Jersey-2026-Talk.html"><![CDATA[<p>I was a speaker at <a href="https://bsidessouthjersey.org/">BSides South Jersey 2026</a> and it was a great event hosted at Rowan University. I’m already looking forward to next years event. I want to thank the Founders, Organizers, Sponsors, and Volunteers for all the time they put in and being so welcoming. I apologize for not getting everyone’s names as you were all so busy and I talked to so many people. Feel free to connect with me on LinkedIn <a href="https://www.linkedin.com/in/christophereng/">https://www.linkedin.com/in/christophereng/</a>.</p>

<p><img src="/images/bsides/BSidesSouthJersey2026.jpg" alt="Speaker Swag" /></p>

<h2 id="learning-out-loud">Learning out Loud</h2>

<p>What follows is the “written” version of my talk at BSides South Jersey 2026.</p>

<p><a href="/files/BSides South Jersey 2025 Presentation.pptx">Powerpoint Slides</a></p>

<h3 id="zeltser-challenge">Zeltser Challenge</h3>

<p>I’m going to be lazy here and point you to a previous post where I talked about the challenge. <a href="https://ogmini.github.io/2026/02/07/2025-Zeltser-Challenge-Recap.html">https://ogmini.github.io/2026/02/07/2025-Zeltser-Challenge-Recap.html</a></p>

<h3 id="logistics">Logistics</h3>

<p>Pick a platform or platforms of your liking and preference. You could make your posts on LinkedIn, Wordpress, Google Pages, Medium, BlueSky, etc. It is also important to have some fun with this whole process. Think of a fun name and logo/image. This is where you can add some personality and flair to it.</p>

<h3 id="the-plan">The Plan</h3>

<p>Have a plan but be ready to throw it all away. I had a very structured, weekly plan for posts and it helped in the initial start of the challenge as I got my footing. It worked for about a month before I ditched it for something else.</p>

<h3 id="reality">Reality</h3>

<p>I realized that this challenge was for me and I could do whatever I wanted. I can go in whatever direction I wanted. My initial plan only last about a month before I decided to just follow where my interests led. It was more important to just post regularly/daily as opposed to keeping to some plan.</p>

<h3 id="wandering">Wandering</h3>

<p>I ended up wandering in my journey of learning out loud. Onlookers might have thought I was lost; but “Not all those who wander are lost”. I was out there to learn and explore. I wanted to push my boundaries and at the same time experience failure and hit dead ends. These should be expected and are just a part of life. One thing to remember, that this whole challenge is not about the likes and reposts. You are doing this for yourself.</p>

<h3 id="my-journey">My Journey</h3>

<p>Again, I’m going to be lazy and just point you at all my previous posts and the multitude of different topics. Your journey will be unique to you. It may be more focused or even more wide and that is OK.</p>

<h3 id="short-detours">Short Detours</h3>

<p>Sometimes, you’ll take a short detour on a subject and realize that maybe it is a little too complex or not that interesting. That is fine! You learned something and can always revisit it in the future with more knowledge or undertanding. A good example for me was looking at <a href="https://ogmini.github.io/tags.html#LevelDB">LevelDB</a>. This topic ended up being far more complex and requiring more time than I wanted to devote at the moment.</p>

<h3 id="day-trips">Day Trips</h3>

<p>Take day trips by reading what others post! Add your spin and apply it to something. Don’t just repost about it. Do something with that knowledge. Maybe you learned about a new tool. Go try that tool out and use it for something. Write about your experience good or bad. Maybe while testing it, you’ll discover something new.</p>

<h3 id="long-journeys">Long Journeys</h3>

<p>This is the big part of this whole challenge. During your wandering, you may come across a topic that really grabs your interest. The destination may not be known yet. Dig in though. See what you can figure out and learn and just enjoy the experience. For me, this long journey was the research I put into Windows Notepad and the eventual publication on DFIR Review. I do not consider this the end of that journey though. I never thought that researching Windows Notepad would lead to that as it just happened naturally.</p>

<h3 id="get-lost">Get Lost</h3>

<p>Don’t be afraid to get lost with topics that you know nothing about. Push your boundaries and learn new things. Take something you know you might be weak with and jump in.</p>

<h3 id="regular-pit-stops">Regular Pit Stops</h3>

<p>You will need to take regular pit stops to keep your momentum going. These types of posts are really useful for when you go on vacation or need some time. They generally don’t require and “work” as you’ve already done it and are just writing about it. Examples would include:</p>

<ul>
  <li>Recap posts</li>
  <li>Training/Coursework</li>
  <li>CTFs/Challenges</li>
</ul>

<p>It is a good idea to write regular recap posts. Maybe every month or week. Looking back really helps you see how far you’ve come and what you were able to accomplish. You will be amazed at the progress that occurs.</p>

<p>We’ve all taken classes, courses, training, and studied. Write up your notes about a class or course. Talk about what tools you used or the main take away. Take notes as you study for certification exams. These can serve you well in the future as you try to remember something from the past.</p>

<p>CTF/Challenge writeups are a very popular thing to do. I would challenge you to go beyond the simple posting of the mechanical steps to the solution. Talk about your process of how you went about solving the problem. Don’t be afraid to talk about your FAILS or missteps you took. I really think this is one thing that is missing. No investigator goes in there and just knows where to look. They have a process that they undertake. It is easy enough to teach how to use tools. It is another to teach how and when to apply those tools.</p>

<h3 id="your-turn">Your Turn</h3>

<p>I guess this would be me re-issuing the Zeltser Challenge to anyone reading this. Honestly, I found this to be a very reinvigorating experience that has led to so much learning, research, and talks. If you decide to take on this challenge, let me know. I’d love to follow your journey.</p>

<ul>
  <li>Make a plan that you don’t have to follow</li>
  <li>Let your curiosity guide you and take detours</li>
  <li>Pick something and take that long journey</li>
  <li>Don’t be afraid to get lost</li>
  <li>Just Post</li>
</ul>]]></content><author><name>ogmini</name></author><category term="Talk" /><category term="BSidesSouthJersey" /><category term="BSides" /><summary type="html"><![CDATA[I was a speaker at BSides South Jersey 2026 and it was a great event hosted at Rowan University. I’m already looking forward to next years event. I want to thank the Founders, Organizers, Sponsors, and Volunteers for all the time they put in and being so welcoming. I apologize for not getting everyone’s names as you were all so busy and I talked to so many people. Feel free to connect with me on LinkedIn https://www.linkedin.com/in/christophereng/.]]></summary></entry></feed>