ISCTF2023

Reverse

ezrust

程序用了check_time反调试 一共三四处 全部nop掉
直接动调看逻辑
image
这两处分别得到[0xff]*32[0x80]*32

image

主check逻辑
v43是一个类似index的数组 采用的是数组间接寻址 找到
image

同理 能够得到v53[]
v52<-v72<-[0x80]
大致调一调 发现v59跟输入很接近 只是ord差了1(输入'a'得到0x60 'I'得到'H')
应该是像赛后出题人所说的关于rust的溢出问题
但不影响做题 找到数组加回去+1即可

print('ISCTF'+'a'*27)
index = [0x0000000000000010, 0x000000000000001C, 0x0000000000000009, 0x0000000000000005, 0x0000000000000003, 0x0000000000000012, 0x000000000000000B, 0x000000000000001F, 0x0000000000000013, 0x0000000000000018, 0x000000000000000F, 0x000000000000000D, 0x0000000000000007, 0x0000000000000019, 0x0000000000000011, 0x000000000000001B, 0x0000000000000017, 0x0000000000000002, 0x0000000000000016, 0x000000000000000A, 0x0000000000000015, 0x0000000000000006, 0x000000000000000E, 0x000000000000001A, 0x0000000000000004, 0x0000000000000008, 0x000000000000001D, 0x000000000000001E, 0x0000000000000001, 0x000000000000000C, 0x0000000000000014, 0x0000000000000000, 0x0000000000000004]
enc = [0x04, 0x15, 0x0D, 0x3B, 0x0B, 0x2D, 0x0F, 0x13, 0x4E, 0x3E, 0x1A, 0x2F, 0x12, 0x4D, 0x22, 0x22, 0x38, 0x22, 0x06, 0x4C, 0x0A, 0x1C, 0x1C, 0x13, 0x0D, 0x1D, 0x51, 0x50, 0x2E, 0x0F, 0x1B, 0x0C]
for c in index:
    try:
        print(enc[c],end=',')
    except:
        pass

key = [56,46,62,45,59,6,47,12,76,13,34,77,19,29,34,80,19,13,28,26,28,15,34,81,11,78,15,27,21,18,10,4,11]
print()
print(hex(ord('I')-56))
for i in key:
    print(chr(0x80-i+1),end='')

ISCTF{Ru5t_4nd_1nteger_0v3rflow}

Crypto

ez_rsa

from secret import flag,key
from Crypto.Util.number import *
from random import randint,getrandbits
from sympy import factorial as factor
from gmpy2 import is_prime as is_strongPrime
from gmpy2 import gcd
from libnum import s2n

def step1(m):
	p,q = getPrime(1024),getPrime(1024)
	n=p*q
	e=getPrime(512)
	phi = (p-1)*(q-1)
	while gcd(e,phi) != 1:
		e=getPrime(512)
	d = pow(e,-1,phi)
	k = randint(800,1500)
	f = factor(k)
	leak = (pow(e, 2) + (e*d - 1)*f)*getPrime(256) + k
	print(f"{n=}")
	print(f"{leak=}")
	e = 65537
	c = pow(m,e,n)
	return c


def step2(m):

	assert key < 10**9
	assert (is_prime(key) and not is_strongPrime(key))

	p,q = getPrime(512),getPrime(512)
	n=p*q
	leak1 = pow(p,q,n) + pow(q,p,n)
	print(f"{n=}")
	print(f"{leak1=}")
	e=0x10001
	c = pow(m,e,n)
	seed = getrandbits(64)
	a = getPrime(256)
	b = getPrime(256)
	leak2 = []
	for i in range(10):
		leak2.append(seed := (seed * a + b) % p)
	print(f"{leak2 = }")
	seed = (seed * a + b) % p
	base = key ^ seed
	final = []
	while c > 0:
		final.append(c % base)
		c //= base

	return final

def is_prime(p):
	check = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
	return all([pow(i,p-1,p)==1 for i in check])


def main():
	assert len(flag) == 2
	print("step1:")
	print("c =",step1(s2n(flag[0])))
	print("step2:")
	print("final =",step2(s2n(flag[1])))


if __name__ == "__main__":
	main()
