Information#
Version#
By | Version | Comment |
---|---|---|
noraj | 1.0 | Creation |
CTF#
- Name : Byte Bandits CTF 2018
- Website : ctf.euristica.in
- Type : Online
- Format : Jeopardy
- CTF Time : link
100 - El Lazo - Web#
It's only when you look closely, you can figure out that all those things which appears same are actually different!
Here is the interesting part of the web page source:
I fired Burp and its Repeater to try the API.
A normal request looks like:
And so the normal answer is:
The only known valid values are 2,3,4
. Want to try 1
?
- payload:
{"id":1}
- answer:
{"msg":"You are not authorized to view that message"}
I think this is where we need to keep looking at.
Then try a type juggling:
- payload:
{"id":"1"}
- answer:
{"msg":"flag{Y0u_c4n_c4ll_m3_law3r3nce3}"}
200 - R3M3MB3R - Web#
The memories are purged at the end of every narrative loop. But they're still in there, waiting to be overwritten. He found a way to access them, like a subconscious. ~Bernard Lowe
It's obvious we have a LFI. Let's try some files:
/etc/os-release
: Debian GNU/Linux 9 (stretch)/proc/self/status
: apache2/proc/self/fd/2
: logs, same as/var/log/apache2/error.log
/etc/apache2/envvars
: default environment variables for apache2ctl/etc/apache2/sites-enabled/000-default.conf
: vhost config/proc/self/fd/7
: logs, same as/var/log/apache2/access.log
/proc/self/environ
is not available but log files are so we will do some log poisoning.
The goal is simple: making a bad request containing a PHP payload in a way that the PHP payload will be written in the log file. Then we will be able to include the log file via the LFI to get the PHP payload executed.
The access log is containing every requested page with the User-Agent of the HTTP client, so if we inject a PHP payload in the User-Agent HTTP header we will be able to get the payload written in the log file.
I inserted <?php system($_GET['c']); ?>
in my User-Agent
and requested c=ls -lAR
by the same time:
The server told me his secrets:
Then we have just to get the flag:
http://web.euristica.in/R3M3MB3R/index.php?f=S3cR3T_FL4G.txt
: flag{S0metim3s_it5_b3tter_to_4_GET}
Note: first access log was unavailable because a player was DoSing the challenge, so I tried to poison the error log, but when I was doing that the challenge's author did a patch to clean the logs every few seconds in order to avoid being DoSed. When he patched the challenge, he blocked the error log file because it was an unintended way to flag, so my method became useless but the access log file was available back, so after a large amount of wasted time I managed to flag.
panoptic
is also a great tool to find some files when we have a LFI.
350 - laz3y - Web#
Mitnick: Saw your website today, didn't know you were such a good web developer.
Linus: Totally not. Just copied a template and made some changes. You can be a developer too :p
http://web.euristica.in/laz3y/
Flag format: flag{secret_string}
PS : this challenge was badly categorized, it's not a web challenge but a pure reverse engineering challenge.
We can find the template from colorlib, download it, and compare the main page with the one actually running.
So we see that there is an additional script setting.js
on the main page.
This looks very obfuscated.
Look at the setting.js
script (on ghostbin or on hastebin) embedded in the website.
First I used Firefox debugger to format the source code, then I began to browse it and I saw _0xd1e9
that looked interesting.
I executed _0xd1e9;
in the console to quickly deobfuscate it:
So we can look for _0xd1e9[12]
== Flag{
.
At L294 we have:
and at L344 & L349:
So we want to get _0x2cc2cf
or _0x190ex2
. _0x190ex2
is never defined but _0x2cc2cf
is a parameter of the solver
function.
But solver
is never called... So I started to replace all _0x15c2
and _0xd1e9
with their value.
After that, I removed all useless statements: else
statements when the if
statement is always true
, if
statements that are always false
.
Here is my work of deobfuscation: setting_deo.js
(on ghostbin or on hastebin).
So the next big part is to deduce the flag from the solver
function.
The part interesting us is this one (that I reworked):
This is giving us the alphabet used, the flag length, some letters, some equalities, and some functions that need to return true. So we need to build a 30 char long flag, we can start to replace some letters but we will need to reverse the crypto
function and all other functions a
, b
, c
, d
, f
.
So I rebuilt the xor
function out of the crypto
one in order to call it, that's how I obtained the last part of the flag: 0bfuscati0n!
.
Then the hardest part was to revert all a
, b
, c
, d
, f
functions (look at the source code), that needed deep analysis and external scripts.
Finally, we don't have all the letters. So I made a ruby script (that I tweaked several times) to bruteforce the remaining letters that also call setting.js
to validate them :
Then we still have a large list of possible flags. But one makes more sense: Flag{That_wAs_a_l0T_0f_0bfuscati0n!}
.