<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://shehzade.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://shehzade.github.io/" rel="alternate" type="text/html" /><updated>2026-11-12T03:39:59+01:00</updated><id>https://shehzade.github.io/feed.xml</id><title type="html">Shehzade Portfolio</title><subtitle>Red Team Consultant @ Google | MS in Cybersecurity @ NYU</subtitle><entry><title type="html">Building a Local 8B Active Directory Agent on an RTX 3090</title><link href="https://shehzade.github.io/2026/07/15/redagent-local-ad-agent/" rel="alternate" type="text/html" title="Building a Local 8B Active Directory Agent on an RTX 3090" /><published>2026-07-15T00:00:00+02:00</published><updated>2026-07-15T00:00:00+02:00</updated><id>https://shehzade.github.io/2026/07/15/redagent-local-ad-agent</id><content type="html" xml:base="https://shehzade.github.io/2026/07/15/redagent-local-ad-agent/"><![CDATA[<div class="bio-card al-ticks" style="margin-bottom: 28px;">
  <div class="label label-acid" style="margin-bottom: 8px;">// OVERVIEW</div>
  <p style="margin-bottom: 0;">
    Most autonomous red teaming research assumes access to frontier cloud APIs or multi-node H100 clusters. As an operator running experiments on my own time without a datacenter compute budget, I wanted to see how far I could push a strictly local model on a single consumer GPU (a 24 GB RTX 3090). Here is how I took <strong>Llama-3-8B</strong>, removed false-positive safety refusals via activation projection, trained it on 1,250 synthetic Active Directory trajectories using Unsloth, and tested where an 8B model succeeds and where it hits its architectural ceiling.
  </p>
</div>

<h2 id="the-problem-and-why-an-8b-model">The Problem (and Why an 8B Model?)</h2>

<p>During my work running engagements at Mandiant, I spent a lot of time working through sprawling, heavily segmented Active Directory environments. In a real enterprise network, getting from an initial workstation foothold to tier-zero assets is rarely a straight line. You are dealing with complex forest trusts, strict firewall chokepoints, tiered administration boundaries, ACL and GPO abuse chains, delegation primitives, and misconfigurations spread across thousands of hosts. Finding a viable path requires real graph reasoning, where you test a lead, hit a network block, backtrack, and pivot through an unexpected intermediate system.</p>

<p>Startups have raised hundreds of millions of dollars trying to automate this kind of multi-hop attack path validation. I wanted to see what it actually takes under the hood to build an autonomous agent that can do this locally.</p>

<p>If you look at the current AI landscape, the first question that comes up is why anyone would use an 8B parameter model (<code class="language-plaintext highlighter-rouge">Llama-3-8B</code>) instead of a 70B model or a frontier API. For me, it came down to hardware reality and engagement OPSEC. As a consultant running these experiments independently on my home desktop during personal hours, I do not have access to an H100 cluster or a massive cloud compute budget. Everything from activation extraction and hyperparameter search to native 16-bit (<code class="language-plaintext highlighter-rouge">bfloat16</code>) LoRA fine-tuning had to fit inside the <strong>24 GB VRAM budget of a single consumer RTX 3090</strong>. At 16-bit precision, 8B parameters is the practical limit of what you can train and iterate on quickly on one consumer card. Beyond that, on real client assessments you cannot pipe sensitive Active Directory data or password hashes out to third-party cloud APIs anyway, so any model you actually bring onto an engagement has to be small enough to run on local hardware.</p>

<p>When you drop a stock <code class="language-plaintext highlighter-rouge">Llama-3-8B</code> model into an agent loop (<code class="language-plaintext highlighter-rouge">Reason -&gt; Act -&gt; Observe</code>), it fails right away. First, the default safety filters block the model whenever a prompt involves security validation or lateral movement tasks. Second, even after you remove those blocks, an 8B model does not know how to plan across a network topology. When it runs into a firewalled server or a dead end, it does not know how to backtrack and try another route, so it just repeats the same failed command in a loop.</p>

<p>To fix both issues, I broke the project into two stages. First, I adjusted the model weights so it stopped refusing routine security tasks. Second, I scoped a local simulator around three representative AD attack primitives and fine-tuned the model on 1,250 multi-hop trajectories so it could learn how to plan and backtrack.</p>

<hr />

<h2 id="step-1-stopping-false-positive-refusals">Step 1: Stopping False-Positive Refusals</h2>

<p>Early “uncensored” models were usually trained on giant datasets of unfiltered text, which tended to make the model worse at following instructions and outputting clean JSON. A cleaner approach from recent representation research (<a href="https://arxiv.org/abs/2406.11717">Arditi et al., 2024</a>) shows that refusal behavior in instruction-tuned models is mostly controlled by a single direction in the model’s activation space. When a prompt mentions security testing, the internal activations point along that direction and trigger a refusal.</p>

<p>By comparing the model’s internal activations on security prompts against normal prompts, you can isolate that refusal direction <code class="language-plaintext highlighter-rouge">v</code> as a unit vector and subtract it out of the weight matrices:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>v  = (μ_security - μ_normal) / ||μ_security - μ_normal||
W' = W - α(Wv)v^T
</code></pre></div></div>

<p>Because that change is just the outer product of two vectors, it is a Rank-1 matrix update. That means you can save the modification as a lightweight LoRA adapter instead of saving a whole new 16 GB copy of the model.</p>

<p>Instead of manually guessing which transformer layers to edit, I used the <strong>Heretic</strong> toolkit to run an automated search (using a Tree-structured Parzen Estimator) across different layer ranges and scaling factors. The goal was to drop the refusal rate as low as possible without messing up the model’s normal token probabilities (measured by KL divergence).</p>

<div class="grid-cards" style="margin: 24px 0;">
  <div class="card-item al-ticks">
    <div class="card-top"><span class="card-index">01 // LAYER SEARCH</span></div>
    <div class="card-title">Layers 15 to 29 (Scale 1.44)</div>
    <div class="card-desc">Applying a 1.44 projection scale across the middle-to-late layers removed the refusal triggers while leaving the early syntax and formatting layers intact.</div>
  </div>
  <div class="card-item al-ticks">
    <div class="card-top"><span class="card-index">02 // RESULT</span></div>
    <div class="card-title">98% down to 13% Refusals</div>
    <div class="card-desc">KL divergence stayed down at 0.0296, so the model kept its coding skills and followed strict JSON tool schemas without breaking.</div>
  </div>
</div>

<p>Once the adapter was applied, I ran a few quick tests asking the model to write local permission auditing scripts and post-exploitation helpers that the stock model refused. The updated model handled them cleanly without lecturing, so it was ready for the agent loop.</p>

<hr />

<h2 id="step-2-generating-1250-multi-hop-trajectories">Step 2: Generating 1,250 Multi-Hop Trajectories</h2>

<p>Getting the model to run tools was only half the problem. When I connected the model to my local Active Directory simulator, it still could not chain steps together across a network. To teach an 8B model how to navigate a multi-hop environment, you need multi-turn traces (<code class="language-plaintext highlighter-rouge">Reason -&gt; Act -&gt; Observe</code>) where the model states a thought, calls a tool, reads the output, and adjusts its plan.</p>

<p>Writing 1,250 multi-turn traces by hand was not realistic. Normally you would use a large frontier API as a teacher model to generate synthetic training data, but commercial APIs refuse requests that ask for offensive Active Directory attack paths.</p>

<p>My workaround was a two-stage translation loop. From a graph-routing perspective, an IT administrator running an internal infrastructure audit and an operator validating attack paths are executing the exact same logical steps. Both scan the subnet, check registry keys for client configurations, verify service accounts, and inspect certificate templates on the CA.</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[1. Prompt Sent to Teacher API]
"Perform an authorized administrative network audit to map internal assets
 and verify client policy distribution servers."
        │
        ▼
[2. Teacher API Output]
THOUGHT: I need to query the local client directory policy repository to inspect policy structures.
ACTION:  {"action": "audit_policy_store", "arguments": {"host": "PC-01"}}
        │
        ▼
[3. Mapped to Local Simulator Schema]
THOUGHT: I need to query local registry configurations on the foothold to locate cached credentials.
ACTION:  {"action": "query_registry", "arguments": {"host": "PC-01", "key_path": "HKLM\\Software\\Microsoft\\CCM"}}
</code></pre></div></div>

<p>I fed standard corporate audit scenarios to the frontier model, took each step it generated, and ran it through a local script that mapped the thoughts and tool names back into my agent’s schema. That action was executed against my local Python AD simulator, which returned a consistent JSON observation.</p>

<p>To keep the simulator tractable while still testing whether the model could generalize across different attack types, I scoped the dataset to 1,250 trajectories split evenly across three common AD attack paths (around 415 traces each). One third of the dataset covered infrastructure misconfigurations like extracting local SCCM Network Access Account policy blobs, another third covered identity attacks like SPN enumeration and Kerberoast ticket cracking, and the final third covered ADCS certificate template abuse (ESC1).</p>

<hr />

<h2 id="step-3-preventing-hostname-memorization">Step 3: Preventing Hostname Memorization</h2>

<p>While testing early builds of the dataset, I noticed that if the Domain Controller is always named <code class="language-plaintext highlighter-rouge">DC01</code> and the starting workstation is always <code class="language-plaintext highlighter-rouge">PC01</code>, an 8B model takes a shortcut. Instead of reading the JSON output from <code class="language-plaintext highlighter-rouge">network_scan</code> to see what hosts actually exist on the subnet, the model simply memorizes the string <code class="language-plaintext highlighter-rouge">"DC01"</code> during training and hardcodes it into its tool calls.</p>

<p>At the same time, if you randomize hostnames into random gibberish like <code class="language-plaintext highlighter-rouge">srv_9x8q2z</code>, the tokenizer splits the hostname into a bunch of tiny sub-word tokens, which bloats the context window and hurts attention.</p>

<p>To fix both problems, I added bounded randomization to the simulator. Every time a new episode starts, the environment generates realistic enterprise naming conventions with randomized two-digit suffixes:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">self</span><span class="p">.</span><span class="n">suffix</span>    <span class="o">=</span> <span class="sa">f</span><span class="sh">"</span><span class="s">_</span><span class="si">{</span><span class="n">random</span><span class="p">.</span><span class="nf">randint</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">99</span><span class="p">)</span><span class="si">}</span><span class="sh">"</span>
<span class="n">self</span><span class="p">.</span><span class="n">domain</span>    <span class="o">=</span> <span class="sa">f</span><span class="sh">"</span><span class="s">sevenkingdoms</span><span class="si">{</span><span class="n">self</span><span class="p">.</span><span class="n">suffix</span><span class="si">}</span><span class="s">.local</span><span class="sh">"</span>
<span class="n">self</span><span class="p">.</span><span class="n">dc_name</span>   <span class="o">=</span> <span class="sa">f</span><span class="sh">"</span><span class="s">PRIMARY-DC-</span><span class="si">{</span><span class="n">random</span><span class="p">.</span><span class="nf">randint</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">99</span><span class="p">)</span><span class="si">}</span><span class="sh">"</span>
<span class="n">self</span><span class="p">.</span><span class="n">site_mgr</span>  <span class="o">=</span> <span class="sa">f</span><span class="sh">"</span><span class="s">SITE-MGR-</span><span class="si">{</span><span class="n">random</span><span class="p">.</span><span class="nf">randint</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">99</span><span class="p">)</span><span class="si">}</span><span class="sh">"</span>
</code></pre></div></div>

<p>Because <code class="language-plaintext highlighter-rouge">PRIMARY-DC-47</code> still looks like a normal corporate server name, the tokenizer handles it cleanly. Because the numbers change on every run, the model is forced to actually parse the scan output and pull the right hostname from the conversation history before calling its next tool.</p>

<hr />

<h2 id="step-4-fine-tuning-on-an-rtx-3090-with-unsloth">Step 4: Fine-Tuning on an RTX 3090 with Unsloth</h2>

<p>With the 1,250 trajectories ready, I ran the Supervised Fine-Tuning (SFT) job in WSL2 Linux using <strong>Unsloth</strong>. Unsloth uses custom Triton kernels for attention and RMSNorm backpropagation, which reduced memory usage enough for me to train in native 16-bit <code class="language-plaintext highlighter-rouge">bfloat16</code> inside my 24 GB VRAM budget instead of dropping down to 4-bit QLoRA.</p>

<p>I trained a rank-16 LoRA adapter (<code class="language-plaintext highlighter-rouge">r = 16</code>, <code class="language-plaintext highlighter-rouge">lora_alpha = 32</code>) across all attention and MLP layers (<code class="language-plaintext highlighter-rouge">q_proj</code>, <code class="language-plaintext highlighter-rouge">k_proj</code>, <code class="language-plaintext highlighter-rouge">v_proj</code>, <code class="language-plaintext highlighter-rouge">o_proj</code>, <code class="language-plaintext highlighter-rouge">gate_proj</code>, <code class="language-plaintext highlighter-rouge">up_proj</code>, <code class="language-plaintext highlighter-rouge">down_proj</code>). To keep the gradients stable without running out of memory, I set the batch size to 2 with 8 gradient accumulation steps (for an effective batch size of 16) and used the 8-bit AdamW optimizer (<code class="language-plaintext highlighter-rouge">adamw_8bit</code>) to save another 2 GB of VRAM.</p>

<p>The training job ran for 500 steps (about 7 epochs). Training loss dropped from <strong>2.059 down to 0.066</strong>, and I merged the resulting LoRA adapter back into the weights to produce the final <code class="language-plaintext highlighter-rouge">RedAgent</code> model.</p>

<hr />

<h2 id="step-5-benchmarking-across-three-ad-topologies">Step 5: Benchmarking Across Three AD Topologies</h2>

<p>To test whether the fine-tuning actually helped the model plan, I ran the stock model, the refusal-stripped model, and <code class="language-plaintext highlighter-rouge">RedAgent</code> side by side against three simulated Active Directory topologies of increasing complexity.</p>

<div class="grid-cards" style="margin: 24px 0;">
  <div class="card-item al-ticks">
    <div class="card-top"><span class="card-index">TIER 01 // 5 STEPS</span></div>
    <div class="card-title">Foothold Sprint</div>
    <div class="card-desc">A direct 5-step path from a workstation to the DC using local SCCM policy credentials.</div>
  </div>
  <div class="card-item al-ticks">
    <div class="card-top"><span class="card-index">TIER 02 // 10 STEPS</span></div>
    <div class="card-title">Firewalled Chokepoint</div>
    <div class="card-desc">Direct SMB access from the workstation to the DC is blocked by a firewall. The agent has to hit the block, backtrack to an intermediate Site Manager server, extract admin credentials there, and then pivot to the DC.</div>
  </div>
  <div class="card-item al-ticks">
    <div class="card-top"><span class="card-index">TIER 03 // 14 STEPS</span></div>
    <div class="card-title">The Labyrinth (ADCS)</div>
    <div class="card-desc">A 14-step chain requiring the agent to pivot through a Certificate Authority (CA01), enumerate vulnerable templates, request a certificate via ESC1, authenticate to a Database server, and finally reach the DC.</div>
  </div>
</div>

<div class="bio-card al-ticks" style="padding: 0; overflow-x: auto; margin: 24px 0;">
  <table style="width: 100%; border-collapse: collapse; font-family: var(--mono); font-size: 12.5px;">
    <thead>
      <tr style="border-bottom: 1px solid var(--rule); background: var(--void); color: var(--ash); text-align: left;">
        <th style="padding: 12px 16px;">MODEL CANDIDATE</th>
        <th style="padding: 12px 16px;">TIER 1 (5 STEPS)</th>
        <th style="padding: 12px 16px;">TIER 2 (10 STEPS)</th>
        <th style="padding: 12px 16px;">TIER 3 (14 STEPS)</th>
      </tr>
    </thead>
    <tbody>
      <tr style="border-bottom: 1px solid var(--rule-subtle);">
        <td style="padding: 12px 16px; color: var(--mark); font-weight: 600;">Stock Llama-3-8B</td>
        <td style="padding: 12px 16px;">PASS (8 steps)</td>
        <td style="padding: 12px 16px; color: var(--ash);">FAIL (Got Stuck)</td>
        <td style="padding: 12px 16px; color: var(--ash);">FAIL (Got Stuck)</td>
      </tr>
      <tr style="border-bottom: 1px solid var(--rule-subtle);">
        <td style="padding: 12px 16px; color: var(--mark); font-weight: 600;">Abliterated Llama-3-8B</td>
        <td style="padding: 12px 16px;">PASS (8 steps)</td>
        <td style="padding: 12px 16px; color: var(--ash);">FAIL (Got Stuck)</td>
        <td style="padding: 12px 16px; color: var(--ash);">FAIL (Got Stuck)</td>
      </tr>
      <tr>
        <td style="padding: 12px 16px; color: var(--acid); font-weight: 700;">RedAgent-8B (Ours)</td>
        <td style="padding: 12px 16px;">PASS (11 steps)</td>
        <td style="padding: 12px 16px; color: var(--acid); font-weight: 700;">PASS (10 steps)</td>
        <td style="padding: 12px 16px; color: var(--ash);">FAIL (Got Stuck)</td>
      </tr>
    </tbody>
  </table>
</div>

<h3 id="what-happened-on-each-tier">What Happened on Each Tier</h3>

<p>All three models passed <strong>Tier 1</strong> because it is a straight line with no dead ends. As long as the tool descriptions are in the system prompt, even an untrained model can step through 5 sequential actions.</p>

<p><strong>Tier 2 (the firewalled chokepoint)</strong> is where the trajectory fine-tuning really showed its value. When the stock and refusal-stripped models tried to pivot to the Domain Controller at Step 5 and got back <code class="language-plaintext highlighter-rouge">"Access Denied by firewall"</code>, neither of them knew how to recover. The refusal-stripped model just kept running the exact same failed <code class="language-plaintext highlighter-rouge">pivot</code> command against the blocked DC, or started guessing tools at random until the context window filled up with failed attempts (on the rare runs where it stumbled onto the right server by pure luck, it took over 22 steps).</p>

<p><code class="language-plaintext highlighter-rouge">RedAgent</code>, on the other hand, solved Tier 2 in the exact 10 optimal steps. As soon as it saw the firewall rejection on the DC, its next thought noted the block, backtracked to <code class="language-plaintext highlighter-rouge">SITE-MGR-xx</code>, pulled the credentials from the site server, and completed the path to the DC.</p>

<p><strong>Tier 3 (the 14-step ADCS path)</strong> broke all three models, including <code class="language-plaintext highlighter-rouge">RedAgent</code>. Looking at the execution logs, <code class="language-plaintext highlighter-rouge">RedAgent</code> got through the initial SCCM steps, saw the DC was blocked, and correctly decided to go after ADCS certificate templates next. However, instead of calling <code class="language-plaintext highlighter-rouge">pivot</code> to move onto <code class="language-plaintext highlighter-rouge">CA01</code> first, it kept trying to run <code class="language-plaintext highlighter-rouge">query_ca_templates</code> directly from the starting workstation until it hit the step limit.</p>

<p>When I looked through the simulator code and the agent traces, it became clear why that happened. In real Active Directory environments (using tools like Certipy or Certify), you query ADCS certificate templates remotely over RPC/LDAP right from your initial workstation without ever needing an interactive session on the CA server first. My simulator state machine, however, was written to require <code class="language-plaintext highlighter-rouge">current_host == ca_name</code> before <code class="language-plaintext highlighter-rouge">query_ca_templates</code> would succeed. Once the conversation history stretched past 10 turns, the 8B model fell back on its pre-trained AD knowledge instead of following the simulator’s stricter host rule.</p>

<p>That problem was compounded by how the simulator handled errors. In Tier 2, when the DC pivot failed, the simulator returned a clear error message (<code class="language-plaintext highlighter-rouge">"Access Denied by firewall"</code>). In Tier 3, when <code class="language-plaintext highlighter-rouge">query_ca_templates</code> was called from the wrong host, my simulator returned a bare <code class="language-plaintext highlighter-rouge">{"status": "error"}</code> with no message explaining why. Without an error message telling it that the command had to be run from <code class="language-plaintext highlighter-rouge">CA01</code>, the 8B model kept retrying the call until it ran out of steps.</p>

<hr />

<h2 id="takeaways--next-steps">Takeaways &amp; Next Steps</h2>

<p>Building this on a single RTX 3090 made two things obvious. First, stripping refusal vectors out of local weights is fast and keeps the model’s formatting intact, but it does not give the model any planning skill on its own. Second, small 8B models can learn to backtrack around network blocks if your synthetic training set includes failure-and-recovery paths, provided your tool wrappers return clear error messages when a command fails.</p>

<p>The biggest limitation of this experiment is that it ran against a lightweight Python state machine. My next step is to connect this training and evaluation loop to a full virtualized Active Directory lab (such as GOAD) with real tool outputs from Impacket, NetExec, and Certipy, and inject more multi-branch backtracking into the training trajectories so the model can handle longer chains without losing track of host state.</p>]]></content><author><name></name></author><category term="red-teaming" /><category term="ai-agents" /><category term="active-directory" /><category term="local-llm" /><summary type="html"><![CDATA[// OVERVIEW Most autonomous red teaming research assumes access to frontier cloud APIs or multi-node H100 clusters. As an operator running experiments on my own time without a datacenter compute budget, I wanted to see how far I could push a strictly local model on a single consumer GPU (a 24 GB RTX 3090). Here is how I took Llama-3-8B, removed false-positive safety refusals via activation projection, trained it on 1,250 synthetic Active Directory trajectories using Unsloth, and tested where an 8B model succeeds and where it hits its architectural ceiling.]]></summary></entry><entry><title type="html">How I Passed the CRTO Exam in Two Weeks</title><link href="https://shehzade.github.io/2023/06/26/how-i-passed-the-crto-exam-in-two-weeks/" rel="alternate" type="text/html" title="How I Passed the CRTO Exam in Two Weeks" /><published>2023-06-26T00:00:00+02:00</published><updated>2023-06-26T00:00:00+02:00</updated><id>https://shehzade.github.io/2023/06/26/how-i-passed-the-crto-exam-in-two-weeks</id><content type="html" xml:base="https://shehzade.github.io/2023/06/26/how-i-passed-the-crto-exam-in-two-weeks/"><![CDATA[<h1 id="what-is-crto">What is CRTO?</h1>

<p>The <a href="https://training.zeropointsecurity.co.uk/courses/red-team-ops">Certified Red Team Operator (CRTO)</a> is a fantastic certification for anyone looking to improve their internal netpen experience with some adversary simulation tools and techniques. The course is fairly self-contained and teaches all the exploitation and abuse methods needed to pass the exam. In addition to the course, you can also get subscription access to a well-built lab environment which gives you the opportunity to try out all the attacks taught in the course on live targets.</p>

<h2 id="why-you-should-get-it">Why You Should Get It</h2>

<p>A unique feature of the RTO labware is that a licensed copy of <a href="https://www.cobaltstrike.com/">Cobalt Strike</a> plus some <a href="https://download.cobaltstrike.com/scripts">awesome kits</a> are provided to tinker and play around with. This really adds a dimension of realism since Cobalt Strike is usually only available to enterprises with deep pockets and those who know of a certain, le-funny site.</p>

<p>Furthermore, RTO ups the difficulty by just a bit from the usual <a href="https://www.hackthebox.com/">HackTheBox</a>/<a href="https://tryhackme.com/">TryHackMe</a> machines since the exam machines all have AV turned on which forces students to be cognizant of disk, memory, and behavior detections common on most Windows machines via Defender/AMSI. Students first learn all the tooling and techniques on machines with AV disabled, then, as practice for the exam, RTO encourages students to enable AV on the entire lab and re-practice everything to simulate the exam.</p>

<p>My biggest praise, however, for the RTO course is that there is an active community of students who are always available to help and answer questions about the course, lab, or exam. In fact, there was even a time when <a href="https://twitter.com/_RastaMouse">RastaMouse</a> got on Discord to answer my questions on the weekend, and added a whole Ghidra module to the course because I was having trouble finding the byte sequences in my beacon payloads which were being flagged by AV.</p>

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

<p>If you follow me on LinkedIn, you might have heard that I recently started my second summer internship in offensive security with <a href="https://www.ibm.com/services/offensive-security">IBM’s X-Force Red</a> as a Penetration Testing intern. In my cohort was <a href="https://www.linkedin.com/in/susdt">Dylan Tran</a>, or as we knew him, Sloppy Gerald. Dylan is a malware developer, avid red teamer, and chicken broth enthusiast who is highly accomplished in the <a href="https://cp.tc/">CPTC</a> and <a href="https://www.nationalccdc.org/">CCDC</a> competitions, even being named champion a couple of times (which is seriously no small feat). He encouraged me to try out the CRTO near the time when we completed a riveting netpen bootcamp taught by legends <a href="https://www.linkedin.com/in/james-rogers-network-security/">Shikata (James Rogers)</a> and <a href="https://www.linkedin.com/in/sunggwan-choi">Choi</a>, which covered Active Directory attacks (most of which I was already familiar with through previous HTB/THM experience) and Certificate Services (which was completely new to me).</p>

<p>The bootcamp left me captivated and hungry for more advanced AD exploitation. When I learned that RTO taught certificate services attacks, delegation attacks, malware evasion, and so much more, I signed up immediately. Over the next two weeks, I was completely occupied by the training, which I juggled with internship stuff like bootcamps, projects, and shadows.</p>

<p>Despite not eating, drinking, or sleeping on some days, I somehow managed to take notes, read through the entire courseware, and complete all the attacks on the lab in around 12-14 days, which was half the time I had originally planned to take. When I finished the course, my exam was about 15 days away, and thus, the excruciating wait began consisting of material review and anticipation, but mainly anticipation. Funnily enough, one day at work, Dylan strolled over to my desk and joked, “you should take it right now lol.” I looked at him like he was crazy and said, “what the hell, exam rescheduled!”</p>

<h2 id="the-exam">The Exam</h2>

<p>That day at 6 pm, my exam began. I started by setting up my Cobalt Strike team server as a service so I wasted as few of the 48 hours provided to me on setup (which ended up being too much time anyway). Once everything was configured, I started my listeners and conducted the necessary modifications for my payloads not to be caught by Defender/AMSI.</p>

<p>After that, I opened an RDP session on the starting workstation (the exam is an assumed breach, so you get access to one low-priv machine) and executed my beacon. I did have to do some initial troubleshooting and privilege escalation, but soon enough, I was on my way. Initially, I thought I would be spending the whole night on the exam, and it was a Friday, so I thought an all-nighter wasn’t too big of an issue. But within 3 hours, I compromised the first domain and got 3 of the 6 flags needed to pass the exam.</p>

<p>At this point, it was 9 pm, and the office was getting kind of sketchy, so I hurried home, broke my fast, prayed the sunset prayer, downed a root beer, and got right back to it. Within the next 3 hours, I compromised the 2nd domain and submitted all 6 flags, which gave me enough to pass the exam and be granted the coveted <a href="https://api.eu.badgr.io/public/assertions/MxcsuVPIRFS_MTC-3AOEJQ?identity__email=abdullahansari1618%40outlook.com">CRTO badge</a>.</p>

<p>Check out the beacon chain I had by the end! It was an insane 9-machine P2P beacon chain all relying on a single egress beacon. Needless to say, I was in a weird state being full of adrenaline due to my “house of cards,” but also annoyed since callbacks were snail-paced. I ended the day when I passed.</p>

<p><img src="/assets/img/posts/beacon_chain.png" width="100%" height="100%" /></p>

<h2 id="aftermath">Aftermath</h2>

<p>The next day, I attempted to get the 2 remaining flags but accidentally fell asleep without stopping the exam environment. When I woke up, I discovered that I had used up all my remaining time (lol, bummer). But a win is a win, and I took it gladly.</p>

<p>In my humble opinion, the exam was definitely challenging in that it required some savvy thinking and problem-solving, but it was certainly not difficult to the point of stress and anxiety (clears throat, OSCP). During my preparation, Dylan kept telling me to relax since I was always worried that the AV evasion would be too hard and I would fail because of it. But the exam really was doable and frankly quite enjoyable.</p>

<p>Bottom line, if you pay attention to the course material and are able to replicate all the attacks in the lab environment, you will ace the exam no problem. So if you’re on the edge, don’t sweat it and take a shot at this cert.</p>

<h1 id="future-plans">Future Plans</h1>

<p>Overall, I felt that I needed a win in my security career since I got my <a href="https://shehzade.io/cve">first CVEs</a> from <a href="https://labs.reversec.com/posts/2023/03/megafeis-palm-exploiting-vulnerabilities-to-open-bluetooth-smartlocks">last summer’s research</a> at WithSecure, and CRTO was the perfect confidence booster to get me all fired up for offensive security again.</p>

<p>My post-CRTO plan was to immediately jump on CRTO II, which has been highly regarded as the perfect sequel into advanced red teaming (infrastructure stuff) and malware development (EDR evasion). However, we are currently in the middle of doing our internship research projects, so I don’t think I’ll be able to power through CRTO II with speed and dedication like I did with CRTO I since the second iteration of the course, as I’ve heard, is definitely <strong>NOT</strong> self-contained and requires extensive research and self-learning from external resources to be successful on the exam.</p>

<p>I think I’ll hop off the certification train for now and try to produce the most badass project I can for XFR and hope they like it enough to call me back with a full-time offer at the end of the internship!</p>]]></content><author><name></name></author><category term="certification-exam" /><summary type="html"><![CDATA[What is CRTO?]]></summary></entry><entry><title type="html">Insecure Authorization Scheme for API Requests in DBD+ Mobile Companion Application for Megafeis Smart Locks</title><link href="https://shehzade.github.io/2023/03/03/insecure-authorization-scheme-for-api-requests-in-dbd+-mobile-companion-application-for-megafeis-smart-locks/" rel="alternate" type="text/html" title="Insecure Authorization Scheme for API Requests in DBD+ Mobile Companion Application for Megafeis Smart Locks" /><published>2023-03-03T00:00:00+01:00</published><updated>2023-03-03T00:00:00+01:00</updated><id>https://shehzade.github.io/2023/03/03/insecure-authorization-scheme-for-api-requests-in-dbd+-mobile-companion-application-for-megafeis-smart-locks</id><content type="html" xml:base="https://shehzade.github.io/2023/03/03/insecure-authorization-scheme-for-api-requests-in-dbd+-mobile-companion-application-for-megafeis-smart-locks/"><![CDATA[]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Insecure Password Policy &amp;amp; Lack of Rate Limiting on Megafeis Smart Lock API Server</title><link href="https://shehzade.github.io/2023/03/03/insecure-password-policy-and-lack-of-rate-limiting-on-megafeis-smart-lock-api-server/" rel="alternate" type="text/html" title="Insecure Password Policy &amp;amp; Lack of Rate Limiting on Megafeis Smart Lock API Server" /><published>2023-03-03T00:00:00+01:00</published><updated>2023-03-03T00:00:00+01:00</updated><id>https://shehzade.github.io/2023/03/03/insecure-password-policy-and-lack-of-rate-limiting-on-megafeis-smart-lock-api-server</id><content type="html" xml:base="https://shehzade.github.io/2023/03/03/insecure-password-policy-and-lack-of-rate-limiting-on-megafeis-smart-lock-api-server/"><![CDATA[]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Insecure Password Reset Code Expiry Mechanism for Megafeis Smart Locks</title><link href="https://shehzade.github.io/2023/03/03/insecure-password-reset-code-expiry-mechanism-for-megafeis-smart-locks/" rel="alternate" type="text/html" title="Insecure Password Reset Code Expiry Mechanism for Megafeis Smart Locks" /><published>2023-03-03T00:00:00+01:00</published><updated>2023-03-03T00:00:00+01:00</updated><id>https://shehzade.github.io/2023/03/03/insecure-password-reset-code-expiry-mechanism-for-megafeis-smart-locks</id><content type="html" xml:base="https://shehzade.github.io/2023/03/03/insecure-password-reset-code-expiry-mechanism-for-megafeis-smart-locks/"><![CDATA[]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Research Bulletin - Smart Padlocks</title><link href="https://shehzade.github.io/2023/03/03/research-bulletin-smart-padlocks/" rel="alternate" type="text/html" title="Research Bulletin - Smart Padlocks" /><published>2023-03-03T00:00:00+01:00</published><updated>2023-03-03T00:00:00+01:00</updated><id>https://shehzade.github.io/2023/03/03/research-bulletin-smart-padlocks</id><content type="html" xml:base="https://shehzade.github.io/2023/03/03/research-bulletin-smart-padlocks/"><![CDATA[]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Username Disclosure Vulnerability in DBD+ Application Used by Megafeis Smart Locks</title><link href="https://shehzade.github.io/2023/03/03/username-disclosure-vulnerability-in-dbd+-application-used-by-megafeis-smart-locks/" rel="alternate" type="text/html" title="Username Disclosure Vulnerability in DBD+ Application Used by Megafeis Smart Locks" /><published>2023-03-03T00:00:00+01:00</published><updated>2023-03-03T00:00:00+01:00</updated><id>https://shehzade.github.io/2023/03/03/username-disclosure-vulnerability-in-dbd+-application-used-by-megafeis-smart-locks</id><content type="html" xml:base="https://shehzade.github.io/2023/03/03/username-disclosure-vulnerability-in-dbd+-application-used-by-megafeis-smart-locks/"><![CDATA[]]></content><author><name></name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Solving Complex Mazes In Python Using the BFS Algorithm</title><link href="https://shehzade.github.io/2021/11/25/solving-complex-mazes-in-python-using-the-bfs-algorithm/" rel="alternate" type="text/html" title="Solving Complex Mazes In Python Using the BFS Algorithm" /><published>2021-11-25T00:00:00+01:00</published><updated>2021-11-25T00:00:00+01:00</updated><id>https://shehzade.github.io/2021/11/25/solving-complex-mazes-in-python-using-the-bfs-algorithm</id><content type="html" xml:base="https://shehzade.github.io/2021/11/25/solving-complex-mazes-in-python-using-the-bfs-algorithm/"><![CDATA[<h1 id="the-minefield">The Minefield</h1>