step1:
n=11947241219140615237486309604628973391930339499486798714294498785973885463922548820705069266901903036359254530976927762175262118185159625298369758973935607721381080656199430417818042316007700805008489750740972102287526203064312544340176751751266738219862839022892152635044837041435349904947659346174437695051460882295109851494351994498403791853684239883961766735230202016890875913906900424655711952381425165331389205409282026144667620577946333963601349932905443037145145394667138672752796990411249984169798953060016353748467221154507518574580014882822860853751863757579945329482337792853278715658322366578632817369803
leak=4825516411405566882589539973300777582630401687252523937619475044718073214792109569356301252345907914527064817796240727881691399437316660502564323688151311441558823720142071322647007043253626474853010585775710666373651910201889816367922377400970334479040370865879692204764210349607801862666059991789964453439198722962928173197103040385999540054988070333338229570681105393323319767364566644771731595597298210924296456293443125736685469259629163687986114207231233692023613120260155832741199446052855856512791809968963821161765216500389495853488545132008219841635172896843241988125093920217328861507191614658581776695350233593334984646128341640512614300048002219790302478025661133721688232990437685571940604588227022076092857294647830142309441330515812342199940466483115991318018705011472671758063610572930560763516803732693572940939851140384123593105367117155740563057395940645038058194280259524467405820813428765139386968927021061208348111646257434870000866555555283176852834141906387086839051793789126474095527358879630274092172435022326207193319806666865704778907868548658370890623182731938070419969709739233504224100413506514936517272134494776127809327563935813198793891897000404156963455000732616317276241867836699641699825594195079194154957636030485909612033254350828892222046169586844737908349421869385194421981553067305581842171364022745759111602699744161574724372962242132415149146766136601016174658042678857388889036814591399168640678928083442174651493660991088328784105160030857387096251561933704301600695757426945716557961698202485226605485682131045560193822624290720243852434254301324766198129736640005205530445739302632191151740246117208267182630330046600955724262084795763080838384593939971523865769318326101179866187596006185138294477350533316908592086441208575935282494961976691089358976722199557082176285926812134290542838960814502829473372780200310674359645482281037654052483716329497333729594792122297988611883754886634452292313599416610842690057657285337854049766320641249317238780428383587602425132767334811708075065922641191109650660427678019567095309270443930385437292172296652003394183918270707887845018685247162812541929998945735270109736669595830167257239265204520272132384023622231518288514767919183916561550558812478144292894132331163501566746036390319663066054892756826660841952717280005731719082266616429646501565960817772663658546555336959754321712751857740551378987853931613973604348308746819562341219749677392565068390386908064199536445684309718116754288299091975226013592388160308117145043236992250577771659408413506586402897189336742792418163003231783947003853396754144599319566763313339145462208172531322682800226151072022731913191728047323245146556315571396082728252085753230639541374982105041248659074695696205654079837224195868428271353983820725017250413714060967825638577327604252122887136259380946072629481202720339169708229866846597577227829317443910036825722430374711816074735238082313198164126791797947010044130222158124667234003098164746100341636238823175289796896896408971518797835906067939914494546110471749352544064300485882179448030898818405400902242119590645639910708635188342567159795613212660990908765619684401061336405049960091659288716162966504703741105477420409053115823924764680153604215949521605456710353305498258615912458036292507652321420277318757146737030628878096962452278346772976364597137682209395761868224382621093921689415088745975049380393255899867417274843474628482169247388041616142896804170033688742622605192409970919836724035274730923747265191248135577704760607590
c = 4058526944014006069084945174812818814825704864122299028618329411106188952604728150732223145114766938864644072527523082946069975859381918224872075058517683896020489424720005770218969436595364473179601299857281520204212872074837132357469599147175121200219338329188718982224238281009625352190581095607599976922610436817213692622671732783554216636941121695116377777616027462234472833366922829073660312229117800995468022619934881890343086653577149166193139948443894324239522101581089953817527886638425552917578146958961373353776642091545344162923084513872918786615317499139918810812014781753970806739855831453833956364967

step2:
n=138222025039224144545251830624229986468723531196582463907557734108529994926504669875900898789473948111199016914847829105939167293515822413866727879262875702026534563930475309506834431656926222982363543666448736091756871792887144283877167509418070979449484508499296324616988840431116233637168977730122017878289
leak1=23535059927033628406212169278224758389583882623183004031205822980722154537430761635153622180505243837027568034322858038302626132200979370182327110682738910
leak2 = [362437850887271063413256292444148642949623196635276044583204094265607936120337004605360832421011, 1932915843524327487337992118762711929552569713433223514001673251237692307587356544615955431611435994003602897830069566867051943572065473955405337889221398, 11222178024143398739150445814520244630341642052876364179793404105841311693968292227072031763726153574031884490677131749512430325919668649359617953965112844, 5408933876805830533113961512210040977462510675785228477646978801328722923647434079128879371684477664804744431834418916837956820965870203842552250165916773, 1447143741705069323823257922715038721270982554690635708441585728089036094805730054505696492295730683300002193478561819037345041940787115528445592303142510, 3707657531268843465369646969917923274507341341483950204025637357600814449263032574496424566705812439915548150679438579110456264431525526309588664326456861, 9263925820149827740182684692442727161206242182976684575667062235695526783971703826794731732152445051579616121306722939129265340347908823003172137299057843, 207494591333501391015462321304802957885928775185602834554977737560856036337667840127810136802887548047878444936730742505483927963807357904024967768148122, 7052936859446617933917872361389151092893299250603966165472023802877016733939957851026719428770748111897050866474067880613419756475700748999497496482278608, 1169538791889404037461397919075674424569430764451305755000680272926397357803359328850780774937432248011264334398346178303234064891680342161511829008635621]
final = [2268617516274900905319941795987877533673889507146326516564545408684476960310333170888941124460992562245780101836116975666368936099249664924148379487909122, 1445275952377746701088629016221431744592935398639655895336779954310077866709012082302847692239730041591520169244063854849129773530127510048494782550102381, 7]

