攻防世界-Crypto

[简单] 初识RSA

刚开始还以为qp,pq跟dp,dq一样

后来发现题目给出了

pq = p*(q-1)
qp = q*(p-1)

hidden key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import  random
import hashlib
from Crypto.Util.number import *

# [140, 96, 112, 178, 38, 180, 158, 240, 179, 202, 251, 138, 188, 185, 23, 67, 163, 22, 150, 18, 143, 212, 93, 87, 209, 139, 92, 252, 55, 137, 6, 231, 105, 12, 65, 59, 223, 25, 179, 101, 19, 215]
# 2669175714787937

enc = [140, 96, 112, 178, 38, 180, 158, 240, 179, 202, 251, 138, 188, 185, 23, 67, 163, 22, 150, 18, 143, 212, 93, 87, 209, 139, 92, 252, 55, 137, 6, 231, 105, 12, 65, 59, 223, 25, 179, 101, 19, 215]

def rand(rng):
return rng - random.randrange(rng)

for idx in range(2669175714787937 << 12, (2669175714787937 << 12) + 4096):
key = long_to_bytes(idx)
random.seed(int(hashlib.md5(key).hexdigest(), 16))
flag = ""
for i in range(len(enc)):
rand(256)
xor = enc[i] ^ rand(256)
flag += chr(xor)
#
if 'flag' in flag:
print("flag is: {}\nkey is: {}".format(flag, idx))

easychallenge

这里我把题目给出的pyc文件重命名为test.pyc,反编译后的源代码放入test.py中,无需事先创建test.py,直接在pyc文件所在位置打开终端,输入下面这句命令即可:
(我用的是MacBook)
uncompyle6 -o test.py test.pyc

简单的LFSR

matrix()

矩阵所处环的表示
ZZ:整数环
QQ:有理数环
Zmod(p):p为素数,定义在Zp上
矩阵操作
声明
超完整定义

mt = matrix(QQ, 3, 2, [1, 2, 3, 4, 5, 6])

完整定义

mt = matrix(ZZ, 3, 4) #定义一个在整数环上的3行4列的矩阵
mt = matrix(ZZ, 0, 4) #定义一个在整数环上0行4列的矩阵,后期可动态添加行

部分定义

1
mt = matrix(QQ, 3, [1, 2, 3, 4, 5, 6]) #定义在有理数环上的3列矩阵,并赋值
求矩阵X满足XA=B

X = A.solve_left(B)

求矩阵X满足AX=B

X = A.solve_right(B)

确实不会直接看的WP

题目源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32


# a 01 string with length 128
# your flag is flag{md5(secret).hexdigest()}
secret='11111111111111011001111114211111111111111111111111111111111111111111111111111111111111111111111111111139111111111111111111111111'
def string2bits(s):#该函数将输入的字符串转换为位列表,其中每个字符都被转换为其二进制表示。
return [int(b) for b in s]

def lfsr(state, mask):
assert(len(state) == 128)
assert(len(mask) == 128)
nnn=0
output = 0
for i in range(128):
nnn=(state[i] * mask[i])
output = output + (state[i] * mask[i])#将 state 和 mask 的对应位相乘,将结果累加起来作为输出值 output
return output#state 和 mask 都是长度为 128 的二进制位序列,输出值 output 是一个十进制数。

if __name__ == '__main__':
initState = [0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0]
mask = string2bits(secret)

for i in range(256):#生成output放到initState的最后一位,并向前移一位i而进行下一次循环
state = initState[i:]
output = lfsr(state, mask)
initState += [output]

outputState = initState[128:]
print('outputState =', outputState)
#
# outputState = [31, 66, 128, 222, 385, 664, 1143, 2000, 3458, 6003, 10379, 17942, 31047, 53687, 92924, 160797, 278304, 481638, 833479, 1442422, 2496163, 4319845, 7475835, 12937561, 22389578, 38746915, 67054735, 116043520, 200822710, 347539886, 601445745, 1040850538, 1801275628, 3117252874, 5394657302, 9335889442, 16156509611, 27960142496, 48387281659, 83738092531, 144915522009, 250787996657, 434008851435, 751087316130, 1299817167363, 2249438425629, 3892834588915, 6736864173067, 11658686709797, 20176297502410, 34916709837729, 60426182042628, 104572380769600, 180970937597032, 313184800936842, 541991553121913, 937960088661442, 1623215570164618, 2809105439634215, 4861383488449105, 8413016146818879, 14559402864389777, 25196220721365800, 43604091771673155, 75460397027739861, 130590302153314191, 225997048627046433, 391106116962451401, 676840674047358730, 1171327366605398299, 2027076463289970382, 3508019282374090135, 6070910253447116278, 10506199749411485204, 18181825882182859769, 31465115864423937634, 54452920337985370536, 94235169707018163674, 163081560265112209496, 282225790871820528073, 488414489680745790033, 845240659945376349091, 1462757121910708796880, 2531419155626961478438, 4380824981460105751921, 7581370898424646092677, 13120173698498971899800, 22705518590912550882405, 39293730885686099313323, 68000969928723717268434, 117681162033195064953557, 203656740661184789826464, 352444412513853856490154, 609933476834387348179796, 1055539066458205919344242, 1826695472762162772755920, 3161243819621244340994611, 5470787351316040252901913, 9467638673598260118507327, 16384512191330329194463349, 28354719587732695891973236, 49070128760035595469947547, 84919814815174884654495265, 146960587438213290271803310, 254327147405947343219170013, 440133637427387650641676733, 761686751771954639615932308, 1318160346062225166536927204, 2281182774793880566386854202, 3947770745464875128215489476, 6831935621711193478803584270, 11823215517979626989252654459, 20461027873324936552011726278, 35409458704049766870463574070, 61278923692217093991616774374, 106048118957748860598268928024, 183524821535095103500935105397, 317604503036094959823791626415, 549640204006492782256703506357, 951196695803666227643791343005, 1646122586216645151673646795131, 2848747878127492747395146497119, 4929987925010971381846789176787, 8531741656523753626888968333475, 14764866932914585711739993009471, 25551792860485990447357753377411, 44219438031623458174827090101591, 76525303351860239321171606062486, 132433208420836012247860425341878, 229186346534231007543300455047052, 396625454174562824696341867974807, 686392332170111774628387415187708, 1187857281228776953526538661167132, 2055682813511567389589959681437591, 3557524878237416677051445431119245, 6156583679200434562674367324375645, 10654464521349051207718915685250792, 18438410026033851006551039004948926, 31909155416202798852780253976608864, 55221366589513932226781115179478434, 95565027912492621164419094117570641, 165382987128929746587819720020389833, 286208595645816231325692474821432127, 495307054513959920117280296979778603, 857168799202977606481906830566592959, 1483399728776458203402121501599814357, 2567142851419860475561591348189292465, 4442647717774532025797522076302827645, 7688360128977964468508623330874749520, 13305327189541069887965447505836108943, 23025941637865784521234444191415083701, 39848248807227476288131461546822173104, 68960607908058729168472941626927516912, 119341892941264496254850267375680858596, 206530769418287872448439164819365157712, 357418151038572249261836365381689027787, 618540932431735991718001801386896334770, 1070434962471260463170389697079661487176, 1852474022011964581139009223827365513544, 3205855677870125101423860144920010424249, 5547991769498476629256700835469967207037, 9601247144996961660705018593534913225922, 16615732425220501988109900409620796156745, 28754864847988594478375696246052761203187, 49762612400465240380187427652132912229336, 86118213596547492163397334421181607606370, 149034513167786192667574788821667110253623, 257916243121530494722068502259305736264048, 446344856986474817826595353109273441918350, 772435768089263602359077702861161388353409, 1336762385595787378549468975393213339116484, 2313375104267880490155624917599100889633507, 4003482167596451918353914186255524345816532, 6928348730257112541629154203810355027525535, 11990066177033590775605142065871666200189459, 20749776393589512464840020374644649655647874, 35909161302935015278730531942138798319507636, 62143699335409560081369603141161471393159562, 107544682943462043814216772302622710407400704, 186114746194704481727730115452186541297539854, 322086576510057527551600558671512063007190557, 557396793585831655018738502556644467159583633, 964620099559052960425720416252526682882655111, 1669352868873354804885622348664567494237803783, 2888949755545809136243688064556192446919868175, 4999560515746991945989073252770067125902428535, 8652142635098861248148452777057412533362877977, 14973230535426489152060521332311783517581989420, 25912382876992006096351135796067625851883928825, 44843468133024591960270046213401958144446811548, 77605237763877474989955856305494246316739147127, 134302122006319171731632762048131880552676359659, 232420652202367984596938247872208285088912788686, 402222680946414142984184322215356821073359953948, 696078784456971603910909918744734815016448573082, 1204620468022900362280402553035290601874308600586, 2084692860035604927076197374205039877760447754956, 3607729103106034863624554004184342562208475089341, 6243466138784576918107250594832177417637788944304, 10804821623826866941723224844111388709787418308073, 18698615116609470739339911758664365362637188157227, 32359461308280335893458609544003265039362932173740, 56000657248244594858300036379967633467510318826268, 96913653239119041752111865895809664169241405330164, 167716892009274048794745102986623447430717183044189, 290247606246426020117292750048691625438809474898504, 502296888062545512718475829352732508523042936581530, 869265269816240261877029457458234318249621243667628, 1504333646627354107869007496936781479204707239575364, 2603370684363759081777877568090078592049534352669947, 4505342904082185194291963661562434728467247085801567, 7796859204598587173314308958000104480418858953375158, 13493093589225451977147040588861591346827624626553088, 23350886533928418622148518003626067086836308029229306, 40410592153292809121198774051487713973447271440824879, 69933788415571610361075397290260005189363125951186151, 121026060286409890014591649872661507384922097295622585, 209445356819655999941471437498154462693217873859873519, 362462079567824464738504374835340908769751488853277318, 627269857492024846036766185061792395514128412691597750, 1085541071185182881358902065797900004206275433304525877, 1878616361292087979017649753948129817575491489985996469, 3251097104102362704835900720328806405351210311448488910, 5626285705844227224482132571164442587287950705132698177, 9736741115435595736854097976874400909429981720207988487, 16850215667245180941552990697851306753178430167486844006, 29160657006948951882262364132481449161390275730087294685, 50464868454466647556267645846637274956572498586114427735, 87333524327649631040132103644841977096784627243509857937, 151137706390139040826448707126591974417399010694640174718, 261555988593488478677610370284679511774525269175612894617, 452643730033345117036459086235348615186246366652477694168, 783336475835524143955537154153262203019092265959952337070, 1355626939379487620769121922144227585175531097052439217983, 2346021735820790423533561047507688175516954900918138334291, 4059979796110323903393797058491537625611005518946149411026, 7026122432346967683382009847205881024752630926437218981740, 12159271452933065576710291263470354882115951853620136774055, 21042599768180623908382939506716338579508214228553692875423, 36415915765826987773364669427220163018133640081486671468436, 63020678797925209300085103082659626905494796721119527734083, 109062366622625198169859916735972641477602693706580750774247, 188741220186912829686057249397861922209555075583934877024777, 326631901551406455092777938653826814900794821912935940782874, 565262845103114204256414747869081614169923740442179762058936, 978232936025018959853100287323851115023773163216042197843195, 1692910980111501346802672231436092377546116455476214539222026, 2929718966760270262844895994547637314231078419236801672684198, 5070114923366815738216357619638190602226980891746062079428250, 8774242726964718704518978915749604855301897112378619823447909, 15184534590503864395968205111669668293209355696392197598100449, 26278061583779512058870924747917968681797893736357134971437061, 45476304623307832769415233578427592641287934525440233150419102, 78700412341998941621862709864667467345902574612843786168968091, 136197409928206718914848388530217366761295027423898231594892758, 235700600786468895717413188934153824796333855958950958366797470]
#

