Esempio n. 1
0
/** Statically analyse the given ast.
 *
 * \param ast_ The AST.
 * \param in_object Whether or not ast_ is within the lexical scope of an object AST.
 * \param vars The variables defined within lexical scope of ast_.
 * \returns The free variables in ast_.
 */
static IdSet static_analysis(AST *ast_, bool in_object, const IdSet &vars)
{
    IdSet r;

    if (auto *ast = dynamic_cast<const Apply*>(ast_)) {
        append(r, static_analysis(ast->target, in_object, vars));
        for (AST *arg : ast->arguments)
            append(r, static_analysis(arg, in_object, vars));

    } else if (auto *ast = dynamic_cast<const Array*>(ast_)) {
        for (AST *el : ast->elements)
            append(r, static_analysis(el, in_object, vars));

    } else if (auto *ast = dynamic_cast<const Binary*>(ast_)) {
        append(r, static_analysis(ast->left, in_object, vars));
        append(r, static_analysis(ast->right, in_object, vars));

    } else if (dynamic_cast<const BuiltinFunction*>(ast_)) {
        // Nothing to do.

    } else if (auto *ast = dynamic_cast<const Conditional*>(ast_)) {
        append(r, static_analysis(ast->cond, in_object, vars));
        append(r, static_analysis(ast->branchTrue, in_object, vars));
        append(r, static_analysis(ast->branchFalse, in_object, vars));

    } else if (auto *ast = dynamic_cast<const Error*>(ast_)) {
        return static_analysis(ast->expr, in_object, vars);

    } else if (auto *ast = dynamic_cast<const Function*>(ast_)) {
        auto new_vars = vars;
        IdSet params;
        for (auto *p : ast->parameters) {
            if (params.find(p) != params.end()) {
                throw StaticError(ast_->location, "Duplicate function parameter: " + p->name);
            }
            params.insert(p);
            new_vars.insert(p);
        }
        auto fv = static_analysis(ast->body, in_object, new_vars);
        for (auto *p : ast->parameters)
            fv.erase(p);
        append(r, fv);

    } else if (dynamic_cast<const Import*>(ast_)) {
        // Nothing to do.

    } else if (dynamic_cast<const Importstr*>(ast_)) {
        // Nothing to do.

    } else if (auto *ast = dynamic_cast<const Index*>(ast_)) {
        append(r, static_analysis(ast->target, in_object, vars));
        append(r, static_analysis(ast->index, in_object, vars));

    } else if (auto *ast = dynamic_cast<const Local*>(ast_)) {
        IdSet ast_vars;
        for (const auto &bind: ast->binds) {
            ast_vars.insert(bind.first);
        }
        auto new_vars = vars;
        append(new_vars, ast_vars);
        IdSet fvs;
        for (const auto &bind: ast->binds)
            append(fvs, static_analysis(bind.second, in_object, new_vars));

        append(fvs, static_analysis(ast->body, in_object, new_vars));

        for (const auto &bind: ast->binds)
            fvs.erase(bind.first);

        append(r, fvs);

    } else if (dynamic_cast<const LiteralBoolean*>(ast_)) {
        // Nothing to do.

    } else if (dynamic_cast<const LiteralNumber*>(ast_)) {
        // Nothing to do.

    } else if (dynamic_cast<const LiteralString*>(ast_)) {
        // Nothing to do.

    } else if (dynamic_cast<const LiteralNull*>(ast_)) {
        // Nothing to do.

    } else if (auto *ast = dynamic_cast<Object*>(ast_)) {
        for (auto field : ast->fields) {
            append(r, static_analysis(field.name, in_object, vars));
            append(r, static_analysis(field.body, true, vars));
        }

    } else if (auto *ast = dynamic_cast<ObjectComposition*>(ast_)) {
        auto new_vars = vars;
        new_vars.insert(ast->id);
        append(r, static_analysis(ast->field, false, new_vars));
        append(r, static_analysis(ast->value, true, new_vars));
        r.erase(ast->id);
        append(r, static_analysis(ast->array, in_object, vars));

    } else if (dynamic_cast<const Self*>(ast_)) {
        if (!in_object)
            throw StaticError(ast_->location, "Can't use self outside of an object.");

    } else if (dynamic_cast<const Super*>(ast_)) {
        if (!in_object)
            throw StaticError(ast_->location, "Can't use super outside of an object.");

    } else if (auto *ast = dynamic_cast<const Unary*>(ast_)) {
        append(r, static_analysis(ast->expr, in_object, vars));

    } else if (auto *ast = dynamic_cast<const Var*>(ast_)) {
        if (vars.find(ast->id) == vars.end()) {
            throw StaticError(ast->location, "Unknown variable: "+ast->id->name);
        }
        r.insert(ast->id);

    } else {
        std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl;
        std::abort();

    }

    for (auto *id : r)
        ast_->freeVariables.push_back(id);

    return r;
}
Esempio n. 2
0
int
main (int argc, char **argv) {

	int c, valid, bnr = 9, showpopup = 0, flags = 0;			/* temporary vars */
	char errbuf[PCAP_ERRBUF_SIZE];						/* error buffer */

	libnet_t *l;								/* libnet handle for address retrieval */
	char libnet_errbuf[LIBNET_ERRBUF_SIZE];					/* libnet error messages */

	char start_time[24], end_time[24];
	time_t acurtime, bcurtime;
	struct tm *aloctime, *bloctime;

	struct configuration conf, *config=&conf;				/* struct to hold config for current session */
	struct validated_queue *start = NULL, *end = NULL;			/* pointers to validated queue */

	/* get current system time */
	acurtime = time (NULL);

	/* convert it to local time representation */
	aloctime = localtime (&acurtime);

	/* format time struct into a char array */
	strftime (start_time, 24, "%d/%b/%Y %H:%M:%S", aloctime);

	/* load default params in config struct */
	config->flags = 0;
	config->verbose = 0;
	config->queue_size = 0;
	config->dev = NULL;
	config->dport = HTTP;
	config->mode = DETECT;
	config->gtimeout = TIME_OUT;
	config->scan_type = SYN_SCAN;

	config->a_port_name = "HTTP";
	config->a_scan_type = "SYN_SCAN";

	/* parse and load cmd-line params in config struct */
	while ((c = getopt (argc, argv, "hi:p:Parsfuetvg:o")) != -1) {
		switch (c) {
			case 'h':
				print_usage ();
				exit (EXIT_SUCCESS);
			case 'i':
				config->dev = optarg;
				break;
			case 'p':
				if (1 <= atoi (optarg) && 65535 >= atoi (optarg)) {
					config->dport = atoi (optarg);
				}
				break;
			case 'P':
				config->mode = PREVENT;
				break;
			case 'a':
				config->scan_type = ACK_SCAN;
				config->flags = config->flags | ACK;
				flags = flags | ACK;
				break;
			case 'r':
				config->scan_type = RST_SCAN;
				config->flags = config->flags | RST;
				flags = flags | RST;
				break;
			case 's':
				config->scan_type = SYN_SCAN;
				config->flags = config->flags | SYN;
				flags = flags | SYN;
				break;
			case 'f':
				config->scan_type = FIN_SCAN;
				config->flags = config->flags | FIN;
				flags = flags | FIN;
				break;
			case 'u':
				config->scan_type = UDP_SCAN;
				config->a_scan_type = "UDP_SCAN";
				break;
			case 'e':
				config->scan_type = ECHO_SCAN;
				config->a_scan_type = "ECHO_SCAN";
				break;
			case 't':
				config->scan_type = TSTAMP_SCAN;
				config->a_scan_type = "TSTAMP_SCAN";
				break;
			case 'v':
				config->verbose = 1;
				break;
			case 'g':


				if (1 <= atoi (optarg) && 9 >= atoi (optarg)) {
					config->gtimeout = atoi (optarg);
				}
				break;
			case 'o':
				showpopup = 1;
				break;
			case '?':
				if ('i' == optopt || 'p' == optopt) {
					print_usage ();
					exit (EXIT_FAILURE);
				} else if (isprint (optopt)) {
					printf ("\n [-] unknown option `-%c'\n", optopt);
					print_usage ();
					exit (EXIT_FAILURE);
				} else {
					printf ("\n unknown option character `\\x%x'\n", optopt);
					print_usage ();
					exit (EXIT_FAILURE);
				}
			default:
				print_usage ();
				exit (EXIT_FAILURE);
		}
	}

	if (0 == flags) { config->flags = SYN; }
	else if (ACK == flags) { config->a_scan_type = "ACK_SCAN"; }
	else if (RST == flags) { config->a_scan_type = "RST_SCAN"; }
	else if (SYN == flags) { config->a_scan_type = "SYN_SCAN"; }
	else if (FIN == flags) { config->a_scan_type = "FIN_SCAN"; }

	/* print an ASCII-ART banner */
	print_banner ();

	switch (config->dport) {
		case HTTP:
				config->a_port_name = "HTTP";
				break;
		case FTP:
				config->a_port_name = "FTP";
				break;
		case TELNET:
				config->a_port_name = "TELNET";
				break;
		case SSH:
				config->a_port_name = "SSH";
				break;
		case SMTP:
				config->a_port_name = "SMTP";
				break;
		default:
				config->a_port_name = "UNKNOWN";
				break;
	}

	/* check if we are root, else exit */
	if (0 != getuid ()) {
		printf ("\n [!] you need to be root buddy...\n\n");
		exit (EXIT_FAILURE);
	}

	/* find a capture device if not specified on command-line */
	if (config->dev == NULL) {
		config->dev = pcap_lookupdev (errbuf);
		if (config->dev == NULL) {
			printf ("\n [-] could not find default device: %s\n\n", errbuf);
			exit (EXIT_FAILURE);
		}
	}

	/* initialize libnet library to find local mac and ip addresses */
	l = libnet_init (LIBNET_LINK, config->dev, libnet_errbuf);
	if (NULL == l) {
		printf ("\n [-] libnet_init() failed: %s\n\n", libnet_errbuf);
		exit (EXIT_FAILURE);
	}

	/* fetch local mac address */
	config->macaddr = libnet_get_hwaddr (l);
	if (NULL == config->macaddr) {
		printf ("\n [-] could not fetch local mac address: %s\n\n", libnet_geterror (l));
		libnet_destroy (l);
		exit (EXIT_FAILURE);
	} else {
		snprintf (config->llmac, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
				config->macaddr->ether_addr_octet[0], config->macaddr->ether_addr_octet[1],
				config->macaddr->ether_addr_octet[2], config->macaddr->ether_addr_octet[3],
				config->macaddr->ether_addr_octet[4], config->macaddr->ether_addr_octet[5]);
	}

	/* fetch local ip address */
	config->ipaddr = libnet_get_ipaddr4 (l);
	if (-1 == config->ipaddr) {
		printf ("\n [-] could not fetch local ip address: %s\n\n", libnet_geterror (l));
		libnet_destroy (l);
		exit (EXIT_FAILURE);
	} else {
		snprintf (config->llip, 16, "%s", libnet_addr2name4 (config->ipaddr, LIBNET_DONT_RESOLVE));
	}

	printf (" [+] session started at %s \n", start_time);
	printf (" [+] default configuration and cmd-line parameters loaded\n");
	printf (" [+] device: \"%s\", mode: \"%s\", port: \"%s\", scan-type: \"%s\"\n",
		config->dev, (config->mode)? "PREVENT" : "DETECT", config->a_port_name,	config->a_scan_type);

	/* start repeat loop */

	/* call sniffer module to fill up our config struct with packet fields */
	printf (" [+] calling arp-sniffer module to capture incoming arp packets\n");
	config = sniffer (config);

	printf ("\n [+] above arp packet was captured and respective fields were saved for analysis\n");
	printf (" [+] calling anamoly-detection module to perform static analysis on saved packet fields\n");

	/* call static_analysis module to perform some static checks on packet fields */
	valid = static_analysis (conf);
	if (EXIT_FAILURE == valid) {
		printf (" [+] analyzed arp packet seems to be specially-crafted. kernel might have added the"
			" poisonous SIP-SMAC entry in arp cache\n");
		if (DETECT == conf.mode) {
			printf (" [+] you need to clean up arp cache manually. delete entry for SIP (%s) - SMAC (%s)\n",
				conf.a_sip, conf.a_sha);
			printf (" [+] to automate this process, please terminate this session and restart arp-secur"
				" in PREVENT mode, i.e with -P switch\n");

		} else if (PREVENT == conf.mode) {
			printf (" [+] cleaning up arp cache by deleting entry for SIP (%s) - SMAC (%s)\n",
				conf.a_sip, conf.a_sha);
				cache_cleanup (conf.a_sip, conf.a_sha);
		}
	} else {
		printf (" [+] analyzed arp packet does not seem to be specially-crafted\n");

		/* check if we have already processed (and validated) the ip-mac pair... */
		if (0 < conf.queue_size) {
			printf (" [+] calling known-traffic-filter module to check if we have validated"
				" IP - MAC (%s - %s) pair earlier (queue_size: %d)\n",
				conf.a_sip, conf.a_sha, conf.queue_size);
			known_traffic_filter (start, conf.a_sip, conf.a_sha, conf.queue_size);
		} else {
			printf (" [+] no IP-MAC pairs have been validated yet (queue_size: %d)\n", conf.queue_size);
		}

		/* ...hmmm, seems to be a new mac-ip pair. let's validate it then... */
		printf (" [+] calling spoof-detection module to validate IP - MAC (%s - %s) pair\n", conf.a_sip, conf.a_sha);
		valid = spoof_detector (conf, start, end);

		if (0 == valid) {
			printf ("\n [+] try other scan types before determining the validity of the IP - MAC (%s - %s)\n",
				conf.a_sip, conf.a_sha);
			if (DETECT == conf.mode) {
				printf (" [+] for safety reasons, you need to clean up arp cache manually."
					" delete entry for (%s - %s)\n", conf.a_sip, conf.a_sha);
				printf (" [+] to automate this process from now onwards,"
					" restart arp-secur in PREVENT mode, i.e with -P switch\n");
			} else if (PREVENT == conf.mode) {
				printf (" [+] cleaning up arp cache by deleting entry for SIP (%s) - SMAC (%s)\n",
					conf.a_sip, conf.a_sha);
				cache_cleanup (conf.a_sip, conf.a_sha);
			}
		}

		/* display session summary in a system popup notification */
		if (1 == showpopup) {
			alert (conf.a_sip, conf.a_sha, valid);
		}

		/* end repeat loop */

		/* end arp-secur session */
		bcurtime = time (NULL);
		bloctime = localtime (&bcurtime);
		strftime (end_time, 24, "%d/%b/%Y %H:%M:%S", bloctime);
		printf ("\n [+] session finished at %s\n\n", end_time);

	}

	return 0;

}//main
Esempio n. 3
0
void jsonnet_static_analysis(AST *ast)
{
    static_analysis(ast, false, IdSet{});
}