网络流量

SQL注入流量分析

可以使用 wireshark 的过滤器过滤出注入的流量,然后导出特定分组

然后使用 tshark 根据字段名提取出所有的注入语句

如果是盲注的话,直接写个正则匹配脚本提取数据即可

Tips:如果返回的响应数据是gzip格式,要注意提取的位置,gzip的文件头是1F 8B 08 00

webshell流量分析

菜刀流量分析

菜刀流量的一个明显的特征就是,响应里可能有 ->| |<- 这样的字符串

哥斯拉流量分析

哥斯拉的默认密钥为:3c6e0b8a9c15224a

哥斯拉流量一般的加密方式就是异或,当然在插件的加持下可能也会用到AES

我们以下面这个编码器为例子,这里要注意异或的时候,是从密钥的第二位开始异或

因此当我们使用CyberChef解密的时候,需要把密钥的第一位移到最后

function encode($D,$K){
    for($i=0;$i<strlen($D);$i++) {
        $c = $K[$i+1&15];
        $D[$i] = $D[$i]^$c;
    }
    return $D;
}

冰蝎流量分析

冰蝎的默认密钥为:e45e329feb5d925b(md5(rebeyond)的前16位)

!!当找不到密钥或者密钥未知的时候可以尝试直接用默认密钥解密试一下!!

CobalStrike流量分析

密钥对文件的情况

先从流量包中导出key文件

我们需要先获取 .cobaltstrike.beacon_keys 文件中的私钥。这个私钥是 RSA 私钥,用于解密元数据。

import base64
import javaobj.v2 as javaobj

with open(".cobaltstrike.beacon_keys", "rb") as fd:
    pobj = javaobj.load(fd)

def format_key(key_data, key_type):
    key_data = bytes(map(lambda x: x & 0xFF, key_data))
    formatted_key = f"-----BEGIN {key_type} KEY-----\n"
    formatted_key += base64.encodebytes(key_data).decode()
    formatted_key += f"-----END {key_type} KEY-----"
    return formatted_key

privateKey = format_key(pobj.array.value.privateKey.encoded.data, "PRIVATE")
publicKey = format_key(pobj.array.value.publicKey.encoded.data, "PUBLIC")

print(privateKey)
print(publicKey)

在数据包的HTTP请求中获得Cookie

然后我们在通过私钥解密元数据、获取 AES KEY,其中 encode_data 为元数据,也就是前面提到的 cookie 的值

import hashlib
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64
import hexdump
PRIVATE_KEY = """-----BEGIN PRIVATE KEY-----
{}
-----END PRIVATE KEY-----"""

encode_data = ""

private_key = RSA.import_key(PRIVATE_KEY.encode())

cipher = PKCS1_v1_5.new(private_key)
ciphertext = cipher.decrypt(base64.b64decode(encode_data), 0)

if ciphertext[0:4] == b'\x00\x00\xBE\xEF':
    raw_aes_keys = ciphertext[8:24]
    raw_aes_hash256 = hashlib.sha256(raw_aes_keys).digest()
    aes_key = raw_aes_hash256[0:16]
    hmac_key = raw_aes_hash256[16:]

    print("AES key: {}".format(aes_key.hex()))
    print("HMAC key: {}".format(hmac_key.hex()))

    hexdump.hexdump(ciphertext)

脚本合成版

import base64
import javaobj.v2 as javaobj
import hashlib
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import hexdump
import hmac
import binascii
from Crypto.Cipher import AES


def format_key(key_data, key_type):
    key_data = bytes(map(lambda x: x & 0xFF, key_data))
    formatted_key = f"-----BEGIN {key_type} KEY-----\n"
    formatted_key += base64.encodebytes(key_data).decode()
    formatted_key += f"-----END {key_type} KEY-----"
    return formatted_key

def extract_key(keyfile):
    with open(keyfile, "rb") as fd:
        pobj = javaobj.load(fd)

    privateKey = format_key(pobj.array.value.privateKey.encoded.data, "PRIVATE")
    publicKey = format_key(pobj.array.value.publicKey.encoded.data, "PUBLIC")
    return privateKey,publicKey
    