分析一下题目逻辑。初始化数组 initState ,即为LFSR(线性反馈移位寄存器)的初始状态,mask 是flag转二进制之后的数组。

最主要的操作就是进行256轮LFSR计算

  • lfsr函数逻辑不算复杂,输入两个长度为128数组 state, mask ,输出 output 值为$out=\sum{state_i \times mask_i}$
  • 注意到每轮 state 数组取值会向右移动一个位置,同时 initState 长度会增长1,即数组尾部追加了 output

关键的关系式$out=\sum{state_i \times mask_i}$
可改写为矩阵乘法形式$out=State \times Mask$
State是 $1\times128$ 向量,Mask是 $128 \times 1$ 向量

256轮循环最终输出 initState 数组后256个元素,命名为 outputState,其中$outputState_{0…127} \times Mask = outputState_{128}
outputState_{1…128} \times Mask = outputState_{129}
\cdots
outputState_{127…254} \times Mask = outputState_{255}$

接下来就是简单的线性方程组求解了。

最终exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#sage
outputState = [31, 66, 128, 222, 385, 664, 1143, 2000, 3458, 6003, 10379, 17942, 31047, 53687, 92924, 160797, 278304, 481638, 833479, 1442422, 2496163, 4319845, 7475835, 12937561, 22389578, 38746915, 67054735, 116043520, 200822710, 347539886, 601445745, 1040850538, 1801275628, 3117252874, 5394657302, 9335889442, 16156509611, 27960142496, 48387281659, 83738092531, 144915522009, 250787996657, 434008851435, 751087316130, 1299817167363, 2249438425629, 3892834588915, 6736864173067, 11658686709797, 20176297502410, 34916709837729, 60426182042628, 104572380769600, 180970937597032, 313184800936842, 541991553121913, 937960088661442, 1623215570164618, 2809105439634215, 4861383488449105, 8413016146818879, 14559402864389777, 25196220721365800, 43604091771673155, 75460397027739861, 130590302153314191, 225997048627046433, 391106116962451401, 676840674047358730, 1171327366605398299, 2027076463289970382, 3508019282374090135, 6070910253447116278, 10506199749411485204, 18181825882182859769, 31465115864423937634, 54452920337985370536, 94235169707018163674, 163081560265112209496, 282225790871820528073, 488414489680745790033, 845240659945376349091, 1462757121910708796880, 2531419155626961478438, 4380824981460105751921, 7581370898424646092677, 13120173698498971899800, 22705518590912550882405, 39293730885686099313323, 68000969928723717268434, 117681162033195064953557, 203656740661184789826464, 352444412513853856490154, 609933476834387348179796, 1055539066458205919344242, 1826695472762162772755920, 3161243819621244340994611, 5470787351316040252901913, 9467638673598260118507327, 16384512191330329194463349, 28354719587732695891973236, 49070128760035595469947547, 84919814815174884654495265, 146960587438213290271803310, 254327147405947343219170013, 440133637427387650641676733, 761686751771954639615932308, 1318160346062225166536927204, 2281182774793880566386854202, 3947770745464875128215489476, 6831935621711193478803584270, 11823215517979626989252654459, 20461027873324936552011726278, 35409458704049766870463574070, 61278923692217093991616774374, 106048118957748860598268928024, 183524821535095103500935105397, 317604503036094959823791626415, 549640204006492782256703506357, 951196695803666227643791343005, 1646122586216645151673646795131, 2848747878127492747395146497119, 4929987925010971381846789176787, 8531741656523753626888968333475, 14764866932914585711739993009471, 25551792860485990447357753377411, 44219438031623458174827090101591, 76525303351860239321171606062486, 132433208420836012247860425341878, 229186346534231007543300455047052, 396625454174562824696341867974807, 686392332170111774628387415187708, 1187857281228776953526538661167132, 2055682813511567389589959681437591, 3557524878237416677051445431119245, 6156583679200434562674367324375645, 10654464521349051207718915685250792, 18438410026033851006551039004948926, 31909155416202798852780253976608864, 55221366589513932226781115179478434, 95565027912492621164419094117570641, 165382987128929746587819720020389833, 286208595645816231325692474821432127, 495307054513959920117280296979778603, 857168799202977606481906830566592959, 1483399728776458203402121501599814357, 2567142851419860475561591348189292465, 4442647717774532025797522076302827645, 7688360128977964468508623330874749520, 13305327189541069887965447505836108943, 23025941637865784521234444191415083701, 39848248807227476288131461546822173104, 68960607908058729168472941626927516912, 119341892941264496254850267375680858596, 206530769418287872448439164819365157712, 357418151038572249261836365381689027787, 618540932431735991718001801386896334770, 1070434962471260463170389697079661487176, 1852474022011964581139009223827365513544, 3205855677870125101423860144920010424249, 5547991769498476629256700835469967207037, 9601247144996961660705018593534913225922, 16615732425220501988109900409620796156745, 28754864847988594478375696246052761203187, 49762612400465240380187427652132912229336, 86118213596547492163397334421181607606370, 149034513167786192667574788821667110253623, 257916243121530494722068502259305736264048, 446344856986474817826595353109273441918350, 772435768089263602359077702861161388353409, 1336762385595787378549468975393213339116484, 2313375104267880490155624917599100889633507, 4003482167596451918353914186255524345816532, 6928348730257112541629154203810355027525535, 11990066177033590775605142065871666200189459, 20749776393589512464840020374644649655647874, 35909161302935015278730531942138798319507636, 62143699335409560081369603141161471393159562, 107544682943462043814216772302622710407400704, 186114746194704481727730115452186541297539854, 322086576510057527551600558671512063007190557, 557396793585831655018738502556644467159583633, 964620099559052960425720416252526682882655111, 1669352868873354804885622348664567494237803783, 2888949755545809136243688064556192446919868175, 4999560515746991945989073252770067125902428535, 8652142635098861248148452777057412533362877977, 14973230535426489152060521332311783517581989420, 25912382876992006096351135796067625851883928825, 44843468133024591960270046213401958144446811548, 77605237763877474989955856305494246316739147127, 134302122006319171731632762048131880552676359659, 232420652202367984596938247872208285088912788686, 402222680946414142984184322215356821073359953948, 696078784456971603910909918744734815016448573082, 1204620468022900362280402553035290601874308600586, 2084692860035604927076197374205039877760447754956, 3607729103106034863624554004184342562208475089341, 6243466138784576918107250594832177417637788944304, 10804821623826866941723224844111388709787418308073, 18698615116609470739339911758664365362637188157227, 32359461308280335893458609544003265039362932173740, 56000657248244594858300036379967633467510318826268, 96913653239119041752111865895809664169241405330164, 167716892009274048794745102986623447430717183044189, 290247606246426020117292750048691625438809474898504, 502296888062545512718475829352732508523042936581530, 869265269816240261877029457458234318249621243667628, 1504333646627354107869007496936781479204707239575364, 2603370684363759081777877568090078592049534352669947, 4505342904082185194291963661562434728467247085801567, 7796859204598587173314308958000104480418858953375158, 13493093589225451977147040588861591346827624626553088, 23350886533928418622148518003626067086836308029229306, 40410592153292809121198774051487713973447271440824879, 69933788415571610361075397290260005189363125951186151, 121026060286409890014591649872661507384922097295622585, 209445356819655999941471437498154462693217873859873519, 362462079567824464738504374835340908769751488853277318, 627269857492024846036766185061792395514128412691597750, 1085541071185182881358902065797900004206275433304525877, 1878616361292087979017649753948129817575491489985996469, 3251097104102362704835900720328806405351210311448488910, 5626285705844227224482132571164442587287950705132698177, 9736741115435595736854097976874400909429981720207988487, 16850215667245180941552990697851306753178430167486844006, 29160657006948951882262364132481449161390275730087294685, 50464868454466647556267645846637274956572498586114427735, 87333524327649631040132103644841977096784627243509857937, 151137706390139040826448707126591974417399010694640174718, 261555988593488478677610370284679511774525269175612894617, 452643730033345117036459086235348615186246366652477694168, 783336475835524143955537154153262203019092265959952337070, 1355626939379487620769121922144227585175531097052439217983, 2346021735820790423533561047507688175516954900918138334291, 4059979796110323903393797058491537625611005518946149411026, 7026122432346967683382009847205881024752630926437218981740, 12159271452933065576710291263470354882115951853620136774055, 21042599768180623908382939506716338579508214228553692875423, 36415915765826987773364669427220163018133640081486671468436, 63020678797925209300085103082659626905494796721119527734083, 109062366622625198169859916735972641477602693706580750774247, 188741220186912829686057249397861922209555075583934877024777, 326631901551406455092777938653826814900794821912935940782874, 565262845103114204256414747869081614169923740442179762058936, 978232936025018959853100287323851115023773163216042197843195, 1692910980111501346802672231436092377546116455476214539222026, 2929718966760270262844895994547637314231078419236801672684198, 5070114923366815738216357619638190602226980891746062079428250, 8774242726964718704518978915749604855301897112378619823447909, 15184534590503864395968205111669668293209355696392197598100449, 26278061583779512058870924747917968681797893736357134971437061, 45476304623307832769415233578427592641287934525440233150419102, 78700412341998941621862709864667467345902574612843786168968091, 136197409928206718914848388530217366761295027423898231594892758, 235700600786468895717413188934153824796333855958950958366797470]
#print(len(outputState))
OOi = []
Oi = []
for i in range(128):
OOi += outputState[i:i+128]#产生128行128列的元组
Oi += [outputState[i+128]]#产生一行,outputState后128位的元组
OO = matrix(ZZ, 128, 128, OOi)#定义在整数环上的128行128列的矩阵,值位OOi
O = matrix(ZZ, 128, 1, Oi)#定义在整数环上的128行1列的矩阵,值为0i

