Honey Accounts

I recently saw a tweet mentioning the use of an AD account with the password in the description attribute and logon hours set to none. I can’t find that tweet anymore so I apologize for the lack of attribution.

The idea is that when someone does breach your network perimeter, some of the first steps in performing recon is collecting information from Active Directory. In this recon, they stumble on a DA account called ‘helpdeskDA’. They even discover a password in the description! Well this looks like an easy win and a critical finding. In order to figure out how to leverage this new found user, the attacker attempts to RDP or use psexec to move to a higher value target. In doing so, AD checks the credentials and returns to the attacker that his newfound account is not allowed to login during this time. Meanwhile, this login attempt has triggered an alert and is being investigated.

I personally love security tools that aren’t just blinky lights and can run natively on devices we already possess. I took a stab at setting this up in my test environment

Setting up the AD Account:

  1. Create your new account in AD Users and Groups and add to the Domain Administrators group.
  2. Set the user description to something believable or just set the password in there and let the attacker make their own assumptions.

  1. Go to the Account tab and select Logon Hours…
  2. Set Logon Denied to 24×7

Q:\Restricted\SECURITY\Application Security Analyst\HoneyAccounts\AD\login.png

Group Policy:

There are a couple Group Policy options that need to be enabled in order for this to work. Depending on your organization, these are already configured.

  1. Edit the Default Domain Policy.

  1. Navigate to: Computer Configuration -> Policies -> Windows Settings -> Security Settings -> Advanced Audit Policy Configuration -> Audit Policies -> Account Logon -> Audit Kerberos Authentication Services and set to audit Failure events.

Q:\Restricted\SECURITY\Application Security Analyst\HoneyAccounts\GP\gp_config1.png

Don’t forget to update group policy on the client by running: gpupdate /force

Event Viewer:

Here is an example of what the event now looks like in Event Viewer.

Q:\Restricted\SECURITY\Application Security Analyst\HoneyAccounts\EventViewer\eventLog.png

And here is the XML view with more details, this is important for writing our event trigger in Task Scheduler. Note the event ID. A normal failed login is event ID 4625. However, since this won’t be a traditional failed login due to the login hours, it falls under 4768 which indicates that the Kerberos authentication ticket was requested and failed due to various reasons, in this case the logon hours.

Q:\Restricted\SECURITY\Application Security Analyst\HoneyAccounts\EventViewer\eventDetails.png

Task Scheduler:

Configuring the task scheduler took a bit of time. This is due to the way the event was logged. Since it is not the traditional 4625 failed login event, the event trigger based on User did not work. I had to write a custom XML trigger rule to catch the username in this context.

  1. Open Task Scheduler and create a new task. Name it whatever you like and make sure to select ‘Run whether user is logged on or not’.

Q:\Restricted\SECURITY\Application Security Analyst\HoneyAccounts\TaskSched\step1_CreateTask.png

  1. Move to the trigger tab and edit trigger.

Q:\Restricted\SECURITY\Application Security Analyst\HoneyAccounts\TaskSched\step2_NewTrigger-Custom.png

  1. Select New Event Filter and select the XML tab. Check Edit query manually. Modify the following query to fit your user and domain. Since we don’t know what username format the attacker will use, we need some OR statements in there to cover our bases. Typically, we could use the SID but in Event 4678, it is not logged. You can also add granularity and only log on certain events but in this case, I thought it best to alert on any account activity.

Q:\Restricted\SECURITY\Application Security Analyst\HoneyAccounts\TaskSched\step3_EventCustomFilter.png

  1. You should be able to save that and move to the Action tab. You can do whatever sort of event here that you like. I chose a powershell script that alerts various people and provides details about the event.

Q:\Restricted\SECURITY\Application Security Analyst\HoneyAccounts\TaskSched\step4_actionEmail.png

  1. Select Start the task only if computer is on AC power.

Q:\Restricted\SECURITY\Application Security Analyst\HoneyAccounts\TaskSched\step5_conditionsTask.png

Powershell Script:

