Tags: git 

Rating: 5.0

Description: Common mistake in web deployments
Url: http://head.eko.cap.tf:30000

After following the link we ar prompted with empty page but a password prompt. Since this was a GIT challenge and the name was `HEAD`. I wondered if there could be the `.git` folder present as that is a common mistake (for example running static client--side-rendered FE apps from CDN, forgotting to exclude the `.git` folder)

So i tried to query
```
http://head.eko.cap.tf:30000/.git/HEAD
```

and indeed got
```
ref: refs/heads/master
```

as a response. After some googling I found [gitdumper](https://github.com/internetwache/GitTools/blob/master/Dumper/gitdumper.sh) tool I've used to dump the whole repository from the `.git` folder.

There appears to be only one file - `index.php` which seems to be a b374k php shell.
```
".gz'.'un'.'com'....
```

`$func` variable seems to be little obfuscated version of some base64 packed payload, lets investigate further before trying to decode that.

Those are all commits in the repository:
```
commit b7d095eea87d18b2a1ca4a68733d5266bbc19de4 (HEAD -> master)
Author: DC <haxor@ekoparty.org>
Date: Thu Sep 24 03:03:50 2020 +0000

Final commit

commit 26925bc713d9cfc666112c9cc62ab49c6671a03e
Author: DC <haxor@ekoparty.org>
Date: Thu Sep 24 03:02:53 2020 +0000

Bad files removal

commit 179e12491a2628c71bb854514f3b05cdf7cb546d
Author: DC <haxor@ekoparty.org>
Date: Thu Sep 24 03:02:21 2020 +0000

Security enhance

commit 783ec943507158f27e4921963c8a2d7bfd02999d (before_second_sec_fix)
Author: DC <haxor@ekoparty.org>
Date: Thu Sep 24 03:01:38 2020 +0000

File creation

commit 5d6b2408488d0f29d687610a49cab40298a6d01b
Author: DC <haxor@ekoparty.org>
Date: Thu Sep 24 02:49:03 2020 +0000

First commit

commit 96575dcf9117e54d34233c1bac9bf5d4efda7103
Author: DC <haxor@ekoparty.org>
Date: Thu Sep 24 02:42:16 2020 +0000

Final commit

commit 39f280f51d37fdc3a0181a0802ae2214041faaf7
Author: DC <haxor@ekoparty.org>
Date: Thu Sep 24 02:41:57 2020 +0000

Bad files

commit 190507b3bd67dff13d168ffd0886f60e77b7d2fa (first_sec_fix)
Author: DC <haxor@ekoparty.org>
Date: Thu Sep 24 02:41:03 2020 +0000

Security enhance

commit 71693af6f6a71b39e0e10375163daafe94e4af20 (before_first_sec_fix)
Author: DC <haxor@ekoparty.org>
Date: Thu Sep 24 02:39:40 2020 +0000

File creation

commit c95c2b60fadf178c1a3ac84c6c404a308e919987
Author: DC <haxor@ekoparty.org>
Date: Thu Sep 24 02:38:45 2020 +0000

Repo init
```

Those security enhance commits looks intereseting, lets look at them.

The first security commit reveals the hash that is in `../secret` in the recent version.
![](https://i.ibb.co/1zgPHD0/Screenshot-from-2020-09-28-12-45-38.png)

So first thing we need that
```
sha1(md5(pass)) == GLOBAL['pass'] == 1e7a1d03e274e66e22bfabf2d8f4a0408970e354
```

Lets check the other security improvement commit:
![](https://i.ibb.co/NLwBbHG/Screenshot-from-2020-09-28-12-48-57.png)

Here we see an even older password hash, but we can also see the php shell code in plaintext! Lets curve out just the `auth` function
```
if(!function_exists('auth')){
function auth(){
if(isset($GLOBALS['pass']) && (trim($GLOBALS['pass'])!='')){
$c = $_COOKIE;
$p = $_POST;
if(isset($p['pass'])){
$your_pass = sha1(md5($p['pass']));
if($your_pass==$GLOBALS['pass']){
setcookie("pass", $your_pass, time()+36000, "/");
header("Location: ".get_self());
}
}

if(!isset($c['pass']) || ((isset($c['pass'])&&($c['pass']!=$GLOBALS['pass'])))){
$res = "
<html>
<head>
<meta charset='utf-8'>
<meta name='robots' content='noindex, nofollow, noarchive'>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, user-scalable=0'>
</head>
<body style='background:#f8f8f8;color:#000000;padding:0;margin:0;'>

<center><noscript>You need to enable javascript</noscript></center>


<script type='text/javascript'>
var d = document;
d.write(\"

<form method='post'><center><input type='password' id='pass' name='pass' style='font-size:34px;width:34%;outline:none;text-align:center;background:#ffffff;padding:8px;border:1px solid #cccccc;border-radius:8px;color:#000000;'></center></form>\");
d.getElementById('pass').focus();
d.getElementById('pass').setAttribute('autocomplete', 'off');
</script>
</body></html>
";
echo $res;
die();
}
}
}
}
```

For unhealthy amount of time I though that this loose comparison is the way to proceed, however that hash was not in `0e[0-9]` format, so I lost alot of time on that.
Then I decided to just go through every line in the code and mark down whatever is it doing. After getting here it pinched me.
```
if($your_pass==$GLOBALS['pass']){
setcookie("pass", $your_pass, time()+36000, "/");
header("Location: ".get_self());
}
```

Wait, after the authentication is sucessful it just set cookie `pass` with the correct pass, which is equal to `$GLOBALS['pass']`. We already know that!
After altering browser cookies with `pass: 1e7a1d03e274e66e22bfabf2d8f4a0408970e354` and refresh the page we are in!
![](https://i.ibb.co/Yd63s13/abc.png)

I was unable to switch to the parent directory in the UI, but I've noticed another `cookie` appear with value `path: /var/ww/html/` so after altering that to `path: /var/ww/` we can see the `flag.txt` file and open it in the webshell.

Flag: EKO{m4st3r_0f_g1t}