⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ratproxy.c

📁 Google 推出一套免費的 Web 安全評估工具
💻 C
📖 第 1 页 / 共 4 页
字号:
/*   ratproxy   --------   A simple HTTP proxy to use for code audits of rich web 2.0 applications.   Meant to detect JSON-related and other script-accessible content problems as   you interact with the tested application and otherwise just mind your business.   Please use this tool responsibly and in good faith. Thanks.   Author: Michal Zalewski <lcamtuf@google.com>   Copyright 2007, 2008 by Google Inc. All Rights Reserved.   Licensed under the Apache License, Version 2.0 (the "License");   you may not use this file except in compliance with the License.   You may obtain a copy of the License at     http://www.apache.org/licenses/LICENSE-2.0   Unless required by applicable law or agreed to in writing, software   distributed under the License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   See the License for the specific language governing permissions and   limitations under the License. */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#include <signal.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <sys/wait.h>#include <ctype.h>#include <netdb.h>#include <openssl/md5.h>#include <time.h>#include "config.h"#include "types.h"#include "debug.h"#include "nlist.h"#include "http.h"#include "mime.h"#include "ssl.h"#include "string-inl.h"static struct naive_list  domains;		/* Domains to keep track of   */static _u8  check_png,				/* Check all PNG files?       */            dump_urls,				/* Dump all visited URLs?     */            all_files,				/* Report all file inclusions */            all_flash,				/* Report all Flash documents */            get_xsrf,				/* Report GET XSRF status     */            bad_js,				/* Report risky Javascript    */            all_post,				/* Report all POST requests   */            all_cookie,				/* Report all cookie URLs     */            picky_cache,			/* Be picky about chdrs       */            use_double,				/* Make 2, not 1 extra req    */            try_attacks,			/* Validate XSRF/XSS suspects */            fix_attacks,			/* Correct XSRF/XSS fallout   */            log_active,				/* Log cross-domain content   */            log_mixed,				/* Log mixed content          */            use_any,				/* Listen on any address      */            all_xss;				/* Report all XSS suspects    */static _u32 use_port = DEFAULT_PORT;		/* Proxy port to listen on    */_u8* use_proxy;					/* Upstream proxy             */_u8* trace_dir;					/* Trace directory            */_u32 proxy_port = 8080;				/* Upstream proxy port        */_u8  use_len;					/* Use length, not cksum      */static FILE* outfile;				/* Output file descriptor     *//* Display usage information */static void usage(_u8* argv0) {  debug("Usage: %s [ -w logfile ] [ -v logdir ] [ -p port ] [ -d domain ] [ -P host:port ] "        "[ -xtifkgmjscael2XCr ]\n"        "   -w logfile    - write results to a specified file (default: stdout)\n"        "   -v logdir     - write HTTP traces to a specified directory (default: none)\n"        "   -p port       - listen on a custom TCP port (default: 8080)\n"        "   -d domain     - analyze requests to specified domains only (default: all)\n"        "   -P host:port  - use upstream proxy for all requests (format host:port)\n"        "   -r            - accept remote connections (default: 127.0.0.1 only)\n"        "   -l            - use response length, not checksum, for identity check\n"        "   -2            - perform two, not one, page identity check\n"        "   -e            - perform pedantic caching headers checks\n"        "   -x            - log all XSS candidates\n"        "   -t            - log all directory traversal candidates\n"        "   -i            - log all PNG files served inline\n"        "   -f            - log all Flash applications for analysis (add -v to decompile)\n"        "   -s            - log all POST requests for analysis\n"        "   -c            - log all cookie setting URLs for analysis\n"        "   -g            - perform XSRF token checks on all GET requests\n"        "   -j            - report on risky Javascript constructions\n"        "   -m            - log all active content referenced across domains\n"        "   -X            - disruptively validate XSRF, XSS protections\n"        "   -C            - try to auto-correct persistent side effects of -X\n"        "   -k            - flag HTTP requests as bad (for HTTPS-only applications)\n"        "   -a            - indiscriminately report all visited URLs\n\n"        "Example settings suitable for most tests:\n"        "  1) Low verbosity  : -v <outdir> -w <outfile> -d <domain> -lfscm\n"        "  2) High verbosity : -v <outdir> -w <outfile> -d <domain> -lextifscgjm\n"        "  3) Active testing : -v <outdir> -w <outfile> -d <domain> -XClfscm\n\n"        "Multiple -d options are allowed. Consult the documentation for more.\n", argv0);  exit(1);}#define sayf(x...) fprintf(outfile,x)/* Check hostname against a list of tracked ones. */static _u8 host_ok(_u8* hname) {  _u32 i, hlen;  /* If no domains defined, accept all. */  if (!domains.c) return 1;  hlen = strlen(hname);  for (i=0;i<domains.c;i++) {    _u32 dlen = strlen(domains.v[i]);    if (dlen > hlen) continue;    if (!strcmp(hname + (hlen - dlen), domains.v[i])) return 1;  }  return 0;}/* Test for XSSable payload */static _u8 xss_field(_u8* value, _u8 head) {  _u32 c = 0;  if (strlen(value) < (head ? MIN_XSS_HEAD : MIN_XSS_LEN)) return 0;  while (no_xss_text[c]) {    if (!strncasecmp(value,no_xss_text[c],strlen(no_xss_text[c]))) return 0;    c++;  }  return 1;}#define MOD_PRED    1#define MOD_AUTH    2#define MOD_ECHO    4#define NOECHO(_x) ((_x) & ~MOD_ECHO)#define ECHO(_x) ((_x) & MOD_ECHO)/* Check if the page has a predictable URL, user-specific content, echoed parameters. */static _u8 get_modifiers(struct http_request* req, struct http_response* res) {  FILE *server;  static struct http_response* mini = 0;  _u32 ret = 0;  _u32 fno = 0;  _u32 i;  /* Test for echoed query parameters in response body... */  if (res->is_text && res->payload_len) {#ifdef CHECK_ECHO_PATH    if (req->path && strstr(res->payload,req->path)) ret = MOD_ECHO;#endif /* CHECK_ECHO_PATH */    for (i=0;!ret && i<req->p.c;i++)       if (!req->p.fn[i][0] && xss_field(req->p.v2[i],0) && strstr(res->payload,req->p.v2[i]))        { ret = MOD_ECHO; break; }  }  /* ...and in HTTP header values. */  for (i=0;!ret && i<req->p.c;i++)    if (!req->p.fn[i][0] && xss_field(req->p.v2[i],1)) {      _u32 j;      for (j=0;j<res->h.c;j++)        if (strstr(res->h.v2[j],req->p.v2[i])) { ret = MOD_ECHO; break; }    }        /* Check for predictable URLs. */  if (!req->xsrf_safe) ret |= MOD_PRED;  /* Check for authentication. */  /* Some field names may override our checks. */  while (auth_fields[fno]) {    _u32 i;    for (i=0;i<req->p.c;i++) {      if (auth_fields[fno][0] == '=') {        if (!strcasecmp(req->p.v1[i],auth_fields[fno] + 1)) return ret | MOD_AUTH;      } else {        if (rp_strcasestr(req->p.v1[i],auth_fields[fno])) return ret | MOD_AUTH;      }    }    fno++;  }  /* No cookies? Then do not resend. */  if (!req->cookies.c) return ret;  /* Try to verify that the request requires authentication by replaying it with     no cookies. This should have no side effects in sanely written applications. */  /* TODO: We should continue also if custom HTTP headers or HTTP auth is detected;     we currently bail out on this, however. */  if (!mini) {    server = open_server_complete(0,req);    if (req->from_ssl) {      ssl_setup();      ssl_start(fileno(server),-1);      fclose(server);      server = fdopen(ssl_srv_tap,"w+");    }    mini = send_request(0,server,req,1);    if (req->from_ssl) ssl_shutdown();    checksum_response(mini);    if (use_double) {      _u64 temp = mini->cksum;      /* ...and do it again! */      server = open_server_complete(0,req);      if (req->from_ssl) {        ssl_setup();        ssl_start(fileno(server),-1);        fclose(server);        server = fdopen(ssl_srv_tap,"w+");      }      mini = send_request(0,server,req,1);      if (req->from_ssl) ssl_shutdown();      checksum_response(mini);       /* If checksum changes over time, give up. */      if (temp != mini->cksum) mini->cksum = res->cksum;    }      }  if (mini->cksum != res->cksum) ret |= MOD_AUTH;  return ret;}/* DISRUPTIVE CHECK: Try removing XSRF protection, see what happens. */static void try_replay_xsrf(struct http_request* req, struct http_response* res) {  FILE *server;  struct http_response* not;  struct http_request r2;  _u32 i;  _u8 got_token = 0;  if (!req->xsrf_safe || req->authsub) return;  memcpy(&r2,req,sizeof(struct http_request));  /* Duplicate parameter value pointer array, so that we may modify it at will. */  r2.p.v2 = malloc(r2.p.c * sizeof(_u8*));  if (!r2.p.v2) fatal("out of memory");  memcpy(r2.p.v2,req->p.v2,r2.p.c * sizeof(_u8*));  /* Do not run contains_token() checks on file fields. */  for (i=0;i<req->p.c;i++)    if (!req->p.fn[i][0] && contains_token(req->p.v1[i],req->p.v2[i])) {      got_token = 1;      r2.p.v2[i] = "0"; /* Clobber value. */    }  /* Ooops! */  if (!got_token) return;  /* Rebuild query / payload strings. */  reconstruct_request(&r2);  server = open_server_complete(0,req);  if (req->from_ssl) {    ssl_setup();    ssl_start(fileno(server),-1);    fclose(server);    server = fdopen(ssl_srv_tap,"w+");  }  not = send_request(0,server,&r2,0);  if (req->from_ssl) ssl_shutdown();  /* Fix potential side effects of our request. */  if (fix_attacks) {    server = open_server_complete(0,req);    if (req->from_ssl) {      ssl_setup();      ssl_start(fileno(server),-1);      fclose(server);      server = fdopen(ssl_srv_tap,"w+");    }    send_request(0,server,req,0); /* sink response */    if (req->from_ssl) ssl_shutdown();  }  checksum_response(not);  /* Clobbering all XSRF-ish tokens caused no change? */  if (not->cksum == res->cksum) req->xsrf_safe = 0;}/* DISRUPTIVE CHECK: Try injecting XSS payload, see what happens. */static _u8 try_replay_xss(struct http_request* req, struct http_response* res) {  FILE *server;  struct http_response* not;  struct http_request r2;  _u32 i;  _u8 got_candidate = 0;  _u8* cur;  _u8 htmlstate = 0, htmlurl = 0;  if (!res->is_text) return 0;  memcpy(&r2,req,sizeof(struct http_request));  /* Duplicate parameter value pointer array, so that we may modify it at will. */  r2.p.v2 = malloc(r2.p.c * sizeof(_u8*));  if (!r2.p.v2) fatal("out of memory");  memcpy(r2.p.v2,req->p.v2,r2.p.c * sizeof(_u8*));  for (i=0;i<req->p.c;i++)     if (!req->p.fn[i][0] && xss_field(req->p.v2[i],0) && strstr(res->payload,req->p.v2[i])#ifndef XSS_XSRF_TOKENS         && !contains_token(req->p.v1[i],req->p.v2[i])#endif /* !XSS_XSRF_TOKENS */  ) {      /* This does not account for all scenarios possible XSS scenarios, but is a         pretty good all-around string. Since we want to minimize the number of         requests generated, it will have to do. */      r2.p.v2[i] = "qg:qg qg=-->qg\"qg>qg'qg>qg+qg<qg>";      got_candidate = 1;    }  if (!got_candidate) return 0;  /* Rebuild query / payload strings. */  reconstruct_request(&r2);  server = open_server_complete(0,req);  if (req->from_ssl) {    ssl_setup();    ssl_start(fileno(server),-1);    fclose(server);    server = fdopen(ssl_srv_tap,"w+");  }  not = send_request(0,server,&r2,0);  if (req->from_ssl) ssl_shutdown();  /* Fix potential side effects of our request. */  if (fix_attacks) {    server = open_server_complete(0,req);    if (req->from_ssl) {      ssl_setup();      ssl_start(fileno(server),-1);      fclose(server);      server = fdopen(ssl_srv_tap,"w+");    }    send_request(0,server,req,0); /* sink response */    if (req->from_ssl) ssl_shutdown();  }  if (!not->payload_len) return 0;  detect_mime(not);  if (not->is_text)    detect_charset(not);  /* Do some minimal and dumbed down HTML parsing on the response to detect q9g     strings in dangerous configurations. */#define HS_IN_TAG   1#define HS_IN_DBLQ  2#define HS_IN_SNGQ  4#define HS_IN_COMM  8#define HS_IN_CDATA 16  cur = not->payload;  while (*cur) {    /* Detect successful XSS attempts... */    if (!strncasecmp(cur,"qg",2)) {      /* <tag foo=bar onload=...> */      if (htmlstate == HS_IN_TAG && !strncasecmp(cur+2," qg=",4)) return 1;      /* <tag src=foo:bar...> */      if (htmlurl && !strncasecmp(cur+2,":qg",3)) return 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -