2021全国大学生信息安全竞赛初赛部分Write up

全国大学生信息安全竞赛初赛部分Write up

纯队友做出来的就不写了,只写一下我参与解题的。(不会WEB,不会PWN,我打个锤子的ctf)

Misc

tiny traffic

流量题,直接过滤http包,在末尾发现两个GET请求,分别获取了testsecret的br包。

http包
使用python对br包进行解压,发现test是proto3的源码,secret是一串字节型数据。

<!-- /test.protp -->
syntax = "proto3";

message PBResponse {
  int32 code = 1;
  int64 flag_part_convert_to_hex_plz = 2;
  message data {
    string junk_data = 2;
    string flag_part = 1;
  }
  repeated data dataList = 3;
  int32 flag_part_plz_convert_to_hex = 4;
  string flag_last_part = 5;
}

message PBRequest {
  string cate_id = 1;
  int32 page = 2;
  int32 pageSize = 3;
}

利用/test的源码可以对数据进行序列化,因此尝试对secret反序列化。

使用protobuf编译工具将/test的源码编译成python脚本。

./protoc.exe --python_out=. test.proto

生成test_pb2.py, 然后用python编写脚本反序列化secret,得到flag的五个部分,按要求进行拼接即可。

test = b'\x1b\x68\x01\x00\x1c\x07\x8e\xdb\x90\xdb\x43\xd4\x8f\x63\xd0\x96\xdb\xbc\x24\xed\x15\x2c\xd3\x02\x5e\xb0\xfe\x58\xa3\x41\x14\xd2\xfa\xd6\x8e\x90\xe5\xad\xa2\x27\xb1\xba\xdf\xde\x66\x14\xd1\x46\xd2\x84\xa6\x91\x4c\x88\x4a\x12\xaa\x12\xe8\x36\xa1\xe3\x11\xc2\xd4\x2d\x09\x8a\xbd\x7d\xed\xef\x74\xa4\x8f\x33\x7e\xd9\xe6\x63\x26\xaf\x02\x8a\x0b\x75\x87\xfe\x8f\x4d\x07\xe1\xcb\xa1\x1a\xe0\x4d\xca\xf6\xeb\x22\xc9\x10\x8f\xea\x2b\x1e\x73\x6c\xca\x27\x2e\xc3\x17\xad\x90\xcb\x02\x99\x0a\x7a\x92\x4c\xeb\xce\xa9\x8f\x4b\x08\x1f\xcc\xd6\x66\xc8\xfa\xf8\x21\x29\xa4\xd1\x04\x0a\x49\x36\x44\x4a\x23\x04\x8b\x19\x31\x33\x24\x8f\x38\x68\x37\x83\x09\xd9\xbc\x0b\x74\xa1\x2d\x7f\xde\x3d\x4f\x8f\x32\xb6\x85\x45\xc2\xe7\xd6\xc1\xa0\x17\x12\x0d\xf1\x73\x07'
secret = b'\x0b\x1c\x80\x08\xc8\x01\x10\xa2\xd4\x99\x07\x1a\x0e\x0a\x05\x65\x32\x33\x34\x35\x12\x05\x37\x61\x66\x32\x63\x1a\x0f\x0a\x06\x37\x38\x38\x39\x62\x30\x12\x05\x38\x32\x62\x63\x30\x20\xc6\xa2\xec\x07\x2a\x09\x64\x31\x37\x32\x61\x33\x38\x64\x63\x03'

import brotli
import test_pb2
# test = brotli.decompress(test).decode('utf-8')
# print(test)
secret = brotli.decompress(secret)
target = test_pb2.PBResponse()
target.ParseFromString(secret)
print(target)
flag = hex(target.flag_part_convert_to_hex_plz)[2:] + target.dataList[0].flag_part + target.dataList[1].flag_part + hex(target.flag_part_plz_convert_to_hex)[2:] + target.flag_last_part
print('CISCN{%s}' %flag)

running_pixel

gif隐写,第一步是分离每一帧,使用kali上的convert命令:

convert running_pixel.gif running_pixel.png

得到382帧图像,仔细查看,发现有些图像中有极小的白点。

异常像素点

使用画图提取小白点的位置和像素,像素值为(233,233,233)。发现临近的帧在临近的位置有相同像素的小白点。使用python脚本提取所有帧中的位置,并按照顺序重新绘图。

from PIL import Image

pix_t = []
pix_s = []
# 获取所有异常像素点
for k in range(382):
    fname = './in/running_pixel-'+str(k)+'.png'
    img = Image.open(fname)
    img = img.convert("RGB")
    for i in range(400):
        for j in range(400):
            tmp = img.getpixel((i,j))
            if tmp == (233,233,233):
                pix_t.append([i,j])
# print(pix_t)      

