Investigating an FB phishing site

Last April 21, people were posting warnings about a suspicious Facebook post where your account will supposedly get hacked when you click it. From the discussions, I gathered that it is a classic phishing site scam. A very effective one too, because as soon as an account gets compromised the attacker logs in and tags the friends in the account allowing it to spread further. The news of this got big that even the PH CERT issued a security advisory on it.

checking-the-fb-phishing-site-02

I was just curious, I swear!

I wanted to see the phishing site for myself but I was unlucky and did not get tagged by anyone. So I reached out to people who did and I eventually got to this page shown below:

checking-the-fb-phishing-site-01

To a trained eye, one could easily see the obvious red flags. But how can one notice them if there is a very attention-catching image in the middle beckoning to be clicked? It's a very simple tactic yet very effective. Clicking this link leads to an external website with an even more tantalizing image masquerading as a video.

checking-the-fb-phishing-site-03

Clicking play on that video would then lead to a fake Facebook login page. We all know what's next after that.

checking-the-fb-phishing-site-06

Of course, the very best course of action when a phishing site is discovered is to report it. I, however, was curious so I decided to poke around first.

The poking begins

Using my knowledge in OSINT (Open Source Intelligence) and pentesting, I poked around to see what I could learn from these set of pages.

One thing that immediately became obvious was that these "set of pages" were hosted on separate domains. The page with the video points to one domain, and the login page to another (that is even protected by DDNS (Dynamic DNS) via No-IP).

investigating-an-fb-phishing-site-08

I also noticed that the way that the two pages were built was different. The coding style is not the same, different frameworks were used, plus the robots.txt of the login page was more restrictive.

Why are they in separate domains? Wouldn't it be cheaper to just have both pages on the same domain?

My hunch is that maybe the two sites were made by different people. One guy made the landing page then a different one made the login page. Or maybe the login page is an out-of-the-box solution you pay for or rent if you want to set up your own phishing scam? A PhAAS (Phishing-as-a-Service)?

investigating-an-fb-phishing-site-09

During my reconnaissance, I also noticed that the URLs for the login page were changed a few times over a few hours. It's possible that the pages were being taken down thanks to the reports and the malicious actors were just making new instances and redirecting to it to make sure that the operation continues.

Đăng nhập hoặc đăng

Another thing I noticed is references to various Vietnamese terms and websites. Both pages have directories using the word "homnay", Vietnamese for the word "today". The source code also has a link to the news website "tuoitre.vn".

checking-the-fb-phishing-site-04

The Google Analytics ID used can also be found in previously tagged but now-defunct Phishing websites with references to Vietnam. It's entirely possible that these phishing sites initially targeted Vietnamese users but eventually got to Philippine users via the tagging spreading mechanism.

checking-the-fb-phishing-site-05

Or maybe it's a deliberate ploy to make it seem that the origin of the phish is Vietnamese. Just to throw off those of us snooping around.

And then it was gone

I was tempted to make a dummy Facebook account and send the login details to the phishing site. The idea was to see how long before an account gets accessed after submitting the credentials and if the tagging of friends is automated or done manually. But sadly I ran out of free time and by the time I came back to it the login page was already completely offline. The landing page is still up though.

This investigation has taught me a lot about phishing sites. It's different from investigating malware but it's easy to see the similarities in intent and approaches. I might try investigating more in the future. I'm curious to find out what the usual modus operandi is and also how the general populace can better protect themselves from it.

This particular site may be down now, but I bet there will be more in the future. As long as there are people to fall for scams like these, this type of attack will continue.

If you want to know more or discuss the details about the phishing site, I would be happy to exchange notes. Drop me a line on Twitter @accidentalrebel.

The Emprisa Maldoc Challenge

I was inspired to make my own CTF challenge after finishing Maldoc101 found at Cyberdefenders.org. The challenge I made is called Emprisa Maldoc and it is now up on their website.

Emprisa is based on a malicious document that I downloaded blindly from a malware sandbox. It used a relatively old but still interesting exploit that is still in use today. After researching more about it I came across a tool that can generate a malicious doc using the same exact exploit. This is when I got the idea to turn it into a challenge.

the-emprisa-maldoc-challenge-01

The challenge has 14 questions with increasing and varying difficulty. The challenge is targeted towards intermediate analysts who already have experience examining maldocs before. The goal is to reinforce the use of common malware analysis tools, but at the same time, teach players new things and techniques. It involves flexing muscles related to open source intelligence, examining shellcodes, and debugging processes.

I don't want to spoil too much but if you are for it, you can give it a go here. It was hella fun to make and I do hope that it is also as fun to solve!


Official write-up with hints coming soon.

I would like to extend my thanks to the team behind CyberDefenders.org. They accepted my submission, reviewed it, and worked with me in improving it. And also to Josh Stroschein for making Maldoc101 and being kind enough to entertain me with my questions related to making challenges.

IOLI Crackme 0x03

I am continuing my reverse engineering review by tackling the IOLI crackmes by @pof. These are beginner friendly challenges that is perfect for newbies or for those who want to review the basics like me. Check out my writeups for 0x00, 0x01, and 0x02.

