PWN
PWN
快速入门
前言
首先我觉得要学习PWN还是要有一定基础的,因为PWN毕竟是和系统底层知识打交道,所以我觉得应该具备如下的一些技能,并且我推荐了一些不错的书籍。
- Linux系统基础知识《鸟哥Linux私房菜》、《Linux就该这么学》、《Linux命令大全》
- Linux下C语言编程 《Linux C编程一站式学习》
- Python编程基础知识 《Python编程:从入门到实践》
- 汇编语言《汇编语言(第4版)》、 王爽8086汇编学习笔记
- 熟悉ELF文件格式 《Linux二进制分析 》
- 熟悉GDB动态调试 gdb调试常用指令
概述
PWN我觉得最开始的时候应该是没有这门学科和系统化的资料教程的,PWN本身属于高阶技能,个人感觉都是以前那些逆向大佬、编程大佬开始玩点高级的东西,然后就开始挖漏洞,结果就挖出了各种二进制漏洞,并且把二进制漏洞也完美的利用起来了,后面就归纳总结出一套体系供后人学习,在此真的膜拜那些前辈的共享精神。
PWN为什么叫PWN呢?其实只是一种声音,pwn!你的电脑爆炸了,你的电脑被攻破了,因为用二进制漏洞挖掘与利用这词来形容pwn未免也太长了,所以就用了简洁的叫法。
术语
这里介绍一些简单的PWN术语:
- Exploit(exp) : 用于攻击的脚本与方案
- Payload : 攻击载荷,是对目标进程劫持控制流的数据
- Shellcode : 调用攻击目标的shell的代码
比赛
详见:ctftime.org
- Pwn2Own
- 世界最难的黑客挑战赛
- 针对主流浏览器的远程攻击
- 要求沙箱逃逸
- CyberGrandChallenge
- 机器人的CTF攻防比赛
- 自动化漏洞挖掘、漏洞利用、程序分析、程序补丁
- https://firmianay.gitbooks.io/ctf-all-in-one/content/doc/1.1_ctf.html
PWN环境搭建
学习PWN知识我们先需要一个指定的环境来进行PWN,这里首选的操作系统为Ubuntu、Kali然后安装必要的PWN环境软件来进行搭建,当然如果你想省力气的话也可以用docker直接部署别人封装好的pwn环境。
具体搭建步骤请看下一章
常见漏洞
- 整数安全
- 格式化字符串
- 栈溢出与ROP
- 堆利用
常见的保护
RELRO
Relocation Read-Onl(RELRO)此项技术主要针对GOT改写的攻击方式,它分成两种,Partial RELRO和FULL RELRO
Partial (部分)RELRO容易受到攻击,例如攻击者可以atoi.got为system.plt进而输入/bin/sh\x00获得shell,完全RELRO使整个GOT只读,从而无法被覆盖,但这样会大大增加程序的启动时间,因为程序在启动之前需要解析所有的符号。
1 |
|
Canary
栈溢出保护是一种缓冲区溢出攻击缓解手段,当函数存在缓冲区溢出攻击漏洞是,攻击者可以覆盖栈上的返回地址来让shellcode能够得到执行,当启用栈保护后,函数开始执行的时候先会往栈里插入类似cookie信息,当函数真正返回的时候会验证cookie信息是否合法,如果不合法就停止程序运行,攻击者在覆盖返回地址的时候往往会将cookie信息给覆盖掉,导致栈保护检车失败而阻止shellcode的执行,在linux中我们将cookie信息称为canary。
1 |
|
NX(DEP)
NX enabled如果这个保护开启就是意味着栈中数据没有执行权限,如此一来,当攻击者在堆栈上部署自己的shellcode并触发时,就会直接造成程序的崩溃,但是可以利用rop这种方法绕过。
1 |
|
ASLR
ASLR 是 Linux操作系统的功能选项,作用于程序(ELF)装入内存运行时。是一种针对缓冲区溢出的安全保护技术,通过对堆、栈、共享库映射等线性区布局的随机化,防止攻击者直接定位攻击代码位置,到达阻止溢出攻击的一种技术。
在传统的操作系统里,用户程序的地址空间布局是固定的,自低向高依次为代码区, BSS区,堆栈区,攻击者通过分析能轻易得出各区域的基地址,在此情况下,只要攻击者的注入代码被执行,攻击者就能随意跳转到想到达的区域,终取得计算机的控制权,试想如果一个程序在执行时,系统分配给此进程三个区域的基地址是随机产生的,每次该程序执行都不一样,那么攻击者注入的代码即使被执行,也终会因为无法找到合法的返回地址而产生错误,终进程停止,攻击者无法入侵,这就是地址空间布局随机化的基本思想。
查看并修改当前系统的ASLR设定:
1 |
|
PIE
PIE 是 gcc 编译器的功能选项,作用于程序(ELF)编译过程中。是一个针对代码段( .text )、数据段( .data )、未初始化全局变量段( .bss )等固定地址的一个防护技术。程序运行时各个段加载的虚拟地址也是在装载时才确定,这就意味着,在PIE开启的情况下,攻击者将对程序的内存布局一无所知。这也防止了通过 ROPgadget 等一些工具来帮助解题。
1 |
|
内存地址随机化机制,有三种情况
- 0 - 表示关闭进程地址空间随机化
- 1 - 表示将mmap的机制,stack和vdso页面随机化
- 2 - 表示在1的基础上增加堆(heap)的随机化
总结
作用位置 | 归属 | 作用时间 | |
---|---|---|---|
ASLR | 1:栈基地址(stack)、共享库(.so\libraries)、mmap 基地址 2:在1基础上,增加随机化堆基地址(chunk) |
系统功能 | 作用于程序(ELF)装入内存运行时 |
PIE | 代码段( .text )、初始化数据段( .data )、未初始化数据段( .bss ) | 编译器功能 | 作用于程序(ELF)编译过程中 |
PWN技巧
- One-gadget
- 通用dadget及Return-to-csu
- 劫持hook函数
- 利用DynELF泄露函数地址
- SSP Leak
- 利用environ泄露栈地址
- 利用_IO_FILE结构
- 利用vsyscall
神奇的小知识
如何检查文件的保护情况
checksec 文件名(要以root权限执行)
编译时如何关闭这些保护呢
1 |
|
查看程序使用了哪些函数
objdump命令是用查看目标文件或者可执行的目标文件的构成的gcc工具
-j hello 仅仅显示指定名称为hello的section的信息
-t 显示文件的符号表入口
objdump -t -j .text hello
查看hello程序的.text段有哪些函数
环境搭建
一、Ubuntu 环境搭建
虚拟机安装
当初尝试搭建ubuntu16.04的环境,但是搭建了大半天pwntools还是不行。所以这次尝试ubuntu20.04,选择20.04是因为现在很多打比赛的题目大部分都是libc2.27以上的了。
官方镜像下载:https://releases.ubuntu.com/focal/
下载好镜像之后就可以在VMware上安装了。
安装完后打开终端更新软件列表:
1 |
|
虚拟机挂起恢复后,无法联网
1 |
|
系统自动登入root账户
Ubuntu20.04安装完成之后,默认是没有root账户登录权限的,这样在操作系统时有诸多不便,比如新建一个文件都提示权限不够!不过可以通过创建的普通用户获取管理员权限,然后修改配置和root账户的密码,最后实现系统自动登录root账户,具体操作步骤如下:
设置密码
1
sudo passwd root
然后按照提示,先输入当前账户的密码,然后是root账户密码,最后再确认密码。
修改系统配置文件 (先安装vim编辑器)
1
sudo vim /usr/share/lightdm/lightdm.conf.d/50-ubuntu.conf
进入50-ubuntu.conf的文件中,并在文件中最后添加两行:
1
2
3
4[Seat:*]
user-session=ubuntu
greeter-show-manual-login=true //手工输入登录系统的用户名和密码
all-guest=false //不允许guest登入修改autologin和password文件
1
sudo vim /etc/pam.d/gdm-autologin
注释掉第三行
1
2
3
4
5
6#%PAM-1.0
auth requisite pam_nologin.so
#auth required pam_succeed_if.so user != root quiet_success //注释掉此行
auth optional pam_gdm.so
auth optional pam_gnome_keyring.so
auth required pam_permit.so保存退出后执行:
1
sudo vim /etc/pam.d/gdm-password
注释掉第三行然后保存退出
1
2
3
4
5
6#%PAM-1.0
auth requisite pam_nologin.so
#auth required pam_succeed_if.so user != root quiet_success //注释掉此行
@include common-auth
auth optional pam_gnome_keyring.so
@include common-account修改profile文件
1
sudo vim /root/.profile
在文件中修改配置如下:
1
2
3
4
5
6
7
8
9# ~/.profile: executed by Bourne-compatible login shells.
if [ "$BASH" ]; then
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
fi
tty -s && mesg n || true //添加此行
mesg n 2> /dev/null || true修改custom.conf文件
1
sudo vim /etc/gdm3/custom.conf
修改如下:
1
2
3
4
5
6
7
8# Enabling automatic login
AutomaticLoginEnable=true #是否自动登录系统,设为ture时每次会自动进入系统,而不用输密码
AutomaticLogin=root #自动登录系统时的默认用户名
# Enabling timed login
TimedLoginEnable=true #是否开启超时自动登录
TimedLogin=root #超时自动登录的用户
TimedLoginDelay=10 #超时时间重启系统就会自动登录到root账户了
1
sudo reboot
安装 vim
vim 是vi的升级版本,它不仅兼容vi的所有指令,而且还有一些新的特性在里面。 vi使用于文本编辑,但是vim更适用于coding。
1 |
|
安装 git
后续会经常在github上拽工具,所以git必装
1 |
|
安装 gcc
GCC(GNU Compiler Collection)是由GNU开发的编程语言译器,必装啦,这个不用说了,自己想要编写一些demo的时候需要gcc进行编译,后续ARM交叉编译环境也需要gcc支持
1 |
|
安装 python3-pip
pip 是一个现代的,通用的 Python 包管理工具。提供了对 Python 包的查找、下载、安装、卸载的功能。
因为python2已经不再维护了,所以后续很多工具所需的依赖python2会出错,python3不会有什么问题。
1 |
|
创建 PWN目录
建议在主目录下创建一个tools目录,这样我们所有git下来的工具就有统一存放的位置,也方便后续查找
1 |
|
安装 pwntools
Pwntools是一个CTF框架和开发库。它是用Python编写的,由rapid设计,旨在让使用者简单快速的编写exploit。
Pwntools有两种安装方法,一种是git项目后安装,另一种是pip直接安装。这里我们把pwntools git下来,但是用pip安装,因为后续的工具需要pwntools项目包里的脚本,pip安装不会出错。
1 |
|
检验以下,如果导包后没报错安装成功:
1 |
|
安装 pwndbg
pwndbg是gdb的插件,帮助我们在做题时进行调试。当然你喜欢gef,或者peda也随意。
1 |
|
安装后在命令行输入gdb回车,如果左下角出现pwndbg代表安装成功。
安装 checksec
一个辅助工具,可以用来检测二进制文件格式和安全防护情况。安装完pwntools后,checksec也会自动被安装上。可以在目录/usr/bin
下找到checksec的脚本。
除了pwntools自带的,我们也可以选择在线安装:
1 |
|
安装 32位的库
gcc-multilib可用于交叉编译(cross compiling),即编译程序以在不同的处理器架构上运行。例如可以在x86_64位处理器上编译出x86_32位程序,运行在32位处理器上,或者在x86平台上编译出可以在ARM处理器上运行的程序。
1 |
|
其他网站
https://hollk.blog.csdn.net/article/details/118188924
https://blog.csdn.net/qq_54218833/article/details/125241618
https://blog.csdn.net/Y_peak/article/details/120712904
二、Kali 环境搭建
虚拟机安装
Ubuntu的界面和命令行不够优雅,所以这次尝试Kali 2021.1,选择这个版本是因为系统相对稳定流程,并且zsh的颜色配置相对完善。
官方镜像下载:https://old.kali.org/kali-images/
下载好镜像之后就可以在VMware上安装了。
安装完后打开终端更新软件列表:
1 |
|
系统自动登入账户
安装完成之后,默认是没有root账户登录权限的,这样在操作系统时有诸多不便,比如新建一个文件都提示权限不够!不过可以通过创建的普通用户获取管理员权限,然后修改配置和root账户的密码,最后实现系统自动登录用户账户,具体操作步骤如下:
设置密码
1
sudo passwd root
然后按照提示,先输入当前账户的密码,然后是root账户密码,最后再确认密码。
修改系统配置文件
1
sudo vim /etc/lightdm/lightdm.conf
进入lightdm.conf的文件中,把这两行的注释删除然后修改参数保存:
1
2
3[Seat:*]
autologin-user=jacckx
autologin-user-timeout=0修改autologin文件,实现自动登入账户
1
sudo vim /etc/pam.d/lightdm-autologin
注释掉这一行
1
#auth required pam_succeed_if.so user != root quiet_success //注释掉此行
重启系统就会自动登录到账户,不需要输入密码了
1
sudo reboot
创建 PWN目录
建议在主目录下创建一个tools目录,这样我们所有git下来的工具就有统一存放的位置,也方便后续查找
1 |
|
安装 pwntools
Pwntools是一个CTF框架和开发库。它是用Python编写的,由rapid设计,旨在让使用者简单快速的编写exploit。
Pwntools有两种安装方法,一种是git项目后安装,另一种是pip直接安装。这里我们把pwntools git下来,但是用pip安装,因为后续的工具需要pwntools项目包里的脚本,pip安装不会出错。
pip 是一个现代的,通用的 Python 包管理工具。提供了对 Python 包的查找、下载、安装、卸载的功能。
因为python2已经不再维护了,所以后续很多工具所需的依赖python2会出错,python3不会有什么问题。
1 |
|
检验以下,如果导包后没报错安装成功:
1 |
|
安装 gdb
kali系统里没有安装gdb
1 |
|
安装 pwndbg
pwndbg是gdb的插件,帮助我们在做题时进行调试。当然你喜欢gef,或者peda也随意。
1 |
|
安装后在命令行输入gdb回车,如果左下角出现红色(pwndbg)代表安装成功。
安装 checksec
一个辅助工具,可以用来检测二进制文件格式和安全防护情况。安装完pwntools后,checksec也会自动被安装上,可以在目录~/.local/bin
下找到checksec的脚本。最后就是把这个路径加到环境变量里,首先打开:
1 |
|
在最后一行添加:
1 |
|
保存退出后运行这个命令来更新:
1 |
|
除了pwntools自带的,我们也可以选择在线安装:
1 |
|
安装 32位的库
gcc-multilib可用于交叉编译(cross compiling),即编译程序以在不同的处理器架构上运行。例如可以在x86_64位处理器上编译出x86_32位程序,运行在32位处理器上,或者在x86平台上编译出可以在ARM处理器上运行的程序。
1 |
|
三、其他选装工具
安装 sublime-text
1 |
|
安装 aptitude
1 |
|
安装 gdebi
gdebi是一个用于安装你自己手动下载的包的GUI程序。
1 |
|
用gdebi安装deb包,它将会自动安装deb包所需要的依赖包:
1 |
|
逆向工程基础
内存管理
在操作系统中,为了防止直接分配和使用物理内存造成的诸如内存不足、安全性不足、内存碎片化等问题,采用了虚拟内存空间技术。利用这一手段,只有在进程真正需要访问内存资源时才产生缺页中断,建立虚拟内存地址和物理地址的映射,从而避免了内存浪费。虚拟内存的主要作用是:
- 为每个进程提供了一致的地址空间。
- 保护每个进程的空间不被其他进程破坏。
- 程序运行时只在内存中保存需要的数据,并根据需要在磁盘和内存之间来回传送数据(缺页中断)。
x86-32位虚拟地址空间
在Linux中,系统为每个进程维持了一个单独的虚拟地址空间,包括了 .text、.data、.bss、stack、heap,共享库等内容。
在这个单独的虚拟地址空间中,空间被划分为内核空间
和用户空间
。访问内核空间需要程序有ring0的权限,尽管存在特权分离,但它们都共享相同的虚拟地址空间。
在Linux x86-32位中,4GB地址空间被划分成:
3GB的用户空间,地址从0x08048000 ~ 0xBFFFFFFF
1GB的内核空间,地址从0xC0000000 ~ 0xFFFFFFFF
而Windows对空间的划分不同于Linux,4G 地址空间中低2G,0x00000000 ~ 0x7FFFFFFF 是用户地址空间。高2G,0x80000000 ~ 0xFFFFFFFF 是系统地址空间。
glibc
glibc 即 GNU C Library,是为 GNU 操作系统开发的一个 C 标准库。glibc 主要由两部分组成,一部分是头文件,位于 /usr/include
;另一部分是库的二进制文件。二进制文件部分主要是 C 语言标准库,有动态和静态两个版本,动态版本位于 /lib/libc.so.6
,静态版本位于 /usr/lib/libc.a
- 本文作者:Jacckx
- 本文链接:http://jacckx.me/2023/07/09/PWN/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!