Aggregator
记一次攻防演习渗透过程
记一次攻防演习渗透过程
记录一次攻防演习渗透过程,文章仅写关于「打点」环节的部分,也就是拿到靶标的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分支。
我们可以来实际的看一下index和head这两个文件:
使用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命名的文件,根本不知道其对应关系:
并且这些文件都没办法看:
查阅相关资料得知此类文件是将原文件内容经过zlib的deflate压缩后存储的( 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包含了:
- SHA(所有用来表示项目历史信息的文件,是通过一个40个字符的(40-digit)“对象名”来索引的)
- Blob对象(用来存储文件的内容)
- Tree对象(有一串bunch指向Blob对象或是其它Tree对象的指针,一般表示内容之间的目录层次关系)
- Commit对象(指向一个Tree对象, 并且带有相关的描述信息.)
(注: 图片来自 git-scm.com )
猜测: 按照这个逻辑,我们需要先获取Commit对象对应文件找到Tree对象对应文件再通过其获得Blob对象对应文件,最后解压即可获得源文件内容。
那这些对象内容都存储在哪里呢?通过之前使用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对象的值,也就根本不需要获取commit、tree对象的值了,表示之前的顺序逆推逻辑是错误的:
接下来按照这个思路去编写脚本恢复源码即可。
编写与恢复
由于项目时间原因简单了解原理之后,没有过多的去研究,也不打算使用原生方法去恢复,还是采用最暴力的方法,使用命令行去恢复.git,想要让Git回退历史,使用git reset --hard commit_id命令,进行版本回退。
基于这个命令,我需要获取网站的这几个文件/目录:
- .git/index
- .git/logs
- .git/head
- .git/objects
- .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):
遇到这种情况尝试以下几种方法:
- 修改后缀访问,判断是否是只针对脚本后缀进行限制(上传.htaccess文件)
- 修改内容访问,判断是否有安全防护对内容进行限制
- 如若以上均未访问成功,则可以考虑覆盖原文件写入
这里我的情况是第三种,大概推测可能是因为新建的文件没有执行权限所导致,因为这里我们已经有源码了所以可以直接找已有的文件(建议选择非业务相关的文件)进行写入(记得事后恢复):
执行phpinfo();函数可以,但无法直接使用管理工具连接,抓包发现目标网站上了云WAF,对请求内容拦截了(该WAF还挺弱),这种情况还是有很多中方式:
- 配合Cknife、蚁剑等自定义修改传输内容(Base64编码等等),但需要修改PHP文件内容配合解码
- 直接上冰蝎、哥斯拉的马就行了
为图方便,选择冰蝎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:
- into outfile -> 失败
- Mysql log -> 失败
- Adminer是最新版本无漏洞 -> 失败
- 获取管理员密码无法解密 -> 失败
最终选择添加新管理员登录:
登录之后寻找对应上传点(以最短攻击路径的方式进行GetWebShell):
测试如下后缀及服务器结果:
Key.jpg -> 上传成功 Key.php -> 上传失败WAF拦截 Key.phtml -> 上传失败文件类型不允许我们在已经有源码的情况下,找到对应的代码进行审计就行,发现这里是白名单设置无法绕过:
直接关键词寻找上传功能,发现函数:xxx_upload_file存在任意文件上传
后续构建请求包以及使用回车直接绕过CloudWAF,上传成功:
至此靶标拿到,结束。
文末很多时候还是需要去探寻事物的本质和原理,才能更加清晰明了的了解这个事物,否则什么东西都是现有的成品一把梭,遇到梭不了,容易出现惯性思维,可能就直接略过了。
影视解说的配音怎么做?找魔音工坊配音神器
Don't Let DDoS Extortionists Deliver a KO Punch
WordPress Malware Setting Up SEO Shops
Genesis Marketplace, a Digital Fingerprint Darknet Store
Authenticated Resolution and Adaptive Resolution: Security and Navigational Enhancements to the Domain Name System
The Domain Name System (DNS) has become the fundamental building block for navigating from names to resources on the internet. DNS has been employed continuously ever since its introduction in 1983, by essentially every internet-connected application and device that wants to interact online. Emerging from an era where interconnection rather than information security was the […]
The post Authenticated Resolution and Adaptive Resolution: Security and Navigational Enhancements to the Domain Name System appeared first on Verisign Blog.