Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / 一个 Linux 病毒

[/]--------------------------------------------------------------------------------------[]===>[ 0x00: 前言 ]我又写了一个新文件(代码),关于Linux的病毒。
一个进程运行在本地机器上!(ELF)[-]--------------------------------------------------------------------------------------[-]===>[ 0x01: 关于ptrace() ]ptrace()是一个系统调用进程控制执行其他事件。
在跟踪进程(child)的现象生成,直到捕捉一个信号时,这一过程发生在进入停止状态,并通知跟踪进程由wait()系统调用。在此过程中的跟踪(parent) 决定什么跟踪过程中应该做的。考虑到,如果跟踪进程捕捉一个SIGKILL这将会被杀掉![-]--------------------------------------------------------------------------------------[-]===>[ 0x02: 有趣的ptrace() ] #include <stdio.h>
#include <unistd.h>int main() { char str[]="Hi Sup Guys? ";
 write(0, str, strlen(str));
 return 0;} (.)输出:$./target1
Hi
Sup Guys?
$下面,在这里你将看到tracer1.c代码: #include <sys/ptrace.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <linux/user.h>
#include <sys/syscall.h>
int main(int argc, char *argv[]) {if (argc < 2) {
 printf("please specify the absolute path of the target1 ");
 printf("%s < /path/target1 > ", argv[0]);
 exit(1);
 }int orig_syscall = 0;
int status;
struct user_regs_struct regs;
pid_t pid;pid = fork();if (pid == 0) { //childptrace(PTRACE_TRACEME, 0, 0, 0);
execl(argv[1], argv[1], NULL);
} else { //parentwait (&status); //等待child while(1) { ptrace(PTRACE_SYSCALL, pid, 0, 0);  //重启停止child并发送一个SIGTRAP wait(&status); //再次等待child ptrace(PTRACE_GETREGS, pid, 0, &regs);
 orig_syscall = regs.orig_eax; //这儿我有原始的eax (syscall编号)  if (orig_syscall == SYS_write) { //我们的syscall编号SYS_write ??
  regs.edx = 3; //调整edx为3(最大msg长度 -> 更多信息在这儿:man write(1) )
  ptrace(PTRACE_SETREGS, pid, 0, &regs); //GP寄存器(s)
  }  }
 } ptrace( PTRACE_DETACH, pid, NULL, NULL );
 return 0;} (.)输出:#./tracer1 /home/netspy/target1
Hi#正如你说看到的输出tracer1是“Hi ”!
但是,为什么?看看tracer1.c源代码;有一个“重要”任务:[...]
regs.edx = 3;
[...]我们设置寄存器edx为3(最大长度“字符串” 在我们的write() syscall)。深入查找tracer1所做的事件:1. 检查syscall write()是否被调用
2. 读取CPU寄存器
3. 设定寄存器edx为3
4. 进程跟踪分离例如:write(0,   -> 标准输出
"Hi Sup Guys? ,  -> 它只输出 Hi (edx = 3)
3);    -> 修改 edx (edx = 3)
你怎么做呢?简单吗?
Cool,现在我只是想尝试解释其他有趣的例子;所以就看看target2.c和tracer2.c源代码! #include <stdio.h>
#include <unistd.h>int main() {
 printf( "user id: %d ", getuid() );
 execl("/bin/csh", "csh", NULL, 0);
 return 0;
} (.) 输出:
$ ./target2
user id: 1000
%id
uid=1000(netspy) gid=100(users) groups=11(floppy),17(audio),18(video),19(cdrom),100(user)
现在看看.. tracer2.c : #include <sys/ptrace.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <linux/user.h>
#include <sys/syscall.h>
int main(int argc, char *argv[]) {if (argc < 2) {
 printf("please specify the absolute path of the target1 ");
 printf("%s < /home/netspy/articles/target1 > ", argv[0]);
 exit(1);
 }int orig_syscall = 0;
int status;
struct user_regs_struct regs;
pid_t pid;pid = fork();if (pid == 0) { //childptrace(PTRACE_TRACEME, 0, 0, 0);
execl(argv[1], argv[1], NULL);
} else { //parent wait (&status); //等待child while(1) { ptrace(PTRACE_SYSCALL, pid, 0, 0);  //重启停止child并发送一个SIGTRAP wait(&status); //再次等待child ptrace(PTRACE_GETREGS, pid, 0, &regs);
 orig_syscall = regs.orig_eax; // 这儿我有原始的eax (syscall编号)  if (orig_syscall == SYS_getuid32) {
  regs.ebx = 0; //设置ebx为0(root访问)
  ptrace(PTRACE_SETREGS, pid, 0, &regs); //GP 寄存器(s)
  }  }
 } ptrace( PTRACE_DETACH, pid, NULL, NULL );
 return 0;} 
(.) 输出:
# ./tracer2 /home/netspy/articles/target2
user id: 0
%id;
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy)
Killed!#如果你读的源代码你会发现我的注释并且我认为/希望你能理解,但对懒惰的人我会解释主要函数。[... 在 child 中 ...]ptrace(PTRACE_TRACEME, 0, 0, 0);
execl(argv[1], argv[1], NULL);[....]只是跟踪的进程...[... 在 parent 中 ...]1. ptrace(PTRACE_SYSCALL, pid, 0, 0);
2. ptrace(PTRACE_GETREGS, pid, 0, &regs);
orig_syscall = regs.orig_eax;3. if (orig_syscall == SYS_getuid32) {
4. regs.ebx = 0;
5. ptrace(PTRACE_SETREGS, pid, 0, &regs);
}[....]这有点更加困难,但如果你懂得C语言,这将不会成为问题。1.   重新启动停止child并读取syscall
2.   读取CPU寄存器
3/4. 如果syscall是SYS_getuid32设置ebx为0并再次以root访问
5.   复制child寄存器现在 /bin/csh shell 是root权限!!
  • 1
  • 2
  • 下一页
Htop:Ubuntu下功能全面的进程查看器[多图]硬件防火墙基本知识相关资讯      Linux病毒 
  • 那些年困扰Linux的蠕虫、病毒和木  (01/07/2015 19:36:53)
  • Ubuntu 11.04 杀毒软件ESET NOD32  (07/11/2011 16:41:51)
  • Linux病毒为何不会泛滥成灾?  (02/28/2011 20:25:43)
  • 研究人员发现针对Linux用户的银行  (08/08/2013 23:16:11)
  • 手机病毒概念疑似夸大宣传 杀软商  (03/17/2011 10:14:30)
  • Penguin Pills :Linux下“杀软”旗  (02/27/2011 08:21:29)
本文评论 查看全部评论 (0)
表情: 姓名: 字数


评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款