Back to Top

Sunday, December 31, 2006

Perl and Windows

0 comments

Perl is a nice scripting language, but originally it wasn't designed for the Win32 OS. There have been many improvements over time however (the greatest of them all being ActivePerl with PPM, which - as opposed to CPAN - doesn't require you to have all those command line tools which you have on 99.9* on the *NIX systems, but you can only get it on Windows by installing several programs). Here are a few pointers for you if you are trying to make it work on Windows:

There is a dedicated subdomain on perl.org to the Win32 issues

Many Windows specific functions / methods do not set the $! or $^E variable correctly in case of errors, making debugging harder. In this case you can use the following construct:

use Win32::API;

...
warn (Win32::FormatMessage(Win32::GetLastError())) if (Win32::GetLastError());
Just remember to call this as soon as possible after the error, because other API calls may reset the value returned to 0 (which means no error).

If you are using ActivePerl, you should install alternative package sources. A great list can be found on the win32.perl.org wiki.

If you find modules on CPAN which are not present in the PPM repositories, you can try downloading the ZIP containing them and copying the directory structure manually to your Perl installation directory (of course you shouldn't just copy all the files, but try to figure out which file goes where - this process is made easier that the ZIP / TAR.GZ file itself has a tree structure which is similar to the target tree structure). Many times this is all that it required to install a module. If you need a free solution to extract the files, try IZArc (now also with command line).

And one final tip: if you created a multi-threaded script with the threads module and it keeps crashing on you, make sure that all your accesses to shared variables are synchronized with lock. Because there is no explicit unlock command, you can use the fact that lock is block scoped and write the code as follows:

... not  synchronized code ...
{
  lock($shared_variable);
  ... synchronized code ...
}
... not  synchronized code ...

Saturday, December 30, 2006

I love the web

0 comments

A few months, 131 posts and I'm already getting very useful feedback. I would like to dedicate this post to all of my readers. Thank you all. Here are two very useful links which I got from my readers:

From Anonymous comes: The Trouble With EM ’n EN (and Other Shady Characters). If you think what you are doing when typing a text in English, just read this. After reading through it I'm afraid to type one more sentence. It's incredible how many slight variation there are to type-press level of writing!

From stelt comes a tip related to adding SVG support to OpenOffice. Go the his collection of great links related to SVG or jump directly to the description. I did not try this because I don't need to make any presentations (in fact I just did one, but I used S5 for that), but it looks really promising.

And I also got my first passionate negative comment. That is good. Be passionate. Fight for what you believe in. I support freedom of speech and I won't censor the contents of this blog for other purposes than spam prevention.

However, I want to remind you that this blog is to generate quality, useful information. Whatever I write is meant to be useful and correct information. I'm not correct all the time, nor do I claim to be. If you have a different opinion about the things I post, feel free to give your counter arguments. I will respond to them to the best of my knowledge. However before you submit your post, please think about the following: will it be useful to somebody? Posting a correction or counter argument to something I wrote probably will. Posting insults probably won't since I have a pretty thick skin (even more so when I'm convinced that I'm right and you didn't give me any reason to think otherwise).

If I don't post anything until tomorrow: Happy Newyear!

Two more things...

0 comments

before I get to bed:

Burrrn works great if you want to write FLAC files to an audio CD

MediaCoder tries to connect to Sourceforge at every startup (presumably to check for updates). However it didn't ask me once if I wanted to do that :(.

Open source debugging

0 comments

While trying to re-encode some podcasts (to have smaller file size), I learned the following lessons:

  • MediaCoder looked very, very professional and I wanted to try it out for a long time. However, it freaked out over my MP3 file and crashed the included MPlayer. No problem I thought, I downloaded the latest Windows build of Mplayer from the main website and replaced the files. Now the encoding errors out on the files with no details about what went wrong. I tried to fiddle with the settings but no success. Maybe it only encodes / transcodes video files?
  • I suspected that the problem was that then included Mplayer version was compiled without runtime CPU detection, but I just checked and the machine I'm on supports all the required instruction sets (MMX and SSE)
  • The user interface is cryptic from time to time with to apparent information source about what some controls mean. For example I assume that the Algorithm Quality slider on the LAME page is equivalent to the -q switch for the command line.
  • My preferred audio player does not have output plugins which encode audio on the fly
  • Winamp doesn't have an output plugin to encode to OGG directly (although it has one for MP3)
  • Re-encoding low quality files produces really bad results, so I gave up on it

And finally:

  • The Sourceforge site has a bug, which can lead you to incorrect links when downloading files whose names contain special characters (like gcc-g++-3.4.5-20060117-1.tar.gz for example). The bug occurs if for whatever reason you don't download the file from the first mirror it offers you and you select an other one. During the redirection it fails to correctly URLEncode the file name, but it tries to decode at the other end, resulting in the link pointing to gcc-g -3.4.5-20060117-1.tar.gz - because + stands for space in URLEncoding. To resolve this, you can either use the back button of your browser to go back to the file list page and click again on the file (your mirror preferences are remembered in a cookie) or look at the direct link and replace the erroneously encoded characters with the right ones. You can use The URLEncode and URLDecode Page to help you with this. In my case this would be gcc-g%2B%2B-3.4.5-20060117-1.tar.gz . They have been notified.

Friday, December 29, 2006

What I learned about Perl today

0 comments

When you start using a new programming language for quite some time you will regularly find new things in it. Some will make you think I wish I knew this yesterday and some will seem interesting. So here is something I learned about Perl today:

If your recursion level exceeds 100 (meaning that you call yourself a 100 times from a subroutine without calling any other subroutine) and you have the use warnings; pragma set (which you should, it's good practice!), you will get a warning. This is very much inline with the main target of Perl (command line automation where you usually wouldn't find any deep recursion). If it bothers you, include the line no 'recursion';. For more details, see the manual page.

BTW, just so that you don't get the impression that I'm a total language zealot, here is a link to What's wrong with Perl ;). While I agree with it on most points, the fact that I can write shorter code seems a very big advantage to me (because I don't have to remember what method of the regular expression object to call, I just write =~ //). Also, to my big surprise, Python is around 10% solver when parsing text files. This seemed incredible to me (since I assumed that when parsing big - 100+ MB - text files the chocking point would be the harddisk), but after doing several tests I have to accept this.

Two spaces

2 comments

Not being a native English speaker myself there are many parts of the culture I don't know about. Like the fact that at some time putting two spaces after sentences was usual. From what I gather however this isn't the case any more since people have failed to show the (supposed) advantage in accessibility. Here are some links:

Somebody supporting the idea

A blog post about it

The obligatory Wikipedia reference :)

The Chicago Manual of Style's opinion

Even more links

0 comments

Have you've had enough yet? :D

Recently I found out about Soushin, an free solution which tries to help you secure your PHP installation (similarly to mod_security - meaning that it doesn't require you to modify the source code of your applications). It seems that a new feature which is currently in beta test is the detection of SQL injections. My opinion about this: as a PHP developer I fought for years to make my applications secure. In a recent project I adopted PEAR::DB as the abstraction layer (with a MySQL backend). Imagine my surprise when it turned out that the so called compiled queries were in fact strings in which it verbatimely included the parameters I gave them. While in Perl it is hard not to do real precompiled queries. So IMHO, at least in this segment - database access, Perl is clearly superior to PHP.

There is a very insightful writeup about the recent advertising tactics of Google over at Blake Ross's blog.

A very nice quote from Susan Jacoby:

When politicians start citing God as the authority for whatever they want to do, they are usually promoting some policy that defies human reason.

Via Slashdot I came across CERTStation. Whoever designed it had no intention for it whatsoever to be usable. Just to much useless movement and animation (other have the same opinion). For a nice relaxing graphic, see the DShield statistic below:

Something similar to DShield: Shadowserver (similar because it too handles large scale security events and it's too decentralized

Via Lifehacker: a free utility for Windows virtual desktops

If your computer CMOS battery is gone, you can use AboutTime to synchronize it if you have Internet access. I personally used the Windows port of the official NTP client. It is a bit harder to configure, but at the time I didn't know about AboutTime. You can find a list of public NTP servers (meaning that not only are these servers publicly accessible, but they were intended to be) here. Be sure to make the first server the one closest to your geographic location and use others as fallback. For example in my case I use them as follows: ro.pool.ntp.org, europe.pool.ntp.org, pool.ntp.org

Hack the Gibson - Episode #72

5 comments

Read the reason for these posts. Read Steve Gibson's response.

The first thing I want to mention is that the constant marketing push for SpinRite makes me curious. I have no way to try it (because Steve doesn't make a demo version publicly available), but after reading a book Kurt (a very well known company that specializes in data recovery since 1989) I have the distinct feeling that running SpinRite on a damaged disk can be very dangerous. I read several stories in their book (which admittedly is also a marketing material) where well meaning individuals ran utilities on dead hard drives which instead of repairing them completely and definitely erased all data from it. To make the example more concrete: let's say that your drive has physical problems (some particles got in through the air filter). Stressing it will result in those particles scratching a wider area of the disk than if you would have sent it off to a specialized data recovery service. And the money back guarantee for the program won't do you much good either: You just lost data valuing 10 000 USD, but you can get back the price of the program (50 USD)? How does that sound? (the prices are fictional and are for illustrative purposes only).

The answer for the mail question was a bit confusing in my opinion. To understand it completely, you must first know how e-mail travels. Below is a small illustration put together with Gliffy:

The high level description of the process is

  1. The sender composes the message
  2. The sender sends the message to her/his ISPs SMTP server with the mention to forward it to the recipients mail server.
  3. The senders SMTP server connects to the recipients mail server and forwards the mail
  4. The recipients mail server puts it in the corresponding inbox, from where the recipient can later retrieve it.

Now for the things I want to clarify: usually (in 99.9% of the cases) the sender and the recipients mail server never talk directly. Only the two mail servers do. If a client machine tries to connect to an SMTP server, it can mean:

  • He's connecting to his ISPs SMTP server, which is ok
  • He is trying to send a forged e-mail
  • He doesn't have access to a SMTP server and wants to send mail direcly

As you can see, if you (the ISP) filter the outgoing SMTP connections (other than to your mail server), you get rid of a large percentage of the problem caused by users or infected machines from your network sending out spam or other unwanted emails. The only disadvantage (also mentioned by Steve) is that if a user wants to use a mail server other than the ISPs, s/he can't. But this affects a very small percentage of the users. To stress my points again:

  • Clients almost never connect to the destination mail server
  • Because of this, you don't need to worry that you need to register each client with SPF. You only have to register you mail server('s)
  • If you are on the road, you again connect to your ISPs mail server to send and retrieve mail, so the fact that you have a different IP doesn't change anything (if your ISP allows connections to the mail server from outside and if the network you are currently on doesn't filter SMTP traffic)

Regading the question With the TOR network, can’t the various routers know who sent them the onion package? In other words, wouldn’t it be possible to use such a record to backtrack the packets’ paths and find out where they were originated?, in my opinion Steve didn't understand the question. My answer (which IMHO is clearer) would be:

In the network you have three kind of nodes (from the users point of view): entry nodes (which you use to connect to the TOR network - the first nodes in your chain), intermediate nodes and exit nodes. Each of these nodes have partial information about you: the entry node knows who you are, the intermediate node knows a portion of the path (where it is receiving information from and where it must forward to) and the exit node knows what the requested information is. The strength of the network is that this knowledge is distributed. If somebody would control all the hosts in your path, then your anonymity would be compromised. The idea is that there are many TOR servers to choose from and you are choosing and if the attacker doesn't control event one server in your path, he will get only partial information.

Regarding the TOR as VPN solution question: first, I found no option in the TOR manual which would specify the number of hosts the traffic should be routed through. Being open source, you can of course hack the source but this isn't possible for everybody. Second, VPN is not a security technology! By using TOR, you would lose the real advantage of the VPN: to get geographically distant hosts on the same (virtual) network. And two more things: DNS usually uses UDP, but it can use TCP also! And secondly: the SOCKS proxy is only on your local computer (between the client application and the TOR client). The traffic between you and the entry node is also encrypted.

Wednesday, December 27, 2006

Perl contest

0 comments

I'm not a Perl guru (although I consider myself a medium level wizard :)), and this last contest shows it. My entry for it was 4.6258 times longer than the shortest one submitted. :(. Some tips (maybe you can do better than me):

  • Wrapping your head around Roman Numerals is hard. I suggest that in addition to the Wolfram research page, you also read this very useful page about the subject (found it through Wikipedia)
  • The Perl::Squish module won't do you any good. It may work for usual modules, but for my code it didn't reduce it even by 1 byte. If you still want to use it, the code needed to run it is:
    use Perl::Squish;
    $s = Perl::Squish->new();
    $s->file 'infile.pl', 'outfile.pl';
    

And even more links

0 comments

Check out the 2006 Vaporware awards

We have also two contests:

One that has ended, and the winner actually produced a 210 bytes executable file which downloads and executes a file from an encrypted (XOR-ed) URL. See also the previous entries at the SecuriTeam blog (look for Tiny PE). And if you are into such things, check out the Code-Crunchers mailing list

Perl Golf - to quote from the website: Perl Golf is a competition to find the shortest (fewest keystrokes) Perl code to solve a given problem

The 23rd Chaos Communication Congress is running now. I eagerly await the videos. In the meantime, check out the videos for the last conference.

Don't be stupid

0 comments

Or alternatively: how to collect malware samples from the file sharing networks:

  1. Be sure that you know what you are doing! These are real, dangerous files (mostly Adware and Spyware).
  2. Get yourself a decent, open source, spyware, adware free multi network client (if you are on Windows)
  3. Search for anything. Be sure to select Any file type
  4. Look for results which are small (less than 500 KB usually) and are executable or archive (which usually contains an executable). Sometime you will also find results which are obviously not related to anything you searched for (like K Lite Gold - Brand New P2P Program Promote this new P2P program, the next big thing 75% for you.zip) or very short movies
  5. Take care! If you do happen to download these files, be sure to submit them to Virustotal, which distributes the samples to the AV companies so that they can update their engines.

Funny quote

0 comments
The internet: Where men are men, women are men, and teenage girls are undercover FBI agents.

Found it over at tssci security

Tuesday, December 26, 2006

More links

0 comments

Zone-H got defaced!. Read the article for an in-depth analysis.

America is in debt bigtime

Pamela-Systems - is it just me or does this name remind others too of the other Pamela (the NSFW one)?

Sunday, December 24, 2006

A mixed bag of comments - part 2

0 comments

Saturday, December 23, 2006

Hack the Gibson - Episode #71

2 comments

Read the reason for these posts. Read Steve Gibson's response.

Hello all! Here is the latest of my rants / commentary series regarding the Security Now! podcast. This podcast is dedicated to discussing a vaporware security freeware: SecurAble. This isn't more than a glorified CPU identification utility, similar but (based on the description) much more limited than many free ones, not to mention commercial ones. There is even at least one open source program out there with the same purpose.

What features does it supposedly have?

  • Detecting the manufacturer of the CPU
  • Detecting if it is a 64-bit (also callde x64) capable CPU
  • Detecting if it has the NX-bit (so that you can have hardware assisted DEP in Windows)
  • Detecting the presence of the NX bit, even if it was disabled in the BIOS
  • Probably a nice little story wrapped around all of these

The first three can be accomplished by the following short program written in FreePascal (if you want to use Turbo Delphi to compile it, make sure to remove the Crt unit, disable optimization and mark it as a console application, because otherwise it generates an erroneous code):

A little more than a hundred lines. Steve Gibson also likes to play the size game. Wherever possible he likes to mention that he writes his programs in assembly to make them as fast and as small as possible. However assembly is more a religion today than an useful tool. The proof is that I've written the above program in one afternoon while he works on his version for at least three weeks now. Also, he mentioned a file size of 24 KB on the show (without the digital signature). The above program, compiled with Turbo Delphi, is 21 405 bytes. No assembly, no magic. Steve also likes to pack his programs with UPX. But this is not enough for him, he also uses some modified version of UPX to hide this fact. Packing is not a protection tool and is mostly useless. But to even the field, since most probably he refers to the size of the packed executable, my executable packed is 11 KB. Of course I don't include stories with my programs, because I write them on my blog.

The last point is the only interesting one. I'll get a little technical here, so I apologize for the non-geeky readers: as Steve stated the only sanctioned way to accomplish this is to write a driver, because the information resides in a MSR register and the instructions required to read them are privileged ones. There are undocumented functions to read them from user mode (see here and here on OpenRCE.org), but they were eliminated starting from Windows 2003 SP1 (as was \Device\PhysicalMemory). From what I gather, this information is available only for Intel processors (maybe AMD doesn't offer the possibility to disable it from the BIOS). For more (technical) information check out the AMD and the Intel documentation (both are hard to find) and some third party info.

I await eagerly the release version of this tool to poke around with it and write about it.

I know what you did last page!

0 comments

With the hype around AJAX many people jumped on the Javascript bandwagon and assumed that everything should be done client side (even encryption) and even when perfectly suitable server side solutions exists, people insist on using Javascript. (Just a quick note: I realize that many times a well written client side script can (a) hide the network latency and (b) reduce the server load, however it is recommended that you use progressive enhancement to ensure that your site is accessible by as many people as possible using different devices / technologies).

The newest craze is widgets. Most of the time they advertise their services like just put this one line in your web page and you can X where that one line is usually a script tag. Their advertisement is entirely correct: they can do X to your page (whatever X may be), but they can do many more:

  • Steal cookies from your visitors (including session id)
  • Execute a session fixation attack
  • Execute a phising attack
  • Execute actions on their behalf
  • Steal passwords (with a technique recently discovered)
  • And generally act as part of your website

The most dangerous thing is to include a third party script in pages which will be viewed by authenticated user (think forums, discussion boards). Also, keep in mind that this can be done either by the site owner or by a third party user (as part of a signature or profile information for example). Admittedly the later is less likely because most of the forum software guard against this, but the the former is former is very, very frequent. Do you use Google Analytics / Sitemeter? Do you add Digg / Reddit buttons to your site? Then you have included third party javascript in your site. (Just to clarify: I do not say that any of the examples mentioned in this post have malicious intent, I just use them to demonstrate how widespread the phenomenon of including third party javascript is)

An other thing to keep in mind that these attacks can be very targeted which makes their discovery and analysis more difficult. The site serving up the javascript may choose to serve up a malicious version only to certain pages (based on the referrer information), only to certain IP ranges or only at random intervals. The fact that you, the site owner, looked through the script when including it doesn't guarantee anything.

I have put together a little demonstration to show the interested a glimpse of the information an attacker may gather this way. Install the following bookmarklet IKWYDLP (by dragging it to your bookmarks toolbar if you are using Firefox or right clicking on it and selecting Add to favorites if you're using Internet explorer - you may need to accept a security warning). Then navigate to any site and click on the button. It will include a javascript hosted on my Google Pages account in the page either directly or with an IFRAME (more on this soon). The nicely formatted version of the source code can be seen below:

Go to some pages and click the bookmarklet to see what an attacker could find out about you. No information is relayed back to me and because Google Pages does not support server side scripting, you can be assured that every time the same javascript is served up. Also, this javascript does basic information gathering for demonstration purposes and doesn't include the advanced techniques described earlier.

Possible protection

How can you protect yourself? First lets take the case of a site owner, because s/he can take the biggest preventory step: include your third party script in a web page, host that web page on a third party service (a very good one IMHO is Google Pages because it has a very good uptime and it doesn't force you to include extra content (like ads) and then include it in your page using an IFRAME. This works because browsers treat domains as security boundaries. Because the content of the IFRAME is hosted on a different domain, it can't interact with the rest of the page. Also, because of this it isn't good enough to create a HTML page on your site, put the script in it and then include it using an IFRAME, because they will still be in the same security zone (from the browsers point of view) and the javascript code can crawl out and access other documents from the same domain. A last note: there are scripts which from a technical point of view absolutely require to be embedded directly on the page. One of them is the Google Analytics script. If you would to use the IFRAME approach presented earlier, it will basically tell that every visitor you had visited a single page. I would also make referrer information useless. In these cases you have to make a decision about the trustfulness of the company. An other interesting example is Widgetbox. In their case you have to include the javascript code directly if you wish to use some of the extra features, however they make sure that each widget is put in an IFRAME for you (so that you only have to trust them, not each individual widget publisher). Good to see that they think about security.

What can you do if you are the publisher of widgets? The easiest migration path is to place them in a IFRAME and give your users the code to include the IFRAME instead of a script file. You will loose some possibilities (like to manipulate the elements directly on the page), however 95% of the things out there don't need that. The more problematic thing is that you loose the ability to automatically resize your content. This can be partially mitigated by giving the user the ability to customize the generated IFRAME code by specifying width and height. Then again this raises problems with the zoom features present in the browsers. An alternative way (practiced partially by Feedburner for example) is to give you the code which serves up images. They can even be animated (if you use GIFs). It is a little harder to migrate to this solution, but it has the benefit or a larger potential audience (because while most forums disallow HTML or scripting in the signature, they do allow for images).

Finally, if you are a simple user, you can use the NoScript extension if you're using Firefox or disable scripting for your Internet zone and add sites you trust manually in the trusted zone if you are using Internet Explorer. Neither solution is perfect, although the NoScript extension is definitely easier to use than zones in Internet Explorer, it's not alway clear what domains you should enable to get the site functional. Also it seems to slow down the browser.

In conclusion: know the risk of including third party javascript on your site. I do have such javascript (from Google Analytics, some from my Google Page account because I don't want to fill my templates with Javascript and from Digg), but I have weight the benefits and the risks and decided that it's worth it. You should do the same.

Friday, December 22, 2006

A mixed bag of comments

3 comments

A short post of things I found in my Google Reader:

Thursday, December 21, 2006

I'm not a 'lone bitter old man :)

0 comments

You might remember this post, where I was criticizing the so called vulnerability in Internet Explorer 7. Alex Eckelberry over at the SunbeltBLOG just came out with a post saying the exact same thing. While I don't agree with many of his previous posts (like those about HIPSs and Patchguard), this one is spot on.

Tuesday, December 19, 2006

What you don't need javascript for - part 2

3 comments

Read part 1 of my rant

There is a saying in Hungarian: Don't look at the teeth of a horse you received as a gift. It refers to the fact that you shouldn't criticize something if you get it for free. However from time to time I feel the need to raise my voice about things which could be better done. Example:

Via Global Nerdy I found a site called JS-Kit which allows you to add dynamic functionality to your own site. After doing a little googling, I found out that supposedly it was created by a Cisco Security Engineer. My comments are: is this the Cisco trust us, we know what's best for you mentality or is this guy just inexperienced in the area of web security? Does he really think that I will include a script from his site that will run in the context of my page? And because the script is on his server, he can change it any time or even do sneaky things like only serve up the modified version when a referrer from my site is detected! An example of somebody getting it (partially) right is Widgetboy. You have to trust their javascript code, but after that they host every widget in an iframe, so that it can't interact with your site.

My other problem is: why do you need javascript to submit a comment? Bulletin boards existed for ages without javascript! What about disabled users who use screen readers?

Here is the way it should be implemented IMHO:

  • The user should insert a single line of HTML in the page: <a href="http://js-kit.com/comment?[page url]>Comment on this<a>, the page url being optional (although recommended, see below)
  • When the user clicks on this link, s/he is redirected to the js-kit website, where a script takes the referrer url (which is activated in 99.9% of the browsers) to find out the page the comment should be placed on. If no referred url is available, it can fall back to the url passed as parameter. If none of these two is available, it gives an error message and terminates.
  • Now it redirects to a page which is divided in two frames: one which displays the original site and one which display the comments. The comments page should contain a prominent close link which redirects the top frame back to the original page, eliminating the comment frame.
  • The comment area can be used to place comments. There is no need to use javascript, plain old forms can do it, however you can use the principle of progressive enhancement to add visual effects with something like script.aculo.us, however the form should be usable without javascript.

The advantages would be:

  • Gives almost the same experience
  • There is no need to trust any third party javascript (no offense)
  • It works on a wide variety of browsers (event lynx knows frames)
  • It should work on speech browsers

Sunday, December 17, 2006

Portable GUI applications

0 comments

After moving almost entirely to Ubuntu (I haven't booted Windows on my home computer for almost a month now :)), I searched for ways to create little applications which I can use at my workplace (in a mostly Windows environment). For command line scripts Perl worked out great (just a reminder to everyone, including myself: Perl has a module for everything including joining path parts in a platform dependent way, you just have to search CPAN), but I wanted to do a simple sticky-notes kind of program, so I looked around for GUI toolkits which work with Perl. Here are my findings:

  • Perl/Tk - is well supported with packages available for both Linux and Windows (including through the PPM, because CPAN can be a pain in the rear end to use on Windows). Has some good articles and presentations about it, however I couldn't find a visual designer for it (I did find this, however I never managed to get it working). Also a lesser (but still existing) problem is that the controls don't look the way native controls look on any platform.
  • wxPerl - the Wx toolkit. No Windows version of the Perl bindings (or at least not through the PPM), so this one is out.
  • Gtk2-Perl - This is the one I ended up using. While not perfect (see below the list of problems and solutions I found), it works cross platform and has a visual editor.
Installing Gtk2-Perl

Under Linux it's pretty much preinstalled if you use a Gnome based desktop (like Ubuntu does). If not, you should install the libgtk2-perl package with apt-get (or Synaptic) rather than trying to install it using CPAN. To install the interface designer, mark the glade-gnome package for installation.

Under Windows it's a little more tricky: the first step is to add the gtk2-perl PPM repository (http://gtk2-perl.sourceforge.net/win32/ppm/) to your list of PPM repositories. Now try to install the Gtk2 package. It may complain about some unresolved dependencies. Go and manually mark them for installation (usually the PPM takes care of this, but for some mysterious reason it didn't do it for me this time, so you might encounter the same problem). Make sure to install the latest version of the Gtk2 package (1.100 at the moment of writing this article). Next you will need the the Gtk2 libraries for Windows. You can get it either at the GIMP Windows installer project page or at the Glade for Windows page. One very important detail (which I found out after several days of cursing) is the fact that the latest version of the Perl libraries which is available for Windows (1.100) is incompatible with the latest version of the Gtk2 toolkit. This issue has been resolved in version 1.120, but that isn't available currently as a PPM package. So make sure that you use the 2.6 branch of the Gtk2 toolkit for Windows to avoid headaches.

There are two ways to install the Gtk2 toolkit on windows: using the installer or downloading and extracting from the archive. The first is ok if you don't have other programs which rely on the latest version of Gtk2 (like GIMP or Gaim), but probably the second method is more safe: download the installer from the Gladewin site and extract it on a test computer. Copy the files from the installation location (C:\GTK by default), then uninstall the products. Now do the following things: copy all the DLLs from the bin folder to the bin folder of your Perl installation (C:\Perl\bin by default). Copy the the etc folder to your Perl directory (e.g. to C:\Perl). Copy the lib folder to your Perl directory (which already contains a lib folder, but don't worry, there is nothing to overwrite since it should contain a single subfolder named pango). Congratulations! Now you have created a portable environment for your GUI scripts, which can be deployed with XCOPY (that is, copying the whole Perl folder to a new computer).

Some more tips

Bear in mind that I'm a beginner to, so these may contain errors or useless (or flat out wrong) advice:

  • Use Glade to create your interface and the Gtk2::GladeXML module to load the design. It will save you a lot of trial and error (under Windows you will need to download libglade and place it in either the system directory or - the way I prefer it - where the Perl executable is located - C:\Perl\bin by default)
  • Gtk2 arranges the controls itself much like Swing does and it can be confusing if you are used to the Delphi or Visual Studio designer. However once you get the hang of it, you will appreciate the fact that your form layout looks good even when the form is resized.
  • There is an extensive documentation available, however it consists mostly of property listings without any additional explanations. It can also contain properties / methods which are not available in the older version of the library you are stuck with under Windows. There are also several tutorials, the best of which in my humble opinion is the Gtk2-Perl Study Guide.
  • For some reason which is beyond me, unless you put an element in the designer in the ComboBox, the inner list representing the elements won't be created. So make sure to put an element in it and then remove it using the remove_text method with the parameter 0. This may also apply to other elements.

The fact that you write for a big site doesn't make you an expert

0 comments

The corollary of the above being: don't rephrase what the expert said if you don't understand it. Real life example from an eweek article:

The Redmond, Wash. software giant has convinced major U.S. computer makers—including Dell, Gateway and Hewlett-Packard—to make default changes at the BIOS level to allow a new Vista security feature called ASLR (Address Space Layout Randomization) to work properly.

This sounded very weird to me since you don't have to enable anything in your BIOS for ASLR to work. I soon discovered that the reporter used Michael Howard's Web Log as a source, most probably the following post:

As I mentioned in a previous series of posts, we recently had all the major OEMs on campus to discuss SDL and how we can work together. My big ask of the OEMs (actually, I grovelled, it was pathetic) was to enable DEP/NX in the BIOS by default on all their shipping PCs in time for Windows Vista.

The reason for this ask is pretty simple, for ASLR to be effective, DEP/NX must be enabled by default too.

...

While this is a little confusing, it doesn't say that ASLR must be enable from the BIOS, it says that DEP/NX must be enabled from the BIOS. I wondered why Michael Howard made the connection between the two protection strategies, so I asked him (in the comments) and basically his answer was:

ASLR and DEP/NX are two barriers (defense in depth is good!) which try to prevent exploits. DEP/NX is aimed more at stack-overflow or heap-overflow type of situations while ASLR is aimed more at return to libc type of attacks. They cross roads in two cases: when an exploit code tries to call functions via hardcoded addresses (because it doesn't have the luxury of the loader resolving the addresses for him) or when it tries to locate a JMP ESP instruction.

Know what you write about! (or at least put a disclaimer there if you don't)

Saturday, December 16, 2006

Offline updating of Windows

0 comments

When re-installing Windows, you should always do so without any network physical connection (meaning unplugged network cables) or you risk infecting yourself via various exploits (for example there is at least one virus which scans the LAN for PCs to infect). Now heise security has put together a tool to download the security updates on an other computer and transfer to a CD/DVD: Installing Windows updates without an internet connection. Disclaimer: I have never used this script.

An other thing which I didn't try out yet but look good, is the collection of security updates as as ISO images over at Microsoft.

A third solution which I did use several time is AutoPatcher. It is a very nice solution, however you should know two things: there are two kinds of AutoPatcher install kits: full install and and update install. You should always have the last available full install and the following update installs. An other thing to keep in mind is that the package contains many additional software, so you should carefully look at the list before launching the installation.

Linux command line options

0 comments

Being a Linux newbie, I'm always looking for tips and tricks related to this new OS I'm learning. Here is an article from IBM, via Slashdot:

Learn 10 good UNIX usage habits

Education

0 comments

I knew that that in Romanian schools you couldn't get decent education, but it seems more and more that that this is a general truth, independent of your country:

Undisclosed Microsoft bug

0 comments

Over at the eEye research site you can read a worrying and little confusing advisory (how can something be a local privilege escalation and a remote code execution attack at the same time?). I'm eagerly awaiting more details about this. In the mean time, don't forget to subscribe to their Zero-Day tracker.

Update: I don't know if this is the same, but SANS pointed me to this Microsoft advisory: MS06-075 - Vulnerability in Windows Could Allow Elevation of Privilege.

Update to the update: maybe it isn't the same because SANS points out that this was patched in the last round of updates and the eEye advisory refers to something unpatched.

The night of the ad eaters

0 comments

I'm getting old. I know this because last night we attended The Night of the Ad Eaters and after sleeping for 8 ours I still can barely keep my eyes open :). My impressions:

    Coca Cola is better than Pepsi (I can't understand how Pepsi can put that much money in their ads and still make them suck)

    Levis is better than Diesel (with Diesel clearly not being targeted at the western market)

    The only IT related advertisement was from Microsoft (who else) for something called WinDays 2005 (which seems to be some business oriented conference - as far as I can tell from their website, because from the ad you couldn't even get the slightest idea what this is about) and it sucked bigtime: it was long and had no clear message (other than that: look we licensed the rights to all these paintings and music).

Friday, December 15, 2006

What virtualization can and cannot do in an anti-malware context

0 comments

Over at the anti-virus rant blog (which is a nice blog because it includes the word rant in the title :)) Kurt Wismer states that virtualization is overhyped as a security technology. While I agree, I want to point out that following some simple rules, it can be a very powerful security which can easily replace a separate computer only for browsing. The rules would be:

  • Don't have writable shares on the network the virtual machine is connected to. If you want to share a directory to extract file, share it from the client OS and copy it from outside
  • If possible put it on a different subnet
  • Use non-persistent hard disks or snapshots and revert to them regularly (currently the only commercial grade product that I know of that can do this is VMWare. QEmu also has this feature, but unfortunately it still needs some time to become a stable solution)

Following these rules you get a more secure and more convenient system than using a separate PC with something like DeepFreeze, but you loose the ability to stay logged on sites (because you loose all your cookies, history and cache).

Tuesday, December 12, 2006

Random stuff

0 comments

For fun: The Opinionated Beer page: if operating systems were beers.

An interesting idea: a search engine with an unusual way to present the results. While the interface is appealing, on the long run it seems an overkill. Also the fact that the first results are advertisements with only very subtle indication of this fact is annoying. Again, in my humble opinion, this interface, while it contains some interesting ideas, is overkill because I'm not likely to spend a long time with my search results.

Monday, December 11, 2006

"not a valid win32 application"

0 comments

An interesting difference between the loader of Win9x and WinNT line (tested with Win98 and Win2K SP4): if SizeOfImage is bigger than the sum of the header sizes and section sizes, Win98 will happily load it, while Win2K will complain that it's not a valid Win32 application. The tricky part about this is that you usually get this error with corrupted files or with DLLs (if you try to execute them), but these files show no signs of damage neither with dumpbin.exe nor with IDA.

Sunday, December 10, 2006

On Delphi

0 comments

Being a long time Delphi programmer, I really enjoyed this blog posting about learning Delphi. My favorite quote:

The Delphi compiler itself is lightning fast. Sometimes I compile twice because I’m not sure I actually hit the compile key.

It is so true. The first thing I do when I install Delphi is to check the show compilation progress box. An other great Delphi blog is The Oracle at Delphi.

FiT Search Engine

2 comments

I started playing with the Google Custom Search Engine and I created a search engine for one of my favorite podcasting / blogging group: FiT. Try it out below:

Google Custom Search

Or consume it in a custom format:

Link to the Google page

Add it to your google page: Add to Google

Hope I didn't leave out any sites.

Saturday, December 09, 2006

The 14th post

0 comments

Because 13 is not a nice number :), and because the submission deadline for the two contests has passed, I thought I share with you my solutions (they are not guaranteed to be complete over correct for that matter):

The Hitch-Hacker's Guide to the Galaxy
  • How did Zay Zeutrino gather the desired data to switch users to the Vogon matter transference officer’s user account?

    When matter transfer officer viewed the spoofed message (which wasn't filtered in a proper way by the Vogon system to eliminate such threats), the script part included in the message wrote an image tag in the browser the URI of which contained all the cookies for the current page. This link was automatically followed by the browser trying to display the image. For this to work as expected, the following conditions have to been met:

    the user interface to read e-mails have to been the same as the one used to control the matter transference system (more precisely the cookies have to been set such a way that there were common for both parts of the system - they have to been on the same domain and the path of the cookie have to be set up in such a way that it was a common prefix for the URLs of both systems).

    authentication data has to been contained in the cookies. This can either be username in password (don't laugh, I've seen this used in real life :( ) in plaintext or in some naivly encrypted format (like rot13 or base64 - which isn't an encryption but some may use this way) or a session identifier.

    the session management was set up in such a way that the session wasn't tied to a given IP

  • How did Zeutrino switch users?

    He inserted the stolen cookies (or at least the ones which identified the session) in his browser (I bet that he was using Firefox 2.0 with the Add N Edit cookie extension - https://addons.mozilla.org/firefox/573/) and thus when he made the requests to the server it believed that this transaction was part of the session which was established when the matter transference officer authenticated himself.

  • What might Pal Homeran have seen in his logs?

    He might have seen several things:

    From the access logs (which are turned on by default) he might have seen an access to the matter transference management system from an IP which was outside the expected IP range

    Also from the access logs he might have seen that someone accessed the system with a different user agent than the standard one (if the Vogons were using IE 5.5 because that was the "company standard" and Zeutrino did not know this or did not spoof his user agent with the User Agent Switcher https://addons.mozilla.org/firefox/59/)

    A third possibility would be that there was a separate log (an audit trail) in the system which logged the actions taken from the interface. This is however unlikely given the poor state of the security. If such a log existed, Pal could have observed a transfer for which there was no paperwork or again which came from an unusual IP range (if such a thing was logged)

  • What should Zeutrino do next?

    He should delete the cookies, remove Firefox and wipe his hard drive. This is of course not a 100% solution because might be remnants of a Firefox installation in many places: in the registry (the registry has its own "filesystem" which in turn contains "slack space" which can't be wiped by a disk eraser utility), in the prefetch directory, in the hibernation file and so on. His best bet is if he used a Firefox from inside a virtual machine, because he can just wipe the space occupied by the virtual disk and you have all the traces erased.

    If he has a dynamic IP address, he should renew his IP address, because hopefully he gets a new one (on Windows this would be ipconfig /release, ipconfig /renew from the command line). To make things ever more hidden, he could change his MAC address by either physically swapping out the NIC (if it isn't on-board) or from software forcing an other MAC. This way it's more probable that he will get a new IP address from the DHCP server. The MAC address change should be performed while no IP is assigned. That is: ipconfig /relese, , ipconfig /renew. This way it would look like that the original terminal went off-line and a new one came online from the logs. If no MAC spoofing is performed from the logs of the DHCP server (if such a thing exists) Pal could find identify the computer even if it had a different IP address (based on the MAC address). The physical changing of the MAC address is really recommended because if it's only spoofed in software it could raise suspicion if the system would to be examined closer and this fact would be discovered.

    If his IP is static, he should try to assign himself either an unoccupied IP from the given subnet, or if he wants to incriminate someone, swap the IP of his terminal with the one of somebody else's terminal.

  • What should Pal Homeran do next?

    Based on the log he probably has the IP address of Zeutrinos computer. If Zeutrino isn't quick in performing the above mentioned changes, he can track down Zeutrinos computer directly. If Zeutrino did implement the countermeasures he could at least narrow down the search to the segment which is served by the DHCP from which the IP originated. Then he could either inspect each computer manually or if Zeutrino didn't change his MAC address, just his IP address, he could look in the DHCP log for the following type of entries:

    <Offending IP> was leased to MAC address <X>
    <Offending IP> released the lease
    <New IP> was leased to MAC address <X>
    

    and identify the IP he should be looking for.

    Assuming that all IP addresses are statically assigned, he can narrow it down to one subnet (assuming there is are no NATs or proxys in the internal network of the ship - which is probably the case). In this case Zeutrinos defense options are limited if he didn't use a fake IP or a proxy during the attack, because the IP will directly lead Pal to his computer.

    If Zeutrino has changed has changed is statically assigned IP, Pal should look for traffic on the given subnet from IP addresses which should not be assigned (we can assume that Pal being a Vogon sysadmin keeps a strict record about which IP are taken and by what). Because may have Zeutrino instead swapped his IP address with an other terminal, he should first inspect the terminal which has currently the offending IP and if he finds no signs that the attack originated from here (such evidence is most readily found in the browser history or in the free space on the disk if it wasn't wiped) he should proceed and look at every computer on the subnet. To confirm that he has the right terminal, he should look for signs that the given computer was used for the attack (most simple way is to search for the contents of the cookie in the raw image of the terminals disk) or that the harddrive of the given terminal was wiped. If he finds only one harddrive which was wiped in the whole subnet and finds the strings nowhere, he can be pretty sure that that terminal was the offending one.

  • Bonus question: The wordcount is 42, which according to the book is the answer to all the questions of the universe.
Malware analysis quiz VII
  1. Is this malware packed? If so, with which packer?

    It is packed with Themida, produced by Oreans (http://www.oreans.com/themida.php), which is a very hard to break protector. It includes optionally detection for virtual machines (VirtualPC and VMware), a feature which is activated in this executable. Because of this analysis is only possible with an other virtual machine (if you don't want to sacrifice a real one :)), my personal choice being Qemu (http://fabrice.bellard.free.fr/qemu/).

    During the process of unpacking the executable dumps a driver in the system32\drivers directory with the name oreans32.sys (size: 33952 bytes, MD5: aad837bf3b475092fd515cd0842334e9). Although this is detected by CAT-QuickHeal as Rootkit.Agent.ad, is not malicious file, but a part of the protector itself. Still, probably most people would like to remove this file too, which can be done by entering net stop oreans32 at the command prompt and then deleting the file itself. Given the way this file was packed, we can say for certain that it was first run by a program having the load driver privilege (usually this is attributed to members of the Administrators group only). On subsequent runs however it wasn't necessary for it to have this privilege since the driver was already installed and running. This is an other reason to delete the driver./

  2. What is the purpose of this malware?

    It has a single purpose: to download and execute any file the master controller instructs it to.

  3. Does it connect to a remote server? With which purpose?

    It connects to uk.undernet.org and joins the channel #secretcow with the password werule which acts as a command and control center for it (the channel has been shut down). The nickname of the user who controls this bot is Daddy.

  4. Which channels does it connects to?

    #secretcow. It also sends status messages to the #yousawthatss channel (like :Downloading. and :Executing.)

  5. Can you get any passwords related to this malware? (Not the infected password) :)

    The channel password for #secretcow is / was werule

  6. Which capabilities does this malware have?

    To download and execute files from a given url. These files are downloaded to C:\dl.exe and executed from there. This is an other indication for the fact that the malware was intended to run with high privileges (because low privileged users do not have write access to c:\). To reconstruct the files which were downloaded and executed (if any), there are two possibilities: looking at the Internet Explorer cache on the infected machine. This works because the malware uses the URLDownloadToFile API, which is part of Internet Explorer and stores the downloaded files in the same cache as it. An other possibility would be to look at the proxy logs if the computer was behind one. Because the malware uses a function which is part of Internet Explorer, it uses the same proxy settings as IE.

  7. What is the hidden message? (if there is any...) :)

    no security without knowledge. No knowledge without research. Be a good guy! It is worthwhile.

    For analysis I ran the program in Qemu for a couple of seconds and then did a full memory dump of the malware using the small program shown in the appendix. I imported the relevant sections (dump_00400000.bin, dump_00401000.bin and dump_00404000.bin) in in IDA (when importing you must take care to mark the sections as 32 bit code). Unfortunately the protector obfuscates the IAT, so the analysis was done mostly by looking at the strings and the method calls to the library functions (it was written in Delphi and IDAs FLIRT signatures managed to identify a couple of library routines).

Appendix – Source code for the memory dumper. Use Turbo Delphi or FreePascal to compile.

program dump_mem;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows;

var 
    hProcess: THandle;
    l: integer;
    buffer: pointer;
    numRead: Cardinal;
    memStart: pointer;
    memInfo: MEMORY_BASIC_INFORMATION;

procedure PutFile(FileName: String; FileDataPtr: Pointer; FileSize: Cardinal);
var
  hFile: THandle;
  Written: Cardinal;
begin
  hFile := CreateFile(PChar(FileName), GENERIC_WRITE, 0, nil, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
  if hFile=INVALID_HANDLE_VALUE then begin
    WriteLn('Failed to open output file!');
    exit;
  end;

  WriteFile(hFile, FileDataPtr^, FileSize, Written, nil);

  If Written <> FileSize then begin
    WriteLn('Failed to write output file!');
    exit;
  end;

  CloseHandle(hFile);
end;

var
  pid: Integer;
begin
  pid := StrToInt(ParamStr(1));

  hProcess := OpenProcess(PROCESS_ALL_ACCESS, false, pid);
  if hProcess <> 0 then begin
    memStart := nil;
    l := VirtualQueryEx(hProcess, memStart, memInfo, SizeOf(MEMORY_BASIC_INFORMATION));
    while l = SizeOf(MEMORY_BASIC_INFORMATION) do begin
      if meminfo.State = MEM_COMMIT then begin
        GetMem(buffer, memInfo.RegionSize);
        if ReadProcessMemory(hProcess, memInfo.BaseAddress, buffer, memInfo.RegionSize, numRead) then begin
          PutFile('dump_' + IntToHex(Integer(memInfo.BaseAddress), 8) + '.bin', buffer, memInfo.RegionSize);
        end;
        FreeMem(buffer);
      end;
      integer(memstart) := integer(meminfo.BaseAddress) + meminfo.regionsize;
      l := VirtualQueryEx(hProcess, memStart, memInfo, SizeOf(MEMORY_BASIC_INFORMATION));
    end;
  end;
  CloseHandle(hProcess);
end.

100th post & various short stories

2 comments

Incredible, isn't it? This is the 100th post! Also a curious thing: in both October an November I had 39 posts (I didn't plan it and didn't observe it until I moved over to the beta Blogger and started tinkering with the customization of my blog). What follows are some small bits of information:

A great Windows Commander / Total Commander / Norton Commander replacement for Gnone: Gnone Commander (yes I know about MC, but for the moment I prefer something with a graphical UI)

If your menu panel locks up under Gnome, switch to a text console (with Ctrl+Alt+F1 for example), log in and do a ps x|grep gnome-panel. You should see two processes: the gnome panel and the grep which is searching for it. Use the PID from the first one and do a kill -9 with it (kill -9 4528 for example). Now go back to the user interface with Ctrl+Alt+F7 and the panel restarts.

To find out why a GUI program isn't starting, try opening up a console and running it from there. Normally the error output of the GUI programs will go nowhere (unless they chose to display a dialog with it), but if you start them from a console window, they might print out error messages there. For example I found out that I need Java 1.5 to run jEdit. To find out which command to run for a particular application, go into System -> Preferences -> Menu Layout, right click on the item you are interested in and select Properties. The command you need to type in is in the Command field.

To find out which Java installation you have, open up a console and type java --version. If Java replies Unrecognized option: --version, use java -version. If you try to update to Java 1.5 (also known as Java 5.0) and after doing sudo apt-get install sun-java5-jre the system still says it's running Java 1.4.2, you might try uninstalling the java-common package (and also all the dependencies) and then reinstalling the sun-java5-jre package. The nice thing is that the packages are in your apt cache (supposing that you didn't do an apt-get clean in the meantime).

Over at Ajaxian you have a great post: . My message to those who say this is nonsense: look inside you. You overcomplicate everything and for every problem you think oh, we need javascript. Almost every problem can and should be solved traditional methods which are guaranteed to work on 99.9% of the web browser. And if you think you should do graceful degradation and find it hard, it is hard because you are coming from the wrong end. Start simple and use progressive enhancement.

Finally about our good friend Steve Gibson. The latest podcast (number #69) was good and fairly accurate (because he stayed away from technical details and talked only in general terms), however I found out what the semi-secret new program of his will be (by reading the mails on his news server - it seems he is an old fashioned man). Quote:

GRC's forthcoming little "SecurAble" freebie will be a simple tool that anyone can run to tell them which of these security enhancing features are already present within the processors of the machines they now own. It would also come in handy for any security-aware shopper to instantly verify that any machine they're looking at and considering purchasing supports these desirable and potentially important security enhancing capabilities. Why would anyone purchase a machine today that didn't have these features? My examination of Intel's chip numbering for "which chips have EM64T" quickly revealed that it's a maze of numbers, and that it's difficult to know WHAT you have without some real study. SecurAble (which I think is a pretty perfect name, but I'm certainly open to anything better) will simply display five attributes of any system it's run on: The manufacturer of the Chip. The model name of the Chip. Whether it support 64 bit extensions. Whether it supports hardware enforced DEP. Whether it supports hardware virtualization.

My opinion: why reinvent the wheel? There are perfectly good system information tools out there (for example WCPUID) which supply the same information (in case of WCPUID look under the Extended Features Flag, and check out the ones name Virtual Mode Extension, 64-bit extension and No Execute page protection to get the same information). My prediction is that this will be a glorified CPUID instruction with a bunch of nonsense written around it. The fact is: no hardware or software can make you magically secure, even though some people might want to make you think that it does. Only by learning secure and cautious behavior can you be safe (in both the real and the virtual world).

Friday, December 08, 2006

My time

0 comments

Update: you can find a simpler to use solution here.

From time to time I find myself reading a blog post which makes a reference to a give date / time (for example when a live stream will be activated). However the problem is that most of the time this reference is not given in my time-zone. So I've put together a little widget which you can see in the side-bar which displays the time in my time-zone (assuming that the clock and the timezone is correctly set on the viewers computer). It is also able to convert time references in the post to the time-zone of the reader (again, assuming that the reader has the correct date/time and timezone set and javascript activated), like the date / time when I'm writing this post (click on it to see the converted version - you must have javascript enabled and viewing this from my blog - not from the RSS feed).

Now for the main thing: how can you use it on your own blog? The easiest way is to go to the Widgetbox version (even more so if you are already using other widgets from the site), however that code has two limitations (because of the security model used by the site): (a) no clickable links will be generated for the date/time references (b) there is no iframe fallback support for browsers which have javascript disabled (because the site itself uses javascript to install the widgets in the blog, there would be no point in trying to create a no-javascript version).

The more complicated way would be to do a manual install. You will need some basic knowledge, access to your blog templates and to a host which can serve up PHP content (if you want to use the iframe fallback mechanism). In this case the steps would be the following:

  1. Upload PHP file to your host. You can see the source code below, or download it from here.
  2. Upload the javascript or you can directly include it in the page (between <script></script> tags of course). The source code can be seen below: Edit the last line (where it says .init(2);) so that in place of 2 you put your own time zone (offset from GMT)
  3. Finally insert the following code where you wish to show the clock: <!-- The url in the SRC attribute should poin where you updated the PHP file --> <!-- The offset is the time zone offset from GMT, the color the background color of the fallback IFRAME --> <!-- This can be ignored if you don't want an IFRAME fallback mechanism --> <iframe frameborder="0" marginheight="0" marginwidth="0" src="http://cdman83.byethost9.com/dateTime.php?offset=2&bgcolor=dfffbf" id="staticDisplayTime" style="width: 12em; height: 5em; border: none;" scrolling="no" ></iframe> <!-- This is where the javascript will display the date/time. Style it accordingly--> <div style="text-align: center; width: 10em;"> <div id="displayAuthorsTime" style="font-size: xx-large;"></div> <div id="displayAuthorsDate" style=""></div> </div> <!-- The script. You can use an external file or include the script directly --> <script src="http://hype.free.googlepages.com/dateTime.js"></script>
  4. To insert an date element, format it like the following code: <span class="date"><!--Dec 08 2006 14:34:15-->click here to get the date/time written in the comment</span>