Joyber 发布的文章

Jenkins 未授权文件读取漏洞(CVE-2024-23897)

这个漏洞使得攻击者只需要知道jenkins公开的服务地址即可轻易的拿到该服务器上任意文件内容,至少第1行的内容,危险程度可想而知了。。。更诡异的是,出了这个问题,找了半天也没明白jenkins搞的这个cli接口怎么关闭

更多信息参考:https://www.leavesongs.com/PENETRATION/jenkins-cve-2024-23897.html

验证工具
https://www.github.com/wjlin0/CVE-2024-23897/cmd/CVE-2024-23897

处理方法:
jenkins 升级到最新版本
影响版本:
Jenkins <= 2.441
Jenkins LTS <= 2.426.2

如果不需要cli功能可以直接禁止请求,如通过nginx反代的话可以在反代前面增加配置:

server{

...

    #禁止client-cli请求
    location /cli {
      return 403;
    }

...

}

#! /bin/bash

BAK_NAME="jenkins_2.440.1"

mkdir ${BAK_NAME}
cd ${BAK_NAME}
cp /var/lib/jenkins/*.xml ./

mkdir jobs
cd jobs
find /var/lib/jenkins/jobs/ -maxdepth 2 -type f -name "*.xml" | xargs -l dirname | xargs -l basename | xargs mkdir

for d in $(ls); 
do
     cp /var/lib/jenkins/jobs/${d}/config.xml ./${d};
done

下载更新包war文件后,用系统命令无法启动jenkins:

systemctl start jenkins

使用2.361.4的包时,升级java到17版本发现可以启动了,但是查看状态仍然是不正常的

systemctl status jenkins

● jenkins.service - LSB: Jenkins Automation Server
   Loaded: loaded (/etc/rc.d/init.d/jenkins; bad; vendor preset: disabled)
   Active: failed (Result: exit-code) since Mon 2024-03-11 16:43:59 CST; 5s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 15191 ExecStart=/etc/rc.d/init.d/jenkins start (code=exited, status=1/FAILURE)

Mar 11 16:43:59 search-server jenkins[15191]: at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorI...ava:77)
Mar 11 16:43:59 search-server jenkins[15191]: at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodA...ava:43)
Mar 11 16:43:59 search-server jenkins[15191]: at java.base/java.lang.reflect.Method.invoke(Method.java:568)
Mar 11 16:43:59 search-server jenkins[15191]: at executable.Main.main(Main.java:351)
Mar 11 16:43:59 search-server runuser[15196]: pam_unix(runuser:session): session closed for user jenkins
Mar 11 16:43:59 search-server jenkins[15191]: [FAILED]
Mar 11 16:43:59 search-server systemd[1]: jenkins.service: control process exited, code=exited status=1
Mar 11 16:43:59 search-server systemd[1]: Failed to start LSB: Jenkins Automation Server.
Mar 11 16:43:59 search-server systemd[1]: Unit jenkins.service entered failed state.
Mar 11 16:43:59 search-server systemd[1]: jenkins.service failed.

由于报出了任意文件查看漏洞 CVE-2024-23897 ,我的目标不是2.361.4这个版本更新,而是想更新到最新版本,目前是2.440.1。

查看到原来的jekins的启动命令是这样的:

ps aux| grep jenkins 

root     13470  0.0  0.0 144420  1556 ?        S    16:25   0:00 runuser -s /bin/bash jenkins -c ulimit -S -c 0 >/dev/null 2>&1 ; /usr/lib/jvm/jdk-17-oracle-x64/bin/java -Djava.awt.headless=true -DJENKINS_HOME=/var/lib/jenkins -jar /usr/lib/jenkins/jenkins.war --logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --daemon --httpPort=8080 --debug=5 --handlerCountMax=100 --handlerCountMaxIdle=20
jenkins  13471  0.0  0.0 113284  1200 ?        Ss   16:25   0:00 bash -c ulimit -S -c 0 >/dev/null 2>&1 ; /usr/lib/jvm/jdk-17-oracle-x64/bin/java -Djava.awt.headless=true -DJENKINS_HOME=/var/lib/jenkins -jar /usr/lib/jenkins/jenkins.war --logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --daemon --httpPort=8080 --debug=5 --handlerCountMax=100 --handlerCountMaxIdle=20
jenkins  13472  7.1 25.0 4913372 2003084 ?     Sl   16:25   1:16 /usr/lib/jvm/jdk-17-oracle-x64/bin/java -Djava.awt.headless=true -DJENKINS_HOME=/var/lib/jenkins -jar /usr/lib/jenkins/jenkins.war --logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --daemon --httpPort=8080 --debug=5 --handlerCountMax=100 --handlerCountMaxIdle=20

升级java版本到21版本最新版本后,那么现在直接执行这个命令发现根本执行不了:

/usr/lib/jvm/jdk-17-oracle-x64/bin/java -Djava.awt.headless=true -DJENKINS_HOME=/var/lib/jenkins -jar /usr/lib/jenkins/jenkins.war --logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --daemon --httpPort=8080 --debug=5 --handlerCountMax=100 --handlerCountMaxIdle=20

报错是不支持这个参数'--daemon',把这个参数去掉又报不支持的参数 ‘--handlerCountMax’, ‘--handlerCountMaxIdle’,那把这几个参数都去掉了,jenkins可以启动了,web端界面也能打开了,看似正常了。

Running from: /usr/lib/jenkins/jenkins.war
Exception in thread "main" java.lang.IllegalArgumentException: Unrecognized option: --daemon
    at winstone.cmdline.CmdLineParser.parse(CmdLineParser.java:53)
    at winstone.Launcher.getArgsFromCommandLine(Launcher.java:506)
    at winstone.Launcher.main(Launcher.java:468)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at executable.Main.main(Main.java:351)

那么现在需要修改 /etc/rc.d/init.d/jenkins 配置文件,修改jenkins的启动命令,把这些启动参数都去掉试试,修改后的内容参考:


JAVA_CMD="$JENKINS_JAVA_CMD $JENKINS_JAVA_OPTIONS -DJENKINS_HOME=$JENKINS_HOME -jar $JENKINS_WAR"
#PARAMS="--logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --daemon"
PARAMS="--logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war "
[ -n "$JENKINS_PORT" ] && PARAMS="$PARAMS --httpPort=$JENKINS_PORT"
[ -n "$JENKINS_LISTEN_ADDRESS" ] && PARAMS="$PARAMS --httpListenAddress=$JENKINS_LISTEN_ADDRESS"
[ -n "$JENKINS_HTTPS_PORT" ] && PARAMS="$PARAMS --httpsPort=$JENKINS_HTTPS_PORT"
[ -n "$JENKINS_HTTPS_KEYSTORE" ] && PARAMS="$PARAMS --httpsKeyStore=$JENKINS_HTTPS_KEYSTORE"
[ -n "$JENKINS_HTTPS_KEYSTORE_PASSWORD" ] && PARAMS="$PARAMS --httpsKeyStorePassword='$JENKINS_HTTPS_KEYSTORE_PASSWORD'"
[ -n "$JENKINS_HTTPS_LISTEN_ADDRESS" ] && PARAMS="$PARAMS --httpsListenAddress=$JENKINS_HTTPS_LISTEN_ADDRESS"
[ -n "$JENKINS_HTTP2_PORT" ] && PARAMS="$PARAMS --http2Port=$JENKINS_HTTP2_PORT"
[ -n "$JENKINS_HTTP2_LISTEN_ADDRESS" ] && PARAMS="$PARAMS --http2ListenAddress=$JENKINS_HTTP2_LISTEN_ADDRESS"
#[ -n "$JENKINS_DEBUG_LEVEL" ] && PARAMS="$PARAMS --debug=$JENKINS_DEBUG_LEVEL"
[ -n "$JENKINS_HANDLER_STARTUP" ] && PARAMS="$PARAMS --handlerCountStartup=$JENKINS_HANDLER_STARTUP"
#[ -n "$JENKINS_HANDLER_MAX" ] && PARAMS="$PARAMS --handlerCountMax=$JENKINS_HANDLER_MAX"
#[ -n "$JENKINS_HANDLER_IDLE" ] && PARAMS="$PARAMS --handlerCountMaxIdle=$JENKINS_HANDLER_IDLE"
[ -n "$JENKINS_EXTRA_LIB_FOLDER" ] && PARAMS="$PARAMS --extraLibFolder=$JENKINS_EXTRA_LIB_FOLDER"
[ -n "$JENKINS_ARGS" ] && PARAMS="$PARAMS $JENKINS_ARGS"

...



case "$1" in
    start)
        echo -n "Starting Jenkins "
        #daemon --user "$JENKINS_USER" --pidfile "$JENKINS_PID_FILE" "$JAVA_CMD" $PARAMS > /dev/null
        daemon --user "$JENKINS_USER" --pidfile "$JENKINS_PID_FILE" "$JAVA_CMD" $PARAMS > /dev/null &

...

netplan命令和/etc/netplan/*.yaml配置文件
在老版的Ubuntu中,是通过/etc/network/interfaces文件进行静态IP地址的配置,通过/etc/resolv.conf进行DNS设置。Netplan 网络配置从 Ubuntu 18.04 开始首次引入,在新版的Ubuntu中,通过/etc/netplan/目录下的yaml文件进行IP和DNS配置。打开该目录下的配置文件如下:

# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
  version: 2
  renderer: networkd
  ethernets:
    ens33:
     dhcp4: false
     addresses: 
        - 192.168.31.2/24
     gateway4: 192.168.31.1
     nameservers:
       addresses: 
        - 114.114.114.114

这是ubuntu服务器版本的配置方法,如果是桌面版,可以使用可视化的NetworkManager来接管网络,则该配置文件的renderer字段可设置为:NetworkManager,后面的部分都删除。当然,桌面版也可以按照上文示例设置,而不使用NetworkManager。
该配置文件的书写格式上有几点需要注意:

ethernets中的网卡名可以通过ip link指令查看,此处的ens33是本人虚拟机的网卡,替换为你自己的。
使用类似于python代码缩进的方式组织代码块。
缩进一级至少为两个空格,且前后一致。
gateway4字段的ip地址不用中括号(只有一个)。
本机addresses字段和域名服务器addresses字段都需要中括号,多个ip之间使用逗号分隔。
配置完成后,需要执行sudo netplan apply使配置生效。

再看另一个示例:

root@Ubuntu20.04:~# cat /etc/netplan/99-eth0.yaml 
network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: false
      match:
        macaddress: 00:16:3e:00:08:54
      addresses: 
         - 10.180.43.126/24
      gateway4: 10.180.43.1
      nameservers:
         addresses: 
             - 114.114.114.114
      mtu: 1360
      routes:
        - to: 0.0.0.0/0
          via: 10.180.47.253
network:
  version: 2
  renderer: NetworkManager
  ethernets:
    ens32:
      dhcp4: yes
    ens34:
      addresses:
        - 20.0.10.1/20
      dhcp4: no
      optional: true
      gateway4: 20.0.0.1
      nameservers:
        addresses:
          - 20.0.0.1

参考内容:https://www.360blogs.top/ubuntu20-04-netplan/

#查看已连接的硬盘
fdisk -l

#进入硬盘分区工具,进行分区设置
fdisk /dev/sdd
#如果是2TB以上硬盘,没用使用GUID分区表的话,会有黄色的警告信息
#查看帮助菜单
m

#创建GUID分区表,在w保存的时候,原有的分区表将移除
g
#保存并退出
w

#重进入分区工具,创建硬盘分区
fdisk /dev/sdd

#新建分区
n

#一路回车之后,保存退出
w

#查看硬盘分区,可以看到 /dev/sdd1 分区了
fdisk /dev/sdd -l

#格式化分区为ext4文件系统
mkfs.ext4 /dev/sdd1

#创建目录并挂载分区到/data目录
mkdir /data
mount /dev/sdd1 /data

#查看已挂载分区信息
df -h

#现在挂载的分区在系统重启后就没有挂载了,需要保存到/etc/fstab文件中,增加一行
vim /etc/fstab

#增加一行内容
/dev/sdd1       /data   ext4    defaults        0       1: