| Posted by
| Nick Gammon
Australia (23,165 posts) Bio
Forum Administrator |
| Message
| OK, here is a nice challenge. :)
If you don't know what you are doing, this may not help, but I'll try to describe another technique for recovering your God password using gdb.
I have just done some posts about using gdb, in this thread:
http://www.gammon.com.au/forum/?bbsubject_id=3653
The "lost password" problem is a nice real, live problem, so I'll apply some of the gdb techniques to it.
If you want to follow through the exact line numbers, I used the latest stable release at the time of writing, namely:
pennmush-1.7.6p14.tar.gz
(PennMUSH v 1.7.6 patch level 14)
After following the configuration instructions and installing it (under Cygwin this time), I got it running. I logged on as "one" and changed the password from the default empty one.
Now, to get to work, assuming I have forgotten it...
A bit of hunting around shows that in bsd.c there is a check for a new connection:
3827 if (string_prefix("connect", command)) {
3828 if ((player = connect_player(user, password, d->addr, d->ip)) == NOTHING) {
This calls "connect_player" in player.c. A little way into connect_player (line 155) is the password check:
153 /* validate password */
154 if (!Guest(player))
155 if (!password_check(player, password)) {
156 #ifdef CREATION_TIMES
157 /* Increment count of login failures */
158 ModTime(player)++;
159 #endif
Since the password check is the one we want to defeat, we'll put a breakpoint on that line (line 155).
First we need to get gdb running, so we'll find the process ID (since in this case PennMUSH is already running, because it needs command line arguments).
Let's find the process ID:
Nick@nick ~/pennmush/src
$ ps waux | grep netmud
PID PPID PGID WINPID TTY UID STIME COMMAND
280 163 280 192 con 1000 10:52:20 /home/Nick/pennmush/src/netmud
OK, the process ID is the first number, 280. Let's get gdb attached to it:
$ gdb ../src/netmud.exe 280
GNU gdb 2003-09-20-cvs (cygwin-special)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-cygwin"...
Attaching to program `/home/Nick/pennmush/src/netmud.exe', process 192
[Switching to thread 192.0x60]
(gdb)
This says it is attaching to process 192 which was the fourth number, the Windows process ID.
Now let's add the breakpoint we decided on ...
(gdb) break player.c:155
Breakpoint 1 at 0x49ac2d: file player.c, line 155.
And continue execution of the MUSH ...
I'll try connecting by typing "co one fred" although I doubt "fred" is the password. Immediately afterwards the breakpoint is reached in the gdb window ...
[Switching to thread 192.0x96]
Breakpoint 1, connect_player (name=0x22dd20 "one", password=0x22cd20 "fred",
host=0x1003108c "localhost", ip=0x100310f1 "127.0.0.1") at player.c:155
155 if (!password_check(player, password)) {
(gdb) cont
Continuing.
I typed "cont" (continue) to see what would happen, and indeed on my client I see this ...
co one fred
Either that player does not exist, or has a different password.
Let's try again, typing "co one fred" into the client ...
Breakpoint 1, connect_player (name=0x22dd20 "one", password=0x22cd20 "fred",
host=0x1003108c "localhost", ip=0x100310f1 "127.0.0.1") at player.c:155
155 if (!password_check(player, password)) {
(gdb)
What we need to do now is convince the program that the password was OK. Let's step into the password_check routine:
(gdb) step
password_check (player=1, password=0x22cd20 "fred") at player.c:70
70 if (!(a = atr_get_noparent(player, pword_attr)))
(gdb) list
65 {
66 ATTR *a;
67 char *saved;
68
69 /* read the password and compare it */
70 if (!(a = atr_get_noparent(player, pword_attr)))
71 return 1; /* No password attribute */
72
73 saved = strdup(uncompress(a->value));
74
(gdb)
Typing "list" shows enough source to indicate that if password_check returns 1, it is an acceptable password (or no password).
So, let's fool it and tell it to return 1...
(gdb) return 1
Make password_check return now? (y or n) y
#0 0x0049ac3f in connect_player (
name=0x22dd20 "one", password=0x22cd20 "fred",
host=0x1003108c "localhost", ip=0x100310f1 "127.0.0.1") at player.c:155
155 if (!password_check(player, password)) {
(gdb) cont
Continuing.
Typing "return 1" tells gdb to return from this function with "1" as the result (it asks for confirmation), then we type "cont" to continue executing.
Now looking at the client window I see ...
Welcome to PennMUSH!
--------------------------------------------------------------------------
Yell at your god to personalize this file
Wizards, tell your friendly neighborhood god to personalize this file!
**********************************************************************
**********************************************************************
Last connect was from localhost on Sat Jan 17 10:32:15 2004.
Last FAILED connect was from localhost on Sat Jan 17 10:55:58 2004.
MAIL: You have no mail.
Room Zero(#0R)
You are in Room Zero. It's very dark here.
Aha! Success! We have connected. Let's fix up our password to a known value (in the client) ...
@newpassword one=swordfish
Password for One changed.
Your password has been changed by One.
@dump
Dumping...
All done. The password is changed, and the database saved. This is probably a good time to shut down the MUSH and restart it, as the debugger is still connected to it.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | | Top |
|