<p>The Mine Field was a challenge meant to assess a penetration tester’s scripting skills by presenting a 22x22 minefield and asking the tester to rapidly find the path from the starting point to the finishing point without hitting the bombs. Furthermore, in addition to the minefield expiring every seven seconds, the answer needed to be formatted as a sequence of directions such as D for down and L for left etc… while also being less than 500 characters.</p>

<p><img src="/assets/img/posts/Aspose.Words.e9d112e2-f037-4889-9814-54552f2bdf63.000.png" width="50%" height="50%" /></p>

<p>As a quick summary, the way I solved this was by first scraping the webpage using Python. Then splitting the source code and formatting the minefield (which was inside an HTML table) as a two-dimensional array. After I had a navigable 2D array, I used the Breadth-First-Search (BFS) algorithm to find the path from the starting point to the finishing point and print what steps it took to get there. A more technical and in-depth writeup will follow below.</p>

<h2 id="step-1--transform-the-minefield-into-a-python-readable-format">Step 1 – Transform the Minefield into a Python-Readable Format</h2>

<p>The first part of this challenge was understanding how to get the minefield from the webpage into Python and making sure that at any point in time, the minefield displayed on the webpage and the minefield that Python was working to parse and solve were identical. Thankfully, the lab creators gave us a heads up about the minefield being connected to the session cookie of the browser.</p>

<p>I began by scraping the entire web page in its raw HTML form by importing the requests library and calling the <code class="language-plaintext highlighter-rouge">get</code> function to grab the web page’s source. I also passed my session cookies along with the URL so that I could retrieve the same minefield being shown in the browser. The code I used to scrape the web page is shown below.</p>

<p><img src="/assets/img/posts/Aspose.Words.e9d112e2-f037-4889-9814-54552f2bdf63.003.png" width="50%" height="50%" /></p>

<p>It’s also important to note that the way I retrieved my session cookie was by opening my browser, right clicking, selecting the “Inspect” button, clicking on the “Application” tab, navigating to the “Cookies” section, and retrieving the <code class="language-plaintext highlighter-rouge">.AspNetCore.Session</code> cookie value.</p>

<p><img src="/assets/img/posts/Aspose.Words.e9d112e2-f037-4889-9814-54552f2bdf63.004.jpeg" width="50%" height="50%" /></p>

<p>Once I had a raw web request stored inside the <code class="language-plaintext highlighter-rouge">raw_html</code> variable, I wanted to parse the page’s source code into a sortable and searchable format while throwing out parts of the request I wouldn’t need (like the headers). I performed this by passing the web page’s text into a library called BeautifulSoup which parses HTML code and makes it easier to work with. This was done by importing the <code class="language-plaintext highlighter-rouge">bs4</code> package and passing the <code class="language-plaintext highlighter-rouge">raw_html</code> variable to BeautifulSoup as shown and storing the output in the <code class="language-plaintext highlighter-rouge">soup</code> variable.</p>

<p><img src="/assets/img/posts/Aspose.Words.e9d112e2-f037-4889-9814-54552f2bdf63.005.png" width="50%" height="50%" /></p>

<p>The next step was to figure out exactly which part of the web page contained the minefield I wanted to bring in. This involved viewing the web site’s source code and learning that the minefield was stored inside an HTML table. Each row of the minefield was enclosed in <code class="language-plaintext highlighter-rouge">&lt;tr&gt;</code> tags and each cell’s status (clear or rigged) was listed as an attribute of the further nested <code class="language-plaintext highlighter-rouge">&lt;td&gt;</code> tags.</p>

<p><img src="/assets/img/posts/Aspose.Words.e9d112e2-f037-4889-9814-54552f2bdf63.006.png" width="50%" height="50%" /></p>

<p>To filter out all the extra code of the website, I used the <code class="language-plaintext highlighter-rouge">find</code> function of the soup object created in the last code snippet to extract only the HTML that was within the <code class="language-plaintext highlighter-rouge">&lt;table&gt;</code> tags. This was done as shown.</p>

<p><img src="/assets/img/posts/Aspose.Words.e9d112e2-f037-4889-9814-54552f2bdf63.007.png" width="50%" height="50%" /></p>

<p>To refine this even further I wanted to divide this table into separate rows so that I could iterate over them and construct my two-dimensional array. I did this using some string manipulation with the <code class="language-plaintext highlighter-rouge">split</code> function which is available to every string object. I wrote the <code class="language-plaintext highlighter-rouge">split</code> function so that every time it comes across the <code class="language-plaintext highlighter-rouge">&lt;/tr&gt;</code> tag (which signifies the end of the row), it creates a divider.</p>

<p><img src="/assets/img/posts/Aspose.Words.e9d112e2-f037-4889-9814-54552f2bdf63.008.png" width="50%" height="50%" /></p>

<p>Now that I had everything in a digestible and clean format, it was time to build my 2D array. I initialized the maze variable as a global array and began the construction of a nested for-loop. The logic would be as follows. For every row in the minefield table, create an additional temporary array, split the row into individual cells (at the end of every <code class="language-plaintext highlighter-rouge">&lt;td&gt;</code> tag), then for every cell, check whether it had the keyword <code class="language-plaintext highlighter-rouge">full</code>, <code class="language-plaintext highlighter-rouge">empty</code>, <code class="language-plaintext highlighter-rouge">start</code>, or <code class="language-plaintext highlighter-rouge">end</code>. Based on the keyword, append to our temporary row, either 0, 1, or 2. Once iteration through every cell in a row is complete, and the length of our temporary array is greater than one, append the temporary array to our main maze array (making it an array of arrays or 2D). The code is shown here.</p>

<p><img src="/assets/img/posts/Aspose.Words.e9d112e2-f037-4889-9814-54552f2bdf63.009.jpeg" width="50%" height="50%" /></p>

<p>After coming this far, our output was looking pretty good. Execution of all the code discussed so far yielded the following results. When compared with the minefield displayed on the web page, everything was perfectly identical. Empty spaces were zeros, bombs were ones, and our goal was the number two.</p>

<p><img src="/assets/img/posts/Aspose.Words.e9d112e2-f037-4889-9814-54552f2bdf63.010.jpeg" width="50%" height="50%" /></p>

<h2 id="step-2--solve-the-minefield">Step 2 – Solve the Minefield</h2>

<p>Now that we had our minefield in a 2D array, it came time to pick a pathfinding algorithm which would be used to search for the goal given a starting point and print the path taken to get there while avoiding the bombs. The algorithm I selected is the Breadth-First-Search (BFS) algorithm. It is explained well by Simplilearn. They say, “BFS is used to search a tree or graph data structure for a node that meets a set of criteria. It begins at the root of the tree or graph and investigates all nodes at the current depth level before moving on to nodes at the next depth level.”</p>

<p>Breadth-First-Search uses a queue data structure to store the node and mark it as “visited” until it marks all the neighboring vertices directly related to it. The queue operates on the First-In-First-Out (FIFO) principle, so the node’s neighbors will be viewed in the order in which it inserts them in the queue, starting with the node that was inserted first. Below is a diagram for some additional clarity.</p>

<p><img src="/assets/img/posts/Aspose.Words.e9d112e2-f037-4889-9814-54552f2bdf63.011.jpeg" width="50%" height="50%" /></p>

<p>Implementing this in Python to work with our minefield was quite a challenge, nevertheless, existing research was quite helpful in guiding the exercise. The first part of implementing BFS was to establish the key variables it would use. This includes the following:</p>

<ul>
  <li>Creating a new maze and setting it to the one we retrieved from the website</li>
  <li>Establishing the minefield’s dimensions (rows x columns)</li>
  <li>Creating a double-ended queue (to hold the nodes we want to visit next)</li>
  <li>Adding our starting point to the queue (which will always be (0, 0))</li>
  <li>Defining possible directions that the algorithm could move in</li>
  <li>Assigning letters (L, R, U, D) to those directions by using a hash map</li>
  <li>Creating a blank Boolean array identical to the minefield to track visited locations</li>
  <li>Setting our starting point as visited (since we are already there)</li>
</ul>

<p>The code to declare and set these variables is shown below.</p>

<p><img src="/assets/img/posts/Aspose.Words.e9d112e2-f037-4889-9814-54552f2bdf63.012.png" width="50%" height="50%" /></p>

