Today I found a delivery notification paper card in my letter box. The DHL courier was here and couldn’t deliver the package. So het dropped a message:
DHL kindly asks to visit www.dhl-delivernow.ch. Once on the page, you have to choose the language and right after that, enter your 7 digit code on your notification card:
What i think is pretty odd is the fact that the number asked for
- consists only of numbers
- has a length of 7 digits
For the fun, I tried to enter some follow-up numbers and tried to get some hits. And in fact, things got really bad and was able to (theoretically) manipulate package delivery instructions for other persons’s packages. I just had to increase my own number several times. Five attempts were required to get 2 positive hits. That was quite strange.
Investigate Page Source
It seems that they take special care of the zero digit. And yes, it is not possible to enter the zero digit as a first place character inside the reference number.
Capture TCP Traffic
In order to look for a possibility to automate a bruteforce attack, I had a look at the traffic going over the wire. Since everything is based on HTTP, is was very easy to check what was going on. All you need is a good traffic capturing tool – I used Wireshark.
The first capture shows the response from the web server, if the notification number was wrong, which means, the number either had already been processed or it has not been found in their system as an still to be processed number:
The image below shows the web server response, if the number matches and the user is asked to give specific details about delivery:
If you have a detailed look at these, you notice that there is a HTTP response header called “WebDevSrc”. This header can be avaluated to check if the number which has been used matches or not. This could be the basis for writing a small bruteforce utility which quickly checks all numbers inside a range and gives the attacker all valid numbers which can be manipulated. Writing such a utility is not difficult and can be done in a day, if HTTP knowledge is available.
Let’s imagine, if one does:
- write a small utility to get a list of valid notification numbers
- one modifies all the delivery times of these valid numbers to some unusual delivery times
If I were the DHL customer service representative I could not sleep any longer 🙂
Let’s do some calculations based on these facts:
- numbers with 7 digits containing only numbers from 0 to 9 offers a maximum of 10 Millions of combinations.
- The digit “0” as a first place digit is not allowed. Now, what does this mean? We do not have 10^7 real combinations. Instead, the total number of possible combinations is 9 * 10^6. massively reduced by 1 Million down to a total of 9 Million combinations. This is a decrease of 10 percent (!).
- My number started with “7”. So, when trying to bruteforce this, I just have to try out 1 Million numbers.
Some other interesting thoughts:
- Let’s take the assumption that DHL Switzerland is using these 10 Million numbers for Swiss cititens only. Switzerland has about 7.78 Mio. citizens at this time. This means, DHL probably uses the same numbers several times.
- There would be some potential to “generate” angry DHL customers by just manipulating DHL deliveries at unusual times.
In my opinion, this is some kind of vulnerability, which is not security-relevant in a first place, but if exploited by others, this could lead to many unattractive customer inquiries which decreases public reputation for DHL.
Now that should really scare DHL…
I received another notification card. with a very similar number. This time, I have to add +5 to my current number to find another parcel of which I was even able to change the complete address of delivery. Ohoh…
Update 25.11.2010 08.20:
Today, I’va informed DHL about their potential vulnerability. I offered them, to give them the details of my investigations.
Update 25.11.2010 09.30:
I’ve got a call from a DHL Switzerland representative. He confirmed the weakness in their web application.He also said, that the problem would be solved by end of this year. So, I’m going to be the first to test that then 😉