Mask = OO.solve_right(O) #使用OO.solve_right(O)函数求解线性方程组,求解OO*Mask = O的Mask向量。这相当于求解一个包含128个未知数的线性方程组,其中OO是系数矩阵,O是右侧向量。最终,我们得到一个128x1的向量Mask,其中每个元素都是一个整数,这些整数可以用来还原出输入状态。最后一行代码将Mask向量转化成一个字符串,方便输出或保存。总的来说求,OO*Mask = O中Mask的值
M=Mask.str().replace('\n','').replace('[','').replace(']','')
print(M)

rsarsa

sage脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
p1= 1687218514918517855575434101578033845149036490224579822827979075465068557041497711556817903
ct= 12064011747803325912866466307234048263037259126111461847199376361139809290978473
n= 26586107738552331744426768003576033375514016341586948681114321820716869769637129058784596344443680415970416750346645932529974300034413034297623751845263127864060953411036172446629820353154963911058471787603315585163748222613808285619182911620989798439871267925818589173138174609487115705820373755843147870743656744828817669892447290611871396352856304511788788431155084959736143569107897238150780382118104265957616726382967416580492631684195794156545072739443492411595146502124172733052938025462196971690279010544099376358676523366221090956163001661252576520987961199693061525924047490066791349182088306086135244487701
c= 25992754856891784830541737103300965001603312505803550734518867983331652067360506309102310176588597992224748887420092986253278784670112180320804675128016470823487185065679104749154630759655677907880519783931786545443195194633493636066961290374061101460605905742286720926706428992888162639167583009041683537389387626572890671903081606945109439086456633959124453951121109882867809787121816169622812075770013843303222379396455066440675945602006581202175212741733511637944875162087732203162858556879085424250668040085632974465833810588417710591745585567328127854775606696523042980479697923631249283800483158275251397607220# p0=n*invert(q0,mod)%mod
pbar=(p1<<724)+ct
PR.<x> = PolynomialRing(Zmod(n))
for i in range(32):
f=pbar+x*mod*32
f=f.monic()
pp=f.small_roots(X=2^454,beta=0.4)
if(pp):
break
pbar+=mod
assert pp
p=pbar+pp[0]*32*mod
print(p,type(p))
print(len(str(p)))
print(n//Integer(p))
q=n//Integer(p)
e=65537
phi=(p-1)*(q-1)
# d = gmpy2.invert(e, (p - 1) *(q - 1))
# m = powmod(c, d, n)
d = inverse_mod(e, phi)
m = pow(c, d, n)
print(m)

告诉你个秘密

积累一下经验吧,这种东西一般就是混合加密了,虽然意义不大,但是记下密码特点终归是不错的

1
636A56355279427363446C4A49454A7154534230526D684356445A31614342354E326C4B4946467A5769426961453067

这个容易看出,数字字母,大概就是base

解出来后

1
cjV5RyBscDlJIEJqTSB0RmhCVDZ1aCB5N2lKIFFzWiBiaE0g

base64

1
r5yG lp9I BjM tFhBT6uh y7iJ QsZ bhM 

键盘密码

你猜猜

内容

1
504B03040A0001080000626D0A49F4B5091F1E0000001200000008000000666C61672E7478746C9F170D35D0A45826A03E161FB96870EDDFC7C89A11862F9199B4CD78E7504B01023F000A0001080000626D0A49F4B5091F1E00000012000000080024000000000000002000000000000000666C61672E7478740A0020000000000001001800AF150210CAF2D1015CAEAA05CAF2D1015CAEAA05CAF2D101504B050600000000010001005A000000440000000000

504B0304是zip文件头image-20230308200012396

要在winhex中创建新的文件1.zip

放到ARCHPR

1
daczcasdqwdcsdzasd

flag_in_your_hand1

之能说是积累经验吧

代码审计js.文件

1
2
3
function checkToken(s) {
return s === "FAKE-TOKEN";
}

以为输入这个就能过了,但没想到不行,看WP说找ic

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function ck(s) {
try {
ic
} catch (e) {
return;
}
var a = [118, 104, 102, 120, 117, 108, 119, 124, 48,123,101,120];
if (s.length == a.length) {
for (i = 0; i < s.length; i++) {
if (a[i] - s.charCodeAt(i) != 3)
return ic = false;
}
return ic = true;
}
return ic = false;
}

也就是这个,变为字符应该就是token了

image-20230309140719222

竟然错了

image-20230309140730870

问题在这if (a[i] - s.charCodeAt(i) != 3)

我们要让输入的字符ASCII码与元组a中数字相减等于3

image-20230309141004551

这个就可以了

工业协议分析2

题目暗示说flag在异常流量中,那直接明文匹配查找flag,没有换成16进制查找

注意要选择分组字节流 字符串 image-20230309142606415

image-20230309142614792

将右下角的16进制转字符即可

image-20230309142700244

点as Printable复制

sherlock

刚开始就觉得有些大写字母很奇怪,还真是要收集大写字母

1
2
直接cat 1.txt | grep -o [A-Z]
是这样的

image-20230309145915287

1
cat 1.txt | grep -o [A-Z] |tr -d '\n'

可以删除换行符

grep -o 只显示匹配到的字符串
tr -d 删除指定字符

1
ZEROONEZEROZEROZEROZEROONEZEROZEROONEZEROZEROONEZEROZEROONEZEROONEZEROONEZEROONEZEROZEROZEROONEZEROONEZEROZEROONEONEZEROONEZEROZEROZEROZEROONEONEZEROONEZEROONEZEROONEZEROZEROZEROONEZEROZEROZEROONEONEZEROZEROONEONEONEONEZEROONEONEZEROONEONEZEROONEZEROZEROZEROZEROZEROONEONEZEROZEROZEROONEZEROONEONEZEROZEROONEZEROZEROZEROZEROONEONEZEROZEROONEONEZEROONEZEROONEONEONEONEONEZEROZEROONEONEZEROZEROZEROONEZEROONEONEZEROONEONEONEZEROZEROONEZEROONEONEONEONEONEZEROONEONEONEZEROZEROZEROZEROZEROONEONEZEROONEONEZEROZEROZEROZEROONEONEZEROONEZEROZEROZEROZEROONEONEZEROZEROZEROONEZEROONEONEZEROONEONEONEZEROZEROONEZEROONEONEONEONEONEZEROZEROONEONEZEROONEZEROONEZEROZEROONEONEZEROZEROZEROONEZEROZEROONEONEZEROONEONEONEZEROZEROONEONEZEROZEROONEONEZEROONEONEONEONEONEZEROONE

接下来又两个思路,一个是二进制一个是摩斯电码

文章内容是福尔摩斯所以先试摩斯电码,但摩斯电码要有空格…

还是先试二进制

1
2
3
4
5
6
7
# 开发时间:2023/2/26 15:53
a='010000100100100101010100010100110100001101010100010001100111101101101000001100010110010000110011010111110011000101101110010111110111000001101100001101000011000101101110010111110011010100110001001101110011001101111101'
b = ''
for i in range (0,len(a),8):
b+=''.join(chr(int(a[i:i+8],2)))#将a中数字8个一组,以二进制转换为十进制,
print(b)
#BITSCTF{h1d3_1n_pl41n_5173}

safer-than-rot13

image-20230309151154846

词频分析网站https://quipqiup.com/

要小写补上_

image-20230309151912073

cr4-poor-rsa

读取公钥脚本

公钥中有 e,n读取出来

1
2
3
4
5
6
from Crypto.PublicKey import RSA
with open("key.pub","rb") as f:
key = f.read()
pub = RSA.import_key(key)
print("n = ",n)
print("e = ",e)

因为这里c是未知的,而flag.b64又不知道怎么打开,

好吧原来是代码写错了,是可以解开的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import gmpy2
import rsa
import base64
n = 833810193564967701912362955539789451139872863794534923259743419423089229206473091408403560311191545764221310666338878019
e = 65537
p=863653476616376575308866344984576466644942572246900013156919
q=965445304326998194798282228842484732438457170595999523426901

phi=(q-1)*(p-1)
d=gmpy2.invert(e,phi)

key = rsa.PrivateKey(n, e, d, p, q)
with open('flag.b64', 'rb') as file:
f = file.read()
c = base64.b64decode(f)
flag = rsa.decrypt(c, key).decode()
print(flag)

crypto垃圾邮件

还真有垃圾邮件解密网站

cat’s gift

莱布尼兹π的莱布尼兹公式。

img

欧拉研究出的

img

根据脚本算出的

1
2
3
4
5
6
7
def gift(n=100):
a = 0
for i in range(n):
a += (-1) ** i * 1 / (2 * i + 1)
return a * 4
print(gift(n=1000000))
#3.1415916535897743

就是π了

找个谐音还是事物的英语

pie

二元一次方程

还是第一次用python解一元二次方程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from sympy import symbols, solve

# 定义变量
p, q = symbols('p q')

# 定义已知条件
eq1 = q * p - 5700102857084805454304483466349768960970728516788155745115335016563400814300152521175777999545445613444815936222559357974566843756936687078467221979584601
eq2 = q + p - 151271785827179519090153916262079069437668895377847660065517418507884817445750

# 解方程组
sol = solve((eq1, eq2), (p, q))

if not sol:
print("此方程组没有解。")
elif len(sol) < 2:
print("找到的解不足两个。")
else:
print("p =", sol[0])
print("q =", sol[1])

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import libnum
from Crypto.Util import number
e = 65537
import gmpy2
n = 5700102857084805454304483466349768960970728516788155745115335016563400814300152521175777999545445613444815936222559357974566843756936687078467221979584601
avg = 75635892913589759545076958131039534718834447688923830032758709253942408722875
c = 888629627089650993173073530112503758717074884215641346688043288414489462472394318700014742820213053802180975816089493243275025049174955385229062207064503
q= 71087768052593510372666084538192216997254291933607002714885530754163087727843
p= 80184017774586008717487831723886852440414603444240657350631887753721729717907
phi=(q-1)*(p-1)
d= gmpy2.invert(e,phi)
m= gmpy2.powmod(c,d,n)
print(libnum.n2s(int(m)))
print(2*avg)

babyFibo

已知c,s c = m^s

可以通过再次异或得到m

1
2
3
4
5
6
7
8
9
10
import libnum

s=43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875
c=43104378128345818181217961835377190975779804452524643191544804229536124095677294719566215359919831933542699064892141754715180028183150724886016542388159082125737677224886528142312511700711365919689756090950704
m = c ^ s
m = libnum.n2s(m)

print(m)
#b'HSCTF{1d9cb42f-3302-46f3-a3a7-0ca30d631cc9}\xf4\x8d\xc1\x8a\x86W\xeb\xe5{4\xce\xa0\xddY\xa6\xb6@\x03\x82\x0e\xdc\xc2WbBn\x88\x9a\xc5]\xa4\x07S@\xa1u\xde\x11\xcdw\x91\x84{'

1
#b'8OcTbAfL6/kOMQnC9v8SNmmSzvQMeGTT8vANM1T+7vIce2fo0fc2RnScrNxTSmeSyuMjMF//w8BWaXX91dsGcnvmreg0NQTw96ceVVXj3sQ3Znn51OU1S0bOyaMtNHTj36AcWFqewN4zRUXD6agGbAPE+tQtd3XG0doAa1Ll9fhcQ1zk0McTM1bv8PIQOAnn3vQ3UgLD3PsONXLs4KkXMnjTyMEQOFn/0uYVUwOY1PsleEHCyNopRVDr+Kc0e2PH9v0XNXfprfIPU3nw7KYTNX/G7twLSkHoyaUlQHXi3v02UHmdy/4iNgme3Pc8bgPp+tYWV1+YzPkXYkXM4ulUc27DrM4SNUPT2fQlckj1qP4Fal+YoPYJMlyZ8qhXfF3Y0tUDdUXl3vg0dFTi++VVOFfH/dgMS1ru9N8WU0HF9cUCTgPe+qVdSn/u7Mkda0GTw/QDcWPZ9KYGN2jSzfk0OVrMzt0yRHD64KMrUgPF2sFWcmP56KZSTAD61PUGeXrd49MgU1bL8OsVNWj91vIsalXwqf0qaWbwzv0lWETA4eElS3L99cYmU1nv9dRQTWbDyclScQTN6NIhV2j//+ZWbH7Z68kwM3Dy4dcUc1PQy8kRTl/4zcU9WGWfoakOMXuf69MXZQTEz+kJT1Dar8UN'

Xor很心疼你

1
# b'8OcTbAfL6/kOMQnC9v8SNmmSzvQMeGTT8vANM1T+7vIce2fo0fc2RnScrNxTSmeSyuMjMF//w8BWaXX91dsGcnvmreg0NQTw96ceVVXj3sQ3Znn51OU1S0bOyaMtNHTj36AcWFqewN4zRUXD6agGbAPE+tQtd3XG0doAa1Ll9fhcQ1zk0McTM1bv8PIQOAnn3vQ3UgLD3PsONXLs4KkXMnjTyMEQOFn/0uYVUwOY1PsleEHCyNopRVDr+Kc0e2PH9v0XNXfprfIPU3nw7KYTNX/G7twLSkHoyaUlQHXi3v02UHmdy/4iNgme3Pc8bgPp+tYWV1+YzPkXYkXM4ulUc27DrM4SNUPT2fQlckj1qP4Fal+YoPYJMlyZ8qhXfF3Y0tUDdUXl3vg0dFTi++VVOFfH/dgMS1ru9N8WU0HF9cUCTgPe+qVdSn/u7Mkda0GTw/QDcWPZ9KYGN2jSzfk0OVrMzt0yRHD64KMrUgPF2sFWcmP56KZSTAD61PUGeXrd49MgU1bL8OsVNWj91vIsalXwqf0qaWbwzv0lWETA4eElS3L99cYmU1nv9dRQTWbDyclScQTN6NIhV2j//+ZWbH7Z68kwM3Dy4dcUc1PQy8kRTl/4zcU9WGWfoakOMXuf69MXZQTEz+kJT1Dar8UN'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
解题.py
import random
import base64

pool = 'qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM'
flag='hsctf{'
enc=b'8OcTbAfL6/kOMQnC9v8SNmmSzvQMeGTT8vANM1T+7vIce2fo0fc2RnScrNxTSmeSyuMjMF//w8BWaXX91dsGcnvmreg0NQTw96ceVVXj3sQ3Znn51OU1S0bOyaMtNHTj36AcWFqewN4zRUXD6agGbAPE+tQtd3XG0doAa1Ll9fhcQ1zk0McTM1bv8PIQOAnn3vQ3UgLD3PsONXLs4KkXMnjTyMEQOFn/0uYVUwOY1PsleEHCyNopRVDr+Kc0e2PH9v0XNXfprfIPU3nw7KYTNX/G7twLSkHoyaUlQHXi3v02UHmdy/4iNgme3Pc8bgPp+tYWV1+YzPkXYkXM4ulUc27DrM4SNUPT2fQlckj1qP4Fal+YoPYJMlyZ8qhXfF3Y0tUDdUXl3vg0dFTi++VVOFfH/dgMS1ru9N8WU0HF9cUCTgPe+qVdSn/u7Mkda0GTw/QDcWPZ9KYGN2jSzfk0OVrMzt0yRHD64KMrUgPF2sFWcmP56KZSTAD61PUGeXrd49MgU1bL8OsVNWj91vIsalXwqf0qaWbwzv0lWETA4eElS3L99cYmU1nv9dRQTWbDyclScQTN6NIhV2j//+ZWbH7Z68kwM3Dy4dcUc1PQy8kRTl/4zcU9WGWfoakOMXuf69MXZQTEz+kJT1Dar8UN'

enc = base64.b64decode(enc)
def generate(length):
return ''.join(random.choices(pool, k=length))

def f(x):
random.seed(x)
return random.getrandbits(8)

def encrypt(plaintext, key):
plaintext = list(map(ord, plaintext))
for i in range(len(plaintext)):
key = f(key)
tmp = (key * r) % 251
#assert tmp != 0 and key != 0
plaintext[i] = plaintext[i] ^ tmp
plaintext = bytes(plaintext)
return plaintext

def decrypt(enc,key):
enc = list(enc)
# key = f(key)
for i in range(len(enc)):
key = f(key)
tmp = (key * r) % 251
#assert tmp != 0 and key != 0
enc[i] = enc[i] ^ tmp
enc = bytes(enc)
print(enc)
return enc

for r in range(2,251):
for key in range(1,256):
m = flag
c = encrypt(m, key)
if(c in enc):
print(r)
print(key)
print(c)
print(enc.index(c))
r=187
key=34
mm = decrypt(enc[247:],key)
print(mm)

直接找的WP

核心部分在我看是这里

1
2
3
4
5
6
7
8
9
for r in range(2,251):
for key in range(1,256):
m = flag
c = encrypt(m, key)
if(c in enc):
print(r)
print(key)
print(c)
print(enc.index(c))

通过爆破的方式,求出r,key,与flag所在位置,因为加密代码中虽然有两个循环,但是他最终是有一个确定的r与key值的

[中等偏下] 线性反馈移位寄存器

这个与之前那个LFSR类似,但是还是不会做,且看WP

原文链接:https://blog.csdn.net/figfig55/article/details/128632051

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from secret import secret
for b in secret: assert(b == '0' or b == '1')
assert(len(secret) == 128)
# a 01 string with length 128
# your flag is flag{md5(secret).hexdigest()}

def string2bits(s):
return [int(b) for b in s]

def bits2string(bs):
s = [str(b) for b in bs]
return ''.join(s)

def lfsr(state, mask):
assert(len(state) == 128)
assert(len(mask) == 128)

output = 0
for i in range(128):
output = output ^ (state[i] & mask[i])

return output

if __name__ == '__main__':
initState = [0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0]
mask = string2bits(secret)

for i in range(256):
state = initState[i:]
output = lfsr(state, mask)
initState += [output]

outputState = bits2string(initState[128:])
print('outputState =', outputState)
#
# outputState = 1010100001001011101000000100100001101011010100101011010101011010100100001110010010110111010111110000000000011011001110100011000111110100110011011011100111000000001100001000001011010011011010110110111100110101001110001001001000001110111011110001111001111111
#

image-20230309231629359

image-20230309231809137

image-20230309232119418

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#sage
def string2bits(s):
return [int(b) for b in s]

if __name__ == '__main__':
initState = [0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0]
outputState = string2bits('1010100001001011101000000100100001101011010100101011010101011010100100001110010010110111010111110000000000011011001110100011000111110100110011011011100111000000001100001000001011010011011010110110111100110101001110001001001000001110111011110001111001111111')
states = initState + outputState

ms = MatrixSpace(GF(2), 128, 128)#一个矩阵
mv = []
for i in range(128):
mv += states[i : i + 128]
m= ms(mv)

vs = MatrixSpace(GF(2), 128, 1)#一个矩阵
vv = outputState[0:128]
v = vs(vv)

secret = m.inverse() * v
M=secret.str().replace('\n','').replace('[','').replace(']','')

转轮机加密

托马斯·杰斐逊- 轮转密码题

拿的别人的脚本稍微改了一下.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 开发时间:2023/3/12 8:52
# 秘钥
key = "2,3,7,5,13,12,9,1,8,10,4,11,6"
# 密文
cipher_text = "NFQKSEVOQOFNP"

f = open("1.txt")
str_first_encry = []

for line in f:
line = line.strip()
str_first_encry.append(line)

key_index = key.split(",")
str_second_encry = []
for k in key_index:
str_second_encry.append(str_first_encry[int(k) - 1])
print(str_first_encry[int(k) - 1])

for i, ch in enumerate(cipher_text):
line = str_second_encry[i]
split_index = line.index(ch)
temp = []
temp[0:len(line) - split_index + 1] = line[split_index:len(line)]
temp[len(temp):] = line[0:split_index]
str_second_encry[i] = "".join(temp)
print("-------------------------------------")
flag = []
g=1
for plain in str_second_encry:
print('第{}列: '.format(g), end='')
print(plain)
g += 1
print("-------------------------------------")
for i in range(len(str_second_encry[0])):
ans = ""
for j in range(13):
ans += str_second_encry[j][i]
flag.append(ans.lower())

k=0
for ans in flag:
print('第{}列: '.format(k),end='')
print(str.lower(ans))
k += 1

best_rsa

共模攻击-扩展欧几里得算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import gmpy2
import libnum
import binascii
n=13060424286033164731705267935214411273739909173486948413518022752305313862238166593214772698793487761875251030423516993519714215306808677724104692474199215119387725741906071553437840256786220484582884693286140537492541093086953005486704542435188521724013251087887351409946184501295224744819621937322469140771245380081663560150133162692174498642474588168444167533621259824640599530052827878558481036155222733986179487577693360697390152370901746112653758338456083440878726007229307830037808681050302990411238666727608253452573696904083133866093791985565118032742893247076947480766837941319251901579605233916076425572961
e1=117
e2=65537
c1=12847007370626420814721007824489512747227554004777043129889885590168327306344216253180822558098466760014640870748287016523828261890262210883613336704768182861075014368378609414255982179769686582365219477657474948548886794807999952780840981021935733984348055642003116386939014004620914273840048061796063413641936754525374790951194617245627213219302958968018227701794987747717299752986500496848787979475798026065928167197152995841747840050028417539459383280735124229789952859434480746623573241061465550303008478730140898740745999035563599134667708753457211761969806278000126462918788457707098665612496454640616155477050
c2=6830857661703156598973433617055045803277004274287300997634648800448233655756498070693597839856021431269237565020303935757530559600152306154376778437832503465744084633164767864997303080852153757211172394903940863225981142502888126928982009493972076013486758460894416710122811249903322437742241269681934551237431668187006176418124934488775505816544733929241927900392924886649420943699356314278255683484998359663404611236056664149725644051300950988495549164517140159041907329062655574220869612072289849679613024196448446224406889484578310512232665571188351621585528255501546941332782446448144033997067917984719103068519
d = gmpy2.gcdext(e1,e2)#扩展欧几里得算法
m1 = gmpy2.powmod(c1,d[1],n)
m2 = gmpy2.powmod(c2,d[2],n)
m = (m1*m2)%n
print(binascii.unhexlify(hex(m)[2:]))

RSA_gcd

1
2
3
4
5
6
7
8
9
10
11
p=gmpy2.gcd(n1,n2)
q1=n1//p
q2=n2//p
phi_1=(q1-1)*(p-1)
phi_2=(q2-1)*(p-1)
d1=gmpy2.invert(e,phi_1)
d2=gmpy2.invert(e,phi_2)
m1=pow(c1,d1,n1)
m2=pow(c2,d2,n2)
print(libnum.n2s(int(m1)))
print(libnum.n2s(int(m2)))

shanghai

维吉利亚密码

OldDriver

低加密指数广播攻击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import gmpy2
from functools import reduce
from Crypto.Util.number import *
e=10
c=[7366067574741171461722065133242916080495505913663250330082747465383676893970411476550748394841437418105312353971095003424322679616940371123028982189502042,
21962825323300469151795920289886886562790942771546858500842179806566435767103803978885148772139305484319688249368999503784441507383476095946258011317951461,
6569689420274066957835983390583585286570087619048110141187700584193792695235405077811544355169290382357149374107076406086154103351897890793598997687053983,
4508246168044513518452493882713536390636741541551805821790338973797615971271867248584379813114125478195284692695928668946553625483179633266057122967547052,
22966105670291282335588843018244161552764486373117942865966904076191122337435542553276743938817686729554714315494818922753880198945897222422137268427611672,
17963313063405045742968136916219838352135561785389534381262979264585397896844470879023686508540355160998533122970239261072020689217153126649390825646712087,
1652417534709029450380570653973705320986117679597563873022683140800507482560482948310131540948227797045505390333146191586749269249548168247316404074014639,
15585771734488351039456631394040497759568679429510619219766191780807675361741859290490732451112648776648126779759368428205194684721516497026290981786239352,
8965123421637694050044216844523379163347478029124815032832813225050732558524239660648746284884140746788823681886010577342254841014594570067467905682359797,
13560945756543023008529388108446940847137853038437095244573035888531288577370829065666320069397898394848484847030321018915638381833935580958342719988978247]
n = [25162507052339714421839688873734596177751124036723831003300959761137811490715205742941738406548150240861779301784133652165908227917415483137585388986274803,
23976859589904419798320812097681858652325473791891232710431997202897819580634937070900625213218095330766877190212418023297341732808839488308551126409983193,
18503782836858540043974558035601654610948915505645219820150251062305120148745545906567548650191832090823482852604346478335353784501076761922605361848703623,
23383087478545512218713157932934746110721706819077423418060220083657713428503582801909807142802647367994289775015595100541168367083097506193809451365010723,
31775649089861428671057909076144152870796722528112580479442073365053916012507273433028451755436987054722496057749731758475958301164082755003195632005308493,
22246342022943432820696190444155665289928378653841172632283227888174495402248633061010615572642126584591103750338919213945646074833823905521643025879053949,
25395461142670631268156106136028325744393358436617528677967249347353524924655001151849544022201772500033280822372661344352607434738696051779095736547813043,
32056508892744184901289413287728039891303832311548608141088227876326753674154124775132776928481935378184756756785107540781632570295330486738268173167809047,
52849766269541827474228189428820648574162539595985395992261649809907435742263020551050064268890333392877173572811691599841253150460219986817964461970736553,
30415984800307578932946399987559088968355638354344823359397204419191241802721772499486615661699080998502439901585573950889047918537906687840725005496238621]

# 中国剩余定理
def CRT(cipher, n):
N = reduce(lambda x, y: x * y, (i for i in n))#N = reduce(lambda x, y: x * y, (i for i in n))
print(N)
result = 0
data = zip(cipher, n)
for ci, ni in data:
Ni = N // ni#将N除以ni并向下取整,得到整数商Ni。
di = gmpy2.invert(Ni, ni)
result += ci * Ni * di
return result % N, N
x, N = CRT(c, n)

m = gmpy2.iroot(gmpy2.mpz(x), e)[0]

print(m)
print(long_to_bytes(m))

easychallenge

image-20230312114511338

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# uncompyle6 version 3.9.0
# Python bytecode version base 2.7 (62211)
# Decompiled from: Python 3.8.7 (tags/v3.8.7:6503f05, Dec 21 2020, 17:59:51) [MSC v.1928 64 bit (AMD64)]
# Embedded file name: ans.py
# Compiled at: 2018-08-09 11:29:44
import base64
from Crypto.Util.number import *
def decode1(final):
s = ''
for i in final:
x = ord(i) - 25
x = x ^ 36
s += chr(x)
return s
def decode2(final):
s=''
for i in final:
x = i^ 36
x = x - 36
s += chr(x)
return s
def decode3(final):
return base64.b32decode(final)
final='UC7KOWVXWVNKNIC2XCXKHKK2W5NLBKNOUOSK3LNNVWW3E==='

flag=decode1(decode2(decode3(final)))
print(flag)

Decrypt-the-Message

Poem Codes

Poem Code 最显著的特点就是一首诗歌。

加密过程

给出一首诗歌

for my purpose holds to sail beyond the sunset, and the baths of all the western stars until I die.

给出5个关键单词。

“for”, “sail”, “all”, “stars”, “die.”

对其进行拆散:

f o r s a i l a l l s t a r s d i e

接下来按照 字母表顺序 进行编号,若遇相同字母,则继续 +1

f o r s a i l a
6 12 13 15 1 7 9 2
l l s t a r s d
10 11 16 18 3 14 17 4
i e
8 5

We have run out of cigars, situation desperate。

先对对其进行编码。因为给出的5个关键词,其长度为18.所以以18为一组。

若一组长度不满18,则用abc(不要求有序)进行补充。img

将排好的消息,按照之前给出的诗歌字母编号写下密文。

for my purpose holds to sail beyond the sunset, and the baths of all the western stars until I die.

如, for --> eud tdk oek 那么得到的又可以按照5个(适当个数)为一组进行重新分组,得到最后密文。

————————————————
版权声明:本文为CSDN博主「J1ay」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_45530599/article/details/108027293

审题解题

首先我们得到一首诗歌

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
The life that I have
Is all that I have
And the life that I have
Is yours.

The love that I have
Of the life that I have
Is yours and yours and yours.

A sleep I shall have
A rest I shall have
Yet death will be but a pause.

For the peace of my years
In the long green grass
Will be yours and yours and yours.

以及 decrypted message (解密消息)

1
emzcf sebt yuwi ytrr ortl rbon aluo konf ihye cyog rowh prhj feom ihos perp twnb tpak heoc yaui usoa irtd tnlu ntke onds goym hmpq

解题脚本

已知原理,我们可以运用网上大佬的 解密工具 ,:

1
python poem.py poem msg

image-20230312123306855

ecb,_it’s_easy_as_123

只有一个cry300放到winhex里面看看

504B0304是zip文件头

解压得到ecb.bmptask.txt

BMP文件实际上不是有效的图像文件,因为它是加密的。它的前几个字节很有趣:加salt __前缀表示此文件OpenSSL加密的OpenSSL解码。紧接着8个字节(Ab31b5e5ca 3db94d)是用于加密文件的salt 。文件的其余部分是加密数据。

原因分析:

因为标题和任务描述中有一些提示:ECB-ECB加密对于图像来说是出了名的不好,因为相同的明文块产生相同的密文。4K分辨率-这告诉我们图像要么是3840×2160像素,要么是4096×2160像素。黑白-我们很可能会看到很多只有白色的积木。

所以,考虑到这一点,让我们来看看十六进制转储:

1
2
3
4
5
6
7
8
9
10
11
12

Bash$xxd ecb.bmp|head-n 13 0000000:5361 6c74 6564 5f5f ab31 b5e5
ca3d b94d Salted__1...=.m 0000010:f409 1aa5 df88 b72c 0ebd 8a73
9815 ba69.,...s...i 0000020:a224 3e09 94cb 791e ea1 ad33 c817
6663.$>...y...3.fc。0000040:fcd8 8e3d 452a 99b0 536b 500d 8a3d
c4b7...=E*..SKP..=..。0000050:629c 6a54 f059 2013年224f b6e2 b6aa
0a8b b.jT.Y.“O.。0000060:5e21 1a9d cf8c a2f6 4580 cb9b B737
da7f^!.E....7.。0000070:7350 88cb df63 ee22 d424 b3b9 f424 ad40
sp...c.“.$...$.@0000080:2F09 e681 9bb5 1388 01fa 0a47 7809
6523/.Gx.e#0000090:323f 8b1e b820 9c99 fcb5 4601 0bc9 4134
2?......f...a4 00000a0:323f 8b1e b820 923。F...A4 00000c0:323F
8b1e b820 9c99 fcb5 4601 0bc9 4134 2?......F...A4。

查阅wp后才发现,只需要改动文件头128位即可

脚本如下

1
2
3
4
5
6
7
8
9
10
11
# 开发时间:2023/3/12 13:25
from Crypto.Util.number import long_to_bytes

with open('ecb.bmp','rb') as f:
data=f.read()
pre = 0x424d76483f00000000007600000028000000000f000070080000010004000000000000483f00000000000000000000000000000000000000000000008000008000000080800080000000800080008080000080808000c0c0c0000000ff0000ff000000ffff00ff000000ff00ff00ffff0000ffffff00ffffffffffffffffffff
#pre=0x424d76483f00000000007600000028000000000f000070080000010004000000000000483f00000000000000000000000000000000000000000000008000008000000080800080000000800080008080000080808000c0c0c0000000ff0000ff000000ffff00ff000000ff00ff00ffff0000ffffff00ffffffffffffffffffffL
out=long_to_bytes(pre)+data[128:]

with open('out.bmp','wb') as g:
g.write(out)

还有一个更好的解决方案。我们只需删除前16个字节(Salted__和Salt),然后用有效的BMP报头替换密文中的前几个字节。这是可行的,因为BMP存储原始数据,我们不会得到无效的块。

1
2
3
4
5
6
7
Bash$xxd sample.bmp|head-n 8 0000000:424d 7648 3f00 0000 0000 7600 
0000 2800 bmvh?.v.。0000010:00000 000f 0000 7008 0000 0100 0400
0000.页.。0000020:0000 0048 3f00 0000 0000 0000...H?.。0000030:
0000 0000 0000 8000 0080.。0000040:0000 0080 8000 8000 0000 8000
8000 8080.。0000050:0000 8080 8000 c0c0 c000 0000 ff00 00ff.。
0000060:0000 00ff ff00 ff00 0000 ff00 ff00 ffff.。0000070:0000ffff
ff00 ffff.。

enc

解到

ALEXCTFTH15O1SO5UP3RO5ECR3TOTXT就不会了

要改为这种形式

ALEXCTF{TH15_1S_5UP3R_5ECR3T_TXT}

wtc_rsa_bbq

读出两个文件信息后,还要再次读取信息内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 开发时间:2023/3/12 15:01
import gmpy2
from Crypto.Util.number import bytes_to_long, long_to_bytes

n = 0x62D3D61C92452630147E89670FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
e = 65537

p = (2**4244)*699549860111847+1
q = (2**4244)*699549860111847-1

Phi = (p - 1) * (q - 1)

d = gmpy2.invert(e, Phi)

with open('cipher.bin', 'rb') as file:
data = bytes_to_long(file.read())
res = long_to_bytes(pow(data, d, n)).decode()
print(res)

使用工具RSACTFTool进行分解,将key.pem与cipher.bin移到与RsaCtfTool.py同目录下:

1
2
3
4
sudo python3 RsaCtfTool.py --publickey key.pem --uncipherfile cipher.bin --attack fermat
python RsaCtfTool.py --publickey key.pem --uncipherfile cipher.bin --attack fermat
#只有这个可以
python3 ./RsaCtfTool.py -n 135127138348299757374196447062640858416920350098320099993115949719051354213545596643216739555453946196078110834726375475981791223069451364024181952818056802089567064926510294124594174478123216516600368334763849206942942824711531334239106807454086389211139153023662266125937481669520771879355089997671125020789 -e 65537 --uncipher 110674792674017748243232351185896019660434718342001686906527789876264976328686134101972125493938434992787002915562500475480693297360867681000092725583284616353543422388489208114545007138606543678040798651836027433383282177081034151589935024292017207209056829250152219183518400364871109559825679273502274955582

工业协议分析1

找到最长的一条image-20230312163214712

1
2
3
4
data = "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"
import base64
with open('img.png','wb')as f:
f.write(base64.b64decode(data))

简单流量分析

流量分析题,分析的方法基本上有:binwalk、查找一些可疑字符串或16进制数据,排序流量包的长度(最长的流量包一般很可疑);当我们对流量包的长度进行排序时,发现流量包最短90字节,最长也不过164字节,其中的data段数据长度从48到122,而ascii表中第48至122个字符为0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz,于是将每个流量包的长度转换为对应字符,然后连接成一段长字符串,看上去像base64编码,对字符串进行base64解码即可!

1
2
3
tcpdump -r 1.pcap | awk -F ' ' '{print $14}' > 1.txt
用这个命令将pcap里的长度字段找出来
不知道什么情况,取出来的长度有重复的...还是去看了,官方WP,虽说耗时有点久了,但好在安装好了环境,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/python
# coding=utf8
import pyshark
import base64
L_flag= []
packets = pyshark.FileCapture('fetus_pcap.pcap')
for packet in packets:
for pkt in packet:
if pkt.layer_name == "icmp":
if int(pkt.type) != 0:
L_flag.append(int(pkt.data_len))
c=len(L_flag)
for i in range(0,c):
L_flag[i]=chr(L_flag[i])
print(''.join(L_flag))
print(base64.b64decode(''.join(L_flag)))
#b'::\\nmongodb:!:17843:0:99999:7:::\\nubuntu:$6$LhHRomTE$M7C4n84UcFLAG{xx2b8a_6mm64c_fsociety}::'

这段代码使用了 pyshark 库来读取一个名为 fetus_pcap.pcap 的数据包捕获文件。pyshark 是一个基于 tshark 的 Python 数据包分析库,它提供了一种简单的方法来解析和分析捕获文件和实时数据包。这个库可以用于网络分析,协议分析等领域。

这个脚本首先创建了一个空列表 L_flag 来存储数据包中 ICMP 层的 data_len 值,然后利用 pyshark.FileCapture() 函数读取指定的数据包捕获文件。之后,它遍历每个捕获到的数据包,遍历每个数据包的每个协议层。如果发现一个数据包包含 ICMP 层且其类型不是 0,则将该数据包的 data_len 值添加到 L_flag 列表中。

在此之后,代码将列表 L_flag 中的整数转换为相应的 ASCII 字符。最后,它将字符列表传递给 base64.b64decode() 函数,以解码 Base64 编码的字符串,并打印解码后的结果。

工控安全取证

下载后是一个capture.log,考虑到都是流量,改成wireshark能识别的后缀,capture.pcapng

打开后发现大量的tcp流量,不难发现,192.168.0.99是靶机,使劲被人攻击。

开始我的策略是手工分析出四个攻击时段的节点,于是就将时间显示格式调整为比较友好的类型,如图:

img

想以时间来区分,后来发现图样图森破,时间都很接近,那么多tcp怎么搞。

于是想到了协议

在进行一次连续的tcp之前一般会发一个icmp包过去,把过滤协议设置为icmp

,排序后,发现ICMP协议貌似刚好分成了四段(去掉了不成功的),如下:

img

ICMP请求第一组编号有发出也有回显正常的信息,我们认为该次扫描为一次正常的扫描;第二组和第三组同理!!!

第四组为什么是155989?第四次我们可以推测在155987到155990之间。

flag{155989}

fanfie

参考文章:https://blog.csdn.net/l8947943/article/details/123397127

1. 找到加密信息

题目给出的是一个txt文件,如下字符:

1
MZYVMIWLGBL7CIJOGJQVOA3IN5BLYC3NHI

这个题目最难的是缺少提示,看到都懵了,原题提示有如下:

任务描述告诉我们标志被转换为base32并以某种方式加密。

假设明文是这样的:BITSCTF{},那我们尝试将BITSCTF*进行加密,代码如下:

1
2
3
from base64 import b32encode

print(b32encode(b'BITSCTF'))

加密结果如下:

1
IJEVIU2DKRDA====

对比原始字符,我们选取前一段的:

1
2
MZYVMIWLGBL7CIJO
IJEVIU2DKRDA====

可以看到M对应I,而且出现了两次,那么我们推测可能是一种单字母替换密码

找到映射关系
我们构造一个简单的字母序表:

1
2
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  2  3  4  5  6  7
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

可以发现原始字符和base32加密后的对应索引关系:

映射 编号
M -> I 12 -> 8
Z -> J 25 -> 9
Y -> E 24 -> 4
V -> V 21 -> 21
I -> U 8 -> 20
W -> 2 22 -> 26

image-20230312171501228

什么是仿射密码?参考链接

举例第一列,A在原始字母表中的顺序为0,带入函数(13 * 0 + 4) mod 32 = 4,在原始字母表中,对应字母E,因此原始字符则有如下对应:

1
2
MZYVMIWLGBL7CIJOGJQVOA3IN5BLYC3NHI IJEVIU2DKRDHWUZSKZ4VSMTUN5RDEWTNPU
IJEVIU2DKRDHWUZSKZ4VSMTUN5RDEWTNPU======
1
2
3
4
5
6
7
8
9
10
11
from base64 import b32decode

def solve():
s='MZYVMIWLGBL7CIJOGJQVOA3IN5BLYC3NHI'
dic='ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'
msg=''.join([dic[(5*dic.find(x)+12)%32] for x in s])
return b32decode(msg+'='*(8-len(msg)%32))

if __name__=='__main__':
#python solve.py
print solve()

simpleRSA

求E1

q = next_prime(getPrime(16) * p + 38219)可知,qp*getPrime(16)+38219的下一个素数,因此getPrime(16)较小,所以我们可以在其取值范围为遍历出符合题目的值,从而解出q

1
2
3
4
5
6
7
8
9
10
11
12
13
for i in range(2 ** 15, 2 ** 16):
if isPrime(i):
q = next_prime(i * iroot(n // i, 2)[0] + 38219)
if n % q == 0:
print(q)
break

p = n // q
phi = (p - 1) * (q - 1)
d = invert(e, phi)
E1 = pow(c, d, n)
print(E1)
#

做到E2就麻了,Crypto先做其他简单的题吧

onetimepad

Crypto先到这里吧

cr2-many-time-secrets

尝试了几个编码不行

题目中提示是One Time Pad的重用导致的攻击。

一次性密码本 one-time pad(OTP):

  • key的长度大于等于message
  • key必须是一次性的,且每次都要随机产生

满足上述两个条件,即称为 OTP

异或加密特性

  • 两个值相同时,返回flase,否则返回true
  • 如果对一个值连续做两次XOR,会返回这个值本身.
  • 假设原始信息是message,密钥是key,第一次 XOR 会得到加密文本cipherText。对方拿到以后,再用key做一次 XOR 运算,就会还原得到message

加密101-异或(xor)
工具
https://github.com/SpiderLabs/cribdrag

简单来说呢,就是利用一些用同个密钥生成的密文,猜对其中部分密文对应的明文,即可求出公共密钥,再用该可能的密钥去解其他的密文,若符合,则为密钥正确。

1
python cribdrag.py 0529242a631234122d2b36697f13272c207f2021283a6b0c79082f28202a302029142c653f3c7f2a2636273e3f2d653e25217908322921780c3a235b3c2c3f207f372e21733a3a2b37263b3130122f6c363b2b312b1e64651b6537222e37377f2020242b6b2c2d5d283f652c2b31661426292b653a292c372a2f20212a316b283c0929232178373c270f682c216532263b2d3632353c2c3c2a293504613c37373531285b3c2a72273a67212a277f373a243c20203d5d243a202a633d205b3c2d3765342236653a2c7423202f3f652a182239373d6f740a1e3c651f207f2c212a247f3d2e65262430791c263e203d63232f0f20653f207f332065262c31683137223679182f2f372133202f142665212637222220733e383f2426386b

历时3个小时终于把这个脚本或者说python2的环境有搞好了.

若是明文中的则是message

若是flag则为key

image-20230313231929145

ALEXCTF{是key

一点一点猜测下面的内容

Decode_The_File

找到了python2的脚本改一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import base64
from string import ascii_uppercase, ascii_lowercase, digits
from Crypto.Util.number import long_to_bytes

def solve():
with open('encode','r') as f:
codes=f.read()
Lc=codes.split('\n')[:-1]
base=ascii_uppercase+ascii_lowercase+digits+'+/'
re2=[]
for code in Lc:
if '==' in code:
re2.append(bin(base.find(code[-3]))[2:].rjust(6,'0')[2:])
elif '=' in code:
re2.append(bin(base.find(code[-2]))[2:].rjust(6,'0')[4:])
ret=''.join(re2)
return long_to_bytes(int(ret[:ret.rfind('1')+1],2))

if __name__=='__main__':
print (solve())
#b'ROIS{base_GA_caN_b3_d1ffeR3nT}'

streamgame1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# flag的长度为25字节,25-6=19个字节
#3<<2可以这么算,bin(3)=0b11向左移动2位变成1100,0b1100=12(十进制)
def lfsr(R,mask):
output = (R << 1) & 0xffffff #将R向左移动1位,bin(0xffffff)='0b111111111111111111111111'=0xffffff的二进制补码
i=(R&mask)&0xffffff #按位与运算符&:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0
lastbit=0
while i!=0:
lastbit^=(i&1) #按位异或运算符:当两对应的二进位相异时,结果为1
i=i>>1
output^=lastbit
return (output,lastbit)

R=int(flag[5:-1],2)
mask = 0b1010011000100011100

f=open("key","ab") #以二进制追加模式打开
for i in range(12):
tmp=0
for j in range(8):
(R,out)=lfsr(R,mask)
tmp=(tmp << 1)^out #按位异或运算符:当两对应的二进位相异时,结果为1
f.write(chr(tmp)) #chr() 用一个范围在 range(256)内的(就是0~255)整数作参数,返回一个对应的字符。
f.close()

题目给的很详细了,但是现在确实做不出来,但总不能不做了吧,看WP

那么我们的任务很明确,就是通过分析lfsr函数,整理成数学表达式的形式求解即可,接下来我们对代码进行逐行解读

1
2
3
4
5
6
7
8
9
10
11
def lfsr(R,mask):
output = (R << 1) & 0xffffff #把R左移一位后低32位,(即抹去R的最高位,然后在R的最低位补0)的值赋给output变量
i=(R&mask)&0xffffff #把传入的R和mask做按位与运算,运算结果取低32位,将该值赋给i变量。
lastbit=0
# 从i的最低位向i的最高位依次做异或运算,将运算结果赋给lastbit变量。
while i!=0:
lastbit^=(i&1) #按位异或运算符:当两对应的二进位相异时,结果为1
i=i>>1
output^=lastbit #将output变量的最后一位设置成lastbit变量的值。
return (output,lastbit)#返回output变量和lastbit变量的值,output即经过一轮lfsr之后的新序列,lastbit即经过一轮lfsr之后输出的一位。

通过上面的分析,我们可以看出在这道题的情境下,lfsr函数本质上就是一个输入R输出lastbit的函数,虽然我们现在已经清楚了R是如何经过一系列运算得到lastbit的,但是我们前面的反馈函数都是数学表达式的形式,我们能否将上述过程整理成一个表达式的形式呢?这就需要我们再进一步进行分析:

1
2
3
4
mask = 0b1010011000100011100
mask 只有第3,5,8,9,13,17,18,19位是1,其余均为0.
mask与R做按位与运算得到i,当且仅当R中的第3,5,8,9,13,17,18,19位也是1时,i中才可能出现1,否则i中将全为0.
lastbit是由i的最低位向i的最高位一次做异或运算得到的,在这个过程中,所有为0的位我们可以忽略不计

将其写成数学表示式的形式,即为:

lastbit=R3^R5^R8^R9^R13^R17^R18^R19

显然lastbit和R之间满足线性关系,那么接下来我们就可以开始求解了

关键就在于这个key如何去解,一开始我是之间复制粘贴,取前19位,发现全都是0,后来直接看了一下key的全部值,发现在最后几位才出现1.

1
2
3
4
5
6
7
import os,sys
os.chdir(sys.path[0])
from Crypto.Util.number import*
f = open('key','rb').read()
key = bytes_to_long(f)
bin_out = bin(key)[2:].zfill(100*8)
print(bin_out[:19])

正确的是这个脚本

https://blog.csdn.net/xiao__1bai/article/details/120399710

1
2
3
xiao__1bai师傅:
然后查了好些资料发些他们从文件中读取二进制数的代码还是不够简便,于是我吸取了我前面base64编码的代码写了一串从文件中读取对齐的二进制的代码,以后也直接拿来用即可。
(在线转换都会省略最开头的0导致结果位数错误,进而导致结果错误,所以自己要注意。)
1
2
3
4
5
6
7
f = open('5key','rb')	#以二进制格式打开文件
content = f.read() #读取的是\xhh类型的十六进制
#print(content)
key=['{:0>8}'.format(str(bin(i)).replace('0b','')) for i in content] #从base64编码汲取的经验,二进制8位对齐。#是将二进制数的字符串形式转换为8位长度,不足的位数用0补齐;
#例如,如果读取的二进制数据是b'ABCD',那么key的值为['01000001', '01000010', '01000011', '01000100']。
print(''.join(key)[:19])#前19位就是key
#0101010100111000111

这里说的lastbit就是key的值(这里是之前一道题的图,也是跟着之前的思路做的)

img

这样我们就可以求出R的第1位,同样的方法,我们可以求出R的第2位:

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 开发时间:2023/3/14 11:38
maks = '0b1010011000100011100'
key = '0101010100111000111'
tmp = key

R = ''
for i in range(19):
output = '?' + key[ :18]
ans = str(int(tmp[-1-i])^int(output[-3])^int(output[-4])^int(output[-5])^int(output[-9])^int(output[-13])^int(output[-14])^int(output[-17]))
R += str(ans)
key=str(ans)+key[:18]
R=R[::-1]
flag="flag{"+R+"}"#这里要不要进行进制转换可以需要参考RR=int(flag[5:-1],2)
print(flag)

Normal_RSA

确实是普通的RSA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 开发时间:2023/3/12 15:01
import gmpy2
from Crypto.Util.number import bytes_to_long, long_to_bytes

n = 87924348264132406875276140514499937145050893665602592992418171647042491658461
e = 65537

p=275127860351348928173285174381581152299
q=319576316814478949870590164193048041239

Phi = (p - 1) * (q - 1)

d = gmpy2.invert(e, Phi)

with open('flag.enc', 'rb') as file:
data = bytes_to_long(file.read())
res = long_to_bytes(pow(data, d, n))
print(res)

easy_ECC

椭圆曲线加密算法

img

要调整为10进制

点CALC R

说我作弊需要证据

追踪数据流我们注意到从Alice(192.168.0.13)和Bob(192.168.0.37)的每个数据包都包含base64编码的有效负载。

看时间猜测是A给B发

解码几行

1
2
3
4
5
SEQ = 13; DATA = 0x3b04b26a0adada2f67326bb0c5d6L; SIG = 0x2e5ab24f9dc21df406a87de0b3b4L;
SEQ = 0; DATA = 0x7492f4ec9001202dcb569df468b4L; SIG = 0xc9107666b1cc040a4fc2e89e3e7L;
SEQ = 5; DATA = 0x94d97e04f52c2d6f42f9aacbf0b5L; SIG = 0x1e3b6d4eaf11582e85ead4bf90a9L;
SEQ = 4; DATA = 0x2c29150f1e311ef09bc9f06735acL; SIG = 0x1665fb2da761c4de89f27ac80cbL;
SEQ = 18; DATA = 0x181901c059de3b0f2d4840ab3aebL; SIG = 0x1b8bdf9468f81ce33a0da2a8bfbeL;

实在搞不出来了.按着风二西师傅的wp做的,我只能说yyds

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import libnum
import gmpy2
from Crypto.Util.number import bytes_to_long
def rsa(c,m):
#print(type(c),16)
c=int(c,16)
m=int(m,16)
n1 = 1696206139052948924304948333474767
e = 0x10001
d1 = 37191940763524230367308693117833
n2= 3104649130901425335933838103517383
d2 = 1427000713644866747260499795119265

a1 = pow(m, e ,n1)
a2 = pow(c, d2, n2)
a1 = libnum.n2s(a1)
a2 = libnum.n2s(a2)
return a1,a2
with open("1.txt","r") as f:
flag=[]
for i in f.readlines():
a1=i.find("DATA = ")
a2=i.find("L;",a1)
a3=i[a1+7:a2]
#print (a3)
b1=i.find("SIG = ")
b2=i.find("L;",b1)
b3=i[b1+6:b2]
#print (b3)
#print b3
a4=rsa(a3,b3)#自己写了一个rsa函数
flag.append(a4)
#print (flag)
flag1=""
for i in flag:
if i[0]==i[1]:
flag1 += chr(bytes_to_long(i[0]))
print(flag1)
#flag{n0th1ng_t0_533_h3r3_m0v3_0n}

第一部分不再赘述

看这个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
with open("1.txt","r") as f:
flag=[]
for i in f.readlines():
a1=i.find("DATA = ")
a2=i.find("L;",a1)
a3=i[a1+7:a2]
#print (a3)
b1=i.find("SIG = ")
b2=i.find("L;",b1)
b3=i[b1+6:b2]
#print (b3)
#print b3
a4=rsa(a3,b3)
flag.append(a4)

find() 是 Python 字符串对象的方法之一,用于在一个字符串中查找子字符串,并返回第一次出现的位置

Easy_Crypto

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
get buf unsign s[256]

get buf t[256]

we have key:hello world

we have flag:????????????????????????????????


for i:0 to 256

set s[i]:i

for i:0 to 256
set t[i]:key[(i)mod(key.lenth)]

for i:0 to 256
set j:(j+s[i]+t[i])mod(256)
swap:s[i],s[j]

for m:0 to 37
set i:(i + 1)mod(256)
set j:(j + S[i])mod(256)
swap:s[i],s[j]
set x:(s[i] + (s[j]mod(256))mod(256))
set flag[m]:flag[m]^s[x]

fprint flagx to file

前半部分是RC4

主要看这里

1
2
3
4
5
6
for m:0 to 37
set i:(i + 1)mod(256)
set j:(j + S[i])mod(256)
swap:s[i],s[j]
set x:(s[i] + (s[j]mod(256))mod(256))
set flag[m]:flag[m]^s[x]

加密操作是异或,而我们又知道他加密的全部过程,所以再次用相同的步骤异或一次就可以得到明文

根据伪码逆着来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
key = 'hello world'
t = []
s = list(range(256))
c = open("E:\\filexz\IDMxz\enc\enc.txt","rb").read()

for i in range(256):
t.append(key[i % len(key)])
print(t)

j = 0
for i in range(256):
j = (j + s[i] + ord(t[i])) % 256
s[i], s[j] = s[j], s[i]
print(s)
i = 0
j = 0
flag = ""
for ci in c:
i = (i + 1) % 256
j = (j + s[i]) % 256
s[i], s[j] = s[j], s[i]
x = (s[i] + (s[j] % 256)) % 256
flag += chr(ci ^ s[x])
print(flag)

Easy-one

加密代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
if (argc != 3) {
printf("USAGE: %s INPUT OUTPUT\n", argv[0]);
return 0;
}
FILE* input = fopen(argv[1], "rb");
FILE* output = fopen(argv[2], "wb");
if (!input || !output) {
printf("Error\n");
return 0;
}
char k[] = "CENSORED";
char c, p, t = 0;
int i = 0;
while ((p = fgetc(input)) != EOF) {
c = (p + (k[i % strlen(k)] ^ t) + i*i) & 0xff;
t = p;
i++;
fputc(c, output);
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
char k[] = "CENSORED";    // 初始化一个密钥字符串,但真正的密钥不是它
char c, p, t = 0; // 定义加密后的字符,上一个字符,以及一个临时变量 t
int i = 0; // 定义计数器 i 并将其初始化为 0

while ((p = fgetc(input)) != EOF) { // 从输入流中读取字符,直到文件末尾
c = (p + (k[i % strlen(k)] ^ t) + i*i) & 0xff; // 对当前字符进行加密
t = p; // 将上一个字符保存到临时变量 t 中
i++; // 递增计数器 i
fputc(c, output); // 将加密后的字符写入输出流
}

在循环中,每次读取一个字符 p,然后计算出一个加密后的字符 c。加密过程中,首先从密钥字符串中取出一个字节进行异或运算,然后加上上一个字符 t 和计数器 i 的平方。最后将结果与 0xff 做与运算(这是一个二进制掩码,用于确保加密后的字符只有一个字节),并将结果赋值给加密后的字符 c

然后将当前字符 p 保存到临时变量 t 中,以备下一次加密使用。计数器 i 也会递增,以便在下一次循环中使用下一个密钥字节。最后,将加密后的字符 c 写入输出流中。

总体来说,这段代码使用简单的加密算法将输入流中的数据加密,并将加密后的数据写入输出流中。密钥字符串可以根据需要更改,以生成不同的加密输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
f1=open("msg001",'rb+')
f2=open("msg001.enc",'rb+')
p=f1.read()
c=f2.read()
p = p.decode()
c = c.decode('ISO-8859-1')
key=''
print(p)
print(c)
p = p.replace(' \\n','')
p = [ord(i) for i in p]
c = [ord(b) for b in c]
print(p)
print(c)
t = 0
key=""
for i in range(len(p)):
k=((c[i]-p[i]-i*i)^t)&0xff
t=p[i]
key=key+chr(k)
print(key)
#VeryLongKeyYouWillNeverGuessVe
#这里后面的Ve是多余的,因为明文的长度,比key的长度2个,

接下来解密

1
2
3
4
5
6
7
8
9
10
11
12
13
f = open('msg002.enc','rb').read()
f = f.decode('ISO-8859-1')
print(f)
c = [ord(i) for i in f]
flag = ''
t = 0
key = 'VeryLongKeyYouWillNeverGuess'
for i in range(len(c)):
# c = (p + (k[i % len(k)] ^ t) + i * i) & 0xff;
p = (c[i] - (ord(key[i % len(key)]) ^ t) - i * i) & 0xff
t = p
flag = flag+ chr(p)
print(flag)

x_xor_md5

放入HEX后就没思路了,

01780C4C109E3237120CFBBACB8F6A53

WP上说:怀疑 重复的内容就是 xor key

用 xor key 去和每一行的数据进行 异或运算,

再将其 转为字符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# -*- coding:utf-8 -*-
def file_xor_key(*m):#原始文件 16 进制 XOR 原始 key(每一行 XOR 原始 key 一行)
num0 = ['69','35','41','01','1C','9E','75','78','5D','48','FB','F0','84','CD','66','79',
'55','30','49','4C','56','D2','73','70','12','45','A8','BA','85','C0','3E','53',
'73','1B','78','2A','4B','E9','77','26','5E','73','BF','AA','85','9C','15','6F',
'54','2C','73','1B','58','8A','66','48','5B','19','84','B0','80','CA','33','73',
'5C','52','0C','4C','10','9E','32','37','12','0C','FB','BA','CB','8F','6A','53',
'01','78','0C','4C','10','9E','32','37','12','0C','FB','BA','CB','8F','6A','53',
'01','78','0C','4C','10','9E','32','37','12','0C','FB','BA','CB','8F','6A','53',
'01','78','0C','4C','10','9E','32','37','12','0C','89','D5','A2','FC']
j = 0
s = ""
num_xor_key = []
for i in range(0,len(num0)):
x = int(num0[i],16)
if j >= 16:
j = 0
y = int(m[j],16)
j += 1
num_xor_key.append(hex(x^y)[2:])
s += chr(x^y)
print(num_xor_key)
print(s)
return(num_xor_key)
m = ['01','78','0C','4C','10','9E','32','37','12','0C','FB','BA','CB','8F','6A','53']
num = file_xor_key(*m)

得到有ctf字样的乱码,说明思路没有出错,还需要进一步操作

img

审查得到的 16 进制列表数据,发现 不应该出现0x00,0x00是绝对意义上的空,而空格 是 0x20

所以猜测应该是 所有数据还要和 0x20 进行 异或运算

1
2
3
4
5
6
7
8
9
10
11
12
13
def file_xor_20(*n):#16 进制数组 XOR 0x20
m = '20'
y = int(m,16)#将16进制转换为10进制,就是32
print(y)
s = ""
num =[]
for i in range(0,len(n)):
x = int(n[i],16)
num.append(hex(x^y)[2:])
s += chr(x^y)
print(num)
print(s)
file_xor_20(*num)

img

这里只需要跟假key异或即可,并得到疑似的key=21582c6c30be1217322cdb9aebaf4a73

疑似的 flag 为 RCTF{We1l_d0n3_ut_wh4t_i5_key },但 FLAG 中最后一列的字符还有非可显示 字符(key 后面是个空格,还有 ut 前面,并且这两个位置都是每次key循环完成后的第16位),说明最后一列的KEY不正确,猜测 key 被两个包括,即key*,所以就是 0x00^0x2a,尝试调整后得到真正的 key: 21582c6c30be1217322cdb9aebaf4a59

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
def getkey():
m = ['01','78','0C','4C','10','9E','32','37','12','0C','FB','BA','CB','8F','6A','53']
y = 32#将16进制的0x20转换为10进制,就是32
s = ""
r_key =[]
for i in range(0,len(m)):
x = int(m[i],16)
r_key.append(hex(x^y)[2:])
print(r_key)
return r_key
def file_xor_key(m):#原始文件 16 进制 XOR 原始 key(每一行 XOR 原始 key 一行)
num0 = ['69','35','41','01','1C','9E','75','78','5D','48','FB','F0','84','CD','66','79',
'55','30','49','4C','56','D2','73','70','12','45','A8','BA','85','C0','3E','53',
'73','1B','78','2A','4B','E9','77','26','5E','73','BF','AA','85','9C','15','6F',
'54','2C','73','1B','58','8A','66','48','5B','19','84','B0','80','CA','33','73',
'5C','52','0C','4C','10','9E','32','37','12','0C','FB','BA','CB','8F','6A','53',
'01','78','0C','4C','10','9E','32','37','12','0C','FB','BA','CB','8F','6A','53',
'01','78','0C','4C','10','9E','32','37','12','0C','FB','BA','CB','8F','6A','53',
'01','78','0C','4C','10','9E','32','37','12','0C','89','D5','A2','FC']
j = 0
s = ""
m = m[:15]+['59']
print("m: ",m)
num_xor_key = []
for i in range(0,len(num0)):
x = int(num0[i],16)
if j >= 16:
j = 0
y = int(m[j],16)
j += 1
num_xor_key.append(hex(x^y)[2:])
s += chr(x^y)
print(num_xor_key)
print(s)
return(num_xor_key)
key = getkey()
file_xor_key(key)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for ii in range(11,99):
print(ii)
m = m[:15] + ['{}'.format(ii)]
# m = m[:15]+['{}'.format(ii)]
print(m)
num_xor_key = []
for i in range(0,len(num0)):
x = int(num0[i],16)
if j >= 16:
j = 0
y = int(m[j],16)
j += 1
num_xor_key.append(hex(x^y)[2:])
s += chr(x^y)
#
math = str.find(s,'RCTF')
print(s[math:math+33])
s =""

也可以爆破一下