Getting the password

After opening the program in IDA I immediately saw that the code is almost exactly as the one in challenge 0x02, with the exception of our expected cmp command being inside the _test function.

ioli-crackme-0x03-01

Reading through the code I realized that the password for this challenge is exactly the same as the previous one!

But what's this? The success and failure messages are all garbled? And plus, what is this other new function called _shift?

ioli-crackme-0x03-02

A different kind of challenge

Opening up the _shift function shows us a short, but interesting looking program flow with two branches and one of the branches looping back. It seems we have a loop here that we could investigate.

ioli-crackme-0x03-03

If we look at the input that the function takes we will find out that the strings that are being passed from the _test function are Lqydolg#Sdvvzrug$ and Sdvvzrug#RN$$$#=, for the failure and success messages, respectively. This tells us that a cipher is applied to these strings. What cipher it is using is what we'll be trying to find out.

Discovering the cipher

The best way to discover the cipher used is to step through the code. We can do it with both static or dynamic analysis, but the latter is way easier.

ioli-crackme-0x03-04

The code above starts with mov eax, [ebp+arg_0] which copies the pointer to the string passed to our _shift function. We then copy that pointer to [esp+98h+Str] which is the memory location pointing to the top of the current stack. This is done so that it can be passed as an argument when we do call _strlen.

After executing, _strlen returns the length of the specified string and is saved to register eax. This is then used in the line cmp [ebp+var_7C], eax.

But what is the value of var_7C? If you scroll up at the start of the subroutine, var_7C is assigned a value of zero. If you know how loops work, you'll realize that this variable is going to be used to hold a counter value. It starts at a value of 0 and it will eventually be incremented after every loop, which is what is happening at 401348.

To make it easy for us to remember this, let's rename var_7C to a more memorable name like var_counter.

ioli-crackme-0x03-05

So going back, to the comparison command cmp [ebp+var_counter], eax, which now translates to cmp 0, 17. 17 being the length of our failure string Lqydolg#Sdvvzrug$. Since this is not equal it now goes to this next block of code.

ioli-crackme-0x03-06

Now this block is interesting. There's a lot that is happening but the gist of it is that the program gets one character from the input string, with var_counter as an offset. It then decrements that character value by 3, and added to a destination string. I'll be going through the code that I described step by step in the next section.

Stepping through

So to start, lea eax, [ebp+var_78] loads the address to var_78 which in my case points to the address 28FE90.

mov edx, eax copies that address to edx so we can use it on the next line.

add edx, [ebp+var_counter] adds to the address of var_78. Because var_counter is still 0, the address remains at 28FE90.

add eax, [ebp+arg_0] does the same thing as above but this time adding to [arg_0] which contains the address 28FF10.

movzx eax, byte ptr [eax] copies the byte contained in [eax] or 28FF10. In this case that byte contains the value 4Ch or L in ASCII. This is the first letter in our failure string Lqydolg#Sdvvzrug$!

sub al, 3 then substracts 3 to 4Ch making it 49h which is ASCII for I.

mov [edx], al saves the new character to the variable var_78 which is the memory location 28FE90. At this point in time the content is currently the character I. To make it easy for us to understand the code, let's rename var_78 to var_dest. This name is apt because this will be the destination for our shifted ASCII characters.

lea eax, [ebp+var_counter] and then inc dword ptr [eax] now increments the value of var_counter, which now makes it an integer value of 1.

Looping back

Alright. Now we go back up again to loc_401320. I'm not going to step through each line again, but I will highlight the important parts now that we have looped back.

cmp [ebp+var_counter] now translates to cmp 1, 17, which is still not equal.

add edx, [ebp+var_counter] now adds 1 to our var_dest variable, turning 28FE90 to 28FE91. The address for the arg_0 variable is also added by 1 at add eax, [ebp+arg_0].

By the time movzx eax, byte ptr [eax] is executed it now gets the next character in our failure string which is 71h or the letter q.

sub al, 3 converts are letter q to the letter n. And is once again saved to our var_dest variable with the command mov [edx], al.

Repeat until...

If I haven't lost you, then you should now be able to follow what will happen in the next steps:

var_counter will get incremented again and again, which will point to the next characters in the string. For example, the next characters: y then d then o will get shifted to v then a then l, respectively. This shifting of each characters will continue until cmp [ebp+var_counter equates to cmp 17, 17.

By the end, var_dest now contains the newly shifted string Invalid Password!. Finally! Applying the same code above to the success message, the garbled message would end with Password OK!!! :).

Wasn't that fun?

On to the next challenge

I hope I was able to explain properly the simple shifting algorithm used by the program above. I did it this way mostly for my own benefit and to make sure I really did understand how the algorithm worked in assembly. In future writeups I'll refrain from stepping through code at such a granular level, unless there is something really important that warrants it. Or maybe a video would be a much better format for these kinds of challenges?

Anyway, I look forward to the next challenge. Hopefully, you are too!