My Rambling Thoughts

Quote:

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.

Brian W. Kernighan

News:

Date: . Source: .

Don't take security lightly!

My home server was barely up on the Internet for 3 days when I find login attempts as root, test, admin, guest and oracle. These are the most common from a total of 1000+ different names.

None of them will ever succeed for two reasons. Either the accounts don't exist or they are not allowed to SSH in. (I only allow a small number of users to log in from the Intranet and an even smaller number from the Internet.)

I am wondering whether I should move my SSH port from 22 to some other number to reduce the log incidents. However, a simple port scan will reveal the new port just as easily.

It is a very good thing a NAT router also serves as a firewall, or a Windows machine will be rooted very easily.

(Joke: what do you call a Windows machine on the Internet? Answer: a bot.)

I am now convinced we need to enforce the following for a general user (whom you can't trust to have a strong password):

  1. Create a special SSH a/c for users to SSH in
  2. The SSH id must not be well-known.
  3. The password must be sufficiently strong.
  4. After the user logs in, he su to his real a/c.

It doesn't work for VNC sessions, though.

How PHP tries to restrict file system access

In an earlier article, I said a poorly written script can expose files outside of the website:

http://<site>/scripts/minify.php?f=/../../../etc/passwd

I found that PHP can stop this using its open_basedir settings. When this is set, only directories under the specified paths are allowed.

The script will now fail. Mission accomplished?

Almost. There are three drawbacks:

  1. PHP also turns off some file/dir caching, so it now parses paths much slower.
  2. It can be bypassed by a determined local user in PHP.
  3. It can be bypassed trivally with Unix commands.

Bypassing, the PHP way

The flaw is that the path checking and accessing is not an atomic operation. This gives rise to a race condition vulnerability:

  • Script 1 continuously opens a specially prepared symbolic link. It will fail most of the time.
  • Script 2 continuously alternates the specially prepared symbolic link between an allowed file and the disallowed target file.

This sequence of event will allow access:

  1. Script 2 sets the symbolic link to an allowed file
  2. Script 1 checks that the symbolic link is allowed
  3. Script 2 sets the symbolic link to a disallowed file
  4. Script 1 now opens the symbolic link

We have to turn off symbolic link in PHP to avoid this vulnerability.

A special symbolic link can be prepared in 5 steps:

  1. mkdir("a/a/a");
  2. symlink("a/a/a", "b");
  3. symlink("b/../../../", "special");
  4. unlink("b");
  5. symlink(".", "b");

So many steps are needed because PHP checks the symlink is a valid and allowed path at each step.

This sort of symlink manipulation has been around for years on multi-user Unix environments, but it is refreshing to see it used on a webserver.

Bypassing, the shell way

This often works:

echo "<pre>" . `ls -l /` . "</pre>";

It completely bypass open_basedir because it is only enforced by PHP.

This works as well:

echo "<pre>" . `cat /etc/passwd` . "</pre>";

Getting the list of users is always the first step towards finding a user with poor security.

(We need to read the passwd file as /home is usually unreadable.)

We have to turn off shell access in PHP to avoid this vulnerability.

To sum up

open_basedir helps to protect against poorly written scripts, but it is not a cure-all. Remember, there is no magic bullet.

Watch out for the file permissions!

Ubuntu's default umask setting is 022. In English, this gives read access to everyone.

Being more security conscious, we change the default umask to 077 in /etc/profile. This gives full access to the user only.

Note that the umask setting affects only new files. Existing files must be manually chmod. In other words, this step should be done asap.

For savvy users, we can change the default umask to 027 in ~/.profile. This gives read access to the group as well.

By default, a user is in his own group. However, I find it useful to make all (human) users part of the users group:

useradd -g users <user>

(-g makes it the primary group. -G just adds it as a secondary group.)

This allows files to be shared more easily between users.

Again, this should be done asap. Existing files can be converted using chown.

Why is file permission important?

One word: security breach.

Scenario 1: suppose a hacker is able to breach Apache or PHP. Apache runs as www-data. Can the hacker read other users' files? Not if the permissions are set right. (By default he can.)

If he can't read other users' files, he has to mount a separate privilege escalation attack to gain root access. This is the second line of defense.

Scenario 2: suppose a hacker breaks a user's weak password. Can he read other users' files? Not if the permissions are set right. (By default he can.)

Putting a home server on the Internet

It is pretty easy to put a home-based server on the Internet — although it may violate your ToS (Terms of Service). This is even cheaper than the cheapest webhosting package (S$100 + S$15 for the domain name, per year).

Basic steps

First, we sign up with a DDNS service provider, so that we can locate our server easily. Instead of typing an arcane 1.2.3.4 that changes every time we reboot our modem, we just need to type in, say, mysite.dyndns.org.

(There are no good free domain names. We can register one for ~$15/year, though.)

Second, we configure our modem to automatically register its WAN IP address with the DDNS service provider.

Third, we configure our router to forward the relevant ports to our server. Typical ports are 22 (SSH), 80 (HTTP) and 443 (HTTPS). Note that we do not need to forward port 5901 (VNC) because we will tunnel through SSH instead.

That's it, we are on the Internet!

Security

The Internet is a very hostile place. There is nothing like putting our own server there to make us paranoid about security.

First, we want to restrict who can log in from the Internet. This can be done by configuring /etc/ssh/sshd_config. root should definitely be disallowed.

And instead of VNC'ing directly to the server, we VNC through a SSH tunnel. VNC transfers in "clear", so it is a bad idea to run VNC as-is over the Internet. Again, it is not very difficult to set up.

The next thing that we definitely want is to access our website over HTTPS. This is especially true for admin pages, such as cPanel (Website management) and phpMyAdmin (administers MySQL databases).

The good thing is that it is pretty easy to generate our own self-signed certificate and configure Apache to use it.

Then, we want to configure Apache and PHP to leak as few information as possible by turning off some HTTP response headers.

Passwords

Passwords are still the keys to the server. If a attacker knows a password, he has access to the server, so choose a strong password!

There are 3 main passwords to watch out for:

  • Passwords of all users who can log in from the Internet
  • VNC password (not so important since need to get past SSH)
  • MySQL password (exposed through phpMyAdmin)

A semi-strong password is at least 8 characters, has 1 digit and 1 symbol.

It is too easy to write insecure code

programming

It is very hard to write secure code — because of our tools and programming techniques.

Buffer overrun

In this era and time, we still have fixed-size arrays and strings that don't know their own size.

Fixed-size arrays are easy to overrun for three reasons:

  • Array bounds are not checked
  • Array bounds are checked only for the debug build
  • Array bounds are checked, but not handled properly

Fixed-size arrays is an archaic programming construct. The programmer needs to decide the worst-case size up-front. If it is much higher than the normal case (usually the case), and allocating for it is not feasible, that is when problem arises.

This is made worse by languages that cannot share an array properly, but require different parts of the program to have their own private copy. Each copy introduces a potential buffer overrun bug. And each copy with the worst-case size adds up pretty quickly.

Fixed-size strings are like arrays, but they are even easier to overrun due to insecure functions: strcpy(), strcat(), sprintf() and the like.

Now, it is trivial to replace sprintf() with snprintf(), but it is not so trivial to use strncpy() and strncat(). For one thing, they do not store the NUL ('\0') terminator. We need to do it ourselves. This is even worse than a potential buffer overflow bug because it is a guaranteed bug.

(Note: it is also not trivial to replace strcmp() with strncmp().)

I've seen code that introduces this bug because some dumb lint program says strcpy(), strcat() and strcmp() are bad and should be avoided.

What happens when the buffer is overrun?

If the variable is on the stack, then the attacker will be able to overwrite other stack elements, including the return address.

So, he injects machine code as the input and overwrites the return address such that it "returns" to the machine code. This requires some trial and error, but once accomplished, it will work every time. (Otherwise the program just crashes.)

This is avoided to a large extent if the OS, together with proper CPU support, disallows program execution from the stack. Modern OS do this.

Even so, hackers have found a way to hack with the so-called return-to-libc attack.

Is the machine compromised?

The executing program is compromised. If it has administrative access, the machine is compromised. This is why it is extremely advisable to run programs as a non-privileged user: when a non-privileged program is compromised, the attacker needs to mount a separate privilege escalation attack to gain administrative access.

Note that a browser or a webserver should be run as a separate user, so that your files — which can be important and sensitive — are not compromised.

(Modern OS have proper user-access controls. However, they are not used most of the time for convenience.)

Is dynamic-sized arrays the answer?

It helps with memory management, but it is still not free from attacks. The attacker can now mount a Denial-of-Service (DoS) attack by causing the array to grow to consume the available memory.

Should strings know their own length?

These strings are more secure, but due to legacy functions or systems, we will have a mix of the two. Some parts of the program accept NUL, but some parts do not — and this is a potential for exploitation.

In fact, this was how users were tricked into clicking malicious URLs a few years back. (The display code stops at the first NUL, while the rest of the browser handles the entire string.)

String injection

Many systems use strings to execute commands. The problem starts when we substitute user input without filtering or escaping the special characters — and there are always special characters.

SQL

The most famous of all string injections is the SQL-injection.

snprintf(buf, buf_size,
 "SELECT * FROM users WHERE name = '%s';", user_name);

What happens when user_name is ' or '1'='1? The query becomes:

SELECT * FROM users WHERE name = '' or '1'='1';

Voila, we get all the users!

HTML

HTML is susceptible too. HTML injection is also known as Cross Site Scripting.

Suppose we have a blog and we didn't sanitize the user comments before displaying them:

var text = $("#user-input").val();
$("#preview").html(text);

This allows the user to put whatever HTML element they want: typically external links or some rogue external JavaScript files.

Being able to execute an external JavaScript file is a big deal because there are other JavaScript/CSS vulnerabilities that allow the attacker to gain control of the current session or even the user's PC (in the case of a browser vulnerability).

Using user input as keys directly

It is well known we should not trust user input, but it is still not easy to do it correctly.

Filesystem

A classic example is using the user input to retrieve a file directly. There are two potential problems:

  1. The user may access a file in the website he has no access to.
  2. The user may access a file outside of the website

(1) works because the webserver (Apache) may call an external program (PHP) which does not know about the webserver's permissions.

For example, if we have a PHP script that minifies JS/CSS files:

http://<site>/scripts/minify.php?f=<file>

Suppose we call it directly:

http://<site>/scripts/minify.php?f=/.htaccess

A poorly written script will return the file. .htaccess is otherwise usually protected by Apache.

All the server-side scripts can be leaked this way if not careful:

http://<site>/scripts/minify.php?f=/scripts/minify.php

(2) looks even more serious:

http://<site>/scripts/minify.php?f=/../../../etc/passwd

Suppose the website is hosted at /home/<user>/public_html, this will get /etc/passwd, or the system's password file! (Well, it gives us the user ids.)

However, the damage is usually not that serious because the webserver runs as a separate user. The user's own private files will not be compromised if he sets his file permissions correctly. (Unfortunately, they are usually not setup that way by default.)

The solution is to sanitize the user input, but it is easier said than done.

(1) is a tradeoff between flexibility and security. Some security is necessary, but we also do not want to lock down the script too much, else we need to update it very often.

(2) is pretty straightforward, but the code can be slow if not designed properly. It can also be buggy if not tested properly.

User-specified keys

Sometimes, when we want to write a generic update function, we allow the webpage to specify both the key and value. (The keys are hidden from the user, of course.)

The problem is that the attacker can specify his own keys and access fields not otherwise exposed by the webpage.

So, how do we write secure code?

Rule 1: there is no magic bullet.

Rule 2: be paranoid.

Programming is not easy.

Park at your own risk

transport

News: TP to stop booking vehicles for illegal parking from Nov 1

Date: 15 September 2010. Source: AsiaOne.

Soon, you will no longer see a Traffic Police (TP) officer booking vehicles for illegal parking offences.

From Nov 1, the Land Transport Authority (LTA) will be taking over five functions from the TP the duty of enforcement against illegal parking offences.

The government statutory board will be empowered to close roads or lane for repair, alongside issuing permits for vehicle loads and the use of excluded vehicles such as mixers, on expressways.

Currently, it is pretty safe to risk parking on pavements, double-yellow lines and other illegal spots under TP's jurisdiction, even though the fine is a hefty $70. The reason is that TP is seldom in action.

($70 may not seem much, but you can park legally for over 100 days!)

No more. It is now better to park legally. LTA has many more enforcement officers than TP.

A true sense of perspective

News: In one day, two asteroids buzz the Earth

Date: 9 September 2010. Source: CNN.
Near Earth Asteroids

Two small asteroids passed within the moon's distance from the Earth about 12 hours apart on Wednesday, NASA confirmed.

Near-Earth asteroid 2010 RX30, which is estimated to be 32 to 65 feet in diameter, passed within 154,000 miles of Earth around 5:51 a.m. ET Wednesday. The second object, 2010 RF12, estimated to be 20 to 46 feet in diameter, passed within 49,088 miles of Earth close to 5:12 pm ET.

That means the two asteroids passed within 0.6 and 0.2 lunar distances from the Earth, respectively.

Mere pebbles, in the grand scheme. We won't even feel it if they hit us. In contrast, the famous asteroid from 65 million years ago that paved the way for mammals was estimated to be 10 km wide.

It frustrates me sometimes that we are in the age of science and technology and yet we are not making use of them properly — we should try to get off this rock!

Think COE is high? Wait for this

transport

News: Move to have zero vehicular growth to tackle road jams "imminent"

Date: 9 September 2010. Source: CNA.

Congestion on Singapore's roads has renewed calls for more aggressive measures to curb the vehicle population.

One solution is to have zero vehicular growth, a point raised by Senior Minister Goh Chok Tong at a dialogue with grassroots leaders recently.

Observers said implementing such a move is imminent as Singapore roads are nearing maximum capacity.

Never let go once you buy a car. You may not be able to afford the COE again.

Existing car owners can always choose to keep their cars, while aspiring car owners will bid the even-more-limited COE supply sky high.

Singapore's policies have a way of backfiring because they never consider the unintended consequences.

Calling for more local gamblers

News: Free IR bus rides probe

Date: 8 September 2010. Source: ST.

THE Government is investigating the free bus rides offered by the two integrated resorts (IRs) here.

The probe could have an impact especially on Resorts World Sentosa (RWS), which introduced free shuttle services between the resort and 12 HDB town centres a few months ago.

When the IRs were being built, the Government said local jobs and foreign gamblers. It turned out to be local gamblers and foreign jobs.

Things do not always go the way you plan, especially if you plan for the best case only.

One thing not addressed here is that it does not seem very difficult/expensive to provide free island-wide shuttle service. It makes you wonder why the bus/MRT fares are going up year after year.

News: WHAT CASINO? IT'S A FREE RIDE

Date: 8 September 2010. Source: ST.

'I'm not going to the casino. Actually, I'm not even going to Sentosa. I'm planning to spend the day in Tampines Mall. So I'm taking the free bus from home in Choa Chu Kang to Sentosa. I'll then hop on the next bus from Sentosa to Tampines. It's my way of beating rising bus fares.'

A 48-year-old unemployed Choa Chu Kang resident who declined to be named

Ding ding ding, we have a winner!

Be a citizen, or go home

News: SM Goh: surge of immigrants caught govt by surprise

Date: 7 September 2010. Source: ST.

Take rational approach to problems: SM Goh. See pressing issues like housing, transport in perspective, he urges

WHEN Senior Minister Goh Chok Tong was a young civil servant working in the former Fullerton Building, he had, on occasion, waited as long as one hour to catch a bus home. Today, most people who fail to get on a packed MRT train have to wait just six to eight minutes to get on the second or third train.

But that is a long wait for them, he noted yesterday, when he drew the comparison to emphasise that Singapore can solve its most pressing problems as long as people adopt a rational approach towards them.

Heads I win, tails you lose. That is how the Singapore government deals with its citizens. (Chinese saying: the word 'government' has two mouths.)

I wonder how the government will pick the 10% "lottery" winners...

Prime targets:

  • 2 PRs who have bought a HDB flat
  • PRs who studied here
  • PRs who have stayed a long time here (15 years)

Is remote scanning a security vulnerability?

Most AiO (All-in-One) printers have a "WebScan" feature: it allows the user to scan using the Web-based interface; no installation required.

Most business-class printers, however, require an admin password to use this feature because of security risks.

Security risk: someone can rescan documents left behind. Question: is this a real security risk?

Anyway, let's fix this by requiring admin password.

What's the problem?

Now, normal users who want to use this feature will have the admin password, which then allows them to access much more things. Thus, most users won't get to use this feature at all.

A better solution is to have two passwords: a user password and an admin password.

Another possible solution: if there is a scan lid sensor, we can disable remote scanning until it is opened/closed. (This assumes the user opens it to remove the document.)

A case of double standards

News: To be or not to be a virgin?

Date: 29 August 2010. Source: The Star.

For most young people these days, it is no longer an issue but many still believe in having sex only after marriage.

WHAT people do behind closed doors is none of anyone's business.

So says Jo Tey who believes the younger generation today should not be judged on whether they are virgins or otherwise.

Some societies/cultures are obsessed with virginity — but only for the female. No one ever cares if the guy is a virgin or not. That tells us something about the society/culture.

Rather than asking someone whether virginity is important or not, we should ask him at what age does he think people lose their virginity.