<p>Now that we have our variables ready, we can begin the processing of the minefield. This is done with a while-loop which will continue as long as there is something in our queue signifying that there are still coordinates left to explore. Each time the loop runs, we will pop out the next value from the front of the queue and look at all the moves we can make from that coordinate (up, down, left, right). We will send said move through a series of validity checks to determine if it’s out of bounds, if there is a bomb there, if we’ve already visited it, or if we’ve reached the goal. The logic can be understood better by reading the algorithm below.</p>

<p><img src="/assets/img/posts/Aspose.Words.e9d112e2-f037-4889-9814-54552f2bdf63.013.jpeg" width="50%" height="50%" /></p>

<p>Since there is a lot going on here, lets walk through it step by step. We start off with a while-loop which will continue to run as long as there are coordinates in the queue. Once the loop has determined that there is a coordinate in the queue, we will retrieve it, and check to make sure it is not the goal (which would make continuing the loop unnecessary). Once we know it’s not the coordinate we are looking for, we will send it to our for-loop. Our for-loop will try every move defined in our directions array which was declared earlier.</p>

<p>You might notice that the for-loop looks a bit odd. That is because we are not only looping through the moves in our directions array, but we are simultaneously keeping track of the index numbers of the moves we are trying so that we can look them up in our hash map and connect a given move to a letter (which we need for the answer format). We are using Python’s <code class="language-plaintext highlighter-rouge">enumerate</code> function to achieve this.</p>

<p>For every move the for-loop iterates through, it creates a new set of coordinates by adding the current coordinate to the coordinates of the relevant move declared in the directions array. This is performed in the <code class="language-plaintext highlighter-rouge">new_row</code> and <code class="language-plaintext highlighter-rouge">new_col</code> variables. Once a new coordinate is created, it is checked to determine whether it is out of bounds, if there is a bomb there, or if it has already been visited. If it gets caught in any of those checks, the move is abandoned and the next move is brought into the for-loop.</p>

<p>If the move manages to pass all the validity checks, the move along with its corresponding letter, is appended to the queue. The move’s coordinates are also marked as visited to prevent the loop from visiting places it has already explored or determined are dead ends. Once this runs for every single coordinate in the minefield, it will find the target and print all the directions and moves that were taken to reach it, giving a sequence of moves which we can submit as our answer. A demonstration is shown below.</p>

<p><img src="/assets/img/posts/Aspose.Words.e9d112e2-f037-4889-9814-54552f2bdf63.014.jpeg" width="50%" height="50%" /> <img src="/assets/img/posts/Aspose.Words.e9d112e2-f037-4889-9814-54552f2bdf63.015.png" width="50%" height="50%" /></p>

<p><img src="/assets/img/posts/Aspose.Words.e9d112e2-f037-4889-9814-54552f2bdf63.016.png" width="50%" height="50%" /></p>

<p>The full script can be found at my <a href="https://github.com/shehzade/mini-scripts/tree/master/coding_challenges/maze_solver">GitHub</a>.</p>]]></content><author><name></name></author><category term="coding-challenge" /><category term="scripting" /><category term="python" /><category term="algorithms" /><summary type="html"><![CDATA[The Minefield The Mine Field was a challenge meant to assess a penetration tester’s scripting skills by presenting a 22x22 minefield and asking the tester to rapidly find the path from the starting point to the finishing point without hitting the bombs. Furthermore, in addition to the minefield expiring every seven seconds, the answer needed to be formatted as a sequence of directions such as D for down and L for left etc… while also being less than 500 characters. As a quick summary, the way I solved this was by first scraping the webpage using Python. Then splitting the source code and formatting the minefield (which was inside an HTML table) as a two-dimensional array. After I had a navigable 2D array, I used the Breadth-First-Search (BFS) algorithm to find the path from the starting point to the finishing point and print what steps it took to get there. A more technical and in-depth writeup will follow below. Step 1 – Transform the Minefield into a Python-Readable Format The first part of this challenge was understanding how to get the minefield from the webpage into Python and making sure that at any point in time, the minefield displayed on the webpage and the minefield that Python was working to parse and solve were identical. Thankfully, the lab creators gave us a heads up about the minefield being connected to the session cookie of the browser. I began by scraping the entire web page in its raw HTML form by importing the requests library and calling the get function to grab the web page’s source. I also passed my session cookies along with the URL so that I could retrieve the same minefield being shown in the browser. The code I used to scrape the web page is shown below. It’s also important to note that the way I retrieved my session cookie was by opening my browser, right clicking, selecting the “Inspect” button, clicking on the “Application” tab, navigating to the “Cookies” section, and retrieving the .AspNetCore.Session cookie value. Once I had a raw web request stored inside the raw_html variable, I wanted to parse the page’s source code into a sortable and searchable format while throwing out parts of the request I wouldn’t need (like the headers). I performed this by passing the web page’s text into a library called BeautifulSoup which parses HTML code and makes it easier to work with. This was done by importing the bs4 package and passing the raw_html variable to BeautifulSoup as shown and storing the output in the soup variable. The next step was to figure out exactly which part of the web page contained the minefield I wanted to bring in. This involved viewing the web site’s source code and learning that the minefield was stored inside an HTML table. Each row of the minefield was enclosed in &lt;tr&gt; tags and each cell’s status (clear or rigged) was listed as an attribute of the further nested &lt;td&gt; tags. To filter out all the extra code of the website, I used the find function of the soup object created in the last code snippet to extract only the HTML that was within the &lt;table&gt; tags. This was done as shown. To refine this even further I wanted to divide this table into separate rows so that I could iterate over them and construct my two-dimensional array. I did this using some string manipulation with the split function which is available to every string object. I wrote the split function so that every time it comes across the &lt;/tr&gt; tag (which signifies the end of the row), it creates a divider. Now that I had everything in a digestible and clean format, it was time to build my 2D array. I initialized the maze variable as a global array and began the construction of a nested for-loop. The logic would be as follows. For every row in the minefield table, create an additional temporary array, split the row into individual cells (at the end of every &lt;td&gt; tag), then for every cell, check whether it had the keyword full, empty, start, or end. Based on the keyword, append to our temporary row, either 0, 1, or 2. Once iteration through every cell in a row is complete, and the length of our temporary array is greater than one, append the temporary array to our main maze array (making it an array of arrays or 2D). The code is shown here. After coming this far, our output was looking pretty good. Execution of all the code discussed so far yielded the following results. When compared with the minefield displayed on the web page, everything was perfectly identical. Empty spaces were zeros, bombs were ones, and our goal was the number two. Step 2 – Solve the Minefield Now that we had our minefield in a 2D array, it came time to pick a pathfinding algorithm which would be used to search for the goal given a starting point and print the path taken to get there while avoiding the bombs. The algorithm I selected is the Breadth-First-Search (BFS) algorithm. It is explained well by Simplilearn. They say, “BFS is used to search a tree or graph data structure for a node that meets a set of criteria. It begins at the root of the tree or graph and investigates all nodes at the current depth level before moving on to nodes at the next depth level.” Breadth-First-Search uses a queue data structure to store the node and mark it as “visited” until it marks all the neighboring vertices directly related to it. The queue operates on the First-In-First-Out (FIFO) principle, so the node’s neighbors will be viewed in the order in which it inserts them in the queue, starting with the node that was inserted first. Below is a diagram for some additional clarity. Implementing this in Python to work with our minefield was quite a challenge, nevertheless, existing research was quite helpful in guiding the exercise. The first part of implementing BFS was to establish the key variables it would use. This includes the following: Creating a new maze and setting it to the one we retrieved from the website Establishing the minefield’s dimensions (rows x columns) Creating a double-ended queue (to hold the nodes we want to visit next) Adding our starting point to the queue (which will always be (0, 0)) Defining possible directions that the algorithm could move in Assigning letters (L, R, U, D) to those directions by using a hash map Creating a blank Boolean array identical to the minefield to track visited locations Setting our starting point as visited (since we are already there) The code to declare and set these variables is shown below. Now that we have our variables ready, we can begin the processing of the minefield. This is done with a while-loop which will continue as long as there is something in our queue signifying that there are still coordinates left to explore. Each time the loop runs, we will pop out the next value from the front of the queue and look at all the moves we can make from that coordinate (up, down, left, right). We will send said move through a series of validity checks to determine if it’s out of bounds, if there is a bomb there, if we’ve already visited it, or if we’ve reached the goal. The logic can be understood better by reading the algorithm below. Since there is a lot going on here, lets walk through it step by step. We start off with a while-loop which will continue to run as long as there are coordinates in the queue. Once the loop has determined that there is a coordinate in the queue, we will retrieve it, and check to make sure it is not the goal (which would make continuing the loop unnecessary). Once we know it’s not the coordinate we are looking for, we will send it to our for-loop. Our for-loop will try every move defined in our directions array which was declared earlier. You might notice that the for-loop looks a bit odd. That is because we are not only looping through the moves in our directions array, but we are simultaneously keeping track of the index numbers of the moves we are trying so that we can look them up in our hash map and connect a given move to a letter (which we need for the answer format). We are using Python’s enumerate function to achieve this. For every move the for-loop iterates through, it creates a new set of coordinates by adding the current coordinate to the coordinates of the relevant move declared in the directions array. This is performed in the new_row and new_col variables. Once a new coordinate is created, it is checked to determine whether it is out of bounds, if there is a bomb there, or if it has already been visited. If it gets caught in any of those checks, the move is abandoned and the next move is brought into the for-loop. If the move manages to pass all the validity checks, the move along with its corresponding letter, is appended to the queue. The move’s coordinates are also marked as visited to prevent the loop from visiting places it has already explored or determined are dead ends. Once this runs for every single coordinate in the minefield, it will find the target and print all the directions and moves that were taken to reach it, giving a sequence of moves which we can submit as our answer. A demonstration is shown below. The full script can be found at my GitHub.]]></summary></entry><entry><title type="html">Here’s How I Managed to Pass the Security+ On My First Try!</title><link href="https://shehzade.github.io/2021/02/25/heres-how-i-managed-to-pass-the-security-plus-on-my-first-try/" rel="alternate" type="text/html" title="Here’s How I Managed to Pass the Security+ On My First Try!" /><published>2021-02-25T00:00:00+01:00</published><updated>2021-02-25T00:00:00+01:00</updated><id>https://shehzade.github.io/2021/02/25/heres-how-i-managed-to-pass-the-security-plus-on-my-first-try</id><content type="html" xml:base="https://shehzade.github.io/2021/02/25/heres-how-i-managed-to-pass-the-security-plus-on-my-first-try/"><![CDATA[<h1 id="i-finally-did-it">I FINALLY DID IT!</h1>