# 将异常像素点按顺序按字符分组绘图并放大
def create_letter(pixel, path):
    img = Image.new("RGB", [15,15], 'white')
    pix = img.load()
    l0, l1 = pix_t[start][0]-5, pix_t[start][1]-5
    for each in pixel:
        pix[each[1]-l1, each[0]-l0] = 1
    img = img.resize((75, 75), Image.ANTIALIAS)
    img.save('./out/'+str(path)+'.png')

start = 0
name = 0
for i in range(1, len(pix_t)):
    if abs(pix_t[i][0]-pix_t[i-1][0])>=2 and abs(pix_t[i][1]-pix_t[i-1][1])>=2:
        create_letter(pix_t[start:i], name)
        name += 1
        start = i
create_letter(pix_t[start:], name)

最后画出来的异常像素如下图所示:
结果

Crypto

rsa

分析源码,三段rsa加密破解分别满足小公钥指数攻击共模攻击已知高位攻击。原理有一点点复杂,但是好在都给了实现的代码,改一改就能用。

对于已知高位攻击,使用sage是最方便的,如果没有装,可以使用在线版

from sage.all import *
import binascii
n = 113432930155033263769270712825121761080813952100666693606866355917116416984149165507231925180593860836255402950358327422447359200689537217528547623691586008952619063846801829802637448874451228957635707553980210685985215887107300416969549087293746310593988908287181025770739538992559714587375763131132963783147
p4 = 7117286695925472918001071846973900342640107770214858928188419765628151478620236042882657992902
cipher = 59213696442373765895948702611659756779813897653022080905635545636905434038306468935283962686059037461940227618715695875589055593696352594630107082714757036815875497138523738695066811985036315624927897081153190329636864005133757096991035607918106529151451834369442313673849563635248465014289409374291381429646
e = 65537
pbits = 512
kbits = pbits - p4.nbits()
p4 = p4 << kbits
PR.<x> = PolynomialRing(Zmod(n))
f = x + p4
roots = f.small_roots(X=2^kbits, beta=0.4)
if roots:
    p = p4 + int(roots[0])
    assert n % p == 0
    q = n/int(p)
    phin = (p-1)*(q-1)
    d = inverse_mod(e,phin)
    flag = hex(int(pow(cipher,d,n)))[2:]
    print(binascii.unhexlify(flag))
    # b'nd black, and pale, and hectic red,\nPestilence-stricken multitudes: O thou,\nWho chariotest to their dark wintry bed\n'

其他两部分python就可以实现

import md5
from gmpy2 import *

n1 = 123814470394550598363280518848914546938137731026777975885846733672494493975703069760053867471836249473290828799962586855892685902902050630018312939010564945676699712246249820341712155938398068732866646422826619477180434858148938235662092482058999079105450136181685141895955574548671667320167741641072330259009
e1 = 3
c1 = 19105765285510667553313898813498220212421177527647187802549913914263968945493144633390670605116251064550364704789358830072133349108808799075021540479815182657667763617178044110939458834654922540704196330451979349353031578518479199454480458137984734402248011464467312753683234543319955893

n2 = 111381961169589927896512557754289420474877632607334685306667977794938824018345795836303161492076539375959731633270626091498843936401996648820451019811592594528673182109109991384472979198906744569181673282663323892346854520052840694924830064546269187849702880332522636682366270177489467478933966884097824069977
e2 = 17
e3 = 65537
c2 = 54995751387258798791895413216172284653407054079765769704170763023830130981480272943338445245689293729308200574217959018462512790523622252479258419498858307898118907076773470253533344877959508766285730509067829684427375759345623701605997067135659404296663877453758701010726561824951602615501078818914410959610
c3 = 91290935267458356541959327381220067466104890455391103989639822855753797805354139741959957951983943146108552762756444475545250343766798220348240377590112854890482375744876016191773471853704014735936608436210153669829454288199838827646402742554134017280213707222338496271289894681312606239512924842845268366950
c3 = invert(c3, n2) 

n3 = 113432930155033263769270712825121761080813952100666693606866355917116416984149165507231925180593860836255402950358327422447359200689537217528547623691586008952619063846801829802637448874451228957635707553980210685985215887107300416969549087293746310593988908287181025770739538992559714587375763131132963783147
c4 = 59213696442373765895948702611659756779813897653022080905635545636905434038306468935283962686059037461940227618715695875589055593696352594630107082714757036815875497138523738695066811985036315624927897081153190329636864005133757096991035607918106529151451834369442313673849563635248465014289409374291381429646
p4 = 7117286695925472918001071846973900342640107770214858928188419765628151478620236042882657992902

def get_m1():
    inputs = range(0, 100)
    for i in inputs:
        a, b = iroot(c1 + i * n1, 3)
        if b == 1:
            return '{:x}'.format(int(a)).decode('hex')

def get_m2():
    s = gcdext(e2, e3)
    s1 = s[1]
    s2 = -s[2]
    m = (pow(c2,s1,n2) * pow(c3 , s2 
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值