Advertisement
Guest User

buffer overflow

a guest
Feb 16th, 2015
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.27 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdint.h>
  5. #include <ctype.h>
  6. #include <openssl/evp.h>
  7.  
  8. char* check_path(char* path) {
  9.     char* res_path = realpath(path, NULL);
  10.     if (!res_path) {
  11.         printf("ERROR: unable to resolve path\n");
  12.         return NULL;
  13.     }
  14.  
  15.     if (strncmp(res_path, "/home", sizeof("/home") - 1)) {
  16.         printf("ERROR: invalid path\n");
  17.         free(res_path);
  18.         return NULL;
  19.     }
  20.  
  21.     return res_path;
  22. }
  23.  
  24. int process_cat(char* path) {
  25.     int ret = 1;
  26.     FILE* input = NULL;
  27.     char* res_path = check_path(path);
  28.     if (!res_path) {
  29.         goto out;
  30.     }
  31.  
  32.     if ((input = fopen(res_path, "r")) == NULL) {
  33.         printf("ERROR: unable to access %s\n", path);
  34.         goto out;
  35.     }
  36.  
  37.     while (!feof(input)) {
  38.         char buf[4096];
  39.         size_t n = fread(buf, 1, sizeof(buf), input);
  40.  
  41.         size_t i = 0u;
  42.         while (i < n) {
  43.             size_t m = fwrite(buf + i, 1, n - i, stdout);
  44.             if (!m) {
  45.                 printf("ERROR: unable to write contents of %s\n", path);
  46.                 goto out;
  47.             }
  48.  
  49.             i += m;
  50.         }
  51.     }
  52.  
  53.     ret = 0;
  54.  
  55. out:
  56.     if (input) {
  57.         fclose(input);
  58.     }
  59.  
  60.     if (res_path) {
  61.         free(res_path);
  62.     }
  63.  
  64.     return ret;
  65. }
  66.  
  67. int process_hash(char* path, uint8_t* hash, size_t* hash_len) {
  68.     int ret = 1;
  69.     FILE* input = NULL;
  70.     char buf[4096];
  71.     const EVP_MD* md;
  72.     EVP_MD_CTX* md_ctxt = NULL;
  73.  
  74.     OpenSSL_add_all_digests();
  75.     md = EVP_get_digestbyname("sha256");
  76.     md_ctxt = EVP_MD_CTX_create();
  77.  
  78.     EVP_DigestInit_ex(md_ctxt, md, NULL);
  79.  
  80.     char* res_path = check_path(path);
  81.     if (!res_path) {
  82.         goto out;
  83.     }
  84.  
  85.     if ((input = fopen(res_path, "r")) == NULL) {
  86.         printf("ERROR: unable to access %s\n", path);
  87.         goto out;
  88.     }
  89.  
  90.     while (!feof(input)) {
  91.         size_t n = fread(buf, 1, sizeof(buf), input);
  92.         EVP_DigestUpdate(md_ctxt, buf, n);
  93.     }
  94.  
  95.     EVP_DigestFinal_ex(md_ctxt, hash, hash_len);
  96.  
  97.     ret = 0;
  98.  
  99. out:
  100.     if (md_ctxt) {
  101.         EVP_MD_CTX_destroy(md_ctxt);
  102.     }
  103.  
  104.     if (input) {
  105.         fclose(input);
  106.     }
  107.  
  108.     if (res_path) {
  109.         free(res_path);
  110.     }
  111.  
  112.     return ret;
  113. }
  114.  
  115. int digittoint(int c) {
  116.     if (c >= '0' && c <= '9') {
  117.         return c - '0';
  118.     } else if (c >= 'a' && c <= 'f') {
  119.         return c - 'a' + 10;
  120.     } else if (c >= 'A' && c <= 'F') {
  121.         return c - 'A' + 10;
  122.     }
  123.  
  124.     return 0;
  125. }
  126.  
  127. int process_verify(char* path, char* hash) {
  128.     size_t computed_hash_len = 0u;
  129.     uint8_t computed_hash[EVP_MAX_MD_SIZE];
  130.     uint8_t hash_buf[EVP_MAX_MD_SIZE * 2];
  131.     if (process_hash(path, computed_hash, &computed_hash_len)) {
  132.         return 1;
  133.     }
  134.  
  135.     strcpy(hash_buf, hash);
  136.     for (size_t i = 0; i < computed_hash_len; i++) {
  137.         if (!isxdigit(hash_buf[2*i]) || !isxdigit(hash_buf[2*i+1])) {
  138.             printf(
  139.                 "ERROR: invalid hash byte (%c%c)\n",
  140.                 hash_buf[2*i],
  141.                 hash_buf[2*i+1]);
  142.             return 1;
  143.         }
  144.  
  145.         hash_buf[i] =
  146.             (digittoint(hash_buf[2*i]) << 4)
  147.             | digittoint(hash_buf[2*i+1]);
  148.     }
  149.  
  150.     if (!memcmp(computed_hash, hash_buf, computed_hash_len)) {
  151.         printf("OK\n");
  152.     } else {
  153.         printf("MISMATCH\n");
  154.     }
  155.  
  156.     return 0;
  157. }
  158.  
  159. int process_command(int argc, char* cmd, char** argv) {
  160.     if (argc >= 1 && !strcmp(cmd, "cat")) {
  161.         return process_cat(argv[0]);
  162.     } else if (argc >= 1 && !strcmp(cmd, "hash")) {
  163.         size_t hash_len = 0u;
  164.         uint8_t hash[EVP_MAX_MD_SIZE];
  165.         if (process_hash(argv[0], hash, &hash_len)) {
  166.             return 1;
  167.         }
  168.  
  169.         for (size_t i = 0; i < hash_len; i++) {
  170.             printf("%02x", hash[i]);
  171.         }
  172.  
  173.         printf("  %s\n", argv[0]);
  174.  
  175.         return 0;
  176.     } else if (argc >= 2 && !strcmp(cmd, "verify")) {
  177.         return process_verify(argv[0], argv[1]);
  178.     } else {
  179.         printf("ERROR: invalid command (%s)\n", cmd);
  180.         return 1;
  181.     }
  182. }
  183.  
  184. int main(int argc, char** argv) {
  185.     if (argc < 2) {
  186.         printf("usage: %s <command> [args...]\n", argv[0]);
  187.         return 1;
  188.     }
  189.  
  190.     return process_command(argc - 2, argv[1], argv + 2);
  191. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement