【网络安全】某安全网关前端JS分析

348 阅读3分钟

一、前言

xxx是一款用于前端防御自动化工具的安全网关,核心代码由服务器下发给客户端执行,通过cookie将执行结果带回,再根据js获取的前端数据判断用户是否异常,完成安全检测

二、代码入口

js计算结果通过cookie传给服务器,参数名为:8PHkpr8y、JF7cGtR5、SflKxwRJ

经过调试分析,代码明文存放在ng_dynamic_defend文件中,核心逻辑位于尾部这几行

三、读取配置

get_global()函数读取配置信息,放入_global_config

window . config = 'eyJmaW5nZXIiOnsibmFtZSI6IkpGN2NHdFI1In0sImJvdCI6eyJlbmFibGVkIjp0cnVlLCJuYW1lIjoiOFBIa3ByOHkifSwic3VibWl0Ijp7ImVuYWJsZWQiOnRydWUsIm5hbWUiOiJVVmpES082biIsInVybCI6IiJ9LCJ0b2tlbiI6eyJlbmFibGVkIjp0cnVlLCJuYW1lIjoiU2ZsS3h3UkoiLCJ1cmwiOiJqc190ZXN0LmNvbTsiLCJpc19jaGVja191cmkiOnRydWUsImlzX2NoZWNrX2dldCI6dHJ1ZX0sImNvbnRlbnQiOnsiZW5hYmxlZCI6ZmFsc2UsIm5hbWUiOiJTZmxLeHdSSiIsImNvbmZ1c2VfdHlwZSI6IjAifSwic2NyaXB0Ijp7ImlzX2FudGlfZGVidWciOmZhbHNlfX0=' ;
! function  ( global ) {
  function _base64_parse ( e ) {
    return CryptoJS . enc . Base64 . parse ( e ). toString ( CryptoJS . enc . Utf8 )
  }

  function get_global () {
    var e = _base64_parse ( global . config ),
    t = JSON . parse ( e );
    _global_config = global . nY1vq7Gi = t
  }
}( window );


/*
{
"finger": {
"name": "JF7cGtR5"
},
"bot": {
"enabled": true,
"name": "8PHkpr8y"
},
"submit": {
"enabled": true,
"name": "UVjDKO6n",
"url": ""
},
"token": {
"enabled": true,
"name": "SflKxwRJ",
"url": "js_test.com;",
"is_check_uri": true,
"is_check_get": true
},
"content": {
"enabled": false,
"name": "SflKxwRJ",
"confuse_type": "0"
},
"script": {
"is_anti_debug": false
}
}
*/ 

【点击查看资料详细】

四、数据采集

以下三个函数会使用到window对象来采集客户端数据:

  • get_tool_feature() 获得工具特征
  • get_browser_feature() 获得浏览器特征
  • get_fingerprint() 获得浏览器指纹

1.get_tool_feature()

get_webdriver ()  //window.navigator.webdriver
get_phantomjs ()  //window.navigator.userAgent
get_bot ()  //检测关键字:'__webdriver_evaluate','__selenium_evaluate','__webdriver_script_function','__webdriver_script_func','__webdriver_script_fn','__fxdriver_evaluate','__driver_unwrapped','__webdriver_unwrapped','__driver_evaluate','__selenium_unwrapped','__fxdriver_unwrapped''_phantom','__nightmare','_selenium','callPhantom','callSelenium','_Selenium_IDE_Recorder'
get_navigator_for_tool ()  //window.navigator.languages
get_canvas_for_tool ()  //window.document.createElement('canvas').getContext
get_storage_for_tool ()  //window.localStorage && window.sessionStorage
get_consol ()  //window.console.log(1)
get_awvs ()  //检测关键字:'SimpleDOMXSSClass','MarvinHooks','MarvinPageExplorer','HashDOMXSSClass'
get_appscan ()  //检测关键字:'appScanSendReplacement','appScanOnReadyStateChangeReplacement','appScanLoadHandler','appScanSetPageLoaded' 

2.get_browser_feature()

get_indexedDB ()  //window.indexedDB
get_openDatabase ()  //window.openDatabase
get_localStorage ()  //window.localStorage
get_sessionStorage ()  //window.sessionStorage
get_audio ()  //window.AudioContext.destination
get_file ()  //'object' == typeof File || 'function' == typeof File
isCanvasSupported ()  //window.document.createElement('canvas').getContext
isWebGlSupported ()  //window.WebGLRenderingContext || window.document.createElement('canvas').getContext('webgl')
get_plugins ()  //window.navigator.plugins
get_languages ()  //window.navigator.languages
get_platform ()  //window.navigator.platform
get_cpuClass ()  //_navigator.cpuClass
get_hardwareConcurrency ()  //_navigator.hardwareConcurrency
get_namespaces ()  //window.document.namespaces
get_documentMode ()  //window.document.documentMode
get_ActivexObject ()  //window.document.ActivexObject
get_StyleMedia ()  //window.StyleMedia
get_opera ()  //window.opera
get_firefox ()  //'undefined' != typeof InstallTrigger
get_chrome ()  //window.chrome
get_safari ()  ///constructor/i.test(window.HTMLElement) || '[object SafariRemoteNotification]' === (!window.safari || safari.pushNotification).toString() 

 

3.get_fingerprint()

get_indexedDB ()  //window.indexedDB
get_openDatabase ()  //window.openDatabase
get_localStorage ()  //window.localStorage
get_sessionStorage ()  //window.sessionStorage
get_audio ()  //window.AudioContext.destination
get_file ()  //'object' == typeof File || 'function' == typeof File
get_canvas ()  //window.document.createElement('canvas')
get_webgl ()  //window..document.createElement('canvas').getContext('webgl')
get_webgl_render ()  //window.document.createElement('canvas').getContext('webgl')
get_plugins ()  //window.navigator.plugins
get_language ()  //window.navigator.language || window.navigator.userLanguage || window.navigator.browserLanguage || window.navigator.systemLanguage ||
get_languages ()  //window.navigator.languages
get_platform ()  //window.navigator.platform
get_cpuClass ()  //window.navigator.cpuClass
get_hardwareConcurrency ()  //window.navigator.hardwareConcurrency
get_timezone_offset ()  //(new Date).getTimezoneOffset()
get_timezone ()  //window.Intl && window.Intl.DateTimeFormat
get_screen_ratio ()  //window.screen.width / window.screen.height * 100
get_screen_resolution ()  //window.screen.availHeight + 'X' + window.screen.availWidth + 'X' + window.screen.availLeft + 'X' + window.screen.availTop
get_touch_support ()  //window.navigator.maxTouchPoints || window.navigator.msMaxTouchPoints
get_media_devices ()  //window.navigator.mediaDevices && window.navigator.mediaDevices.enumerateDevices
get_battery ()  //window.navigator.getBattery
get_adBlock ()  //window.document.getElementsByClassName('adsbox') [0].offsetHeight
get_userAgent ()  //window.navigator.userAgent

4.数据处理

set_bot_cookie()set_fingerprint()两个函数分别将tool_featurebrowser_featurefingerprint加密写入到cokie中,变量名为:8PHkpr8yJF7cGtR5

1.set_bot_cookie()

2.set_fingerprint()

五、 事件监听

1.a标签

设置EventListenerEx()监听,当页面加载完成时触发load_func(),对当前cookie执行base64编码操作,并设置参数名为KBwtGA

function confuse_cookie ()   {
  var e ;
  _document . cookie && 0 != _global_config . content . enabled && '1' == _global_config . content . confuse_type && ( e = _document . cookie , clearAllCookie (), CookieUtil . set ( 'KBwtGA' , btoa ( e )))
} 

当发生点击事件时触发a_click_handler(),对请求地址添加令牌,变量名为SflKxwRJ

replace_url()调用get_token()生成加密tonken

2.form表单

设置EventListenerEx()监听,当发生表单事件时触发form_hook(),调用get_submit()对表单内数据加密,参数名为UVjDKO6n,调用get_token()生成加密tonken,参数名为SflKxwRJ

3.ajax请求

当发生ajax事件时触发ajax_hook(),对不同请求方式做了单独处理

监听到get请求时调用get_body_for_get()对args数据使用get_token()加密,监听到post请求时调用get_body_for_post()对请求体get_submit()加密、对url使用replace_url()调用get_token()生成加密tonken

六、总结

xxx的核心代码未经过加密或混淆以明文形式下发,格式化后通过调试分析比较容易弄清楚执行逻辑,代码主要实现以下两个功能:

  1. 采集window或者navigator的部分特征值,按位计算形成一个整数,再利用rc4算法加密,指纹特征存放在cookie中JF7cGtR5、工具特征存放在cookie中8PHkpr8y
  2. 设置a标签form表单ajax请求监听,触发时对数据内容调用get_submit()使用rc4算法加密、对url调用get_token()使用rc4算法计算token令牌