Apache Module : HTTP Firewall untuk mencegah SQL Injection, LFI, dan RFI - Elang Sakti
Download Ebook Belajar Arduino PDF, Arduino untuk pemula
Jasa Pembuatan Program Arduino, pemrograman Arduino
# Hack Your Skills! to be Professional Mechatronics

Apache Module : HTTP Firewall untuk mencegah SQL Injection, LFI, dan RFI

Tidak ada komentar
Script ini merupakan modul apache yang disetting untuk mencegah serangan SQL Injection Attack atau SQL Injectin Hack, LFI, dan RFI. Modul Apache ini sebenarnya adalah hasil tugas akhir saya di UIN Maulana Malik Ibrahim Malang, kampus tercinta hehe. Sebenarnya modul ini bisa lebih sederhana lagi, sebab pada modul ini saya tanamkan algoritma pencocokan string Zhu-Takaoka (download Jurnal Algoritma Zhu-Takaoka). Algoritma tersebut berfungsi untuk mencari string serangan yang cocok pada HTTP Request kemudian memberi tahu sistem bahwa request tersebut mengandung serangan atau tidak.

Untuk lebih simpelnya, algoritma tersebut perlu diganti dengan fungsi pencocokan string standar Apache atau bawaan bahasa C. Alasannya adalah keaamanan, bisa jadi script algoritma tersebut ada cacat pada penulisannya. Alasan yang lain adalah dengan menggunakan pencocokan string pada Apache atau C adalah lebih simpel dan terintegrasi dengan base-nya.

Berikut saya sertakan script module yang saya buat. Mungkin ada yang mau mengembangkannya untuk tugas akhir, penelitian, atau sekedar iseng :). Untuk cara compile dan installnya belum bisa saya sertakan di sini, temen-temen bisa berkunjung ke sini dulu, Apache Module Tutorial. :)
#include <httpd.h>
#include <http_config.h>
#include <http_request.h>
#include <http_log.h>
#include <util_filter.h>
#include <apr_strings.h>
#include <http_protocol.h>
#include <apr_hash.h>
#define BUFLEN 8192

module AP_MODULE_DECLARE_DATA hx_module;

//pattern
struct attack{
  char *keyword;
};

struct attack xss[]={"%3e","%3c"};
struct attack sql[]={"'--","%27--","\"--","%22--","'+or","%27+or","\"+or","%22+or","')+or","%27)+or","\")+or","%22)+or","order+by","order%20by","'%20or","%27%20or","\"%20or","%22%20or","')%20or","%27)%20or","\")%20or","%22)%20or","union+select","union%20select","union+all+select","union%20all%20select"};
struct attack lfi[]={"??","","../","..%2f"};
struct attack rfi[]={"??","","=http://","=http%3a%2f"};

//post pengaturan awal string match
void suffixes(char *x, int m, int *suff){
  int f,g,i;
  suff[m-1]=m;
  g=m-1;
  for (i=m-2;i>=0;--i){
    if (i>g&&suff[i+m-1-f]<i-g)
      suff[i]=suff[i+m-1-f];
    else{
      if(i<g) g=i;
      f=i;
      while(g>=0&&x[g]==x[g+m-1-f]) --g;
      suff[i] = f-g;
    }
  }
}

//untuk hitungan BM Good Suffix
void preBmGs(char *x, int m, int bmGs[]){
  int i, j, suff[strlen(x)];

  suffixes(x, m, suff);

  for (i=0;i<m;++i)
    bmGs[i]=m;
    j=0;
    for(i=m-1;i>=0;--i)
      if(suff[i]==i+1)
        for(;j<m-1-i;++j)
          if(bmGs[j]==m)
            bmGs[j]=m-1-i;
  for(i=0;i<=m-2;++i)
    bmGs[m-1-suff[i]]=m-1-i;
}

//cuma cari nilai maksimum
int max(int a, int b){
  if(a>b) return a;
  return b;
}

//algoritmanya Zhu-Takaoka (Bad Chaacter)
void preZtBc(char *x, int m, int ztBc[1000][1000]){
  int i,j;
  for(i=0;i<strlen(x);++i)
    for(j=0;j<strlen(x);++j)
      ztBc[i][j]=m;
  for (i=0;i<strlen(x);++i)
    ztBc[i][x[0]]=m-1;
  for (i=1;i<m-1;++i){
    ztBc[x[i-1]][x[i]]=(m-1-i);
  }
}

/*x=pattern, y=text*/
int ZT(char *x, int m, char *y, int n){
  int i,ztBc[1000][1000],bmGs[n];
  int p,q;
  for(p=0;p<1000;p++){
    for(q=0;q<1000;q++){
      ztBc[p][q]=0;
    }
  }
  for(p=0;p<n;p++){
    bmGs[p] = 0;
  }

  /* Preprocessing */
  preZtBc(x, m, ztBc);
  preBmGs(x, m, bmGs);

  /* Searching */  
  int j = 0, count = 0;

  while(j<=n-m){
    i=m-1;
    while(i<m&&x[i]==y[i+j]){
      --i;
    }

    if (i < 0) {
      //kalo ketemu di sini
      count++;
      j += bmGs[0];
    }else{
      j += max(bmGs[i], ztBc[y[j + m - 2]][y[j + m - 1]]);
    }
  }
  return (count);
}

//ngonvert ke lower case
char *lower(char *str){
  char *v = malloc(strlen(str) * sizeof(str));
  int f=0;
  for(; *str; str++){
    *(v+f) = tolower(*str);
    f++;
  }
  v[f]='\0';
  return v;  
}

