1

I am doing an assignment where I have a passwd file and I am to find all the passwords in it. Most of them were easy with Jack the ripper and some tweaking but the extra credit requires I find a 8 byte Alphanumeric password generated by rand in perl 5.10.0 and encrypted with crypt. I came up with three ways to approaching this:

  1. Brute force: 62^8 Computations = 300 Weeks on my machine. I could rent a server with 300 times my machine power to do in 1 week. Somehow that feels like a waste of resources/electricity for an extra credit.
  2. Break Crypt: Not sure on this one, I have however generated a char-set from the other passwords I found, reducing the Incremental brute force to 5 days, but I think that will only work if this password contains only characters present in the previous ones (17 plain-texts), so maybe if i get lucky! (Highly Unlikely)

  3. Break rand: If I can find the same seed used to generate the password. I can then generate dictionaries to feed to Jack. In order to get the seed from the file given to me however I have to understand how perl is creating the seed (and if it is even possible on 5.10.0).

From what I have researched on earlier Perl versions only the System Time was used as a seed. I made a script that uses the m_time (Time From Epoch) on the passwd file given to me (+-10 to be sure although I'm sure the file got generated in one second) as seed to generate a dictionary, in this format, since I do not know at what call of rand() my password actually starts:

abcdefgh
bcdefghi
cdefhijk

I fed the dictionary to Jack. Of course this didn't work because after Perl 5.004 Perl uses other stuff (the point of my question) to generate a seed.

So, my question is if anyone knows where to find the source code Perl uses to generate the seed, and/or source code for rand/srand. I was looking for something that looked like this, but for version 5.10.0:

What are the weaknesses of Perl's srand() default seed, post version 5.004?

I tried using grep in the /lib/perl directory but I get lost in all the #define structure files.

Also feel free to let me know if you think I am completely offtrack with the assignment and/or any advice on the matter.

Community
  • 1
  • 1
Reni
  • 63
  • 2

1 Answers1

4

You don't want to look in /lib/perl, you want to look in the Perl source.

Here is Perl_seed() in util.c as of v5.10.0, which is the function called if srand is called without an argument, or if rand is called without srand being called first.

As you can see, on a Unix system with random device support, it uses bytes from /dev/urandom to seed the RNG. On a system without such support, it uses a combination of the time (with microsecond resolution if possible), the PID of the Perl process, and memory locations of various data structures in the Perl interpreter.

In the urandom case, guessing the seed is effectively impossible. In the second case, it's still of difficulty probably similar to brute-forcing the passwords; you have 20 bits of unpredictability from the microsecond timestamp, up to 16 bits from the PID, and an unknown amount from the memory addresses, probably between 0 and 20 bits if you know details of the system where it was run, but up to 64 or 96 bits if you have no knowledge at all.

I would say that attacking Perl's rand by guessing the seed is probably not practical, and reversing it from its output is probably not either, especially if it was run on a system with drand48. Have you considered a GPU-based brute-forcing tool?

hobbs
  • 223,387
  • 19
  • 210
  • 288
  • but if the password was generated on windows, where (until more recent perls) you only have 15 bits of random value (and no extra seed, afaik), it's another story – ysth Sep 13 '15 at 23:52
  • Thanks for the fast responses. I will play with the information for the next few days before I mark as answered. I haven't tried GPU-based yet as well so I will look into it. I was concentrating on the srand/rand side because of hints from people who done this before, however it seems to me that unless he used "use 5.004;" then there is no adequate (easy) way of breaking rand. – Reni Sep 14 '15 at 00:48
  • Well after spending a week on it I finally I understand how perl rand works.
    1) At the first rand of perl it will call srand(), it uses an integer value as a seed (2^32) possibilities, but the REAL seed has 2 trailing bytes unused. 2) Each rand will actually use the UNIX drand48() and change the seed following the documentation.
    – Reni Sep 20 '15 at 18:33
  • I'm sorry for failing posting replies, having a hard time formatting in a response. This link explains drand48 on Unix system : http://man7.org/linux/man-pages/man3/drand48.3.html The real seed has always 6 bytes. Thanks a lot hobbs for putting me in the right direction. – Reni Sep 20 '15 at 18:44