Lesson Plan Title: How to Perform Silent Transactions Attacks.

Concept / Topic To Teach:

This lesson teaches how to perform silent transactions attacks.

How the attacks works:

Any system that silently processes transactions using a single submission is dangerous to the client. For example, if a normal web application allows a simple URL submission, a preset session attack will allow the attacker to complete a transaction without the user's authorization. In Ajax, it gets worse: the transaction is silent; it happens with no user feedback on the page, so an injected attack script may be able to steal money from the client without authorization.

General Goal(s):

This is a sample internet banking application - money transfer page.

It shows below your balance, the account you are transferring to and amount you will transfer.
The application uses AJAX to submit the transaction after doing some basic client side validations.
Your goal is to try to bypass the user's authorization and silently execute the transaction.

Figure 1 AJAX Security - Silent transaction attacks

Solution:

This web application uses JavaScript on the client to initiate a transaction for transferring money. Examining the HTML source reveals that two JavaScript functions are being used:

<script>

function processData(){

var accountNo = document.getElementById('newAccount').value;

var amount = document.getElementById('amount').value;

if ( accountNo == ''){

alert('Please enter a valid account number to transfer to.')

return;

}

else if ( amount == ''){

alert('Please enter a valid amount to transfer.')

return;

}

var balanceValue = document.getElementById('balanceID').innerText;

balanceValue = balanceValue.replace( new RegExp('$') , '');

if ( parseFloat(amount) > parseFloat(balanceValue) ) {

alert('You can not transfer more funds than what is available in your balance.')

return;

}

document.getElementById('confirm').value = 'Transferring'

submitData(accountNo, amount);

document.getElementById('confirm').value = 'Confirm'

balanceValue = parseFloat(balanceValue) - parseFloat(amount);

balanceValue = balanceValue.toFixed(2);

document.getElementById('balanceID').innerText = balanceValue + '$';

}

function submitData(accountNo, balance) {

var url = 'attack?Screen=74&menu=1150&from=ajax&newAccount='+ accountNo+ '&amount=' + balance +'&confirm=' + document.getElementById('confirm').value;

if (typeof XMLHttpRequest != 'undefined') {

req = new XMLHttpRequest();

} else if (window.ActiveXObject) {

req = new ActiveXObject('Microsoft.XMLHTTP');

}

req.open('GET', url, true);

req.onreadystatechange = callback;

req.send(null);

}

function callback() {

if (req.readyState == 4) {

if (req.status == 200) {

var result = req.responseText ;

var resultsDiv = document.getElementById('resultsDiv');

resultsDiv.innerHTML = '';

resultsDiv.innerHTML = result;

}}}

</script>

The function processData() is called when the user fills out an account number and an amount to transfer. The function processData() will check if the user has sufficient balance before initiating the transaction. After validation of the balance, the JavaScript function submitData(accountNo, balance) is called which actually submits the required information, target account number and the amount to transfer, to the back-end web application.

If you are able to call this JavaScript function submitData(accountNo, balance) from the browser, you are able to bypass the client-side validation and execute this transaction silently, without an additional approval or digital signature of the user.

The latest generation of browsers allows to call JavaScript from the address bar, using javascript:function();. Try to execute: javascript:submitData(1234556,11000);

Figure 2 Follow the hints....

Figure 3 HTTP Request generated from Javascript function submitData(123456,110000);

Figure 4 Lesson completed

Solution by Erwin Geirnaert |