[pearlctf 2024] crypto 部分

news/2024/5/20 0:14:52 标签: ctf

休的时间有点长,慢慢的不想打比赛了。周六有个外国比赛,上来签到题就卡了。

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 #n

rick 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个题有点看不懂。


http://www.niftyadmin.cn/n/5423660.html

相关文章

三色标记过程

可达性分析 GC过程中需要对对象图遍历做可达性分析。使用了三色标记法进行分析。 什么三色&#xff1f; 白色&#xff1a;尚未访问过。 黑色&#xff1a;本对象已访问过&#xff0c;而且本对象 引用到 的其他对象 也全部访问过了。 灰色&#xff1a;本对象已访问过&#xff0…

【数据挖掘】实验1:R入门(内含详细R和RStudio安装教程)

实验1&#xff1a;R入门 一&#xff1a;实验目的与要求 1&#xff1a;根据上课PPT内容&#xff0c;掌握课堂知识并进行代码练习操作&#xff0c;提供练习过程和结果。 2&#xff1a;可COPY代码运行结果直接提交&#xff0c;如涉及到输出图等可截图。 二&#xff1a;实验内容 …

蓝牙系列七:开源蓝牙协议栈BTStack数据处理(Wireshark抓包分析)

继续蓝牙系列的研究。 在上篇博客&#xff0c;通过阅读BTStack的源码&#xff0c;大体了解了其框架&#xff0c;对于任何一个BTStack的应用程序都有一个main函数&#xff0c;这个main函数是统一的。这个main函数做了某些初始化之后&#xff0c;最终会调用到应用程序提供的btst…

【Node.js从基础到高级运用】七、基本的网络编程

基本的网络编程 在这一节中&#xff0c;我们将介绍 Node.js 在网络编程方面的基础&#xff0c;特别是如何使用 Node.js 创建一个 HTTP 服务器。这是构建 Web 应用和服务的核心技能。 创建 HTTP 服务器 Node.js 的 http 模块提供了创建 HTTP 服务器和客户端的能力。以下是创建…

AHU 汇编 实验四

实验名称&#xff1a;实验四 两个数的相乘 实验内容&#xff1a; 用子程序形式编写&#xff1a; A*B&#xff1a;从键盘输入a和b&#xff0c;计算A*B&#xff0c;其中乘法采用移位和累加完成 实验过程&#xff1a; 源代码&#xff1a; data segmentmul1 db 16,?,16 dup(?…

共享内存使用

1.shmget 创建/获取内核共享内存 2.shmat(attach)关联到当前进程地址空间 3.通过指针读写共享内存 4.shmdt(detech)进程分离共享内存 5.shmctl删除共享内存 附上案例 第一种&#xff1a;在同一个执行文件中通过fork的方式创建子进程 #include <stdio.h> #include …

在OpenStack架构中,Controller节点的配置(基础)

虚拟机的安装 新建虚拟机&#xff0c;选择自定义 默认选择即可 操作系统的镜像稍后选择 客户及操作系统选择Linux&#xff0c;注意选择centos 7 64位 给虚拟机命名 处理器的配置建议1&#xff1a;2 内存大小选择建议为&#xff1a;4GB 网络连接选择为&#xff1a;NAT 默认即可…

npm、gnvm常用命令

npm常用命令 npm -v:查看npm版本号npm config list:查看配置信息&#xff0c;比如node_cache和node_global的位置npm config get registry&#xff1a;查看镜像地址npm config set registry https://npm.aliyun.com/ 设置镜像地址 npm cache clean --force&#xff1a;强制清理…