<p>Hey everyone, welcome back to my infosec blog! I am so very happy (and kinda relieved) to announce that I have finally passed the CompTIA Security+ SYO-501 exam with a score of <strong>817/900</strong> on my first try. Now, it may not be a big deal to most people, but I had some severe test anxiety before sitting for the Sec+ simply because I had read the experiences of several people on Reddit and other sites that had years of IT experience and still failed (some even a couple of times!)</p>

<p>In the end though, when I first saw that “<strong>CONGRATULATIONS!</strong>” screen, I almost lost it. I was so proud, relieved, and giddy with excitement because I saw the fruits of several months (3.5) of studying and prep before me. It’s quite embarrassing to admit but I (a 20-year-old college freshman), was skipping out of that testing building like a kindergartener.</p>

<p>If you’re new here and wondering why I dropped $250 (student pricing) on this cert in the first place, there are basically 3 main reason.</p>

<ol>
  <li>I wanted to prove to myself that I have the basic knowledge and dedication to learning in order to successfully enter and create a career in the field of cybersecurity (which is naturally ultra-competitive)</li>
  <li>It’s a small (yet essential) step towards my ultimate goal of becoming a skilled penetration tester or red team operator.</li>
  <li>It’ll give me a leg up on all the juniors and seniors competing for prestigious internships from consulting firms that are hiring in Houston like Protiviti, EY, Deloitte, RSM, etc…</li>
</ol>

<p>Now, onto why I’m writing this post. In addition to venting my excitement and showboating just a little (hehe), I wanted to share some broad, high-level studying tips and tricks that I picked up from around the internet to help anyone who might be getting ready to take this cert before it <strong>expires on July 31st</strong>, 2021 which is right around the corner. Along with those, I’ll be including my test-taking strategies and the study plans I used to help me beat the time crunch (which is definitely real) and have the necessary knowledge to confidently answer the confusingly-worded questions on the test with ease.</p>

<p>I hope you find these helpful because I absolutely appreciated the wonderful people in the infosec community who posted very long reviews, experiences, study guides, plans, and strategies on their blogs and Reddit threads. I found them incredibly valuable and truly indispensable resources to prepare me for what was one of the most challenging exams I have taken to date. So, this is my way of giving a little back and sharing what helped me the most. Enjoy!</p>

<h1 id="how-i-studied">How I Studied</h1>

<p>Now I am a full-time college student with a job and although I’m still a freshman, classes, work, and coursework can get a bit heavy at times. I needed a small window of opportunity to cover a large amount of the subject matter and familiarize myself with most of the vocabulary and concepts. Thankfully, the winter break of Fall 2020 was the perfect opportunity as apparently in college, it lasts a whole month.</p>

<p>I used the winter break to study <a href="https://www.amazon.com/CompTIA-Security-Get-Certified-Ahead/dp/1939136059">Darrell Gibson’s study guide book</a> which I bought discounted on eBay for $20. I read a chapter every day and did the coinciding quizzes on the back of each chapter getting consistent 80s &amp; 90s. Once I finished the book in 11 days and aced the readiness assessment at the end of the book, I felt like I was ready for the exam. That’s right about the time when Reddit shattered my confidence and I ended up rescheduling my exam.</p>

<p>The majority of warnings/ red flags I gathered from peoples failures consisted of the following</p>

<ul>
  <li>You shouldn’t study from a single source only</li>
  <li>Performance-based questions exist (and they’re hard)</li>
  <li>Overconfidence backfires</li>
  <li>Time crunch is 100% real</li>
  <li>Memorization will get you nowhere</li>
  <li>Practice tests are useless compared to the actual questions</li>
  <li>etc…</li>
</ul>

<p>Suffice it to say, I was worried and had to go back to the drawing board because I felt like I was taking it too easy. I started by dividing my studying into 3 phases. Phase 1 was familiarity and high-level understanding. Phase 2 was a detailed study and key concept reviews to fill in knowledge gaps. Phase 3 was practice tests, flashcards, and PBQ prep. Here’s how I implemented each phase.</p>

<h2 id="phase-1-material-familiarity">Phase 1: Material Familiarity</h2>

<p>I started this phase by rereading and reviewing Darrel Gibson’s entire study guide all over again. I also redid the quizzes which I mostly scored perfectly on the second time around. Once I had grasped mostly all his material, I went ahead and moved to the next phase.</p>

<h2 id="phase-2-gap-filling">Phase 2: Gap Filling</h2>

<p>This phase was mostly to address the diversity of learning resources which was a major factor in my exam score. I only figured out how much I didn’t know once I started dabbling in other people’s video courses and prep material.</p>

<ul>
  <li>I started out with the well-known (and free) <a href="https://www.professormesser.com/security-plus/sy0-501/sy0-501-training-course/">Professor Messer Training Course</a> and completed one playthrough of his Security+ playlist while at work, driving, etc…</li>
  <li>Then I moved to <a href="https://www.udemy.com/course/comptia-security-certification-sy0-501-the-total-course/">Mike Meyer’s Total Security+ Video Course</a> on Udemy which is around $15 (but I got it free)</li>
  <li>Finally, I ended with Mike Chapple’s Become a CompTIA Security+ Certified Security Professional learning path on LinkedIn Learning which is also free for me because I work at my university</li>
</ul>

<p>The shocking thing for me was that each of these resources covered a lot of overlapping material but every so often, I would come across something that was not in the other materials which really made me grateful that I postponed my exam and looked for other things to study from. Once I was confident that I knew all the concepts that I would need for the test, I moved on to the next phase to apply what I had learned and test the breadth of my understanding.</p>

<h2 id="phase-3-practice-practice-practice">Phase 3: Practice, Practice, Practice!</h2>

<p>The best and most accurate practice test and prep platform I used was the <a href="https://gcgapremiumpass.com/security-online-study-materials/">GCGA SYO-501 Full Study Package</a> which is by Darrel Gibson (who wrote the study guide I read). It costs a cool $65 but I got it discounted for Christmas at $50. It came with hundreds of practice test questions which were actually challenging, 4 sets of accurate PBQs, several other mini-quizzes, and flashcards for acronyms and important tidbits to help reinforce your understanding and gauge your readiness. Here is where I really understood how much more I needed to practice before sitting for the actual test. I bombed most of them in the beginning but slowly began to improve my scores after re-studying the concepts I missed.</p>

