当前位置: 首页 > news >正文

HackTheBox - Medium - Linux - Format

Format

Format 是一种中等难度的 Linux 机器,它突出显示了由解决方案的结构方式引起的安全问题。立足点涉及PHP源代码审查,发现和利用本地文件读/写漏洞,并利用Nginx中的错误配置在Redis Unix套接字上执行命令。横向移动包括浏览 Redis 数据库以发现用户密码,而权限提升则围绕以 root 权限运行的 Python 脚本展开,该脚本容易受到代码注入的影响。


外部信息收集

端口扫描

循例nmap

file

Web枚举

80端口 - app.microblog.htb

file

3000端口 - microblog.htb

file

Foldhold

和我预想的一样,gitea包含了app子域的源码,毕竟遇到这种情况的次数也不少了

file

我们首先在app子域创建一个账号并登录

file

这里有一个最显眼的功能也是唯一一个功能就是创建新博客,我们可以指定子域域名,我们在源码里面定位到那个功能的代码

一开始我把目光放到了addsite函数上

addSite($_POST['new-blog-name']);function addSite($site_name) {if(isset($_SESSION['username'])) {...$tmp_dir = "/tmp/" . generateRandomString(7);system("mkdir -m 0700 " . $tmp_dir);system("cp -r /var/www/microblog-template/* " . $tmp_dir);system("chmod 500 " . $tmp_dir);system("chmod +w /var/www/microblog");system("cp -rp " . $tmp_dir . " /var/www/microblog/" . $site_name);...

我们应该可以尝试控制$_POST[‘new-blog-name’]来尝试执行系统命令,但是我发现后端对new-blog-name进行了严格的过滤,只允许26个字母,所以使我打消了这个念头

if (isset($_SESSION['username']) && isset($_POST['new-blog-name'])) {if(!preg_match('/^[a-z]+$/', $_POST['new-blog-name']) || strlen($_POST['new-blog-name']) > 50) {print_r("Invalid blog name");

我创建了一个test子域

在gitea中我看到一个sunny子域,我猜那个应该是由app子域创建的,所以我刚刚创建的test子域应该与sunny子域有同样的代码结构

file

在edit/index.php中,我发现了任意文件读写

//add header
if (isset($_POST['header']) && isset($_POST['id'])) {chdir(getcwd() . "/../content");$html = "<div class = \"blog-h1 blue-fill\"><b>{$_POST['header']}</b></div>";$post_file = fopen("{$_POST['id']}", "w");fwrite($post_file, $html);fclose($post_file);$order_file = fopen("order.txt", "a");fwrite($order_file, $_POST['id'] . "\n");  fclose($order_file);header("Location: /edit?message=Section added!&status=success");
}//add text
if (isset($_POST['txt']) && isset($_POST['id'])) {chdir(getcwd() . "/../content");$txt_nl = nl2br($_POST['txt']);$html = "<div class = \"blog-text\">{$txt_nl}</div>";$post_file = fopen("{$_POST['id']}", "w");fwrite($post_file, $html);fclose($post_file);$order_file = fopen("order.txt", "a");fwrite($order_file, $_POST['id'] . "\n");  fclose($order_file);header("Location: /edit?message=Section added!&status=success");
}

尝试读取passwd

file

我尝试着在web目录下写入webshell,但很不幸的是应该是没有权限和解析php

Nginx配置错误

读/etc/nginx/sites-available/default

...
location ~ /static/(.*)/(.*) {resolver 127.0.0.1;proxy_pass http://$1.microbucket.htb/$2;
...

这篇文章讲述了nginx的proxy_pass支持将请求代理到本地unix套接字

现在我们可以控制$1,我们看到register.php设置的字段

file

通过nginx的proxy_pass来对redis进行操作

将自己的账户的pro字段设置为true

file

刷新一下

file

function provisionProUser() {if(isPro() === "true") {$blogName = trim(urldecode(getBlogName()));system("chmod +w /var/www/microblog/" . $blogName);system("chmod +w /var/www/microblog/" . $blogName . "/edit");system("cp /var/www/pro-files/bulletproof.php /var/www/microblog/" . $blogName . "/edit/");system("mkdir /var/www/microblog/" . $blogName . "/uploads && chmod 700 /var/www/microblog/" . $blogName . "/uploads");system("chmod -w /var/www/microblog/" . $blogName . "/edit && chmod -w /var/www/microblog/" . $blogName);}return;
}

现在我们是pro,上面这些命令会使我们能够对uploads/目录写入文件,借此来getshell

file

然后通过rce来使用祖传python3 payload

file

本地横向移动 -> cooper

在redis发现了一个系统用户名的key

file

读一下发现了他的密码

hgetall cooper.dooper

file

直接登ssh

file

本地权限提升

sudo -l

file

这是一个python脚本

我们主要关注脆弱点

    username = r.hget(args.provision, "username").decode()firstlast = r.hget(args.provision, "first-name").decode() + r.hget(args.provision, "last-name").decode()license_key = (prefix + username + "{license.license}" + firstlast).format(license=l)

这里的license_key由几个变量拼接进来然后format,应该存在模板注入,而username这些都是在redis读取的,我们可以控制redis来触发模板注入

secret = [line.strip() for line in open("/root/license/secret")][0]
secret_encoded = secret.encode()
salt = b'microblogsalt123'
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),length=32,salt=salt,iterations=100000,backend=default_backend())

通过模板注入来获取secret,设置username

file

再次运行

file

root flag还在老地方

file

相关文章:

  • Could not resolve com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.28.
  • java8 reduce操作
  • PHP函数定义和分类
  • springMVC-与spring整合
  • Kafka日志
  • 编写一个Java程序,其中包含三个线程: 厨师(Chef)、服务员(Waiter)和顾客(Customer)
  • docker安装的php 在cli中使用
  • 构建数字化金融生态系统:云原生的创新方法
  • pycharm修改项目文件夹名称
  • PostGreSQL:货币类型
  • hiveserver负载均衡配置
  • cpp_05_类_string类
  • Vue3 性能优化
  • Java 解决远程调用 ssl 证书认证问题
  • 智能优化算法应用:基于鹈鹕算法3D无线传感器网络(WSN)覆盖优化 - 附代码
  • 【React系列】如何构建React应用程序
  • 【RocksDB】TransactionDB源码分析
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • CSS 三角实现
  • CSS 专业技巧
  • docker容器内的网络抓包
  • JS字符串转数字方法总结
  • k8s 面向应用开发者的基础命令
  • Vue2 SSR 的优化之旅
  • yii2中session跨域名的问题
  • 番外篇1:在Windows环境下安装JDK
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 机器学习中为什么要做归一化normalization
  • 利用DataURL技术在网页上显示图片
  • 聊一聊前端的监控
  • 如何在 Tornado 中实现 Middleware
  • 事件委托的小应用
  • 我有几个粽子,和一个故事
  • 用quicker-worker.js轻松跑一个大数据遍历
  • 1.Ext JS 建立web开发工程
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • #pragma pack(1)
  • #pragma 指令
  • #数学建模# 线性规划问题的Matlab求解
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (2)Java 简介
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox)
  • (转)Oracle 9i 数据库设计指引全集(1)
  • (转)一些感悟
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • .“空心村”成因分析及解决对策122344
  • .java 9 找不到符号_java找不到符号
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容