Advertisement
Guest User

Sample1

a guest
Mar 3rd, 2019
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.64 KB | None | 0 0
  1. /*
  2. NYU Polytechnic Institute
  3. CS6573: Penetration Testing and Vulnerability Analysis
  4. Code Auditing Homework Assignment
  5.  
  6. There are a number of security holes in this network service,
  7. but your assignment is to only find 3.
  8. They could be both architectural or implementation problems.
  9. Look for bad logic and memory mismanagement.
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <unistd.h>
  15. #include <stdlib.h>
  16. #include <stdarg.h>
  17. #include <signal.h>
  18. #include <sys/wait.h>
  19.  
  20. #include <netinet/in.h>
  21. #include <arpa/inet.h>
  22. #include <sys/socket.h>
  23. #include <sys/types.h>
  24. #include <netdb.h>
  25.  
  26. #define PORT 9090
  27. #define USERNAME 0x01
  28. #define PASSWORD 0x02
  29. #define BADUSER "\x33\x44 BAD USERNAME!"
  30. #define BADPASS "\x33\x45 BAD PASSWORD!"
  31. #define READY "\x41\x41 READY!"
  32. #define USERPATH "./users/"
  33. #define ARTICLEPATH "./articles/"
  34. #define LISTCOMMAND "ls ./articles/ > list.txt"
  35. #define FILENOTAVAIL "\x33\x31 FILE NOT AVAILABLE!"
  36. #define BEGINFILE "\x41\x41 BEGIN FILE: END WITH '!!!'"
  37. #define ARTICLEWROTE "\x41\x42 ARTICLE HAS BEEN WRITTEN!"
  38. #define LIST_ARTICLES 0x22
  39. #define READ_ARTICLE 0x23
  40. #define WRITE_ARTICLE 0x24
  41. #define COMMAND 0x25
  42. #define ADD_USER 0x26
  43.  
  44. void logData(FILE *logfile, char *format, ...);
  45. int setupSock(FILE *logf, unsigned short port);
  46. int writeSock(int sock, char *buf, size_t len);
  47. int readSock(int sock, char *buf, size_t len);
  48. void mainLoop(FILE *logf, int sock);
  49. void handleConnection(FILE *logfile, int sock);
  50. int userFunctions(FILE *logfile, int sock, char *user);
  51. char *findarg(char *argbuf, char argtype);
  52. int authenticate(FILE *logfile, char *user, char *pass);
  53.  
  54. int writeSock(int sock, char *buf, size_t len)
  55. {
  56. ssize_t byteswrote = 0;
  57. ssize_t ret = 0;
  58.  
  59. while (byteswrote < len)
  60. {
  61. ret = send(sock, buf + byteswrote, len - byteswrote, 0);
  62.  
  63. if (ret < 0)
  64. {
  65. return -1;
  66. }
  67.  
  68. if (ret == 0)
  69. {
  70. break;
  71. }
  72.  
  73. byteswrote += ret;
  74. }
  75.  
  76. return byteswrote; //ssize_t is not assigned but int is assigned and so if they are unassigned variables then
  77. }
  78.  
  79. int readSock(int sock, char *buf, size_t len) //ssize_t is not int
  80. {
  81. ssize_t ret = 0;
  82. ssize_t bytesread = 0;
  83.  
  84. while (bytesread < len)
  85. {
  86. ret = recv(sock, buf + bytesread, len - bytesread, 0);
  87.  
  88. if (ret == 0)
  89. {
  90. break;
  91. }
  92.  
  93. if (ret < 0)
  94. {
  95. return -1;
  96. }
  97.  
  98. bytesread += ret;
  99. }
  100.  
  101. return bytesread;
  102. }
  103.  
  104. void writeArticle(int sock, FILE *logfile, char *action)
  105. {
  106. FILE *file;
  107. char *p;
  108. size_t x, y;
  109. int complete = 0;
  110. char buf[1024];
  111. char path[1024];
  112.  
  113. strcpy(path, ARTICLEPATH);
  114. strncat(path, &action[1], sizeof(path)); // buffer overflow, the size of the argument in 'strncat' is too large might lead to a buffer overflow
  115.  
  116. logData(logfile, "user writing article: %s", path);
  117.  
  118. file = fopen(&action[1], "w");
  119.  
  120. if (!file)
  121. {
  122. writeSock(sock, FILENOTAVAIL, sizeof(FILENOTAVAIL));
  123. return;
  124. }
  125.  
  126. writeSock(sock, BEGINFILE, sizeof(BEGINFILE));
  127.  
  128. while (1)
  129. {
  130. memset(buf, 0, sizeof(buf));
  131. x = readSock(sock, buf, sizeof(buf)-1); // just a warning of using size_t as an integer
  132. for (y = 0; y < x; ++y)
  133. {
  134. if (buf[y] == '!')
  135. {
  136. if (buf[y+1] == '!' && buf[y+2] == '!')
  137. {
  138. buf[y] = 0x0;
  139. complete = 1;
  140. }
  141. }
  142. }
  143. fputs(buf, file);
  144. if (complete)
  145. {
  146. break;
  147. }
  148. }
  149.  
  150. writeSock(sock, ARTICLEWROTE, sizeof(ARTICLEWROTE));
  151. fclose(file);
  152. }
  153.  
  154.  
  155. void readArticle(int sock, FILE *logfile, char *action)
  156. {
  157. FILE *file;
  158. char buf[100];
  159. char path[100];
  160.  
  161. logData(logfile, &action[1]);
  162.  
  163. strcpy(path, ARTICLEPATH);
  164. strcat(path, &action[1]);
  165.  
  166. logData(logfile, "user request to read article: %s", path);
  167.  
  168. file = fopen(path, "r");
  169.  
  170. if (file != NULL) {
  171.  
  172. /* fgets for the size of the buffer (100), from the file
  173. writing the article to the user each time! */
  174.  
  175. while (fgets(buf, 1000, file)) {
  176. writeSock(sock, buf, strlen(buf));
  177. }
  178.  
  179. fclose(file);
  180.  
  181. return; // return is not within the while statement no use for it because we're closing file out
  182. } else {
  183. writeSock(sock, FILENOTAVAIL, sizeof(FILENOTAVAIL));
  184. }
  185. }
  186.  
  187. void listArticles(int sock, FILE *logfile, char *action)
  188. {
  189. char buf[100];
  190. FILE *list;
  191.  
  192. logData(logfile, "user has requested a list of articles");
  193.  
  194. /* i wish i had more time! i wouldnt have to write
  195. this code using system() to call things! */
  196.  
  197. memset(buf, 0, sizeof(buf));
  198. system(LISTCOMMAND);
  199.  
  200. list = fopen("list.txt", "r");
  201.  
  202. while (fgets(buf, sizeof(buf)-1, list))
  203. {
  204. writeSock(sock, buf, strlen(buf));
  205. }
  206.  
  207. fclose(list);
  208. return; // when running code we run it through void but if it doesnt pass parameters then no return possible
  209. }
  210.  
  211. void command(FILE *log, int sock, char *action)
  212. {
  213. logData(log, "executing command: %s", &action[1]);
  214. system(&action[1]);
  215. }
  216.  
  217. void addUser(FILE *log, int sock, char *action)
  218. {
  219. char *p;
  220. char buf[1024];
  221.  
  222. p = strchr(&action[1], ':');
  223.  
  224. if (p == NULL) return;
  225.  
  226. *p = 0x0;
  227. logData(log, "Adding user: %s with pass: %s", &action[1], &p[1]);
  228. snprintf(buf, sizeof(buf) - 1, "echo %s > %s%s.txt", &p[1], USERPATH, &action[1]);
  229. // when running code we run it through void but if it doesnt pass parameters then no return possible void does not return a value after the function executes
  230. }
  231.  
  232. int adminFunctions(FILE *logfile, int sock)
  233. {
  234. char action[1024];
  235. size_t len;
  236. while (1)
  237. {
  238. writeSock(sock, READY, sizeof(READY));
  239. memset(action, 0, sizeof(action));
  240. len = readSock(sock, action, sizeof(action)); // the value stored in len is never read
  241.  
  242. if (action[0] == ADD_USER)
  243. {
  244. addUser(logfile, sock, action);
  245. }
  246. else if (action[0] == COMMAND)
  247. {
  248. command(logfile, sock, action);
  249. }
  250. else
  251. {
  252. logData(logfile, "unknown action: %x", action[0]);
  253. }
  254. }
  255.  
  256. }
  257. //ENDLESS LOOP BUG because no parameter because we haven't indecated a value to get out of the loop
  258. int userFunctions(FILE *logfile, int sock, char *user)
  259. {
  260. char action[1024];
  261. size_t len;
  262.  
  263. if (0 == strncmp(user, "admin", 5))
  264. {
  265. adminFunctions(logfile, sock);
  266. return 0; // needed to change this to return zero in order for the program to run on oclint (analyzer)
  267. }
  268.  
  269. while (1)
  270. {
  271. writeSock(sock, READY, sizeof(READY));
  272. memset(action, 0, sizeof(action));
  273. len = readSock(sock, action, sizeof(action)); // Value stored in len is never read
  274.  
  275. if (action[0] == LIST_ARTICLES)
  276. {
  277. listArticles(sock, logfile, action);
  278. }
  279. else if (action[0] == READ_ARTICLE)
  280. {
  281. readArticle(sock, logfile, action);
  282. }
  283. else if (action[0] == WRITE_ARTICLE)
  284. {
  285. writeArticle(sock, logfile, action);
  286. }
  287. else
  288. {
  289. logData(logfile, "unknown action %x", action[0]);
  290. return 0;
  291. }
  292. }
  293.  
  294. return 0;
  295. }
  296.  
  297. /* return 1 for success, 2 on bad username, 3 on bad password */
  298. int authenticate(FILE *logfile, char *user, char *pass)
  299. {
  300. char search[512];
  301. char path[1024];
  302. char userfile[1024];
  303. char data[1024];
  304. FILE *file;
  305. int ret;
  306.  
  307. memset(path, 0, sizeof(1024)); //?
  308.  
  309. /* FIXME: hard coded admin backdoor for password recovery */
  310. if (memcmp(pass, "baCkDoOr", 9) == 0)
  311. {
  312. return 1;
  313. }
  314.  
  315. /* look up user by checking user files: done via system() to /bin/ls|grep user */
  316. logData(logfile, "performing lookup for user via system()!\n");
  317. snprintf(userfile, sizeof(userfile)-1, "%s.txt", user);
  318. snprintf(search, sizeof(userfile)-1, "stat %s`ls %s | grep %s`", USERPATH, USERPATH, userfile); // buffer overflow, snprintf will always overflow destination buffer
  319. ret = system(search);
  320.  
  321. if (ret != 0)
  322. {
  323. return 2;
  324. }
  325.  
  326. snprintf(path, sizeof(path)-1, "%s%s", USERPATH, userfile);
  327.  
  328. /* open file and check if contents == password */
  329. file = fopen(path, "r");
  330.  
  331. if (!file)
  332. {
  333. logData(logfile, "fopen for userfile failed\n");
  334. return 2;
  335. }
  336.  
  337. logData(logfile, "getting userfile info\n");
  338. fgets(data, sizeof(data)-1, file);
  339.  
  340. fclose(file);
  341.  
  342. /* Password Check! */
  343. if (memcmp(data, pass, 3)) // memcmp was called but we're not comparing the results
  344. {
  345. return 3;
  346. }
  347.  
  348. return 1;
  349. }
  350.  
  351. char *findarg(char *argbuf, char argtype)
  352. {
  353. char *ptr1;
  354. char *found = NULL;
  355. char type = 0; // type is assigned but never accessed
  356. size_t size;
  357.  
  358. ptr1 = argbuf;
  359.  
  360. while (1)
  361. {
  362. memcpy((char *)&size, ptr1, 4);
  363. if (size == 0)
  364. {
  365. break;
  366. }
  367. if (ptr1[4] == argtype)
  368. {
  369. found = &ptr1[5];
  370. break;
  371. }
  372. ptr1 += size;
  373. }
  374.  
  375. return found;
  376. }
  377.  
  378. void handleConnection(FILE *logfile, int sock)
  379. {
  380. char buffer[1024];
  381. char argbuf[1024];
  382. char *user = NULL;
  383. char *pass = NULL;
  384. int len = 0;
  385. int ret = 0;
  386. size_t segloop;
  387. size_t segmentcount;
  388. size_t segnext;
  389. size_t argsize;
  390. char *ptr1;
  391. char *ptr2;
  392.  
  393. /* read in data */
  394. memset(buffer, 0, sizeof(buffer));
  395. len = readSock(sock, buffer, sizeof(buffer));
  396. logData(logfile, "handling connection");
  397.  
  398. if (len == -1)
  399. {
  400. return;
  401. }
  402.  
  403. /* parse protocol */
  404. ptr1 = buffer;
  405. ptr2 = argbuf;
  406.  
  407. /* get count of segments */
  408. memcpy((char *)&segmentcount, ptr1, 4);
  409.  
  410. logData(logfile, "Segment count is %i", segmentcount);
  411.  
  412. /* make sure there aren't too many segments!
  413. so the count * 8(bytes) should be the max */
  414. if (segmentcount * 8 > sizeof(argbuf))
  415. {
  416. logData(logfile, "bad segment count");
  417. return;
  418. }
  419.  
  420. ptr1 += 4;
  421.  
  422. memset(argbuf, 0, sizeof(argbuf));
  423.  
  424. for (segloop = 0; segloop < segmentcount; ++segloop)
  425. {
  426. logData(logfile, "adding segment %i", segloop+1);
  427. memcpy((char *)&segnext, ptr1, 4);
  428. logData(logfile, "next segment offset %i", segnext);
  429. ptr1 += 4;
  430. memcpy((char *)&argsize, ptr1, 4);
  431. logData(logfile, "argsize: %i", argsize);
  432. memcpy(ptr2, ptr1, argsize);
  433. ptr2 += argsize;
  434. ptr1 += segnext;
  435. }
  436.  
  437. logData(logfile, "looking up user args");
  438.  
  439. user = findarg(argbuf, USERNAME);
  440. pass = findarg(argbuf, PASSWORD);
  441.  
  442. snprintf(buffer, sizeof(buffer)-1, "User attempting to authenticate: %s", user);
  443. logData(logfile, buffer);
  444.  
  445. logData(logfile, "calling authenticate");
  446. ret = authenticate(logfile, user, pass);
  447. logData(logfile, "returned from authenticate");
  448.  
  449. if (ret != 1)
  450. {
  451.  
  452. if (ret == 2)
  453. {
  454. writeSock(sock, BADUSER, sizeof(BADUSER));
  455. }
  456.  
  457. if (ret == 3)
  458. {
  459. writeSock(sock, BADPASS, sizeof(BADPASS));
  460. }
  461.  
  462. snprintf(buffer, sizeof(buffer)-1,"user: %s failed to login with password %s", user, pass);
  463. logData(logfile, buffer);
  464. return;
  465. }
  466.  
  467. logData(logfile, "user %s authenticated!", user);
  468.  
  469. userFunctions(logfile, sock, user);
  470.  
  471. return; // we've been returning to complete the function but the end of the function for the void function its self has no return
  472. }
  473.  
  474. void mainLoop(FILE *logf, int sock)
  475. {
  476. int clientfd = 0;
  477. struct sockaddr_in client;
  478. socklen_t clientlen = 0;
  479. pid_t offspring = 0;
  480.  
  481. memset((char *)&client, 0, sizeof(client));
  482.  
  483. logData(logf, "entering main loop...");
  484.  
  485. while (1)
  486. {
  487. clientfd = accept(sock, (struct sockaddr *)&client, &clientlen);
  488. if (clientfd == -1)
  489. {
  490. continue;
  491. }
  492.  
  493. offspring = fork();
  494.  
  495. if (offspring == -1)
  496. {
  497. continue;
  498. }
  499.  
  500. if (offspring == 0)
  501. {
  502. handleConnection(logf, clientfd);
  503. close(clientfd);
  504. exit(0);
  505. }
  506.  
  507. close(clientfd);
  508. }
  509. }
  510.  
  511. void spawnhandler(int signumber) // this parameter of signumber is never used
  512. {
  513. pid_t pid;
  514. int stat;
  515.  
  516. while ((pid = waitpid(-1, &stat, WNOHANG))>0)
  517. {
  518. printf("circle of life completed for %i\n", pid);
  519. }
  520. }
  521.  
  522. int setupSock(FILE *logf, unsigned short port)
  523. {
  524. int sock = 0;
  525. struct sockaddr_in sin;
  526. int opt = 0;
  527.  
  528. if (signal(SIGCHLD, spawnhandler)== SIG_ERR)
  529. {
  530. perror("fork() spawn handler setup failed!");
  531. return -1;
  532. }
  533.  
  534. memset((char *)&sin, 0, sizeof(sin));
  535.  
  536. sin.sin_family = AF_INET;
  537. sin.sin_port = htons(port);
  538.  
  539. sock = socket(AF_INET, SOCK_STREAM, 0);
  540.  
  541. if (sock == -1)
  542. {
  543. logData(logf, "socket() failed");
  544. return -1;
  545. }
  546.  
  547. opt = 1;
  548.  
  549. if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1)
  550. {
  551. logData(logf,"setsockopt() failed");
  552. return -1;
  553. }
  554.  
  555. if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) == -1)
  556. {
  557. logData(logf, "bind() failed");
  558. return -1;
  559. }
  560.  
  561. if (listen(sock, 10) == -1)
  562. {
  563. logData(logf, "listen() failed");
  564. return -1;
  565. }
  566.  
  567. return sock;
  568. }
  569.  
  570. int main(int argc, char *argv[]) // parameter argc and argv are never used
  571. {
  572. int sock;
  573. FILE *logf;
  574.  
  575. /* setup log file */
  576. logf = fopen("logfile.txt", "w");
  577.  
  578. if (!logf)
  579. {
  580. perror("unable to open log file\n");
  581. exit(1);
  582. }
  583.  
  584. /* go daemon */
  585. daemon(0,0); //
  586.  
  587. /* setup socket */
  588. sock = setupSock(logf, PORT);
  589.  
  590. if (sock == -1)
  591. {
  592. logData(logf, "failed to setup socket, exiting");
  593. exit(1);
  594. }
  595.  
  596. logData(logf, "intial socket setup complete");
  597.  
  598. mainLoop(logf, sock);
  599.  
  600. /* this should never execute */
  601. exit(0);
  602. }
  603.  
  604. /* printf-style data logging */
  605. void logData(FILE *logfile, char *format, ...)
  606. {
  607. char buffer[4096];
  608. va_list arguments;
  609. va_start(arguments, format);
  610. vsnprintf(buffer, sizeof(buffer)-1, format, arguments);
  611. va_end(arguments);
  612. fprintf(logfile, "LoggedData [Proccess:%i]: %s\n", getpid(), buffer);
  613. fflush(logfile);
  614. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement