Linux Pwn环境设置
ssooking Lv5

系统推荐

  • REMnux:Ubuntu14.04 64位
  • SEEDLabs:Ubuntu16.04 32位

系统环境

Ubuntu16.04 xenial 32

1
2
3
4
5
$ dpkg --print-architecture
i386

# 可选源
# deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse

使用Ubuntu 16.04,因为该发行版默认已经开启了内核调试支持

1
2
3
4
5
6
7
8
9
10
$ cat /boot/config-4.8.0-36-generic |grep GDB
# CONFIG_CFG80211_INTERNAL_REGDB is not set
CONFIG_SERIAL_KGDB_NMI=y
CONFIG_GDB_SCRIPTS=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
# CONFIG_KGDB_TESTS is not set
CONFIG_KGDB_LOW_LEVEL_TRAP=y
CONFIG_KGDB_KDB=y

安装增强功能

ps:SEEDLabs Ubuntu16.04 32安装open-vm-tools-desktop会无法正常使用桌面环境。解决方法是安装旧版本的vmware-tools。

安装一些编译32位C程序的依赖

32位系统上

1
2
sudo apt-get update -y
sudo apt-get install libc6-dev lib32readline-gplv2-dev

On 32-bit Ubuntu, skip that package. Just install libc6-dev and whatever other packages you need.

The specific package that corresponds to libc6-dev-i386 for a 32-bit system is just libc6-dev, which you are already installing.

There is no libc6-dev-i386 package for your system, because it’s only available on 64-bit systems. This, in turn, is because its purpose is to provide you with the ability to build and run 32-bit programs on a 64-bit system.

https://askubuntu.com/questions/947927/unable-to-locate-package-libc6-dev-i386

64位系统上

1
2
3
sudo apt-get update -y
# sudo dpkg --add-architecture i386
sudo apt-get install lib32z1 libc6-dev-i386 lib32readline-gplv2-dev

在64位系统上使用linux32命令进入32位环境。

关闭安全防护

Ubuntu和其他Linux发行版已经实现了几种安全机制,使缓冲区溢出攻击变得困难,因此如果出于学习和测试目的,我们可以先关闭这些安全防护功能。

1
2
3
4
5
echo 0 > /proc/sys/kernel/exec-shield							#turn it off
echo 0 > /proc/sys/kernel/randomize_va_space #turn it off

echo 1 > /proc/sys/kernel/exec-shield #turn it on
echo 1 > /proc/sys/kernel/randomize_va_space #turn it on

地址空间随机化

地址空间布局随机化(ASLR),ASLR会随机化可执行文件的堆和栈的起始地址以及关键数据区地址,给缓冲区漏洞的利用带来困难。测试时可以先关闭这个功能。

1
2
3
4
# /proc/sys/kernel/randomize_va_space
sudo sysctl -w kernel.randomize_va_space=0
# or
echo 0 > /proc/sys/kernel/randomize_va_space

StackGuard Protection

GCC编译器实现了一种称为StackGuard的安全机制来防止缓冲区溢出。有了这种保护,缓冲区溢出攻击将不起作用。我们可以在编译期间使用-fno-stack-保护者选项禁用此保护。例如,要编译一个禁用StackGuard的程序example.c,可以执行以下操作:

1
$ gcc -fno-stack-protector example.c

Non-Executable Stack

Ubuntu used to allow executable stacks, but this has now changed: the binary images of programs (and shared libraries) must declare whether they require executable stacks or not, i.e., they need to mark a field in the program header. Kernel or dynamic linker uses this marking to decide whether to make the stack of this running program executable or non-executable. This marking is done automatically by the recent versions of gcc, and by default, stacks are set to be non-executable (further reading: [3]). To change that, use the following option when compiling programs:

For executable stack:

1
2
3
$ gcc -z execstack -o test test.c
For non-executable stack:
$ gcc -z noexecstack -o test test.c

Configuring /bin/sh

Ubuntu 16.04 VM only

shellcode
此外,为了进一步防范缓冲区溢出攻击及其它利用shell程序的攻击,许多shell程序在被调用时自动放弃它们的特权。因此,即使你能欺骗一个Set-UID程序调用一个shell,也不能在这个shell中保持root权限,这个防护措施在/bin/bash中实现。
linux系统中,/bin/sh实际是指向/bin/bash或/bin/dash的一个符号链接。为了重现这一防护措施被实现之前的情形,我们使用另一个shell程序(zsh)代替/bin/bash。下面的指令描述了如何设置zsh程序:

1
2
sudo rm /bin/sh
sudo ln -s /bin/zsh /bin/sh