//klin
char *clean(char *in2){
  char *buff =(char *)malloc(sizeof(buff)*strlen(in2));
  int num=0;
  for(; *in2; in2++){
    if(*in2<32 || *in2>126){
      *(buff+num) = '\0';
      return buff;
    }else{
      *(buff+num) = *in2;
      num++;
    }
  }
  *(buff+num) = '\0';
  return buff;
}

int get_filter(request_rec *r){
  char *text;
  if(r->args != NULL){
    text = (char *) malloc(sizeof(r->args)*strlen(r->args));
    strcpy(text,r->args);
  }
  return (goto_error(clean(lower(text)), r));
}

static apr_status_t post_filter(ap_filter_t *f, apr_bucket_brigade *bbout, ap_input_mode_t mode, apr_read_type_e block, apr_off_t nbytes){
  request_rec *r = f->r;
  apr_status_t status;
  int asdf, end = 0;
  const char *buf;
  apr_bucket *b;
  apr_bucket *nextb;
  apr_bucket_brigade *bb;

  apr_size_t bytes = 0;

  int has_input = 0;
  const char *hdr = apr_table_get(r->headers_in, "Content-Length");
  if(hdr){
    has_input = 1;
  }

  if(hdr != NULL){
    bytes = strtol(hdr,NULL,0);
  }else{
    bytes = BUFLEN;
  }

  if(has_input){
    bb = apr_brigade_create(f->r->pool, f->r->connection->bucket_alloc);
    do{
      status = ap_get_brigade(f->next, bb, AP_MODE_READBYTES, APR_BLOCK_READ, BUFLEN);
      if(status == APR_SUCCESS){
        for(b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb); b = nextb){
          nextb = APR_BUCKET_NEXT(b);
          APR_BUCKET_REMOVE(b);
          APR_BRIGADE_INSERT_TAIL(bbout, b);
          if(APR_BUCKET_IS_EOS(b)){
            end = 1;
            break;
          }else if(APR_BUCKET_IS_METADATA(b)){
            continue;
          }
          // di sini
          status = apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ);
          asdf = goto_error(clean(lower((char *)buf)), r);
        }
      }
      apr_brigade_cleanup(bb);
    }while(!end && (status == APR_SUCCESS));
  }
  ap_rprintf(r,"%d",asdf);
  if(asdf == 400){
  }else{
    return ap_get_brigade(f->next, bbout, mode, block, bytes);
  }
}

int goto_error(char *low, request_rec *r){
  //xss
  char method[5];
  if(r->method_number == M_GET){
    strcpy(method,"GET");
  }else{
    strcpy(method,"POST");
  }

  int hxss = 0, maling=0, num;
  for(num=0; num<2; num++){
    if(strlen(xss[num].keyword) <= strlen(low)){
      int nilai = ZT(xss[num].keyword, strlen(xss[num].keyword), low, strlen(low));
      hxss += (nilai>0)? 1 : 0;
    }
  }
  if(hxss>1){
    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "XSS!  %s Data: %s",method,low);
 return 400;
  }

  //lfi
  int hlfi = 0;
  for(num=0; num<4; num++){
    if(strlen(lfi[num].keyword) <= strlen(low)){
      int nilai = ZT(lfi[num].keyword, strlen(lfi[num].keyword), low, strlen(low));
      if(nilai>0){
        hlfi += (lfi[num].keyword == "../" || lfi[num].keyword == "..%2f")? 2 : 1;
      }
    }
  }
  if(hlfi>1){
    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "LFI!  %s Data: %s",method,low);
 return 400;
  }

  //rfi
  int hrfi = 0;
  for(num=0; num<4; num++){
    if(strlen(rfi[num].keyword)<=strlen(low)){
      int nilai = ZT(rfi[num].keyword, strlen(rfi[num].keyword), low, strlen(low));
      if(nilai>0){
        hrfi += (rfi[num].keyword == "=http://" || rfi[num].keyword == "=http%3a%2f")? 2 : 1;
      }
    }
  }
  if(hrfi>2){
    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "RFI!  %s Data: %s",method,low);
 return 400;
  }

  //sqli
  int sqli = 0;
  for(num=0; num<26; num++){
    if(strlen(sql[num].keyword)<=strlen(low)){
      int nilai = ZT(sql[num].keyword, strlen(sql[num].keyword), low, strlen(low));
      sqli += (nilai>0) ? 1 : 0;
    }
  }
  if(sqli>0){
    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "SQLi!  %s Data: %s",method,low);
 return 400;
  }

  return OK;
}

static int main_filter(request_rec *r){
  if(r->method_number == M_GET){
    return get_filter(r);
  }else if(r->method_number == M_POST){
    ap_add_input_filter("posthx", NULL, r, r->connection);
  }
  return OK;
}

static void register_hooks(apr_pool_t *p){
  ap_hook_post_read_request(main_filter,NULL,NULL,APR_HOOK_LAST);
  ap_register_input_filter("posthx", post_filter, NULL, AP_FTYPE_RESOURCE);
}

module AP_MODULE_DECLARE_DATA hx_module ={ STANDARD20_MODULE_STUFF, NULL, NULL, NULL, NULL, NULL, register_hooks};



Written by Hari Santoso
Apache Module : HTTP Firewall untuk mencegah SQL Injection, LFI, dan RFI
Bahasan: Script ini merupakan modul apache yang disetting untuk mencegah serangan SQL Injection Attack atau SQL Injectin Hack , LFI , dan RFI . Mo...
Published at Kamis, 07 Maret 2013, Updated at Kamis, 07 Maret 2013
Reviewed by dr. on
Rating: 4.7

Tidak ada komentar :

Poskan Komentar