def get_AES_HMAC_key(PRIVATE_KEY,encode_data):
    '''
    提取协商密钥
    '''
    private_key = RSA.import_key(PRIVATE_KEY.encode())
    cipher = PKCS1_v1_5.new(private_key)
    ciphertext = cipher.decrypt(base64.b64decode(encode_data), 0)

    if ciphertext[0:4] == b'\x00\x00\xBE\xEF':
        raw_aes_keys = ciphertext[8:24]
        raw_aes_hash256 = hashlib.sha256(raw_aes_keys).digest()
        aes_key = raw_aes_hash256[0:16]
        hmac_key = raw_aes_hash256[16:]

        print("AES key: {}".format(aes_key.hex()))
        print("HMAC key: {}".format(hmac_key.hex()))
        hexdump.hexdump(ciphertext)
        
        return aes_key.hex(),hmac_key.hex()
    
def decrypt_submit_data(SHARED_KEY,HMAC_KEY,encrypt_data):
    '''
    使用协商密钥解密CS的数据
    '''
    SHARED_KEY = binascii.unhexlify(SHARED_KEY)
    HMAC_KEY = binascii.unhexlify(HMAC_KEY)
    def decrypt(encrypted_data, iv_bytes, signature, shared_key, hmac_key):
        if hmac.new(hmac_key, encrypted_data, digestmod="sha256").digest()[:16] != signature:
            print("message authentication failed")
            return

        cipher = AES.new(shared_key, AES.MODE_CBC, iv_bytes)
        return cipher.decrypt(encrypted_data)

    encrypt_data = base64.b64decode(encrypt_data)
    encrypt_data_length = int.from_bytes(encrypt_data[:4], byteorder='big', signed=False)
    encrypt_data_l = encrypt_data[4:]

    data1 = encrypt_data_l[:encrypt_data_length-16]
    signature = encrypt_data_l[encrypt_data_length-16:encrypt_data_length]
    iv_bytes = b"abcdefghijklmnop"

    dec = decrypt(data1, iv_bytes, signature, SHARED_KEY, HMAC_KEY)
    print("="*80)
    print("counter: {}".format(int.from_bytes(dec[:4], byteorder='big', signed=False)))
    print("任务返回长度: {}".format(int.from_bytes(dec[4:8], byteorder='big', signed=False)))
    print("任务输出类型: {}".format(int.from_bytes(dec[8:12], byteorder='big', signed=False)))
    print(dec[12:int.from_bytes(dec[4:8], byteorder='big', signed=False)])
    print(hexdump.hexdump(dec))


if __name__ == "__main__":
    keyfile = "key" # 题目一般会提供,该文件本质上为 KeyPair 的 Java 对象
    privateKey,publicKey = extract_key(keyfile)
    # print(privateKey)
    # 协商密钥和主机信息被使用 rsa 公钥加密之后放在了心跳包的 cookie 中
    cookie_data = "U8jm3+oqzYLuUiRd9F3s7xVz7fGnHQYIKF9ch6GRseWfcBSSk+aGhWP3ZUyHIkwRo1/oDCcKV7LYAp022rCm9bC7niOgMlsvgLRolMKIz+Eq5hCyQ0QVScH8jDYsJsCyVw1iaTf5a7gHixIDrSbTp/GiPQIwcTNZBXIJrll540s="
    SHARED_KEY,HMAC_KEY = get_AES_HMAC_key(privateKey,cookie_data)
    submit_data = ["000000e046950d669f91c7c7d9a7580c78f13a9f568122f2a8aba597a52f3832b0afbde054602fe158dbe173ff2532036facafdada898e3c9d798ea5e803269221fef2436fc22428e4d4aac53979ce80dd4809a2d3391dfdb1ea043e9761250175b0ceb38157319e366af76a88464f7d8672e614a051ca4fa846d6e22ee654ce0271381867f13c44ee15a26fc03316596f64bb0786e16af8a8fd900f7d0c7fa895c408e3915fa6a9a5085df6854c34dbf55d968d7f69b00b12083750c30564f94547f6eb6ee62beacda5a73d72ea7d81c79919802aecafed6d991bd0b1b18e04fca5c480","00000040e992086d1e786eeb9b4329bf6eee6f593e44609505d7d0118af590b5e40840782232f30b12ed76f54ef4898d69470498cb4afe43841790fe12af184011858984","000000c093dff6b2f058ba4231e3900276566441f2bb4c76e5c8480874a4d99df083054a5ea1dd4aea5523c751af7d123ee8e9f2253a5ccdcf54427d147c556b15657ee2607e92b35732f26341bc0a26c58bf2bcf2383ad640641c364159387223360cc16ff3dc14ab1f00e6ee4fb53f5e15b767bd379451d0d7b6f4aeae9db0c3f30f3ef167b7db3e6ac241643ed2513e73f9e9148ebe7afaa122ea75e945c8ab8a816179e43180257bd8be752827dd0de26826d5611ee09391ee5545897dae1d3a9698","000000e0453bf91036fff19e04ce60d065f37f4ed23345246fa7b5ce91d64de96781604717aa720a0f411cf5545d66c750ff0ee7aaa7f4be7e7070ba1ff180f6373d670c7b0e8c73617ec9e3f388a4f99a3d00aca4e85e80db6a8e1a661da37b184b2d779d2d5f6e594ca4c81b3c2fe16856b24d2d6551fed5f79540fcc4ca1ce66168d32f656ea5b7f66d26ae99812a6612da54670acc82524160fc765c1c8cc89cdf110fe4a40a195aa693bd98965abc3244f5c4bd89c104dafcd5e87542dfd90751cf8ea82a769070b01d9af4b037e1ba618de23a378d83104375cc9745893ddc5482"]
    for item in submit_data:
        encrypt_data = base64.b64encode(bytes.fromhex(item))
        decrypt_submit_data(SHARED_KEY,HMAC_KEY,encrypt_data)

