当前位置:网站首页>[2022强网杯] polydiv和gamemaster
[2022强网杯] polydiv和gamemaster
2022-08-03 22:51:00 【石氏是时试】
目录
polydiv
题目先需要先爆破一个4字节的sha256再求40次 模二多项式,成功以后就直接给flag
import socketserver
import os, sys, signal
import string, random
from hashlib import sha256
from secret import flag
from poly2 import *
pad = lambda s:s + bytes([(len(s)-1)%16+1]*((len(s)-1)%16+1))
testCases = 40
class Task(socketserver.BaseRequestHandler):
def _recvall(self):
BUFF_SIZE = 2048
data = b''
while True:
part = self.request.recv(BUFF_SIZE)
data += part
if len(part) < BUFF_SIZE:
break
return data.strip()
def send(self, msg, newline=True):
try:
if newline:
msg += b'\n'
self.request.sendall(msg)
except:
pass
def recv(self, prompt=b'> '):
self.send(prompt, newline=False)
return self._recvall()
def close(self):
self.send(b"Bye~")
self.request.close()
def proof_of_work(self):
random.seed(os.urandom(8))
proof = ''.join([random.choice(string.ascii_letters+string.digits) for _ in range(20)])
_hexdigest = sha256(proof.encode()).hexdigest()
self.send(f"sha256(XXXX+{proof[4:]}) == {_hexdigest}".encode())
x = self.recv(prompt=b'Give me XXXX: ')
if len(x) != 4 or sha256(x+proof[4:].encode()).hexdigest() != _hexdigest:
return False
return True
def guess(self):
from Crypto.Util.number import getPrime
a,b,c = [getPrime(i) for i in [256,256,128]]
pa,pb,pc = [PP(bin(i)[2:]) for i in [a,b,c]]
r = pa*pb+pc
self.send(b'r(x) = '+str(r).encode())
self.send(b'a(x) = '+str(pa).encode())
self.send(b'c(x) = '+str(pc).encode())
self.send(b'Please give me the b(x) which satisfy a(x)*b(x)+c(x)=r(x)')
#self.send(b'b(x) = '+str(pb).encode())
return self.recv(prompt=b'> b(x) = ').decode() == str(pb)
def handle(self):
#signal.alarm(1200)
if not self.proof_of_work():
return
for turn in range(testCases):
if not self.guess():
self.send(b"What a pity, work harder.")
return
self.send(b"Success!")
else:
self.send(b'Congratulations, this is you reward.')
self.send(flag)
class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
#class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer):
class ForkedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
if __name__ == "__main__":
HOST, PORT = '0.0.0.0', 10000
server = ForkedServer((HOST, PORT), Task)
server.allow_reuse_address = True
server.serve_forever()
运算式子很简单,已知r,a,c求b,其实有个除法就行了
r = pa*pb+pc题目给定了一个 模二多项式环的运算 的类(有删减),里边用到除的部分被删掉了,从网上找原版,发现原版被删了,只有搜索引擎的缓存,但python程序在缓存时压缩了空格并删掉了回车换行这样的程序基本无法读。并且把 [0] 也丢掉。拿到程序根据意思理解也很难,然后用搜狗搜了一下发现一个正常版的。搜狗平常啥都搜不到,但偶尔还会有点用。
def div(self,other):
r,b = self.param[::-1],other.param[::-1]
if len(r) < len(b):
return Polynomial2(),self
q= [0]*(len(r) - len(b) + 1)
for i in range(len(q)):
if len(r)>=len(b):
index = len(r) - len(b) + 1 # 确定所得商是商式的第index位
q[-index] = int(r[0] / b[0]) # 更新被除多项式
b_=b.copy()
b_.extend([0]*(len(r) - len(b)))
b_ = [t*q[i] for t in b_]
r = [(r[t] - b_[t])%2 for t in range(len(r))]
for j in range(len(r)): #除去列表最左端无意义的0
if r[0]==0:
r.remove(0)
else:
break
else:
break
return Polynomial2(q),Polynomial2(r)
同时由于给出的数据是多项式,需要改为可处理的方式(第三种)
def p3(s):
return eval( b'['+s.replace(b'+', b',').replace(b', 1', b', 0').replace(b'x^', b'').replace(b'x', b'1')+ b']' )
然后就可以连后台了
from pwn import *
import string
from hashlib import sha256
from poly2 import *
def get_proof(last, shav):
s = string.ascii_letters+string.digits
for v1 in s:
for v2 in s:
for v3 in s:
for v4 in s:
t = (v1+v2+v3+v4).encode() + last
#print(t, sha256(t).hexdigest(), shav)
#return
if sha256(t).hexdigest() == shav:
return (v1+v2+v3+v4).encode()
context.log_level = 'debug'
p = remote('59.110.212.61', 26882)
#爆破sha256
p.recvuntil(b'sha256(XXXX+')
last = p.recvuntil(b') == ', drop=True)
shav = p.recvline()[:-1]
print('last:', last)
print('sha256:', shav)
found = get_proof(last, shav.decode())
p.sendlineafter(b'Give me XXXX: ', found)
#计算guess
for i in range(40):
p.recvuntil(b'(x) = ')
pr = Poly(p3(p.recvline()[:-1]))
p.recvuntil(b'(x) = ')
pa = Poly(p3(p.recvline()[:-1]))
p.recvuntil(b'(x) = ')
pc = Poly(p3(p.recvline()[:-1]))
pb = (pr - pc).div(pa)
p.sendlineafter(b'> b(x) = ', str(pb[0]))
p.recvuntil(b'Success!\n')
p.recv()
p.recv()
p.recv()
p.recv()
pause()
re_gamemaster
这是个逆向题,结了一个.net写和游戏和一个gamemessage文件
用dnSpy打开找到以下几段
1,BlackjackConsole Program.Main() 里将gamemessage读入memory变量
FileStream fileStream = File.OpenRead("gamemessage");
int num = (int)fileStream.Length;
Program.memory = new byte[num];
fileStream.Position = 0L;
fileStream.Read(Program.memory, 0, num);
2,BlackjackConsole Game.goldFunc 567 将memory的内容按字节与34异或
for (int i = 0; i < Program.memory.Length; i++)
{
byte[] array = Program.memory;
int num = i;
array[num] ^= 34;
}
3,BlackjackConsole Game.goldFunc() 538 将memory 用AES,ECB 解密生成ExploitClass.dll
byte[] key = new byte[]
{
66,
114,
97,
105,
110,
115,
116,
111,
114,
109,
105,
110,
103,
33,
33,
33
};
ICryptoTransform cryptoTransform = new RijndaelManaged
{
Key = key,
Mode = CipherMode.ECB,
Padding = PaddingMode.Zeros
}.CreateDecryptor();
Program.m = cryptoTransform.TransformFinalBlock(Program.memory, 0, Program.memory.Length);
这样就可以恢复这个动态库了
data = open('gamemessage', 'rb').read()
data = bytes([v^0x22 for v in data])
from Crypto.Cipher import AES
key = bytes([0x42, 0x72, 0x61, 0x69, 110, 0x73, 0x74, 0x6f, 0x72, 0x6d, 0x69, 110, 0x67, 0x21, 0x21, 0x21])
aes = AES.new(key,AES.MODE_ECB)
m = aes.decrypt(data)
pos = 0x13eb
m = m[pos:]+m[:pos]
open('temp.dll', 'wb').write(m)
然后用dnSpy再打开这个动态库就可以找到加密部分了
主要函数是check1 在程序中会对3个数字赋值(当然不知道是多少了),然后进行检查,查检通过后把这3个数作成12字节的key与密文异或就是flag
check1把这3个数向左移位并填充尾位(用其它位运算得到)共320次循环,最终这320个1位结果作成40个字节去校验。
private static void Check1(ulong x, ulong y, ulong z, byte[] KeyStream)
{
int num = -1;
for (int i = 0; i < 320; i++)
{
x = (((x >> 29 ^ x >> 28 ^ x >> 25 ^ x >> 23) & 1UL) | x << 1);
y = (((y >> 30 ^ y >> 27) & 1UL) | y << 1);
z = (((z >> 31 ^ z >> 30 ^ z >> 29 ^ z >> 28 ^ z >> 26 ^ z >> 24) & 1UL) | z << 1);
bool flag = i % 8 == 0;
if (flag)
{
num++;
}
KeyStream[num] = (byte)((long)((long)KeyStream[num] << 1) | (long)((ulong)((uint)((z >> 32 & 1UL & (x >> 30 & 1UL)) ^ (((z >> 32 & 1UL) ^ 1UL) & (y >> 31 & 1UL))))));
}
}
解法想来想去最后想到z3,1000多个变量,不过运算比较快1分钟之内就解决。
from z3 import *
first = [101,5,80,213,163,26,59,38,19,6,173,189,198,166,140,183,42,247,223,24,106,20,145,37,24,7,22,191,110,179,227,5,62,9,13,17,65,22,37,5]
array5 = [60,100,36,86,51,251,167,108,116,245,207,223,40,103,34,62,22,251,227]
sec = [0]*320
for i in range(40):
for j in range(8):
sec[i*8+j] = (first[i] >>(7-j))&1
x = [BitVec(f'x{i}',1) for i in range(360+30)]
y = [BitVec(f'y{i}',1) for i in range(360+31)]
z = [BitVec(f'z{i}',1) for i in range(320+32)]
s = Solver()
s.add([x[0]==0,x[1]==0,y[0]==0])
for i in range(320):
x[i+32] = x[i+2]^x[i+3]^x[i+6]^x[i+8]
y[i+32] = y[i+1]^y[i+4]
z[i+32] = z[i]^z[i+1]^z[i+2]^z[i+3]^z[i+5]^z[i+7]
s.add(sec[i] == (z[i]&x[i+2])^((z[i]^1)&y[i+1]))
if s.check() == sat:
d = s.model()
print('x=', end='')
for i in range(32):
print(str(d[x[i]]), end='')
print('\ny=', end='')
for i in range(32):
print(str(d[y[i]]), end='')
print('\nz=', end='')
for i in range(32):
print(str(d[z[i]]), end='')
#x=00001001010100010101010001100101
#y=00110011110000101000100101110011
#z=10111010101000101100011000110011
#156324965,868387187,3131229747
最后通过这3个数字得到flag
n1 = 156324965
n2 = 868387187
n3 = 3131229747
from pwn import p32
key = (p32(n1)+p32(n2)+p32(n3))*2
array5 = [60,100,36,86,51,251,167,108,116,245,207,223,40,103,34,62,22,251,227]
for i,v in enumerate(array5):
print(chr(v^key[i]), end='')
#[email protected]_G3meM3s7er!边栏推荐
- Research status of target detection at home and abroad
- Codeup brushing notes - simple simulation
- 云平台建设解决方案
- win10系统下yolov5-V6.1版本的tensorrt部署细节教程及bug修改
- utlis 线程池
- 完全二叉树问题
- 如何基于WPF写一款数据库文档管理工具(二)
- Websocket multi-threaded sending message error TEXT_PARTIAL_WRITING--Use case of spin lock replacing synchronized exclusive lock
- RPA助力商超订单自动化!
- Binary search tree to solve the fallen leaves problem
猜你喜欢