function sendMail{

Write-Host "Sending Email"

#SMTP server name

$smtpServer = "smtpserver"

#Creating a Mail object

$msg = new-object Net.Mail.MailMessage

#Creating SMTP server object

$smtp = new-object Net.Mail.SmtpClient($smtpServer)

$file = "C:\users\Administrator\Desktop\alert.txt"

$att = new-object Net.Mail.Attachment($file)

#Email structure

$msg.From = "[email protected]"

$msg.ReplyTo = "[email protected]"

$msg.To.Add("securit[email protected]")

$msg.To.Add("[email protected]")

$msg.subject = "ALERT:Honey Account"

$msg.body = "Honey Account Activity Detected"

$msg.Attachments.Add($att)

#Sending email

$smtp.Send($msg)

 


}

function collectDetails{

 $attachment= Get-WinEvent -LogName "Security" -FilterXPath "*[EventData[(Data='[email protected]' or Data='ws_admin' or Data='SECURITY-DC\ws_admin')]]" | Format-List -Property * | Out-File C:\users\Administrator\Desktop\alert.txt

}

#Calling function

collectDetails

sendMail

HTTP Security Headers

HTTP security headers seem to be findings on nearly every assessment I have been doing lately. I decided to come up with some handy quick references for these headers in order to better understand them. HTTP Response headers are a way for a server and client to exchange information. In this case, these headers are enforced to ensure that the client is protected from common client side vulnerabilities.

Content-Security-Policy

Content-Security-Policy – CSP is a HTTP security header that allows the web application to specify the source for any file that must be loaded from a separate domain. Its main use is to prevent cross-site scripting (XSS) and other injection techniques that load malicious data from an external source. An example of a CSP that restricts the source for all scripts, images and fonts would look like this:

Content-Security-Policy: default-src 'self'

If you were to add sources for other script, you could simply append the trusted domain. It even accepts wildcards for specifying subdomains.

Content-Security-Policy: default-src 'self' *.jordanpotti.com

You can get more granular and specify image-src, media-src, child-src and a host of other restrictions. You can also use report-uri in order to POST reports of policy failures to a URI of your choice. Here is an example of that:

Content-Security-Policy: default-src 'self' *.google.com ; report-uri https://errorcollector.jordanpotti.com/collection.php

Reporting these violations could give your developers diagnostic information as well as possibly alert you to a vulnerability or attempt to exploit a vulnerability.

Perhaps the most beneficial feature is CSP’s ability to prohibit inline JavaScript from executing. This prevents malicious code from being inserted into the page, the downside is that you now have to migrate all of you JavaScript to External Resources. Using External Resources is best practice so doing this increases your security as well as code cleanliness.

For more information on CSP, visit: https://content-security-policy.com/

Subresource Integrity:

Subresource Integrity – SRI is similar to CSP as it applies a layer of security to the scripts and other external data sources your application may use. SRI works by verifying the hash of an external data source before attempting to use it. This works by taking the hash of the external data and placing it in an ‘integrity’ attribute inside a <script> or <link> element. If the external data source inside that element do not match the provided integrity hash value, the resource is not loaded.

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

You can also use Content-Security-Policy to require that all scripts run have Subresource Integrity set in order to run. Applying this to our last CSP policy, it would look like this:

Content-Security-Policy: default-src 'self' *.google.com ; report-uri https://errorcollector.jordanpotti.com/collection.php ; require-sri-for script;

For more information on SRI, visit: https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity

CroSs Origin Resource Sharing

CORS is a way for applications to access resources not stored locally. CORS aims at scaling back the restrictions of the same-origin policy in order to allow the legitimate sharing of web resources.  In the above sample for SRI, we used crossorigin=”anonymous”, this specifies that this resource can be accessed without providing credentials.

The most basic CORS request are simple, they consist of the request to the resources from the client, and a response stating the resource it is requesting, the typical headers as well as a Origin header. The Origin header is similar to the Referrer header except that is has less information. For example, the Referrer header states the entire path and the Origin header only states the server name. When the server receives the CORS request, it verifies if the Origin is allowed. If it is allowed, Access-Control-Allow-Origin is set as a response header.

Access-Control-Allow-Origin: https://jordanpotti.com

When the browser receives the response, it verifies that server name sent back the browser in the new header matches the site the browser is visiting. Access-Control-Allow-Credentials also allows the passing of credentials through these requests in order to access to protected content. Some sites allow all by specifying a wild card ‘*’ for allowed Origins. This is a very dangerous practice and can open the door to a multitude of attacks.

