Tuesday, June 03, 2008

sysnotes

一直在寻找一个免费托管的软件仓库,昨天下午闲来无事,搜到了sharesource,可以提供svn/hg访问。于是注册了一个项目 - sysnotes,用来放置我的LaTeX笔记。今天上午过来已经便收到确认通知邮件。:)

$ hg clone http://hg.sharesource.org/sysnotes

Labels:

code injection

有很多文章关于代码注入,主要过程是用ptrace系统调用attach一个进程,注入代码(shellcode),然后再detach该进程使得被注入 的代码得以执行。通常注入的代码被存放于堆栈中,因为它的大小可以动态调整,并且这些``蛛丝马迹''执行后可以被后续过程调用擦除。然而现代CPU(如 Intel IA32)都包含了NX位,即可修改内存不可执行(writable xor executable),这使得大部分注入到stack中的shellcode都无法运行,从而提高了系统的安全性。

有许多方法可以绕过该限制,比如: return to libc。作为代码注入的示例,我们可以直接将代码注入到EIP指向的内存区域:
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
perror("ptrace failed");
exit(-1);
}

waitpid(pid, NULL, 0);
printf("[1] - Process attached\n");

if (ptrace(PTRACE_GETREGS, pid, NULL, &regs)!=-1) {
printf("[2] - Extract register eip (0x%.8x)\n", regs.eip);

for (i=0; i ptrace(PTRACE_POKEDATA, pid, regs.eip+i, *(int*)(injected_code+i));
printf("[3] - Code inserted\n");
}

ptrace(PTRACE_DETACH, pid, NULL, NULL);
printf("[4] - Running Code\n");
其 中injected_code即为shellcode首地址,一般以汇编语言书写,如上例as风格汇编代码(当然一般是exece("/bin/sh", ["/bin/sh", NULL], NULL)。由于被注入进程的文本段被修改,这样该进程的行为被修改,这并不是一个好主意。这里仅仅是代码注入的一个简单示例罢了。

INJECTED_LEN是被注入代码的字节长度,可以由size命令获得。

Labels: , ,

汇编语言的艺术

Linux下使用汇编语言 有很多选择:内联汇编,as或者nasm/yasm,下面是使用 as的例子:
.text
.globl _start
_start:
jmp get_string
print_string:
movl $4, %eax /* __NR_write */
movl $1, %ebx
popl %ecx
movl $6, %edx
int $0x80

movl %eax, %ebx
movl $1, %eax /* __NR_exit */
int $0x80

get_string:
call print_string
.string "hello\n"

这 段汇编使用了传统的int $0x80系统调用,这里最重要的窍门是怎样获取字符串的首地址(call/popl)。这个小技巧使得生成的代码是位置无关的(PIC - Position Independent Code)。这在code injection中注入shellcode非常普遍。

Labels: , ,