USB流量

常见的类型有鼠标流量和键盘流量,当然有时候还会出现数位板这种设备的流量

流量包中数据存储的字段有两种:usb.capdatausbhid.data

键盘流量分析

键盘流量的数据常见的长度为8字节

首先根据数据存储的字段,用tshark提取出数据,注意在有多个IP的情况下要用过滤器分IP提取

tshark -r example.pcapng -T fields -e usb.capdata | sed '/^\s*$/d' > data.txt
tshark -r example.pcapng -T fields -e usbhid.data | sed '/^\s*$/d' > data.txt

tshark -r example.pcapng -Y 'usb.src == "2.3.1"' -T fields -e usbhid.data | sed '/^\s*$/d' > data.txt
# -r:指定了需要读取的文件
# -Y:使用过滤器
# -T:表示仅仅输出所选字段
# -e:指定提取的字段
# sed '/^\s*$/d':在sed中使用正则表达式过滤掉所有空行(其中 ^\s*$ 匹配空行,d 表示删除)

然后使用脚本根据对照表还原出键盘输入的数据即可

然后有时候还会出现这样一种考点就是:出题人会把关键信息藏在被<DEL>的字符中

因此我们需要把被删除的字符也还原出来

鼠标流量分析

键盘流量的数据常见的长度为4字节、6字节、7字节、8字节

和键盘流量的过程一样,第一步都是先用tshark提取出数据

tshark -r example.pcapng -T fields -e usb.capdata | sed '/^\s*$/d' > data.txt
tshark -r example.pcapng -T fields -e usbhid.data | sed '/^\s*$/d' > data.txt

tshark -r example.pcapng -Y 'usb.src == "2.3.1"' -T fields -e usbhid.data | sed '/^\s*$/d' > data.txt
# -r:指定了需要读取的文件
# -Y:使用过滤器
# -T:表示仅仅输出所选字段
# -e:指定提取的字段
# sed '/^\s*$/d':在sed中使用正则表达式过滤掉所有空行(其中 ^\s*$ 匹配空行,d 表示删除)

数位板流量分析

# 先导出数据并去除空行
tshark -r hard_Digital_plate.pcapng -T fields -e usb.capdata | sed '/^\s*$/d' > out.txt
# -r 指定了需要读取的文件
# -T 表示仅仅输出所选字段
# -e 指定提取的字段
# 在sed中使用正则表达式过滤掉所有空行(其中 ^\s*$ 匹配空行,`d` 表示删除)

xbox手柄流量分析

蓝牙等各种无线流量

蓝牙流量

OBEX协议

过滤器中输入OBEX,然后导出传输的压缩包,然后再在搜索中输入PIN Code选择分组列表和字符串即可找到解压密码

ATT协议

工控流量