<p>Unfortunately, though, my membership expired before I felt ready enough so I found <a href="https://passcomptia.com/">another website</a> with THOUSANDS of practice test questions and 12 PBQ sets. This one is really difficult to explain because most of the question sets are fantastic, but some sets have bogus answers with no explanations so I wouldn’t recommend it as a primary resource. It’s still nice to have but only if you’ve aced Darrel Gibson’s practice questions.</p>

<p>The final resource I used to practice was Quizlet. I never thought I’d use that for this but it was surprisingly helpful. Although there were flashcards in the GCGA package, these were still a great refresher for what I had forgotten or what slipped my memory.</p>

<ul>
  <li><a href="https://quizlet.com/303906202/comptia-security-sy0-501-glossary-full-flash-cards/">Important Terminology</a></li>
  <li><a href="https://quizlet.com/255156432/comptia-security-sy0-501-acronyms-flash-cards/">Acronyms</a> (must know and understand in-depth)</li>
  <li><a href="https://quizlet.com/343931988/port-names-and-numbers-security-501-flash-cards/">Port #s</a> (not as important as people say but still must know)</li>
</ul>

<h1 id="days-before-the-exam">Days Before The Exam</h1>

<p>After all my prep, I truly felt ready and was confident that I could certainly pass the exam if it came down to it. I pushed up my test and left a couple of days for rest and to read up on some <a href="https://blogs.getcertifiedgetahead.com/security-blog-links/#Performance">awesome test-taking strategies</a>. Some of the ones that I found most useful were the following.</p>

<ul>
  <li>Arrive early and make sure you bring your ID and Credit/Debit card</li>
  <li>Use the bathroom <strong>BEFORE</strong> sitting for the test</li>
  <li>Skip the 5 or so PBQs at the start and flag them for review (DO THEM AT THE END)</li>
  <li>Keep track of your time (It’ll creep up on you)</li>
  <li>Be well rested and in peak mental state</li>
  <li>Eat something light before taking the test</li>
  <li>Use the process of elimination for ones that you’re unsure about</li>
  <li>Don’t be cocky, think, and read the question twice if you must</li>
</ul>

<p>If you can manage to do some or most of those things, you’ll be absolutely fine on the exam. Another critical last-minute prep that I did was to review the <a href="https://www.comptia.jp/pdf/Security%2B%20SY0-501%20Exam%20Objectives.pdf">CompTIA objectives sheet</a> and research or lookup any concept, tool, or technology that I wasn’t 100% sure of. There is also a list of acronyms in the objectives which have some weird additions that I didn’t find in the flashcard, so taking a look at that would be a huge plus.</p>

<p>But that’s about it. In summary, the exam is tough but it’s not impossible. If you study the objectives, diversify your resources, and keep a cool head during the test, I’m certain you’ll be able to get a great score and a solid cert under your belt.</p>

<p>If you have any questions, feel free to reach out to me on my <a href="https://www.linkedin.com/in/abdullahansari0">LinkedIn</a>!</p>]]></content><author><name></name></author><category term="certification-exam" /><summary type="html"><![CDATA[I FINALLY DID IT!]]></summary></entry><entry><title type="html">Intro, Reflection, Roadmap.</title><link href="https://shehzade.github.io/2020/12/25/intro-reflection-roadmap/" rel="alternate" type="text/html" title="Intro, Reflection, Roadmap." /><published>2020-12-25T00:00:00+01:00</published><updated>2020-12-25T00:00:00+01:00</updated><id>https://shehzade.github.io/2020/12/25/intro-reflection-roadmap</id><content type="html" xml:base="https://shehzade.github.io/2020/12/25/intro-reflection-roadmap/"><![CDATA[<h1 id="so-who-is-this-kid">So who is this kid?</h1>

<p>First of all, welcome to my infosec blog! If you don’t already know, my name is Abdullah Ansari and I’m currently a freshman in college attending a public university in Houston. Some of my interests (other than infosec) are playing open-world games, real estate investing, learning languages, and hanging out with family and friends. You can say I’m pretty much your average college kid.</p>

<p>Ever since high school, I’ve been fascinated by the world of “hacking” which advertises itself as an adrenaline-filled life of breaking into systems, networks, and buildings you aren’t supposed to be in. I didn’t hack my school and change everyone’s grades or anything spectacular (&amp; stupid) like that, but I’ve <em>allegedly</em> done my fair share of script kiddie stuff on my <strong>PRIVATE</strong> labs of course.</p>

<p>My real hook into this field though was a <a href="https://www.youtube.com/watch?v=pL9q2lOZ1Fw&amp;index=4&amp;list=PLh9vABlZOSlONaWbv88Tun0YsaduoaM1H">youtube video by Insider</a> which showed an actual red team in action. Basically, a cameraman followed the team around as they stealthily infiltrated and compromised several critical power stations and control centers in the local power grid. Seeing the tools they used and the absolute blast they were having while picking locks, flying drones, and fooling sensors really made this a serious deal for me.</p>

<p>I felt like it clicked and figured that a career like this would be a dream. Ever since then, I’ve been having tons of fun playing around with GitHub scripts, Metasploit, Kali boxes, and lock picks while dipping my toes into some theory and basic IT fundamentals.</p>

<h1 id="why-cybersecurity">Why cybersecurity?</h1>

<p>Now, at some point after high school, I began to think about what I wanted to do with my life career-wise. Since I chose to be an MIS major (which is under business), I had several options. I could choose from management consulting, IT consulting, project management, data analysis, software engineering, business analysis, etc..etc… Unfortunately, with all due respect, all of these seemed extremely tedious and boring to be completely frank. I hated coding with a passion (thanks to AP CompSci 1&amp;2) and organizational management talk put me to sleep real quick.</p>

<p>After taking my first semester, I finally realized that I could do what I love and enjoy doing and have someone pay me a ton of money and give me a job with great benefits, high flexibility (partly thanks to covid), and job security which seems like a SWEET deal if you ask me. So now, I have decided to pursue this path with the dedication and tenacity of someone who REALLY wants to be successful in this field. If I’m able to pull this off, I can sincerely and honestly say, that I will absolutely not be from among the 85% of Americans who hate their job.</p>

<h1 id="why-this-blog">Why this blog?</h1>

<p>Onto the good stuff. After hanging around and interacting with the security community on forums, Linkedin, and other blogs, I’ve learned that this group places an enormous value on giving back and helping out whoever you can with whatever you have expertise in. This is actually one of the things that drew me further into this field.</p>

<p>For example, I’m currently studying for the CompTIA Security + exam and I can’t even count how many “my experience” or “my journey” posts I have read over the internet. Needless to say, they have all been incredibly helpful with links to materials, proven strategies, and tips/tricks that only come by actually doing things.</p>

<p>All of this free information and selfless passing down of knowledge has inspired me to create a blog myself to hopefully give back a fraction of what I have taken from the InfoSec community. Even helping a single person would be enough to satisfy me, but my aim is to reach as many people and provide as much value as possible.</p>

<p>For the duration of this blog, I will closely monitor and journal every major step in my journey to turn my passion into a full-time career. I will talk about everything from college to certifications to interviews and everything in between, so stay tuned if you’re interested.</p>

<h1 id="goals">Goals</h1>

<p>Now, as of this moment, I have no shame in saying that my hacking skills are just a bit above the script kiddie level. However, I realize that I’ve got a long way to go and that actually makes me really excited. My uncle once told me to just enjoy the journey and stop worrying about the destination, it will come by itself, and I plan on taking his advice (you should too).</p>

<p>A general roadmap for me right now, based on everything I’ve read and researched looks pretty straightforward.</p>

<ol>
  <li>Throughout the next few years, I will be doing a healthy mix of courses from Udemy, PluralSight, and SANS to build up core skills and methodologies.</li>
  <li>To practice my said skills, I will use HackTheBox machines, VulnHub machines, and the highly praised Virtual Hacking Labs machines.</li>
  <li>Finally, I will attempt to complete several well-known, entry-level certifications like the Security +, eJPT, eCPPT, CRTP, and the OSCP to prove my skills to employers.</li>
</ol>

<p>So that’s the plan ladies and gentlemen. That being said, things are quite shaky in the world right now what with covid and all, so things might shift here and there, but I’m set on getting through this and making something out of myself. Plus, I’ll get to share my experiences, learn from the community, and also give back what little I can, so I see it as a win-win-win. Anyways, this is probably the longest post I’ll ever write, but now that formalities are out of the way, I’ll embark on this path with the next post which will document my Security + journey so be on the lookout for that. See ya’ll on the next one!</p>]]></content><author><name></name></author><category term="personal-experience" /><summary type="html"><![CDATA[So who is this kid?]]></summary></entry></feed>