2023 巅峰极客 pwn
linkmap
main函数栈溢出,但是没有可以泄露的常规方法
使用ropper可以发现一段gadget
0x000000000040066b: lea rdx, [rax + 0x601020]; mov rax, qword ptr [rbp - 8]; mov qword ptr [rdx], rax; nop; pop rbp; ret; |
.text:000000000040076D B8 00 00 00 00 mov eax, 0 |
main函数返回时mov eax,0所以可以利用这段gadget把rbp - 8处的数据读到0x601020 .bss处
把read的got读到0x601020附近
把读到bss段的read最后一位改为0x90 即syscall地址
pwndbg> disassemble read
Dump of assembler code for function __GI___libc_read:
0x00007fb1a3514980 <+0>: endbr64
0x00007fb1a3514984 <+4>: mov eax,DWORD PTR fs:0x18
0x00007fb1a351498c <+12>: test eax,eax
0x00007fb1a351498e <+14>: jne 0x7fb1a35149a0 <__GI___libc_read+32>
0x00007fb1a3514990 <+16>: syscall利用gadget控制参数执行调用号为0x3B的sys_execve系统调用
from pwn import * |
这里最后时 syscall <SYS_execve>
rsi参数需要为0,rdx不必需
除了栈迁移还可用csu里的gadget来执行到syscall
.text:00000000004007C0 4C 89 EA mov rdx, r13 |
darknote
只有add功能可以用,其他功能需要canary为0才可以,基本不可能
下面的函数存在整数溢出
puts("How many dark notes do you want?"); |
printf("Index: "); |
note_count*8后如果溢出,会导致申请的堆块小于 v6 = (void **)((char *)note_ptr_ar + 8 * index_add); *v6 = malloc(0x68uLL);
可写的堆块,所以我们利用mmap申请到libc上方的堆块,就可以往libc写我们申请的堆地址
思路
- 把我们申请堆的地址写入到 main_arena.fastbin[5]的位置,我们就可以在申请堆伪造下一个堆,造成任意堆的申请
- 利用输出菜单函数泄露libc
- 利用存储着系统的环境变量的__environ泄露stack地址
- 在stack上布置rop链
- malloc_hook改为触发rop链的gadget
任意堆申请时要注意申请的任意堆的fd域即任意堆地址+0x10处要为0,不然过不了检测
from pwn import * |