hang with pty's and processes
John J. Lee
jjl at pobox.com
Sun Oct 28 14:01:53 EST 2001
I'm not used to forking, pty's, etc., so I'm hoping my problem here is
something elementary.
On the 84th password tried (on my linux machine at least), this program
hangs in pty_Popen.read, in os.read (see the line marked with # !!) -- it
never returns or raises an exception. Why??
Perhaps I'm hitting some kind of system limit on pty's or something?
There are, at most, only a couple of relevant processes (mount, python,
losetup, etc) listed at any one time while this is running, so it doesn't
seem to be a process limit.
#!/usr/bin/env python
"""Crack off-by-one encrypted partition password.
pty_Popen is derived from code posted to comp.lang.python by Alex
Coventry.
Yes, I'm a fool for not writing my password down properly.
"""
import sys, os, pty, time
class pty_Popen:
def __init__(self, command, args, delay=0.1):
self._delay = delay
self._cmd = command
self._pid, self._child = pty.fork()
if self._pid == 0:
r = os.execv (command, [''] + args)
os._exit(r)
def wait(self):
os.waitpid(self._pid, 0)
def read(self, max_read):
time.sleep(self._delay)
ret = os.read(self._child, max_read) # !!
return ret
def write(self, text):
time.sleep(self._delay)
return os.write(self._child, text)
def response(self):
while 1:
try:
response = self.read(1024).strip()
except OSError: # no output
response = ""
break
if response:
break
return response
def expect(self, expected, actual):
if expected != actual:
raise ValueError, "expected '%s', got '%s' from %s" % (
expected, actual, self._cmd)
def ok(self, expected, actual):
if expected == actual: return 1
else: return 0
class PswdIterator:
min = 33
max = 126
def __init__(self, passwd):
self.p = passwd
self.i = 0
self.cn = None
self._new_char = 1
def next(self):
p = self.p
if self.i >= len(p):
return None
if self._new_char:
self.cn = self.min
self._new_char = 0
else:
self.cn += 1
if self.cn >= self.max:
self.i += 1
if self.i >= len(p):
return None
self._new_char = 1
return p[:self.i] + chr(self.cn) + p[self.i+1:]
def crypton(crypt, device, cryptname, passwd):
"""Attempt to turn encrypted partition on, return 1 on success."""
delay = 0.001
p = pty_Popen("/sbin/losetup", ["-e", "serpent", device, crypt], delay)
p.expect("Password :", p.response())
p.write(passwd+"\n")
p.expect("", p.response())
p.wait()
p2 = pty_Popen("/bin/mount", [device], delay)
success = p2.ok("", p2.response())
p2.wait()
p3 = pty_Popen("/usr/local/bin/encoff", [cryptname], delay)
r = p3.response()
p3.expect("", r)
p3.wait()
if success:
return 1
def crack():
cryptname = "crypte"
crypt = "/home/cd2/cryptfilee"
passwd = "goeshere"
device = "/dev/loop2"
pwi = PswdIterator(passwd)
while 1:
print
print "trying %s" % (passwd,)
if crypton(crypt, device, cryptname, passwd):
print "got it!"
print passwd
break
passwd = pwi.next()
if passwd is None: print "failed"
if __name__ == "__main__":
t = time.time()
crack()
t = time.time() - t
print t
print t/60.0
Thanks for any help
John
More information about the Python-list
mailing list