Note: this is a little of an unusual post for me!
Martin has always been fairly positive about the ScribeFire plugin for Mozilla Firefox. True, it has its quirks, but the plugin seems to work fairly well. I decided to also take a look at it, but was unable to get it to work at my first attempt. I just could not get my blog added to the interface, yet I am running a supported engine (Movable Type). ScribeFire insisted that I provided an invalid username/password.
Here is what I did to get it to work.
Martin has always been fairly positive about the ScribeFire plugin for Mozilla Firefox. True, it has its quirks, but the plugin seems to work fairly well. I decided to also take a look at it, but was unable to get it to work at my first attempt. I just could not get my blog added to the interface, yet I am running a supported engine (Movable Type). ScribeFire insisted that I provided an invalid username/password.
Here is what I did to get it to work.
First, on my web server, I started sniffing network traffic:
$ sudo tcpdump -s0 -Anl port 80 and host ip-address-of-my-pc
This will dump the entire packet content of any traffic flowing to or from port 80 on my server, going to or from my PC from which I attempt to log in.
The packet that is sent from my PC to the server's xml-rpc script looks fairly easy:
13:09:29.919805 IP 10.0.1.2.56236 > 10.0.1.3.80: P 857:1238(381) ack 1 win 65535
E.....@.w....d7.H.S%...P.}k.x.t]P...#...<?xml version="1.0" encoding="UTF-8" ?><methodCall>
<methodName>blogger.getUsersBlogs</methodName>
<params>
<param>
<value>
<string/>
</value>
</param>
<param>
<value>
<string>username</string>
</value>
</param>
<param>
<value>
<string>password</string>
</value>
</param>
</params>
</methodCall>
Nothing exciting in there.
However, the server's response was more interesting and contained an RPC fault message, which included a string "Invalid login". Since Movable Type is Open Source, I was able to locate that same string in the code using a simple grep. After changing that string by postfixing it with a bunch of 'XXX', I retried my request to make sure that I was indeed looking at the correct code.
This is where I had my first revelation; the code was:
my $auth = $author->api_password eq $pass;
Movable Type was not checking my regular user's password, but some kind of special API password! That's a problem, since I have no idea what that password is. I looked through the GUI, but was unable to find where it is set.
So, how do you find a password that you don't know?
Simple: add a line:
die _fault(MT->translate($author->api_password));
right after that password check.
This will create another RPC fault for any username/password combination that I try, but instead of the fault description, it will include the representation of the value of the $author->api_password variable.
If MovableType stores that password in an unprotected form in that variable, I would be golden. If they would only store a hash, that would make my life (significantly) more complicated.
Fortunately for me, but as illustrated by this post, not very securely, they do not. Pasting the string that was returned to me in my tcpdump output into the password field, and removing the line above gave me full access to my blog's content.
Just to make sure that the API password is indeed stored in plain text in the database, I logged on to the mysql server and checked:
mysql>; select author_api_password from mt_author where author_nickname='my-login';
+---------------------+
| author_api_password |
+---------------------+
| zeekrut_pazz |
+---------------------+
1 row in set (0.00 sec)
On the positive note: my "normal" user password is encrypted using some algorithm. I'm
sure the source code will also tell me what that is. Just to make sure, I changed the password in the database.
Posted through ScribeFire.
$ sudo tcpdump -s0 -Anl port 80 and host ip-address-of-my-pc
This will dump the entire packet content of any traffic flowing to or from port 80 on my server, going to or from my PC from which I attempt to log in.
The packet that is sent from my PC to the server's xml-rpc script looks fairly easy:
13:09:29.919805 IP 10.0.1.2.56236 > 10.0.1.3.80: P 857:1238(381) ack 1 win 65535
E.....@.w....d7.H.S%...P.}k.x.t]P...#...<?xml version="1.0" encoding="UTF-8" ?><methodCall>
<methodName>blogger.getUsersBlogs</methodName>
<params>
<param>
<value>
<string/>
</value>
</param>
<param>
<value>
<string>username</string>
</value>
</param>
<param>
<value>
<string>password</string>
</value>
</param>
</params>
</methodCall>
Nothing exciting in there.
However, the server's response was more interesting and contained an RPC fault message, which included a string "Invalid login". Since Movable Type is Open Source, I was able to locate that same string in the code using a simple grep. After changing that string by postfixing it with a bunch of 'XXX', I retried my request to make sure that I was indeed looking at the correct code.
This is where I had my first revelation; the code was:
my $auth = $author->api_password eq $pass;
Movable Type was not checking my regular user's password, but some kind of special API password! That's a problem, since I have no idea what that password is. I looked through the GUI, but was unable to find where it is set.
So, how do you find a password that you don't know?
Simple: add a line:
die _fault(MT->translate($author->api_password));
right after that password check.
This will create another RPC fault for any username/password combination that I try, but instead of the fault description, it will include the representation of the value of the $author->api_password variable.
If MovableType stores that password in an unprotected form in that variable, I would be golden. If they would only store a hash, that would make my life (significantly) more complicated.
Fortunately for me, but as illustrated by this post, not very securely, they do not. Pasting the string that was returned to me in my tcpdump output into the password field, and removing the line above gave me full access to my blog's content.
Just to make sure that the API password is indeed stored in plain text in the database, I logged on to the mysql server and checked:
mysql>; select author_api_password from mt_author where author_nickname='my-login';
+---------------------+
| author_api_password |
+---------------------+
| zeekrut_pazz |
+---------------------+
1 row in set (0.00 sec)
On the positive note: my "normal" user password is encrypted using some algorithm. I'm
sure the source code will also tell me what that is. Just to make sure, I changed the password in the database.
Posted through ScribeFire.
The web services password is found in your user profile in MT.
Click your name at top right(or you can work your way there via Manage->Users), then look under the Preferences heading.