其实题目出的挺好的傻逼的我赛时没做出来
两部分
PART1:
给了leak的一个表达式 这里要注意到 k! 非常的大
所以 x = (leak-k)//k! ≈ (ed-1)xgetprime(256)
然后我们通过 gcd(leak-k,x) => getprime(256)
进而可以得到 ed-1 => k×phi
这里得到ed-1要精确恢复

for k in range(800,1500):
    fact = factorial(k)
    ed_1_prime256 = (leak-k)//fact
    prime256 = int(gcd(ed_1_prime256,leak-k))
    if prime256.bit_length()>=200:
        print(f'k= {k}\nprime256= {prime256}')
        break

得到了kphi其实直接求e相对kphi的逆元作为d就能解RSA了(学群论后基础数论忘了好多)

k= 1039
prime256= 108265111455950860152587704451025053167231031155722144225275801978438974863031
f = factorial(k)
e_2_prime256 = (leak-k)%f
ed_1 = (leak-k-e_2_prime256)//(f*prime256)
kphi = ed_1
e = 65537
e = int(e)
kphi = int(kphi)
d = modinv(e,kphi)
print(long_to_bytes(pow(c,d,n)))
# b'ISCTF{yOu_kn0W_RSAgcd_and_g0Od_at'

PART2:
注意到这个key的生成方式 可以发现符合卡迈克尔数的特性 查表 or 爆破都行
给的leak1其实就是给的p+q solve解一下即可
然后就是LCG恢复a,b 这里注意! p,q换一换试一试。。。 我一直以第一个解出的p 结果一直LCG恢复不对 后面一看 题目没规定顺序...难绷

p = 
q = 
p,q = q,p
a = (leak2[-1]-leak2[-2])*modinv(leak2[-2]-leak2[-3],p)%p
b = (leak2[-1]-a*leak2[-2])%p
print(a,b)
seed = a*leak2[-1]+b
seed %= p
base = seed^key
c=base*(final[1]+final[2]*base)+final[0]
d = modinv(65537,(p-1)*(q-1))
m = long_to_bytes(pow(c,d,n))
print(m)
# b'_LCG_also_like_Carmichael_number}'

flag: ISCTF{yOu_kn0W_RSAgcd_and_g0Od_at_LCG_also_like_Carmichael_number}

babyGroup

Per.py

import random
from gmpy2 import invert,sqrt,gcd

class P:
	def __init__(self, data):
		if type(data) is int:
			self.size = data
			self._list = [i+1 for i in range(self.size)]
			self._initialize()			
		elif type(data) is list:
			self._list = data
			self.size = len(self._list)

	def __mul__(self, other):
		return P(self._iterList(self.getList(),other.getList()))

	def __repr__(self):
		return str(self._list)

	def __len__(self):
		return len(self._list)

	def __pow__(self, other):
		tempList = self._list
		for _ in range(1,other):
			tempList = self._iterList(tempList, tempList)
		return P(tempList)

	def __str__(self):
		return str(self._list)

	def getList(self):
		return self._list

	def _initialize(self):
		for i in range(10):
			random.shuffle(self._list)

	def _iterList(self, List1,List2):
		new_list = []
		for elem in List1:
			new_list.append(List2[elem - 1])
		return new_list

pass