3D 语义分割——2DPASS

Bytebase database schema change management tool

The principle and use of AOSP CameraLatencyHistogram

Adobe是什么?

What is the difference between the generator version and the viewer version?

Zilliz 2023 秋季校园招聘正式启动!

for loop exercises

FinClip最易用的智能电视小程序

封装、包、访问权限修饰符、static变量

Pytest学习-setup/teardown
随机推荐
网络基础学习系列四(网络层,数据链路层和一些其他重要协议或技术)
.NET6之MiniAPI(十四):跨域CORS(上)
2022/8/3 考试总结
Storage engine written by golang, based on b+ tree, mmap
藏宝计划TreasureProject(TPC)系统模式开发技术原理
完全二叉树问题
Codeup brushing notes - simple simulation
【论文阅读】TRO 2021: Fail-Safe Motion Planning for Online Verification of Autonomous Vehicles Using Conve
override学习(父类和子类)
OPC UA 与IEC61499 深度融合(1)
创建函数报错,提示DECLARE定义语法问题
直播预告 | 构建业务智联,快速拥抱财务数字化转型
云计算国内外发展现状
PowerMockup 4.3.4::::Crack
Adobe是什么?
物联网新零售模式,引领购物新潮流
complete binary tree problem
HDU 5655 CA Loves Stick
为什么我们需要回调
软件测试内卷严重,如何提升自己的竞争力呢?