diff --git a/src/pentesting-ci-cd/gogs-security/README.md b/src/pentesting-ci-cd/gogs-security/README.md new file mode 100644 index 000000000..de5e77269 --- /dev/null +++ b/src/pentesting-ci-cd/gogs-security/README.md @@ -0,0 +1,103 @@ +# Gogs Security + +{{#include ../../banners/hacktricks-training.md}} + +## Що таке Gogs + +**Gogs** — це **self-hosted lightweight Git service**, написаний мовою Go. З точки зору attacker, розглядайте його як **multi-tenant Git hosting platform**, де користувач із низькими привілеями все ще може контролювати branch names, pull requests, webhooks, tokens і repository settings. + +## Git option injection through refs / branch names + +If an application passes an attacker-controlled **ref name** directly to a Git command **without `--` or `--end-of-options`**, a branch beginning with `--` can be parsed as a **Git option** instead of as data. + +Typical dangerous pattern: +```bash +git +``` +Більш безпечний шаблон очікується в defensive code: +```bash +git -- +# or +git --end-of-options +``` +Поширене хибне припущення полягає в тому, що перевірка ref за допомогою `git rev-parse --verify ` є достатньою. Це **не так**: + +- attacker може спочатку **create a real branch** whose name starts with `--` +- `rev-parse --verify` лише перевіряє, що ref розв’язується в object +- пізніший небезпечний Git-виклик все ще може розпарсити те саме значення як **option** + +Це перетворює будь-яку Git-hosting feature, яка повторно використовує збережені branch names, на потенційний RCE primitive. + +## Зловживання `git rebase --exec` для RCE + +`git rebase` підтримує `--exec=`, який запускає command через `sh -c` після replaying commits. Тому, якщо base branch pull request доходить до виклику, подібного до: +```bash +git rebase --quiet +``` +and `` є під контролем attacker, branch such as: +```bash +--exec=touch${IFS}/tmp/rce_proof +``` +може бути інтерпретовано як **Git flag** замість назви branch. + +### Чому `${IFS}` має значення + +Git refs не можуть містити literal spaces, але shell expansion все одно відбувається, коли Git виконує `--exec` через `sh -c`. `${IFS}` розгортається у whitespace під час runtime, дозволяючи payloads на кшталт: +```bash +--exec=touch${IFS}/tmp/rce_proof +--exec=id${IFS}>/tmp/out +``` +Для payloads, які вимагають заборонені в Git символи (`:`, `~`, `^`, `?`, `*`, `[`, `\\`, `//`), закодуйте реальну команду та декодуйте її під час виконання: +```bash +--exec=echo${IFS}|base64${IFS}-d|sh +``` +## Windows-specific payload delivery + +У Windows inline payloads більш обмежені, оскільки Git зберігає branch refs як файли, а NTFS забороняє символи на кшталт `|` у назвах файлів. Практична альтернатива: + +1. Commit payload script into the repository (for example `.abcdef`) +2. Create a branch like: +```bash +--exec=sh${IFS}.abcdef +``` +Якщо Git for Windows запускає payload через **MSYS2 `sh`**, метасимволи PowerShell можуть бути спотворені. Практичний workaround — дозволити committed script викликати: +```bash +cmd.exe //c .abcdef.bat +``` +де `//c` — це безпечна для MSYS2 форма Windows `/c`. + +## Abuse state-machine merge / PR + +Під час тестування Git-hosting platforms не лише перевіряйте кінцевий небезпечний command. Також перевіряйте **попередні validation paths** і **background rechecks**. + +Корисний pattern exploitation: + +1. Initial validation path використовує **safe** clone/fetch flow з `--end-of-options`, тож malicious branch приймається як data +2. Pull request стає **mergeable** +3. Пізніший merge або checkout path повторно використовує збережену branch name в **unsafe** Git call +4. Code execution відбувається навіть якщо пізніший step завершується помилкою і UI повертає **HTTP 500** + +Це означає, що feature може бути exploitable навіть тоді, коли final merge завершується з error, а target repository може лишитися в **corrupted partial rebase state** після того, як payload уже відпрацював. + +## Practical hunting ideas + +Під час перевірки Gogs instance або подібного Git service звертайте увагу на: + +- Branch names, що починаються з `--` +- Merge failures, пов’язані з `git checkout '--exec=...'` +- Pull requests, які застрягли як mergeable, хоча пізніша branch validation fails +- Repositories, залишені в partial rebase / broken Git state після failed merges +- Неочікувані committed helper files на Windows payload paths (наприклад dotfiles плюс `.bat` launchers) +- Підозрілі API tokens, створені незадовго до failed PR merges + +Example log artifact: +```text +merge: git checkout '--exec=<...>': exit status 128 - error: unknown option `exec=<...>' +``` +## References + +- [Rapid7 - Authenticated RCE via Argument Injection in Gogs (NOT FIXED)](https://www.rapid7.com/blog/post/ve-authenticated-rce-via-argument-injection-gogs-unfixed) +- [Metasploit module PR for Gogs rebase argument injection](https://github.com/rapid7/metasploit-framework/pull/21515) +- [Git rebase documentation (`--exec`)](https://git-scm.com/docs/git-rebase) + +{{#include ../../banners/hacktricks-training.md}}