class Block():
	def __init__(self):
		while True:
			self.q = random.getrandbits(2048)
			self.f = random.randint(1, sqrt(self.q // 2))
			self.g = random.randint(sqrt(self.q // 4), sqrt(self.q // 2))
			if gcd(self.f, self.q * self.g) == 1:
				break

		self.h = invert(self.f, self.q) * self.g % self.q
		
	def getPublicKey(self):
		return (int(self.q), int(self.h))
	
	def enc(self, m):
		assert m < sqrt(self.q//4)
		r = random.randint(1, sqrt(self.q // 2))
		e = (r * self.h + m) % self.q
		
		return int(e)

	def dec(self, e):
		a = self.f * e % self.q
		b = invert(self.f, self.g) * a % self.g
		return b

task.py

from Per import P,Block
from secret import flag
import hashlib
from libnum import s2n

mask = P(256)

print(mask**2)
mask_hash = hashlib.sha512(str(mask).encode()).hexdigest()
print("the mask hash is:" + mask_hash)

mul = P(256)
print(f"{mul=}")
temp = hashlib.sha512(str(mask * mul).encode()).hexdigest()

msg = s2n(flag) ^ int(temp,16)

worker = Block()
print(f"pubkey(q,h):{worker.getPublicKey()}")
c = worker.enc(msg)
print(f"{c=}")
dec = worker.dec(c)


output

[82, 237, 32, 83, 30, 200, 116, 114, 4, 147, 171, 152, 193, 19, 170, 136, 186, 8, 124, 159, 225, 6, 180, 125, 74, 14, 255, 60, 187, 132, 222, 121, 56, 79, 57, 229, 87, 27, 72, 197, 201, 191, 75, 38, 135, 177, 165, 149, 17, 172, 173, 59, 210, 108, 31, 142, 163, 227, 178, 226, 73, 256, 190, 12, 103, 238, 129, 157, 219, 131, 67, 28, 68, 236, 168, 209, 245, 93, 61, 122, 208, 137, 49, 94, 111, 18, 161, 106, 54, 175, 70, 16, 110, 5, 218, 81, 233, 45, 91, 188, 151, 104, 148, 184, 228, 248, 150, 176, 167, 35, 130, 242, 126, 156, 42, 169, 232, 102, 50, 214, 179, 205, 9, 235, 97, 84, 246, 36, 76, 240, 52, 144, 98, 86, 99, 21, 64, 217, 15, 202, 206, 55, 244, 65, 23, 53, 250, 78, 22, 215, 25, 66, 143, 107, 195, 80, 196, 254, 174, 33, 162, 252, 141, 153, 43, 185, 211, 220, 115, 127, 216, 251, 139, 95, 146, 48, 239, 241, 37, 199, 13, 160, 90, 223, 123, 181, 120, 164, 118, 112, 128, 192, 249, 39, 2, 207, 71, 182, 145, 62, 3, 92, 183, 194, 100, 24, 133, 10, 117, 234, 29, 11, 140, 166, 85, 224, 230, 134, 189, 63, 46, 58, 231, 247, 47, 154, 44, 77, 89, 101, 69, 40, 26, 243, 253, 41, 51, 105, 155, 138, 1, 212, 20, 203, 213, 198, 158, 88, 109, 34, 119, 221, 113, 96, 204, 7]

the mask hash is:91881f508f08fbafec1a6879fc3a1f215135c94c78f03fae8534d54dc05bd4a122a4e4508d32b9e02be08fbbb42a9e3335fc433c20e2da2e012d11b7324f6952

mul=[114, 189, 92, 56, 252, 161, 202, 250, 131, 9, 111, 226, 223, 24, 14, 6, 99, 208, 195, 216, 141, 116, 167, 34, 5, 129, 15, 158, 178, 197, 4, 187, 27, 200, 144, 76, 74, 154, 86, 249, 93, 112, 46, 104, 25, 248, 40, 225, 38, 98, 186, 169, 64, 118, 33, 88, 26, 106, 183, 43, 201, 198, 242, 135, 110, 218, 244, 120, 83, 212, 192, 185, 148, 142, 11, 45, 232, 107, 18, 170, 60, 130, 247, 67, 65, 211, 182, 213, 134, 254, 70, 191, 210, 176, 145, 217, 82, 229, 125, 193, 155, 41, 113, 103, 49, 231, 133, 75, 109, 238, 126, 245, 163, 233, 227, 181, 51, 12, 143, 234, 239, 59, 240, 209, 42, 205, 230, 253, 203, 219, 23, 136, 32, 87, 102, 94, 85, 62, 172, 236, 124, 100, 256, 196, 50, 101, 206, 150, 89, 29, 61, 69, 246, 237, 16, 37, 184, 90, 162, 22, 36, 10, 31, 52, 190, 17, 55, 115, 251, 77, 214, 122, 1, 255, 151, 157, 241, 224, 3, 44, 48, 175, 194, 138, 179, 159, 160, 53, 80, 73, 8, 35, 156, 117, 58, 140, 221, 180, 72, 123, 147, 95, 228, 97, 71, 204, 39, 149, 2, 19, 173, 139, 146, 54, 96, 220, 79, 66, 57, 127, 243, 188, 165, 47, 235, 119, 7, 199, 30, 177, 63, 78, 105, 207, 153, 28, 132, 168, 84, 166, 171, 108, 21, 215, 164, 174, 121, 128, 91, 68, 20, 222, 81, 137, 13, 152]

pubkey(q,h):(18172777775303192159727657832771688633216215598877965158949208820296023901084764760222881725262986702478735713462424007788959106272018399708244805316198640706589775789778454299532286932532522325791791312289833643271330941006206604894333175027113622330874626579800679513666624938603337561309816936129926352661091319564303604867093095700819543458178063985869752612663625872468653351930763784372987474747809415652595112648835928004343413910248386752899307068129610089712815257479121368111201632430687614657790581254030567845143865728745079851692195657361359959987504557281840928862881924309178036648485188421874327022341, 392638098592460228418508462226385074690422702429214284385732305774317959159895775092251586043956914155602546821559652111400517952111932579557319610857122515237088379905875982863782386657213421074126519458271560586678974481499715849371311979995450766948182818105567819897007307737370051632369390705725712223883589110699340619034611462216676501782567065261228166297471411589579035544131060706331012337024260046692910523900152236991203944000276133732456285962825434272960749340504092014446362862600803570698206213069473248298100863523331832957430305801141935737006263947843411592717969844892834332104365594346376118846)
c=4605640253217003331334964510174592254013178259349707648547335080743845433538772185582533054930473399495034133342299169373655297635370654237814250924077096784419954824350471683280656146814012837777204413608581553756866045890045788846665715321962704221105416079118007959490372975054302058194463432668018727266982561600329852084442818715440190956213811944269576719501924787366260795121132011879061730892865163591549129768412164655406373350666250339077746317309673325358941772202710386313434421388779073207650619564862431076222163014501544922959835509589742031678624743915535537547452120771609556012990490607104696154771

先看第二部分关于msg的还原 一个很经典的格
第一部分则是已知置换的平方还原置换 参考https://dexterjie.github.io/2023/11/29/%E8%B5%9B%E9%A2%98%E5%A4%8D%E7%8E%B0/2023ISCTF/#baby-group

思路很惊艳 代码实现也很有难度 不愧只有2solves orz

P2 = [82, 237, 32, 83, 30, 200, 116, 114, 4, 147, 171, 152, 193, 19, 170, 136, 186, 8, 124, 159, 225, 6, 180, 125, 74, 14, 255, 60, 187, 132, 222, 121, 56, 79, 57, 229, 87, 27, 72, 197, 201, 191, 75, 38, 135, 177, 165, 149, 17, 172, 173, 59, 210, 108, 31, 142, 163, 227, 178, 226, 73, 256, 190, 12, 103, 238, 129, 157, 219, 131, 67, 28, 68, 236, 168, 209, 245, 93, 61, 122, 208, 137, 49, 94, 111, 18, 161, 106, 54, 175, 70, 16, 110, 5, 218, 81, 233, 45, 91, 188, 151, 104, 148, 184, 228, 248, 150, 176, 167, 35, 130, 242, 126, 156, 42, 169, 232, 102, 50, 214, 179, 205, 9, 235, 97, 84, 246, 36, 76, 240, 52, 144, 98, 86, 99, 21, 64, 217, 15, 202, 206, 55, 244, 65, 23, 53, 250, 78, 22, 215, 25, 66, 143, 107, 195, 80, 196, 254, 174, 33, 162, 252, 141, 153, 43, 185, 211, 220, 115, 127, 216, 251, 139, 95, 146, 48, 239, 241, 37, 199, 13, 160, 90, 223, 123, 181, 120, 164, 118, 112, 128, 192, 249, 39, 2, 207, 71, 182, 145, 62, 3, 92, 183, 194, 100, 24, 133, 10, 117, 234, 29, 11, 140, 166, 85, 224, 230, 134, 189, 63, 46, 58, 231, 247, 47, 154, 44, 77, 89, 101, 69, 40, 26, 243, 253, 41, 51, 105, 155, 138, 1, 212, 20, 203, 213, 198, 158, 88, 109, 34, 119, 221, 113, 96, 204, 7]
for i in range(len(P2)):		
    P2[i] -= 1

def find_Chain(P2):
	Chain = []
	for i in range(len(P2)):			
		head = i
		chain = [head]
		c = P2[head]
		for j in range(len(P2)):		
			chain.append(c)
			c = P2[c]
			if c == head:				
				if chain not in Chain:	
					lag = 1
					for k in range(len(Chain)):		
						for l in chain:				
							if l in Chain[k]:
								lag = 0
								break
					if lag == 1:
						if len(chain) == 2:			
							Chain.append(chain[:-1])
							break
						else:
							Chain.append(chain)
							break
	return Chain

Chain = find_Chain(P2)
print(Chain)
LEN = []
for line in Chain:
    LEN.append(len(line))

LEN = sorted(LEN)[::-1]
print(LEN)

这样可以找到其中所有的环
再根据单环唯一确定 分裂出的双环有len种可能 嵌套循环枚举即可

class P:
	def __init__(self, data):
		if type(data) is int:
			self.size = data
			self._list = [i+1 for i in range(self.size)]
			self._initialize()			
		elif type(data) is list:
			self._list = data
			self.size = len(self._list)

	def __mul__(self, other):
		return P(self._iterList(self.getList(),other.getList()))

	def __repr__(self):
		return str(self._list)

	def __len__(self):
		return len(self._list)

	def __pow__(self, other):
		tempList = self._list
		for _ in range(1,other):
			tempList = self._iterList(tempList, tempList)
		return P(tempList)

	def __str__(self):
		return str(self._list)

	def getList(self):
		return self._list

	def _initialize(self):
		for i in range(10):
			random.shuffle(self._list)

	def _iterList(self, List1,List2):
		new_list = []
		for elem in List1:
			new_list.append(List2[elem - 1])
		return new_list
q,h = (18172777775303192159727657832771688633216215598877965158949208820296023901084764760222881725262986702478735713462424007788959106272018399708244805316198640706589775789778454299532286932532522325791791312289833643271330941006206604894333175027113622330874626579800679513666624938603337561309816936129926352661091319564303604867093095700819543458178063985869752612663625872468653351930763784372987474747809415652595112648835928004343413910248386752899307068129610089712815257479121368111201632430687614657790581254030567845143865728745079851692195657361359959987504557281840928862881924309178036648485188421874327022341, 392638098592460228418508462226385074690422702429214284385732305774317959159895775092251586043956914155602546821559652111400517952111932579557319610857122515237088379905875982863782386657213421074126519458271560586678974481499715849371311979995450766948182818105567819897007307737370051632369390705725712223883589110699340619034611462216676501782567065261228166297471411589579035544131060706331012337024260046692910523900152236991203944000276133732456285962825434272960749340504092014446362862600803570698206213069473248298100863523331832957430305801141935737006263947843411592717969844892834332104365594346376118846)
c=4605640253217003331334964510174592254013178259349707648547335080743845433538772185582533054930473399495034133342299169373655297635370654237814250924077096784419954824350471683280656146814012837777204413608581553756866045890045788846665715321962704221105416079118007959490372975054302058194463432668018727266982561600329852084442818715440190956213811944269576719501924787366260795121132011879061730892865163591549129768412164655406373350666250339077746317309673325358941772202710386313434421388779073207650619564862431076222163014501544922959835509589742031678624743915535537547452120771609556012990490607104696154771

# M = Matrix(ZZ,2,2)
# M[0,0] = q
# M[0,1] = 0
# M[1,0] = h
# M[1,1] = 1
# Ge = M.LLL()
# for i in Ge:
#     g = int(abs(int(i[0])))
#     f = int(abs(int(i[-1])))
#     if f.bit_length()>=1000:
#         print(f'g= {g}\nf= {f}')
g= 80543133918404127488886301361326962793877182221425816412488158480855679387656522509067598512536004160200624450488501194899256437338964914229878803213278892167375927469338861409899138503409679804107844511855116009860285942703093653856978725198914922514759932610039646534971856735780113276875287001841258831367
f= 32114304664198200626949886557688567679378682689751764347873070091968817850723916157318846285817806084079915102989056457680818558130765168139779429885473027282918240513106424858891869095107110954431130817704525309921431164907347496920955065921260371828842317536589144089446549194267607829948059792467278739234

mul=[114, 189, 92, 56, 252, 161, 202, 250, 131, 9, 111, 226, 223, 24, 14, 6, 99, 208, 195, 216, 141, 116, 167, 34, 5, 129, 15, 158, 178, 197, 4, 187, 27, 200, 144, 76, 74, 154, 86, 249, 93, 112, 46, 104, 25, 248, 40, 225, 38, 98, 186, 169, 64, 118, 33, 88, 26, 106, 183, 43, 201, 198, 242, 135, 110, 218, 244, 120, 83, 212, 192, 185, 148, 142, 11, 45, 232, 107, 18, 170, 60, 130, 247, 67, 65, 211, 182, 213, 134, 254, 70, 191, 210, 176, 145, 217, 82, 229, 125, 193, 155, 41, 113, 103, 49, 231, 133, 75, 109, 238, 126, 245, 163, 233, 227, 181, 51, 12, 143, 234, 239, 59, 240, 209, 42, 205, 230, 253, 203, 219, 23, 136, 32, 87, 102, 94, 85, 62, 172, 236, 124, 100, 256, 196, 50, 101, 206, 150, 89, 29, 61, 69, 246, 237, 16, 37, 184, 90, 162, 22, 36, 10, 31, 52, 190, 17, 55, 115, 251, 77, 214, 122, 1, 255, 151, 157, 241, 224, 3, 44, 48, 175, 194, 138, 179, 159, 160, 53, 80, 73, 8, 35, 156, 117, 58, 140, 221, 180, 72, 123, 147, 95, 228, 97, 71, 204, 39, 149, 2, 19, 173, 139, 146, 54, 96, 220, 79, 66, 57, 127, 243, 188, 165, 47, 235, 119, 7, 199, 30, 177, 63, 78, 105, 207, 153, 28, 132, 168, 84, 166, 171, 108, 21, 215, 164, 174, 121, 128, 91, 68, 20, 222, 81, 137, 13, 152]
from primefac import *
from hashlib import *

m = ((c*f)%q)*modinv(f,g)%g
msg = m%g


P2 = [82, 237, 32, 83, 30, 200, 116, 114, 4, 147, 171, 152, 193, 19, 170, 136, 186, 8, 124, 159, 225, 6, 180, 125, 74, 14, 255, 60, 187, 132, 222, 121, 56, 79, 57, 229, 87, 27, 72, 197, 201, 191, 75, 38, 135, 177, 165, 149, 17, 172, 173, 59, 210, 108, 31, 142, 163, 227, 178, 226, 73, 256, 190, 12, 103, 238, 129, 157, 219, 131, 67, 28, 68, 236, 168, 209, 245, 93, 61, 122, 208, 137, 49, 94, 111, 18, 161, 106, 54, 175, 70, 16, 110, 5, 218, 81, 233, 45, 91, 188, 151, 104, 148, 184, 228, 248, 150, 176, 167, 35, 130, 242, 126, 156, 42, 169, 232, 102, 50, 214, 179, 205, 9, 235, 97, 84, 246, 36, 76, 240, 52, 144, 98, 86, 99, 21, 64, 217, 15, 202, 206, 55, 244, 65, 23, 53, 250, 78, 22, 215, 25, 66, 143, 107, 195, 80, 196, 254, 174, 33, 162, 252, 141, 153, 43, 185, 211, 220, 115, 127, 216, 251, 139, 95, 146, 48, 239, 241, 37, 199, 13, 160, 90, 223, 123, 181, 120, 164, 118, 112, 128, 192, 249, 39, 2, 207, 71, 182, 145, 62, 3, 92, 183, 194, 100, 24, 133, 10, 117, 234, 29, 11, 140, 166, 85, 224, 230, 134, 189, 63, 46, 58, 231, 247, 47, 154, 44, 77, 89, 101, 69, 40, 26, 243, 253, 41, 51, 105, 155, 138, 1, 212, 20, 203, 213, 198, 158, 88, 109, 34, 119, 221, 113, 96, 204, 7]
for i in range(len(P2)):		
    P2[i] -= 1

def find_Chain(P2):
	Chain = []
	for i in range(len(P2)):			
		head = i
		chain = [head]
		c = P2[head]
		for j in range(len(P2)):		
			chain.append(c)
			c = P2[c]
			if c == head:				
				if chain not in Chain:	
					lag = 1
					for k in range(len(Chain)):		
						for l in chain:				
							if l in Chain[k]:
								lag = 0
								break
					if lag == 1:
						if len(chain) == 2:			
							Chain.append(chain[:-1])
							break
						else:
							Chain.append(chain)
							break
	return Chain

Chain = find_Chain(P2)
print(Chain)
LEN = []
for line in Chain:
    LEN.append(len(line))

LEN = sorted(LEN)[::-1]
print(LEN)

chain64_1 = [0, 81, 136, 63, 11, 151, 65, 237, 104, 227, 76, 244, 212, 139, 201, 91, 15, 135, 20, 224, 46, 164, 42, 74, 167, 219, 62, 189, 111, 241, 211, 10, 170, 215, 223, 246, 157, 253, 95, 80, 207, 9, 146, 249, 33, 78, 60, 72, 67, 156, 195, 206, 132, 97, 44, 134, 98, 90, 69, 130, 51, 58, 177, 240]
chain64_2 = [1, 236, 50, 172, 138, 14, 169, 126, 245, 197, 181, 159, 32, 55, 141, 54, 30, 221, 57, 226, 43, 37, 26, 254, 203, 193, 38, 71, 27, 59, 225, 153, 106, 149, 214, 84, 110, 129, 239, 137, 216, 229, 100, 150, 24, 73, 235, 40, 200, 2, 31, 120, 178, 36, 86, 160, 161, 251, 220, 45, 176, 238, 154, 194]
chain29_1 = [4, 29, 131, 143, 64, 102, 147, 77, 92, 109, 34, 56, 162, 140, 205, 23, 124, 96, 232, 25, 13, 18, 123, 234, 252, 112, 125, 83, 93]
chain29_2 = [7, 113, 155, 79, 121, 204, 99, 187, 163, 152, 142, 243, 202, 182, 89, 174, 145, 52, 209, 233, 242, 19, 158, 173, 94, 217, 133, 85, 17]
chain20_1 = [3, 82, 48, 16, 185, 180, 12, 192, 248, 108, 166, 210, 28, 186, 119, 213, 165, 184, 122, 8]
chain20_2 = [5, 199, 61, 255, 6, 115, 168, 114, 41, 190, 127, 35, 228, 88, 53, 107, 175, 47, 148, 21]
chain9_1 = [39, 196, 70, 66, 128, 75, 208, 116, 231]
chain9_2 = [68, 218, 188, 117, 101, 103, 183, 222, 230]
chain4_1 = [22, 179, 198, 144]
chain4_2 = [49, 171, 250, 118]
chain3 = [87, 105, 247]
chain1 = [191]

dictionary = {}

def singlering(chain):
    new = [0]*len(chain)
    for i in range(len(chain)):
        new[i*2%len(chain)] = chain[i]
    for i in range(len(chain)):
        dictionary[new[i]] = new[(i+1)%len(chain)] # map

singlering(chain1)
singlering(chain3)

# 大循环嵌套
from tqdm import *
for i1 in trange(64):									
    ring_128 = [0 for i in range(128)]
    for j in range(128):
        if(j%2 == 0):
            ring_128[j] = chain64_1[j//2]
        else:
            ring_128[j] = chain64_2[(j//2+i1)%64]
    for j in range(128):
        dictionary[ring_128[j]] = ring_128[(j+1)%128]	
        
    for i2 in range(29):								
        ring_58 = [0 for i in range(58)]
        for j in range(58):
            if(j%2==0):
                ring_58[j] = chain29_1[j//2]
            else:
                ring_58[j] = chain29_2[(j//2+i2)%29]
        for j in range(58):
            dictionary[ring_58[j]] = ring_58[(j+1)%58]	

        for i3 in range(20):							
            ring_40 = [0 for i in range(40)]
            for j in range(40):
                if(j%2 == 0):
                    ring_40[j] = chain20_1[j//2]
                else:
                    ring_40[j] = chain20_2[(j//2+i3)%20]
            for j in range(40):
                dictionary[ring_40[j]] = ring_40[(j+1)%40]	
                
            for i4 in range(9):								
                ring_18 = [0 for i in range(18)]
                for j in range(18):
                    if(j%2 == 0):
                        ring_18[j] = chain9_1[j//2]
                    else:
                        ring_18[j] = chain9_2[(j//2 + i4)%9]
                for j in range(18):
                    dictionary[ring_18[j]] = ring_18[(j+1)%18]	
                    		
                for i5 in range(4):								
                    ring_8 = [0 for i in range(8)]
                    for j in range(8):
                        if(j%2 == 0):
                            ring_8[j] = chain4_1[j//2]
                        else:
                            ring_8[j] = chain4_2[(j//2+i5)%4]
                    for j in range(8):
                        dictionary[ring_8[j]] = ring_8[(j+1)%8]
                        
                    M = [dictionary[j]+1 for j in range(256)]
                    mask = P(M)
                    mul = P(mul)
                    _hash = sha512(str(mask).encode()).hexdigest()
                    mask_hash = "91881f508f08fbafec1a6879fc3a1f215135c94c78f03fae8534d54dc05bd4a122a4e4508d32b9e02be08fbbb42a9e3335fc433c20e2da2e012d11b7324f6952"
                    if _hash == mask_hash:
                        print(f"P= {mask}")
                        temp = sha512(str(mask * mul).encode()).hexdigest()
                        from libnum import *
                        flag = msg ^ int(temp,16)
                        print(n2s(int(flag)))

Misc

Beyond Hex_Meet Heptadecimal

我:给我来个自创的古典密码编码类型的题目 chatGPT:明白了,你想要一个编码题目,但它应该有一些非传统的编码方式。让我给你设计一个类似的题目。 你获得了一段看起来像是十六进制的字符串,但解码后得到的内容并不是预期的文本。你需要深入挖掘,并发现隐藏在其背后的秘密!

ID71QI6UV7NRV5ULVJDJ1PTVJDVINVBQUNT

发现最大的是V 对应0~9+A~V 刚好是32
猜测是32进制 一共35个字符
字符对应的是128=2**7 ~ 2**5
也就是7->5的关系

s2b = ""
for c in s:
    if(ord(c)>=ord('0') and ord(c)<=ord('9')):
        s2b += bin(ord(c)-ord('0'))[2:].zfill(5)
    else:
        s2b += bin(ord(c)-ord('A')+10)[2:].zfill(5)

print(s2b,len(s2b))
flag = ""
for i in range(len(s2b)//7):
    c = s2b[i*7:i*7+7]
    flag += chr(int(c,2))
    print(flag)

ISCTF{so_ez_flag_for_uuu}

xxx,snowing desu

先字典爆破解开zip
blueSHARK666

得到一个tip和flag(fake)
tip里是一大串base64 一直解 解到不能再解为止
然后上字频统计
image
得到 ISCTFZ023
结合题目猜测tip里是snow隐写 密码就是 ISCTFZ023

./SNOW.EXE -C -p "ISCTFZ023" flag.txt dec.txt
ISCTF{34da-a87s-sk87-s384-3982-398233}

splashes

base64解开得到一大堆点的坐标 用pyplot画散点图

data = [1,2.75,1,1,2.5,1,1,2.25,1,1,1.75,1,1,2,1,1,3,1,1.5,3,1,2,3,1,2,2.75,1,2,2.5,1,2,2.25,1,2,2,1,2,1.75,1,2,1.5,1,1,2.25,1,1.5,2.25,1,1,1.5,1,1.5,1.5,1,
4,2.75,1,4,2.5,1,3,3,1,3.5,3,1,4,3,1,3.5,2.25,1,4,2.25,1,4,2,1,4,1.75,1,4,1.5,1,3,1.5,1,3.5,1.5,1,3,2.25,1,3,2.5,1,3,2.75,1,
5,3,1,5.5,3,1,6,3,1,6,2.25,1,6,2,1,6,1.75,1,6,1.5,1,5.5,1.5,1,5,1.5,1,5,2.25,1,5.5,2.25,1,5,2.5,1,5,2.75,1,
7,3,1,7.5,3,1,8,3,1,8,2.5,1,8,2,1,8,1.5,1,8,2.75,1,8,2.25,1,8,1.75,1,
9,3,1,9.5,3,1,10,3,1,10,2.75,1,10,2.5,1,10,2.25,1,9.5,2.25,1,9,2.25,1,9,1.5,1,9.5,1.5,1,10,1.5,1,10,2,1,10,1.75,1,
11.5,3,1,12,3,1,11,3,1,12,2.25,1,12,2,1,12,1.75,1,12,1.5,1,11.5,1.5,1,11,1.5,1,11,1.75,1,11,2,1,11,2.25,1,11,2.5,1,11,2.75,1,11.5,2.25,1]

import matplotlib.pyplot as plt
x = data[::3]
y = data[1::3]

plt.scatter(x,y)
plt.title("plot")
plt.xlabel("X")
plt.ylabel("Y")
plt.show()

得到压缩包密码
image

解开一个二维码扫一下得到flag

posted @ 2024-02-15 20:33  N0zoM1z0  阅读(215)  评论(0编辑  收藏  举报