Pwn安全措施
NX: No Exection
    gcc -z execstack
Canary: defeat bof, 在 return 前做 canary check
    - security_init() => fs:0x28 (stack guard)
    - canary end with \x00
    gcc -fno-stack-protector: no canary
    gcc -fstack-protector-all: 所 function 都开启 canary
ASLR:
    - Address Space Layout Randomization
    - stack, heap, shared libraries
    echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
PIE:
    - Position Independent Executable
    - binary randomization
    gcc -fno-pie
FULL RELRO:
    - load binary  library, 并设为只读

No eXecute (NX Bit)

No eXecute 或 NX Bit,也称为 Data Execution Prevention (数据执行保护, 简称 DEP)将程序的某些区域标记为不可执行,这意味着存储的输入或数据不能作为代码执行。它可以防止攻击者跳转到他们存储在堆栈或全局变量中的自定义 shellcode。

Stack Canaries

Stack Canaries 是放置在堆栈上的秘密值,每次启动程序时都会更改。 在函数返回之前,检查 Stack Canary,如果它被修改,程序立即退出。

Stack

绕过 Stack Canaries

Stack Canaries 似乎是减轻任何堆栈破坏的一种明确方法,因为仅靠猜测随机获取 64 位值是相当不可能的。 然而,泄露地址暴力破解是两种可以绕过 Canary 检查的方法。

泄露 Stack Canary

如果可以读取 Stack Canary 中的数据,我们可以稍后将其发送回程序,因为 Canary 在整个执行过程中保持不变。 然而,Linux 通过将 Stack Canary 的第一个字节设置为 NULL 使这有点棘手,这意味着字符串函数将在遇到它时停止。 解决此问题的一种方法是部分覆盖,然后将 NULL 放回原处,或者找到一种方法在任意堆栈偏移量处泄漏字节。

可能会泄漏 Canary 的几种情况:

  • 用户控制的格式字符串
  • 用户控制的输出长度

爆破 Stack Canary

Canary 是在程序第一次启动时确定的,这意味着如果程序 fork,它会在子进程中保留相同的堆栈 cookie。 这意味着如果将可以覆盖 Canary 的输入被发送给子进程,我们可以根据它是否崩溃来一次暴力破解 1 个字节!

此方法可用于将连接拆分到子进程的 fork-and-accept 服务器上,但仅在某些条件下适用,例如当程序不向接收的输入插入 NULL 字节( readrecv )时。

Buffer (N Bytes) ?? ?? ?? ?? ?? ?? ?? ?? RBP RIP

向缓冲区填充 N Bytes + 0x00 没有导致崩溃

Buffer (N Bytes) 00 ?? ?? ?? ?? ?? ?? ?? RBP RIP

向缓冲区填充 N Bytes + 0x00 导致了崩溃

N Bytes + 0x00 + 0x01 导致了崩溃

N Bytes + 0x00 + 0x02 导致了崩溃

...

N Bytes + 0x00 + 0x51 没有导致崩溃

Buffer (N Bytes) 00 51 ?? ?? ?? ?? ?? ?? RBP RIP

重复这个过程爆破剩下的 6 个字节......

Buffer (N Bytes) 00 51 FE 0A 31 D2 7B 3C RBP RIP

现在我们有了堆栈 cookie,我们可以覆盖 RIP 寄存器并控制程序!

Address Space Layout Randomization (ASLR)

Address Space Layout Randomization (地址空间布局随机化,简称 ASLR)是内存中程序、共享库、堆栈和堆所在位置的随机化。 这使得攻击者更难利用,因为在不同的程序启动之间无法重用堆栈、堆或 libc 的位置。 这是防止攻击者在没有泄漏的情况下跳转到例如 libc 的一种部分有效的方法。

通常,只有堆栈、堆和共享库启用了 ASLR。 主程序启用 ASLR 的情况仍然很少见,尽管它越来越频繁地出现并且正在慢慢成为默认设置。

Position Independent Executable (PIE)

Position Independent Executable(位置无关的可执行文件,简称 PIE)是可执行文件层面的 ASLR。

在 gcc/linkers 中启用 PIE 支持后,程序主体被编译并链接为与位置无关的代码。 动态链接器对程序模块进行完全重定位处理,就像动态库一样。 全局数据的任何使用都通过全局偏移表 (GOT) 转换为访问,并添加了 GOT 重定位。

Relocation Read-Only (RELRO)

Relocation Read-Only(重定位只读,简称 RELRO)是一种安全措施,使某些二进制节(sections)只读。

有两种重定位模式:partial(部分) 和 full(全部)。

Partial RELRO

Partial RELRO 是 GCC 中的默认设置,几乎所有二进制文件都至少有Partial RELRO。

从攻击者的角度来看,部分 RELRO 的作用在于强制 GOT 位于内存中的 BSS 之前,消除了全局变量上的 缓冲区溢出 覆盖 GOT 条目的风险。

Full RELRO

Full RELRO 使整个 GOT 成为只读的,从而消除了执行“GOT 覆盖”攻击的能力。

Full RELRO 不是默认编译器设置,因为需要必须在程序启动之前解析所有符号,会大量增加程序启动时间。 在需要链接数千个符号的大型程序中,这可能会导致启动时间明显延迟。

整理自网络

主要来源:

https://ctf101.org/binary-exploitation/what-is-binary-security/

https://hackmd.io/@u1f383/pwn-cheatsheet

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