STACK PIVOT


STACK PIVOT


简介

Stack Pivot攻击手法不同于一般的栈溢出,往往是在栈的溢出空间不够的情况之下,可能又时候我们所能进行溢出的空间只能是一个ret的函数位置,这时候我们需要去寻找合适的内存空间去完成攻击,往往是要联系栈偏移的方法。


实验

准备

我这里选用了一道名为ciscn_2019_es_2的题目,我们先用idea去看一下题目的背景,很明显的可以看到这道题它不允许去进行超长的payload攻击,只提供了一个返回地址溢出的空间,这时候常规的方法便不再适用,我们要另寻蹊径:

int vul()
{
  char s; // [esp+0h] [ebp-28h]
  memset(&s, 0, 0x20u);
  read(0, &s, 0x30u);
  printf("Hello, %s\n", &s);
  read(0, &s, 0x30u);
  return printf("Hello, %s\n", &s);
}

分析

这道题目只开了NX保护,那我们也不需要去泄露canary的值了,所以直接去栈里写shellcode是不科学的,我们可以发现在idea里可以找到system的函数调用,这样的话我们只要去找一个”/bin/sh\x00”就可以实现劫持了。很容易可以想到这道题我们可以去栈里写一个字符串,很巧的是刚好可以leak出ebp的值,我们所知道栈段里所拥有的是变量的值,前一个栈帧的ebp,父函数调用子函数时父函数的text段位置。

.text:0804854B ; =============== S U B R O U T I N E =======================================
.text:0804854B
.text:0804854B ; Attributes: bp-based frame
.text:0804854B
.text:0804854B                 public hack
.text:0804854B hack            proc near
.text:0804854B ; __unwind {
.text:0804854B                 push    ebp
.text:0804854C                 mov     ebp, esp
.text:0804854E                 sub     esp, 8
.text:08048551                 sub     esp, 0Ch
.text:08048554                 push    offset command  ; "echo flag"
.text:08048559                 call    _system
.text:0804855E                 add     esp, 10h
.text:08048561                 nop
.text:08048562                 leave
.text:08048563                 retn
.text:08048563 ; } // starts at 804854B

那我们可以去实验一下前一个栈帧ebp的值是什么,可以发现它的值是高了这个ebp的0x10位置,那么距离buf位置就是0x38:

现在我们拥有了偏移量,就可以知道写入”/bin/sh”的位置了,那么我们就可以构造payload了。这里还用到了一个叫double_ret的手法,这个往往适合用在stack pivot里:

sp指针往往指向栈顶的位置,bp指针指向栈底,在return的时候,首先把bp和sp的位置对齐,然后将前一个栈帧的栈底位置赋值给bp,这时候sp指向函数返回位置,那么如果用两次leave呢?可以想到函数会再一次的去对其sp和bp,把新的返回位置赋值给ip。那么我们就可以去构造这个payload了。

leave_ret:
mov sp bp
pop bp
ret:
pop bp



文章作者: Dydong
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Dydong !
  目录