DEP(NX) 不允许执行栈上的数据
RELRO 这个介绍有点长分为两种:
1.Partial RELRO GOT表仍然可写
2.Full RELRO GOT表只读
ASLR(PIE 随机化系统调用地址
stack 栈溢出保护

缓冲区溢出保护机制——Linux

https://blog.csdn.net/woaisk/article/details/82531761

checksec

https://blog.csdn.net/qq_37414405/article/details/84846551

这里简单介绍一下各字段的含义:

1
2
3
4
5
6
7
8
9
10
11
12
13
Arch:只文件运行的平台为:32位的i386,小端字节序列

RELRO:RELRO会有Partial RELRO和FULL RELRO,如果开启FULL RELRO,意味着我们无法修改got表

Stack:如果栈中开启Canary found,那么就不能用直接用溢出的方法覆盖栈中返回地址,而且要通过改写指针与局部变量、leak canary、overwrite canary的方法来绕过

NX: (No-eXecute) 不可执行的意思,NX(DEP)的基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。
若为:NX enabled 这个保护就会开启,意味着栈中数据没有执行权限,以前的经常用的call esp或者jmp esp的方法就不能使用,但是可以利用rop这种方法绕过

PIE: (Postion-Indenpendent executable)地址无关可执行文件,对应windows上ASLR机制,一般情况下NX(Windows平台上称其为DEP)和地址空间分布随机化(ASLR)会同时工作。ASLR和DEP配合使用,能有效阻止攻击者在堆栈上运行恶意代码。
若为:PIE enabled,则程序开启了这个地址随机化选项,就意味着程序每次运行的时候地址都会变化,而现在是没有开PIE的,那么No PIE (0x8048000),括号内的数据就是程序的基地址

RXW:即我们平常对文件的三个权限 read execute write,这里指有可读可写可执行的段。

Windows安全机制

缓冲区溢出

Stack-Guard 针对修改栈空间上函数返回地址的攻击,Stack-Guard给出两种方式阻止攻击:1.在函数返回前检测函数返回地址是否被修改;2.阻止任何程序对函数返回地址的修改。
ProPolice的主题思想和StackGuard很相似,他们也是使用canary值来检测堆栈攻击。他们的创新之处在于他们重新安排本地变量使得char缓冲区一直是在顶部来保护栈,这样其他的本地变量就不会被溢出破坏
CCured是C中加强类型及边界检查的研究,他们都是采用动静结合方式。CCured 辨别的目的在于防止指针的不恰当时使用,并且可以防止程序进入其不应该进入的内存区域。
Chaperon针对二进制代码检测缓冲区溢出,不需要源代码的支持。它可以截取malloc和free系统调用,检测堆访问的合法性;并且可以检测出堆上的内存泄漏;以及对未初始化内存的访问。相比于堆上的缓冲区溢出检测,Chaperon对栈缓冲区溢出检测比较简单粗糙。探测代码有时也会因为缓冲区溢出而被覆盖,导致最后给出错误的缓冲区溢出信息
Libsafe实际上是一个动静结合的工具。静态的方面,他为C中的库函数中一些潜在的缓冲区溢出漏洞打补丁。在实际的函数调用前做一个边界检查可以保证返回值和基指针不被重写。
Memcheck通过为内存的每个比特位建立影子内存从而更准确的发现比特级别的内存错误。对每一次内存操作Memcheck都需要进行探测并对影子内存进行相应的修改。由此带来的是性能上的严重损失,通常会比正常运行程序慢20-30倍

编译程序

打开栈执行,并且给程序可执行权限

https://www.anquanke.com/post/id/85138

1
2
$ gcc -g -fno-stack-protector -z execstack -o vul1 vul1.c
$ chmod +s vul1 //给程序可执行权限

编译方式:

1
gcc -O0 -g -m32 -fno-stack-protector -z execstack 1.c -o 1

参数解释:

  • -O0: 不进行任何优化
  • -g:使程序包含调试信息以进行源码级调试
  • -m32:生成32位程序 (x86机器上编译不用加)
  • -fno-stack-protector: 不开启canary栈溢出检测
  • -z execstack: 开启栈可执行,关闭NX

gcc -g参数生成的程序,编译时会把调试信息加到可执行文件中,这样可以便于gdb调试,如使用list 1,20命令查看代码。

一些工具

1
2
3
4
5
6
7
8
gdb: apt-get install gdb
gcc: apt-get install gcc
gdb-peda: https://github.com/longld/peda
pwntools: pip install pwntools
gcc-multilib: apt-get install gcc-multilib
socat: apt-get install socat
rp++: https://github.com/0vercl0k/rp
readelf: apt-get install readelf

教程

Binary Security Assembly Course

  • Post title:Linux Pwn环境设置
  • Post author:ssooking
  • Create time:2019-12-26 21:57:00
  • Post link:https://ssooking.github.io/2019/12/linux-pwn环境设置/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.