#define _XOPEN_SOURCE 600 #include "pentest_state.h" #include #include #include void pentest_state_init(struct pentest_state *p_s, size_t max_targets, size_t max_attacks, size_t max_scans) { p_s->max_targets = max_targets; p_s->num_targets = 0; p_s->targets = malloc(max_targets * sizeof(char*)); p_s->max_attacks = max_attacks; p_s->num_attacks = 0; p_s->attacks = malloc(max_attacks *sizeof(struct active_attack*)); p_s->max_scans = max_scans; p_s->num_scans = 0; p_s->scans = malloc(max_scans *sizeof(struct active_scan*)); p_s->max_failed = PENTEST_STATE_INIT_NUM_PAST_ATTACKS; p_s->num_failed = 0; p_s->failed = malloc(p_s->max_failed * sizeof(struct past_attack)); p_s->max_worked = PENTEST_STATE_INIT_NUM_PAST_ATTACKS; p_s->num_worked = 0; p_s->worked = malloc(p_s->max_worked * sizeof(struct past_attack)); p_s->max_done = PENTEST_STATE_INIT_NUM_PAST_SCANS; p_s->num_done = 0; p_s->done = malloc(p_s->max_done * sizeof(struct past_scan)); pthread_mutex_init(&p_s->lock,NULL); } void pentest_state_cleanup(struct pentest_state *p_s) { for(size_t i = 0;i < p_s->num_targets;i++) { free(p_s->targets[i]); } free(p_s->targets); //destroy mutex too for(size_t i=0; i < p_s->num_failed ; i++) { past_attack_cleanup(&p_s->failed[i]); } free(p_s->failed); for(size_t i=0; i < p_s->num_worked ; i++) { past_attack_cleanup(&p_s->worked[i]); } free(p_s->worked); for(size_t i=0; inum_attacks;i++) { active_attack_cleanup(p_s->attacks[i]); } free(p_s->attacks); pthread_mutex_destroy(&p_s->lock); } void pentest_state_add_target(struct pentest_state *p_s, char *target) { pthread_mutex_lock(&p_s->lock); if(p_s->num_targets >= p_s->max_targets) { fprintf(stderr,"[Panic] Trying to add a target beyond the allowed threshold\n"); } p_s->targets[p_s->num_targets] = strdup(target); p_s->num_targets++; pthread_mutex_unlock(&p_s->lock); } void pentest_state_add_attack(struct pentest_state *p_s, struct active_attack *attack) { pthread_mutex_lock(&p_s->lock); if(p_s->num_attacks >= p_s->max_attacks) { fprintf(stderr,"[Panic] Trying to add an attack beyond the allowed threshold\n"); } p_s->attacks[p_s->num_attacks] = attack; p_s->num_attacks++; pthread_mutex_unlock(&p_s->lock); } void pentest_state_add_scan(struct pentest_state *p_s, struct active_scan *scan) { pthread_mutex_lock(&p_s->lock); if(p_s->num_scans >= p_s->max_scans) { fprintf(stderr,"[Panic] Trying to add an scan beyond the allowed threshold\n"); } p_s->scans[p_s->num_scans] = scan; p_s->num_scans++; pthread_mutex_unlock(&p_s->lock); } //Do we also do memory cleanup here? void pentest_state_rem_attack(struct pentest_state *p_s, struct active_attack *a) { pthread_mutex_lock(&p_s->lock); for(size_t i = 0; i < p_s->num_attacks ; i++) { struct active_attack *a_a = p_s->attacks[i]; if(!strcmp(a->attack->name,a_a->attack->name) && !strcmp(a->target,a_a->target)) { if(i != p_s->num_attacks -1 ) { p_s->attacks[i] = p_s->attacks[p_s->num_attacks-1]; } p_s->num_attacks--; active_attack_cleanup(a_a); break; } } pthread_mutex_unlock(&p_s->lock); } void pentest_state_rem_scan(struct pentest_state *p_s, struct active_scan *scan) { pthread_mutex_lock(&p_s->lock); for(size_t i = 0; i < p_s->num_scans ; i++) { struct active_scan *a_s = p_s->scans[i]; if(active_scan_eq(scan,a_s)) { if(i != p_s->num_scans -1 ) { p_s->scans[i] = p_s->scans[p_s->num_scans-1]; } p_s->num_scans--; active_scan_cleanup(a_s); break; } } pthread_mutex_unlock(&p_s->lock); } void pentest_state_rem_target(struct pentest_state *p_s, char *target) { //pthread_mutex_lock(&p_s->lock); for(size_t i = 0; i < p_s->num_targets ; i++) { char *a_target = p_s->targets[i]; if(!strcmp(a_target,target)) { if(i != p_s->num_targets -1 ) { p_s->targets[i] = p_s->targets[p_s->num_targets-1]; } p_s->num_targets--; //Free target? break; } } pthread_mutex_unlock(&p_s->lock); } void pentest_state_add_failed(struct pentest_state *p_s, char *a_p, char *target) { pthread_mutex_lock(&p_s->lock); if(p_s->num_failed >= p_s->max_failed) { //can fail spectacularly if malloc fails p_s->max_failed *= 2; p_s->failed = realloc(p_s->failed, p_s->max_failed*sizeof(struct past_attack)); } past_attack_init(&p_s->failed[p_s->num_failed], a_p, target); p_s->num_failed++; pthread_mutex_unlock(&p_s->lock); } void pentest_state_add_worked(struct pentest_state *p_s, char *a_p, char *target) { pthread_mutex_lock(&p_s->lock); if(p_s->num_worked >= p_s->max_worked) { //can fail spectacularly if malloc fails p_s->max_worked *= 2; p_s->worked = realloc(p_s->worked, p_s->max_worked*sizeof(struct past_attack)); } past_attack_init(&p_s->worked[p_s->num_worked], a_p, target); p_s->num_worked++; pthread_mutex_unlock(&p_s->lock); } void pentest_state_add_done(struct pentest_state *p_s, char *scan, char *target) { pthread_mutex_lock(&p_s->lock); if(p_s->num_done >= p_s->max_done) { //can fail spectacularly if malloc fails p_s->max_done *= 2; p_s->done = realloc(p_s->done, p_s->max_done*sizeof(struct past_scan)); } past_scan_init(&p_s->done[p_s->num_done], scan, target); p_s->num_done++; pthread_mutex_unlock(&p_s->lock); } bool pentest_active_target(struct pentest_state *p_s, char *target) { bool res = false; pthread_mutex_lock(&p_s->lock); for(size_t i = 0; i < p_s->num_targets;i++) { if(strcmp(p_s->targets[i],target) == 0) { res = true; break; } } pthread_mutex_unlock(&p_s->lock); return res; } bool pentest_exploited_target(struct pentest_state *p_s, char *target) { bool res = false; pthread_mutex_lock(&p_s->lock); pthread_mutex_unlock(&p_s->lock); return res; } bool pentest_attack_active(struct pentest_state *p_s, char *attack, char *target) { bool res = false; pthread_mutex_lock(&p_s->lock); for(size_t i = 0; i < p_s->num_attacks;i++) { struct attack_pattern *a_p = p_s->attacks[i]->attack; char *a_target = p_s->attacks[i]->target; if(strcmp(a_p->name, attack) ==0 && strcmp(a_target,target) == 0) { res = true; break; } } pthread_mutex_unlock(&p_s->lock); return res; } bool pentest_attack_failed(struct pentest_state *p_s, char *attack, char *target) { bool res = false; pthread_mutex_lock(&p_s->lock); for(size_t i = 0; i < p_s->num_failed; i++) { struct past_attack *p_a = &p_s->failed[i]; if(!strcmp(p_a->a_p, attack) && !strcmp(p_a->target, target)) { res = true; break; } } pthread_mutex_unlock(&p_s->lock); return res; } bool pentest_attack_worked(struct pentest_state *p_s, char *attack, char *target) { bool res = false; pthread_mutex_lock(&p_s->lock); for(size_t i = 0; i < p_s->num_worked; i++) { struct past_attack *p_a = &p_s->worked[i]; if(!strcmp(p_a->a_p, attack) && !strcmp(p_a->target, target)) { res = true; break; } } pthread_mutex_unlock(&p_s->lock); return res; } size_t pentest_state_num_attacks(struct pentest_state *p_s) { size_t num_attacks = 0; pthread_mutex_lock(&p_s->lock); num_attacks = p_s->num_attacks; pthread_mutex_unlock(&p_s->lock); return num_attacks; } size_t pentest_state_max_attacks(struct pentest_state *p_s) { size_t max_attacks = 0; pthread_mutex_lock(&p_s->lock); max_attacks = p_s->max_attacks; pthread_mutex_unlock(&p_s->lock); return max_attacks; } size_t pentest_state_num_targets(struct pentest_state *p_s) { size_t num_targets = 0; pthread_mutex_lock(&p_s->lock); num_targets = p_s->num_targets; pthread_mutex_unlock(&p_s->lock); return num_targets; } size_t pentest_state_max_targets(struct pentest_state *p_s) { size_t max_targets = 0; pthread_mutex_lock(&p_s->lock); max_targets = p_s->max_targets; pthread_mutex_unlock(&p_s->lock); return max_targets; } size_t pentest_state_num_scans(struct pentest_state *p_s) { size_t num_scans = 0; pthread_mutex_lock(&p_s->lock); num_scans = p_s->num_scans; pthread_mutex_unlock(&p_s->lock); return num_scans; } size_t pentest_state_max_scans(struct pentest_state *p_s) { size_t max_scans = 0; pthread_mutex_lock(&p_s->lock); max_scans = p_s->max_scans; pthread_mutex_unlock(&p_s->lock); return max_scans; } size_t pentest_state_num_failed(struct pentest_state *p_s) { size_t num_failed = 0; pthread_mutex_lock(&p_s->lock); num_failed = p_s->num_failed; pthread_mutex_unlock(&p_s->lock); return num_failed; } size_t pentest_state_max_failed(struct pentest_state *p_s) { size_t max_failed = 0; pthread_mutex_lock(&p_s->lock); max_failed = p_s->max_failed; pthread_mutex_unlock(&p_s->lock); return max_failed; } size_t pentest_state_num_worked(struct pentest_state *p_s) { size_t num_worked = 0; pthread_mutex_lock(&p_s->lock); num_worked = p_s->num_worked; pthread_mutex_unlock(&p_s->lock); return num_worked; } size_t pentest_state_max_worked(struct pentest_state *p_s) { size_t max_worked = 0; pthread_mutex_lock(&p_s->lock); max_worked = p_s->max_worked; pthread_mutex_unlock(&p_s->lock); return max_worked; } bool pentest_scan_active(struct pentest_state *p_s, char *scan, char *target) { bool res = false; pthread_mutex_lock(&p_s->lock); for(size_t i = 0; i < p_s->num_scans;i++) { struct scan *a_s = p_s->scans[i]->scan; char *a_target = p_s->scans[i]->target; if((!target && a_target) || (target && !a_target)) { continue; } if(strcmp(a_s->name, scan) ==0 && ( ((!a_target && !target) || strcmp(a_target,target) == 0))) { res = true; break; } } pthread_mutex_unlock(&p_s->lock); return res; } bool pentest_scan_done(struct pentest_state *p_s, char *scan, char *target) { bool res = false; pthread_mutex_lock(&p_s->lock); for(size_t i = 0; i < p_s->num_done; i++) { struct past_scan *s = &p_s->done[i]; if( (!target && s->target) || (target && !s->target)) { continue; } if(!strcmp(s->scan, scan) && ((!s->target && !target) || !strcmp(s->target, target) )) { res = true; break; } } pthread_mutex_unlock(&p_s->lock); return res; } char *pentest_state_get_target(struct pentest_state *p_s, size_t idx) { char *target = NULL; pthread_mutex_lock(&p_s->lock); if(idx < p_s->num_targets) { target = p_s->targets[idx]; } pthread_mutex_unlock(&p_s->lock); return target; } struct active_attack *pentest_state_get_attack(struct pentest_state *p_s, size_t idx) { struct active_attack *a_a = NULL; pthread_mutex_lock(&p_s->lock); if(idx < p_s->num_attacks) { a_a = p_s->attacks[idx]; } pthread_mutex_unlock(&p_s->lock); return a_a; } struct active_scan *pentest_state_get_scan(struct pentest_state *p_s, size_t idx) { struct active_scan *a_s = NULL; pthread_mutex_lock(&p_s->lock); if(idx < p_s->num_scans) { a_s = p_s->scans[idx]; } pthread_mutex_unlock(&p_s->lock); return a_s; } void pentest_state_active_attack_update(struct pentest_state *p_s, struct active_attack *a_a) { //There's probably a better way to do this. if(a_a->cur_step_state != AAS_DONE) { return; } //current step done if(a_a->cur_step_state == AAS_DONE) { //Did we succeed?) if(a_a->cur_res) { if(a_a->cur_step == a_a->attack->num_steps -1) { //all steps complete, move to the attacks that worked and remove from active pentest_state_add_worked(p_s,a_a->attack->name, a_a->target); pentest_state_rem_attack(p_s,a_a); } else { //move on to the next step active_attack_next_step(a_a); } } else { //If a step fails, the whole attack fails pentest_state_add_failed(p_s,a_a->attack->name, a_a->target); pentest_state_rem_attack(p_s,a_a); } } } void pentest_state_active_scan_update(struct pentest_state *p_s, struct active_scan *a_s) { //current step done if(a_s->scan_state == AS_DONE) { //scan complete, move done nad remove from active pentest_state_add_done(p_s,a_s->scan->name, a_s->target); pentest_state_rem_scan(p_s,a_s); } }