To read more on the security of CORS, read this: http://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html

For more information on CORS, visit: https://www.w3.org/TR/cors/

X-Frame-Options:

X-Frame-Options has a very specific purpose. It is used to prevent malicious iframe’s from loading on a site. In regards to other HTTP headers, it is fairly simple with only three directives. DENY, SAMEORIGIN, an ALLOW-FROM ‘domain’. This is to enforce the source of <iframe>, <frame> and <object>. The most common I have seen is SAMEORIGIN which enforces the source to come from the sites own domain.

X-Frame-Options: SAMEORIGIN or X-Frame-Options: ALLOW-FROM https://jordanpotti.com

For more information on X-Frame-Options, visit: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options

X-XSS-Protection:

X-XSS-Protections is similar to X-Frame-Options in that it has a narrower scope than some other security headers. It has the ability to report violations, block a page from rendering is it detects a XSS attack as well as the ability to report only and not block. It has two main directives; 0 and 1. 0 disables XSS filtering and 1 enables it. If set to 1 with no other options, the browser will sanitize the page by removing the detected XSS portions. Adding mode=block will prevent the page from loading at all if XSS is detected.

X-XSS-Protection: 1; mode=block

For more information on X-XSS-Protection, visit: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection

X-Content-Type:

X-Content-Type is a HTTP header that tells the server not to overwrite the response content-type. If the server specifies content as non-executable such as text/html, the browser will render it that way. It only has one option making it very easy to setup.

X-Content-Type-Options: nosniff

For more information on X-Content-Type-Options, visit: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options

HTTP Strict-Transport-Security

HSTS is a way for a server to tell the browser to always upgrade a connection to HTTPS. If set, any pages on that domain that only work over HTTP will no longer work.

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

This specifies how long the browser should respect this header, it covers all sub-domains, and it also is eligible for being added to a browsers HSTS list. This will enforce HTTPS on your site even after the HSTS header is removed.

Visit: https://hstspreload.org/ to add your site to the HSTS hard-coded list.

For more information on HSTS, visit: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security

 

To view how your site rates, check: https://securityheaders.io/ . Scott Helme also has a pretty informative post on these headers as well so go check that out to learn more.

 

 

How I Gained Access to Nearly Half A Million College Transcripts

Last year I spent some time digging into bug bounty programs. Since I was quite new to the scene, I spent most of my time just figuring out how a lot of the tools worked, as well as figuring out a good process that worked for me. I spent loads of time in the Web Application Hackers Handbook and tried to figure out what looked normal, and what didn’t look normal.

My first bug however wasn’t from a bug bounty. It was on a massive university system. This system has collectively approximately 500,000 enrolled students at this time.

Now I do not recommend going bug hunting on a system that isn’t part of a bounty program or one that you do not have explicit authorization to do so.

I came across this bug sort of by accident. While I was checking my academic record, or my transcript, I noticed something strange. The URL had two suspicious parameters that seemed to be sequential and pre-fixed with the current days date. One was jobQSeqNo and the other was job_id. Out of curiosity, I tried to open the link in an incognito window, which stripped my cookies from the request. I still could see my transcript..

That seemed strange since the URL did not provide any sense of obscurity. Using Burp Intruder, I cycled the numbers in the two identified parameters and started seeing hundreds and hundreds of transcripts. It turns out there was no authentication checked on the page as well as easily guessable URL parameters. I immediately contacted the security team for the system and they responded and resolved the vulnerability quite quickly. Luckily they did not sue me and my transcripts are safe now. Win, Win. They were even okay with disclosing, which was quite surprising, so kudos to them.

Some of the information gleaned from someone’s transcript includes:

  • Student ID Number
  • Student Name
  • Degree
  • Courses Taken
  • Grades for Each Course
  • Total GPA

This information is protected by FERPA, in fact, at the bottom of each report, there was a FERPA statement.

Overall, there aren’t many technical details to include. It really consisted of some curiosity, Burp Intruder, and a list of 1000 sequential numbers.

Here are the Intruder results showing quite a few results: