休的时间有点长,慢慢的不想打比赛了。周六有个外国比赛,上来签到题就卡了。
Rick Roll
给了个pdf,一眼丁真就是维吉尼亚
Civvc Ihsce Gzgg Rtj Yp
Np'tx sd wtilpzjgw tf wqoj
Nsu byqp ywi rlwgl fch sf oq B
F uylc nqfrxxmvyv'l bwet Z'x vancoier qy Ddy wffnws'i kek ejbx uvod lpr tilei rwr N yysk hcgsp xecw ahz wsw Z'x
hxjamnx Rqmyp qabp ahz jrdvcumfch
Nvggk ldrnr rkoj nsu la Pxatv gfypt qtx yff fhbc
Rempt ztcra ifp twdynu lpw itweie ahz Civvc ihsce mrvg rtj grp
Ygojg koeyc lfn kofodrj
Civvc ihsce tvwn t qxi aeo jnwi col Hg'oj zrony gthw stypt ytg wo czpz
Ddyr ypcky'h fevy cvmxrg sfv rtj've kzq lmn xo jla by Xrszog pj qsty vphb llak'd dxjc kozyi hs
tzqo pdsdkft mr soyhzqyki zg xfqiqhzsqu
Wv vphb ile xlox fch wv'cg ztcra gwcr ni Enu th rtj esb xg atl M'm wpgenck
Dfy'v mjap mv jqn'wt xof mnbss xo jpg Gjkir xzpgf vmvv jqn ze
Rempt ztcra cpv rtj hony
Pxatv gfypt wjr aizwgi prd upuxwi col Ygojg koeyc ffzi yff ekd
Civvc ihsce srj ihtsfyv
Ygojg koeyc mjap a ctg tss luie ahz Civvc ihsce gzgg rtj yp
Epxxw vsnel nxy nsu uzyg
Stzei rqgsp vue lthzch aeo fxxtvt pzw Gjkir xzpgf bekv jqn hgc
Nvggk ldrnr dcr ldsdsjg
Gjkir xzpgf iilc l nbj prd yftm ddy Nvggk ldrnr rkoj, civvc ihsce gzgg (Znki yff wi)
(Tdl) Nvggk ldrnr rkoj, civvc ihsce gzgg (Znki yff wi)
但到网站上解出来后,离flag还很远
Never Gonna Give You Up
We're no strangers to love
You know the rules and so do I
A full commitment's what I'm thinking of You wouldn't get this from any other guy I just wanna tell you how I'm
feeling Gotta make you understand
Never gonna give you up Never gonna let you down
Never gonna run around and desert you Never gonna make you cry
Never gonna say goodbye
Never gonna tell a lie and hurt you We've known each other for so long
Your heart's been aching but you're too shy to say it Inside we both know what's been going on
evqx ebzyvbt vg qvtsvqhzg gb ibqrffgnbq
We know the game and we're gonna play it And if you ask me how I'm feeling
Don't tell me you're too blind to see Never gonna give you up
Never gonna let you down
Never gonna run around and desert you Never gonna make you cry
Never gonna say goodbye
Never gonna tell a lie and hurt you Never gonna give you up
Never gonna let you down
Never gonna run around and desert you Never gonna make you cry
Never gonna say goodbye
Never gonna tell a lie and hurt you Never gonna give, never gonna give (Give you up)
(Ooh) Never gonna give, never gonna give (Give you up)
显然flag就是那句
evqx ebzyvbt vg qvtsvqhzg gb ibqrffgnbq
在看了别人flag后复现,先用3字节的长度来爆破
qidj rolling is difficums to uoddsssaoc #key length:3 key:onn
然后分别用o和n来作为key分别来解,再根据大概意思组成可读单词
qhcj qnlkhnf hs chfehctls sn uncdrrsznc #o
ridk romliog it digfidumt to vodesstaod #nrick rolling is difficult to understand
pearlctf{rick_rolling_is_difficult_to_understand}
3 spies
古典密码已经没法玩了,全是musc,终于这题回到正题了,一个低加密指数广播攻击的题e=3给出3组n,c,直接用中国剩余定理
n1 = 125267411676839013904356880992044234494446196964982422223130579882047339346910691451497681975351838034684254305738613386927222900898672184001345811471784343779083336010063097729870079645284178978512325038316112509718505547104307526489798594871208559607331790920412305711830820739308995357441030646151241475357
e = 3
c1 = 53377681151597930200174280269480737905892580547675095951568028531545776989476273786562435486230550919422086944133253611872983670236114054374565938184593173194919064517779661178744278071496565181181705071524501841159717567250259220092464925447795412484629687708208662079791459184303259833667333882817260906165
n2 = 101985110329687359982214188967281711679876126442294375297547334583432698756724057183438691227371260175904715854057793173086301783390154807726779286131084537704721881438398569476214173211311977143694032174701007005033830070482491565424683664984059187439768982994371382763048098663670188786016786612348042190633
e = 3
c2 = 86370003324603283962938004647941072863866893771153362222202759619566185050496089684606274416415418388916028237984708280964054009059814813483639010674182298294505525549842057730933691736372086557397211586739691237738757897947336698446258197604918828646265244195686107866422922575275382813594250335044143485624
n3 = 83259448903366278561128205003734328779222118906091604625605804813528274055482582431201682767294594942491788720967344243567819654813240542076250030802111361571504667752481579915864184180358691091092122509649590043074189547962292835856503625214027405901620103615424259796442446412031011575671410630232956892267
e = 3
c3 = 25601241268900087228853235319569275926328919786631787991019848828558430219449358810095537362492238844266084660904521793373698736119824512458196492049138821633273765102576368573691391116632126183996786969554104441242376959688329346567745607825277943462236901478944551669406261301309719409165457168678763092118
m = crt([c1,c2,c3],[n1,n2,n3])
long_to_bytes(iroot(m,3)[0])
得到一个链接,出来base64的image,厨子直接能解base64
baby message out
第2个RSA的题,n由5个因子组成,每个因子又是由其它因子next组成
from Crypto.Util.number import getPrime, isPrime, bytes_to_long
from flag import FLAG
from math import log
import sys
n = pow(10, 5)
sys.setrecursionlimit(n)
def nextPrime(p):
if isPrime(p):
return p
else:
return nextPrime(p + 61)
p = getPrime(256)
q = nextPrime(nextPrime(17*p + 1) + 3)
r = nextPrime(29*p*q)
s = nextPrime(q*r + p)
t = nextPrime(r*s*q)
n = p*q*r*s*t
e = 65537
m = bytes_to_long(FLAG.encode())
c = pow(m, e, n)
print(f"c: {c}")
print(f"n: {n}")
c=1838979268925267202615818395622122484893202706167722156383681963142079180161531237936585341507802530813847301831886857107840552940103096671213346624172927405178565892385733216702672851783423891229382579221604596673156151519463795808010572632138076246765227545034269340790242411584582692558549837221897037971538915332866933837117883228953143242965510280921618063635225603250391037969273250144174802927111408106890496901519737395485115788436384012937788617630381389196078818501905993385084557887716148781944416313908553565974546239241287340505018036547080504009483360838747251073440799502791555942879229132369697126614944991347408598924472158561247485575276852356316968119522601927483600978106155875300324966339458896992260918634629607740522754923275555209240690069838566642421234035117257380757518902549668151860260985363114235340791362277047923494577018035035653075155240898800910887230020812289524262582877697129108304758256250595391379019020972909027192107727799235384374670082518555887502478560056865020860127002
n= 485889862688353809145356849681869098056742135790325154633816315764783289109350404808839464043297429168130293002483316664607770068196944445394490388957147529192164743228508084885030734914365245916125607677185307000076761646830755541107131137865984020648243428286711853728051263128076845261298240617545417811431124904304446607845470628505361436115651109768237103000946120781642652665829238385087624612205525857191218811570122228639908283598707567056620352822139985271817003262919597858495812801663331842855143930997258260164422858382713240717739568744168349527025412634588705503126870149875268600539407786323924132037483972529603572727892740460450963315253482630345996561505957763886776070413535287129043703855880444326909520084249767518737040222995586717034060176093473694948961503759770499124924886087468497100053775745634680192678426965540847613838559522315570932873854027804486662281273550134766570419630624914801192395060568099367828616501877701994364906741451132770474154689411119296104818089636891131318495955929
虽然next是作的61*k,但相对来说增量不大,大根算出一个关系
'''
q = 17*p + k1
r = 29*17*p^2
s = qr+p = 17*p*29*17*p^2 = 29*17^2*p^3
t = rsq = 17^4*29^2*p^6
n = p *17*p *29*17*p^2 *29*17^2*p^3 *17^4*29^2*p^6 = 17^8*29^4*p^13
'''
根据这个算出一个大概的p,再小爆破一下
from gmpy2 import iroot,invert
from sympy import prevprime
from Crypto.Util.number import long_to_bytes
tp = iroot(n//(17**8*29**4),13)[0]
for i in range(100000):
tp = prevprime(tp)
if n%tp == 0:
print(tp)
break
#99882362437773265966124030773296517807358944792642701044820437308947621061961
long_to_bytes(pow(c,invert(0x10001, tp-1),tp))
#b'pearl{7h1s_0n3_w4s_f0r_7h3_k1ds}'
Security++
魔改的AES的padding oracle,固定pad,但分奇偶段加密,没作,应该不难。
from flag import flag, key
from base64 import b64encode
from enc import encrypt_block, pad
def encrypt(data: bytes):
pt = data + flag
pt = pad(pt)
block_count = len(pt) // 16
encText = b''
for i in range(block_count):
if i % 2 == 0:
encText += encrypt_block(pt[i * 16:i * 16 + 16], key[0:16])
else:
encText += encrypt_block(pt[i * 16:i * 16 + 16], key[16:])
return encText
def main():
while 1:
msg = input("\nEnter plaintext: ").strip()
res = encrypt(msg.encode())
print(b64encode(res).decode())
if __name__ == '__main__':
main()
from copy import copy
s_box = (
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16,
)
def bytes2matrix(text):
return [list(text[i:i + 4]) for i in range(0, len(text), 4)]
def matrix2bytes(m):
plaintext = b''
for row in range(4):
for j in range(4):
plaintext += chr(m[row][j]).encode('latin-1')
return plaintext
def pad(text: bytes):
if len(text) % 16 != 0:
pad_len = ((len(text) // 16) + 1) * 16 - len(text)
else:
pad_len = 0
text = text.ljust(len(text) + pad_len, b'.')
return text
def sub_bytes(state, sbox):
for i in range(len(state)):
for j in range(4):
state[i][j] = sbox[state[i][j]]
return state
def shift_rows(s):
s[1][0], s[1][1], s[1][2], s[1][3] = s[1][1], s[1][2], s[1][3], s[1][0]
s[2][0], s[2][1], s[2][2], s[2][3] = s[2][2], s[2][3], s[2][0], s[2][1]
s[3][0], s[3][1], s[3][2], s[3][3] = s[3][3], s[3][0], s[3][1], s[3][2]
return s
def gmul(a, b):
if b == 1:
return a
tmp = (a << 1) & 0xff
if b == 2:
return tmp if a < 128 else tmp ^ 0x1b
if b == 3:
return gmul(a, 2) ^ a
def mix_col(col):
temp = copy(col)
col[0] = gmul(temp[0], 2) ^ gmul(temp[1], 3) ^ gmul(temp[2], 1) ^ gmul(temp[3], 1)
col[1] = gmul(temp[0], 1) ^ gmul(temp[1], 2) ^ gmul(temp[2], 3) ^ gmul(temp[3], 1)
col[2] = gmul(temp[0], 1) ^ gmul(temp[1], 1) ^ gmul(temp[2], 2) ^ gmul(temp[3], 3)
col[3] = gmul(temp[0], 3) ^ gmul(temp[1], 1) ^ gmul(temp[2], 1) ^ gmul(temp[3], 2)
return col
def add_round_key(state, round_key):
for i in range(len(state)):
for j in range(len(state[0])):
state[i][j] = state[i][j] ^ round_key[i][j]
return state
def encrypt_block(ptext: bytes, key):
cipher = ptext
rkey = bytes2matrix(key)
for i in range(10):
ctext = bytes2matrix(cipher)
ctext = sub_bytes(ctext, s_box)
ctext = shift_rows(ctext)
temp = copy(ctext)
for j in range(4):
column = [temp[0][j], temp[1][j], temp[2][j], temp[3][j]]
column = mix_col(column)
for k in range(4):
ctext[k][j] = column[k]
ctext = add_round_key(ctext, rkey)
cipher = matrix2bytes(ctext)
return cipher
Bit War
用c写的加密程序,输入2进制flag得到密文,由于是逐个加密的,所以可以逐爆破字典。感觉像作个pwn
#include <stdio.h>
#include <stdlib.h>
int main(){
char str[100];
int length = 8;
int rounds = 1000;
char * end;
unsigned int buffer = 0;
unsigned int bufferMask = 0xff;
unsigned int leftMask = 0x80;
unsigned int rightMask = 0x1;
while(scanf("%s", str)){
buffer = strtol(str, &end, 2); //2进制
unsigned int input = buffer;
for(int i = 0; i < rounds; i++){
unsigned int new = ((buffer & leftMask) >> 7) ^ (buffer & rightMask);
buffer = ((buffer << 1) & bufferMask) ^ new;
}
int inputBits[length];
int bufferBits[length];
int i = length;
while(i){
if(input & 0x1) inputBits[i-1] = 1;
else inputBits[i-1] = 0;
if(buffer & 0x1) bufferBits[i-1] = 1;
else bufferBits[i-1] = 0;
input = input >> 1;
buffer = buffer >> 1;
i--;
}
for(int i = 0; i < length; i++){
printf("%d", bufferBits[i]);
}
printf(" ");
}
}
from pwn import *
context.log_level = 'debug'
p = process('./a.out')
enc = '01001000 11010111 11010001 11001011 01011010 01000110 11011101 01001110 01001010 01110000 11010001 01110000 01011010 11010101 01001010 11001011 11000011'.split(' ')
dic = {}
for j in range(0x20,0x7f):
k = bin(j)[2:].zfill(8)
p.sendline(k)
v = p.recvuntil(b' ')[:-1].decode()
dic[v] = chr(j)
print(dic)
print(''.join([dic[i] for i in enc]))
#pearl{its_a_lfsr}
还差3个题有点看不懂。