企业内部有多个业务系统、管理系统,而这些系统相互独立,也无相关审计工具对操作人员进行审计,使用人员或者管理员在对账户等也存在一定疏忽,为加强网络安全以及保证内部信息安全,一般都要求这些管理系统接入堡垒机,堡垒机的审计原理:使用人员登录堡垒机系统,选中要登录的管理系统,堡垒机自动打开远程桌面,并代自动填入需要访问系统的账户和密码,这一过程对使用者透明,但堡垒机可通过录制使用者操作视频以及记录相关登入登出操作,达到对多个管理系统统一管理。
关键功能配置在此:
需在堡垒机系统上配置纳入审计的URL、账号和密码,其自带功能仅支持ie浏览器登录,而内部使用多个系统已不支持ie或者IE体验极差(包括旧管理系统和新管理系统),在应用类型选项仅有“IE代填以及自定义代填”两项选择,却没有类似“IE代填、Chrome代填、FireFox代填这些选项”, 而实际使用场景为使用Chrome浏览器代填,堡垒机厂家提供的自定义代填功能竟然无相关程序。
如上图:厂家提供的默认选项IE代填,无需给出账户以及密码输入框的Xpath,即可实现通过IE打开相应web管理页面,但仅限IE打开!
选择自定义代填,从界面选项来看,它仅提供目标地址url、登录账户、登录密码,如果要用chrome打开该url,首先要解决的是如何定位账户输入框位置和密码输入框位置,以便使用selenium打开webdriver定位到相应元素并自动填入信息。显然厂家无法提供该脚本,需自行开发!故需构造类似这样的脚本应用路径:
python autoFillingIn.py -url ** -user ** -psw ** -wait ** -hup ** -hpp ** -lp** -al **
其中-hup –hpp这两个入参为用户名输入框的xpath和密码输入框的xpath
堡垒机通过打开远程桌面后并运行该autoFillingIn.py,该程序通过入参调用chrome driver.exe从而打开chrome浏览器
以下为开发过程:
(1)环境准备:
由堡垒机打开的远程桌面所在服务器需安装python3.5环境、selenium库,以及chrome driver.exe
chromedriver下载
在阿里的镜像源:http://npm.taobao.org/mirrors/chromedriver/2.8/
chromedriver_win32.zip (可适用32位和64位windows)
selenium离线安装包
git clone https://github.com/SeleniumHQ/selenium.git
里面已有setup.py,将该离线包上传到远程桌面所在服务器
python setup.py install
注:如果使用其他浏览器例如Firefox、Edge 、Safari,可在以下官网下载相应driver
https://pypi.org/project/selenium/
(2)建议将chromedriver.exe和autoFillingIn.py放在同一目录下
这里放在c:\ chromeTools目录下
程序逻辑如下
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
| import os import re import time import argparse from selenium import webdriver
def keep_double_quotes(xpath): """ 通过Chrome右键Copy Xpath获取目标url账户、密码、登录按钮输入框的Xpath有两种通用形式: 第一种在其html元素显示给出id值的://*[@id="usernameInput"] 以及 //*[@id="loginForm"]/fieldset/div[1]/input 第二种在其html元素没有id索引的:/html/body/form/table[1]/tbody/tr[5]/td[3]/input 或 /html/body/form/table[1]/tbody/tr[5]/td[3]/img 对于第一种Xpath,当使用入参 -up //*[@id="login_input"]时,会被argparse解析为 //*[@id=login_input],双引号没了!因此需要还原输入参数的格式, 否则find_element_by_xpath将无法定位,无法实现自动代填 该bug相对隐藏! """ m=re.search(r'=(.*?)\]',xpath) if m: id_name=m.group(1) quotes_id_name='"'+id_name+'"' double_quotes_path=re.sub(r'{}'.format(id_name),quotes_id_name,xpath) return double_quotes_path else: return xpath
parser=argparse.ArgumentParser(description='自动代填') parser.add_argument('-url',type=str,required=True,help='网站url,支持http和https') parser.add_argument('-user',type=str,required=True,help='用户名') parser.add_argument('-psw',type=str,required=True,help='密码') parser.add_argument('-wait',type=int,default=5,help='网页加载等待秒数,保证元素加载出来后才能定位成功')
parser.add_argument('-up',type=keep_double_quotes,help='用户input提示元素的Xpath,取第一个input元素的id,style为"display: block;",如没有该id,则可忽略该-up选项') parser.add_argument('-hup',type=keep_double_quotes,required=True,help='用户input存放用户名元素的Xpath,style为"display: none;",表示隐藏用户名输入')
parser.add_argument('-pp',type=keep_double_quotes,help='密码input提示元素的Xpath,取第一个input元素的id,style为"display: block;",如没有该id,则可忽略该-pp选项') parser.add_argument('-hpp',type=keep_double_quotes,required=True,help='密码input真实密码填入元素的Xpath,style为"display: none;",表示隐藏密码输入')
parser.add_argument('-lp',type=keep_double_quotes,help='登录按钮的Xpath,使用Chrome的Copy Xpath定位元素路径') parser.add_argument('-al',type=str,help='指定是否自动登录,如指定自动,填入Y或y,如需要填入验证码、短信等二次认证的输入框,请填入N或n')
inputs=parser.parse_args() target_url=inputs.url username=inputs.user password=inputs.psw sleep_time=inputs.wait u_inp=inputs.up hidden_u_inp=inputs.hup psw_inp=inputs.pp hidden_psw_inp=inputs.hpp login_input=inputs.lp auto_login=inputs.al
chrome_name = 'chromedriver.exe' dir_name = os.path.dirname(os.path.abspath(__file__)) chrome_driver_path = os.path.join(dir_name, chrome_name)
options=webdriver.ChromeOptions() options.add_argument('--disable-popup-blocking') options.add_argument('--disable-infobars') options.add_argument('--allow-running-insecure-content') options.add_argument('--start-maximized') options.add_argument('--disable-gpu') driver=webdriver.Chrome(chrome_driver_path,chrome_options=options)
driver.get(target_url)
time.sleep(sleep_time)
selector=driver.find_element_by_xpath
if u_inp: u_inp_selector=selector(u_inp) driver.execute_script("arguments[0].focus();",u_inp_selector)
hidden_u_inp_selector=selector(hidden_u_inp) driver.execute_script("arguments[0].focus();", hidden_u_inp_selector) hidden_u_inp_selector.send_keys(username)
if psw_inp: psw_inp_selector=selector(psw_inp) driver.execute_script("arguments[0].focus();",psw_inp_selector)
hidden_psw_inp_selector=selector(hidden_psw_inp) driver.execute_script("arguments[0].focus();", hidden_psw_inp_selector) hidden_psw_inp_selector.send_keys(username)
login=selector(login_input)
if auto_login in ('Y','y'): login.click() else: pass
|
这里为何不设计为以下代码结构:
def auto_filling_in(**kargs):
pass
if name==”main”:
获取入参
调用auto_filling_in(**kargs)
因为使用该形式运行时,selenium会以子进程运行chromedriver.exe
if name==”main”:以下的代码作为父进程
而父进程在获取入参和调用auto_filling_in()后会结束,导致子进程运行的chrome也退出
(3)程序使用说明
最后在堡垒机上的配置该脚本:
应用路径:c:\ chromeTools\ autoFillingIn.py
运行参数:-url %Target -user %Username -psw %Password -wait 5 -fup /html/body/form/table[1]/tbody/tr[5]/td[1]/input -fpp /html/body/form/table[1]/tbody/tr[5]/td[4]/input -lp /html/body/form/table[1]/tbody/tr[5]/td[5]/img -al Y
登录地址:需要审计的管理系统url
登录账户:账户名
登录密码:密码
以上部分参数说明:
-fup账户输入框Xpath: /html/body/form/table[1]/tbody/tr[5]/td[1]/input,若为隐藏元素,则需要加入up选项
-fpp密码输入框Xpath: /html/body/form/table[1]/tbody/tr[5]/td[4]/input,若为隐藏元素,则需要加入pp选项
-lp登录输入框Xpath: /html/body/form/table[1]/tbody/tr[5]/td[5]/img
==重点内容==:
以上都是基于用户输入框和密码输入框都为输入字符可见的条件下,可以代成功,但是对于用户名、密码输入框设为输入字符隐藏时,需要加入以下两个选项才能定位到元素并正确代填,需要将鼠标先focus到用户名输入框或者密码输入框。
-up账户输入框Xpath: /html/body/form/table[1]/tbody/tr[5]/td[2]/input
-pp密码输入框Xpath: /html/body/form/table[1]/tbody/tr[5]/td[3]/input
(4) 运行效果:
任务栏开启了两个远程桌面窗口,一个是autoFillingIn.py运行窗口,另一个为chrome打开的被审计web系统
综上,最关键的设计:入参双引号处理,以及wait等待页面加载完毕的时间,因为某些旧管理系统服务器性能较低,打开页面慢,容易导致selenium无法定位元素位置。另外对于有验证码、短信等二次认证的web管理页面,自动登录选项 -al 要设为N或n,即不自动登录到首页,由使用人员自行填入验证码(账户和密码已经后台自动填到输入框内,无需再填入,除非使用人刷新了以打开的登录窗口,那么账户和密码输入框会被清空)。
由于解决了argparse对入参Xpath字符串路径问题,本文的解决方案适用所有管理系统需要通过Chrome自动代填达到审计目的场景,之前在全网以及检索国外论坛,都未找到合适参考的方案,用了几天时间自行研究到部署可用,恰好满足实际场景(否则堡垒机系统使用受限,而且厂家无法提供该技术支持!)。在这里,也要介绍国内也有非常出色的开源堡垒机系统例如:Jumpserver,使用python+django开发(个人擅长的技术栈),而且该开源堡垒机系统还符合4A(认证Authentication、账号Account、授权Authorization、审计Audit)的专业运维审计系统,可docker化部署!
Jumpserver的官网:http://www.jumpserver.org/
github:https://github.com/jumpserver/jumpserver
相关开源堡垒机系统的对比参考文章:
https://blog.csdn.net/enweitech/article/details/88840456