Advertisement
Guest User

vuln-server.c

a guest
Dec 24th, 2012
4,167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.16 KB | None | 0 0
  1. /*
  2.    Description: Simple server program with intentional vulnerabilities for
  3.    learning purposes.
  4.  
  5.    WARNING: Do not use this code as an example to write your own production
  6.    server application. This is toy code, and is not robust. It WILL allow
  7.    attackers to gain access to your machine.
  8.  
  9.    LICENSE: BSD-style (without the advertising clause)
  10.  
  11.    To Compile under Windows:
  12.      cl vuln_server.c /link ws2_32.lib
  13.  
  14.    To Compile under Linux or Cygwin:
  15.      make vuln_server
  16.  
  17.    To Compile under Sun:
  18.      gcc -lsocket -lnsl vuln_server
  19.  
  20.    Running:
  21.      From one command prompt, type "vuln_server 5700"
  22.      From another prompt, type "telnet 127.0.0.1 5700"
  23.  
  24.    Buffer overflow exercises:
  25.    1. What happens when you type in the string "Hello world!"?
  26.       (You'll need to apply this knowledge in the format string exercises)
  27.    2. Type in a long string (more than 100 characters).
  28.       It should crash. Where is the buffer overflow?
  29.    3. Fix the buffer overflow, recompile, and demonstrate that it doesn't  
  30.       crash on long input lines any more.
  31.    4. Bonus: Can you get a shell?
  32.    
  33.    Format string exercises:
  34.    1. Where is the format string problem?
  35.    2. How do you crash the program? Hint: use %s
  36.    3. How do you print the contents of memory to divulge the secret which  
  37.       is 0xdeadc0de? Hint: use %08x
  38.    4. Bonus: Can you change the contents of "secret" without crashing the
  39.       program?
  40.    5. Bonus: Can you get a shell?
  41.  */
  42.  
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46. #include <stdarg.h>
  47.  
  48. #ifdef _WIN32
  49. #  include <winsock2.h>
  50. #else
  51. #  include <sys/types.h>
  52. #  include <sys/socket.h>
  53. #  include <netinet/in.h>
  54. #  include <unistd.h>
  55. #  define SOCKET int
  56. #endif
  57.  
  58.  
  59.  
  60. #define END_LINE '\n'
  61.  
  62. void logit(FILE *fp, char *client, char *message);
  63. int read_line(int fd, char *buf, int buf_size);
  64. void reverse(char *dest, const char *source);
  65. int write_client(int fd, const char *fmt, ...);
  66. void winsock_init();
  67.  
  68. int main(int argc, char *argv[]) {
  69.     SOCKET listenfd, sockfd;
  70.     int clientLen, serverPort;
  71.     char reversed_line[100];
  72.     struct sockaddr_in clientAddress, serverAddress;
  73.     char line[500];
  74.     FILE *fpLog = NULL;
  75.     int secret = 0xDEADC0DE;
  76.     int clientQuit = 0;
  77.  
  78.     if (argc != 2)
  79.     {
  80.         printf("Usage: %s <port>\n", argv[0]);
  81.         return 1;
  82.     }
  83. #ifdef _WIN32
  84.     winsock_init();
  85. #endif
  86.  
  87.     serverPort = atoi(argv[1]);
  88.     /* create socket */
  89.     listenfd = socket(PF_INET, SOCK_STREAM, 0);
  90.     if ( listenfd < 0 )
  91.     {
  92.         perror("socket error ");
  93.         return 1;
  94.     }
  95.  
  96.     /* bind server port */
  97.     memset(&serverAddress, 0, sizeof(serverAddress));
  98.     serverAddress.sin_family = AF_INET;
  99.     // serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
  100.     serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
  101.     serverAddress.sin_port = htons(serverPort);
  102.  
  103.     if ( -1 == bind(listenfd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) )
  104.     {
  105.         perror("bind error");
  106.         return 1;
  107.     }
  108.  
  109.     if (-1 == listen(listenfd, 5))
  110.     {
  111.         perror("listen error");
  112.         return 1;
  113.     }
  114.  
  115.     fpLog = fopen("server.log", "w");
  116.     if (fpLog == NULL)
  117.     {
  118.         perror("couldn't open server.log for writing");
  119.         return 1;
  120.     }
  121.  
  122.     while ( ! clientQuit )
  123.     {
  124.         printf("%s: waiting for connection on TCP port %u\n\n", argv[0], serverPort);
  125.  
  126.         clientLen = sizeof(clientAddress);
  127.         sockfd = accept(listenfd, (struct sockaddr *) &clientAddress, &clientLen);
  128.         if ( -1 == sockfd )
  129.         {
  130.             perror("error accepting connection ");
  131.             return 1;
  132.         }
  133.  
  134.         write_client(sockfd, "Type QUIT on a line by itself to quit\n");
  135.  
  136.         /* init line */
  137.         memset(line, 0, sizeof(line));
  138.  
  139.         clientQuit = 0;
  140.         while ( !clientQuit &&  read_line(sockfd, line, sizeof(line)) != 0)
  141.         {
  142.             printf( "%s:%d %s\n",
  143.                     inet_ntoa(clientAddress.sin_addr),
  144.                     ntohs(clientAddress.sin_port),
  145.                     line);
  146.             if (0 == strncmp(line, "QUIT", 4))
  147.             {
  148.                 clientQuit = 1;
  149.                 write_client(sockfd, "Goodbye\n");
  150.                 close(sockfd);
  151.             }
  152.             else
  153.             {
  154.                 reverse(reversed_line, line);
  155.                 write_client(sockfd, reversed_line);
  156.                 write_client(sockfd, "\n");
  157.                 // logit(fpLog, inet_ntoa(clientAddress.sin_addr), line);
  158.             }
  159.             memset(line, 0, sizeof(line));
  160.         }
  161.     }
  162. #ifdef _WIN32
  163.     WSACleanup();
  164. #endif
  165. }
  166.  
  167. int write_client(int fd, const char *fmt, ...)
  168. {
  169.     va_list args;
  170.     char message[100];
  171.  
  172.     if (fmt == NULL)
  173.         return 0;
  174.     va_start(args, fmt);
  175. #ifdef _WIN32
  176.     vsprintf(message, fmt, args);
  177. #else
  178.     vsnprintf(message, sizeof(message), fmt, args);
  179. #endif
  180.     va_end(args);
  181.     return send(fd, message, strlen(message), 0);
  182. }
  183.  
  184. int read_line(int fd, char *buf, int buf_size)
  185. {
  186.     int nleft, nread, buf_len;
  187.  
  188.     nleft = buf_size;
  189.     while (nleft > 0)
  190.     {
  191.         if ((nread = recv(fd, buf, nleft, 0)) < 0)
  192.         {
  193.             return nread;
  194.         }
  195.         else if (nread == 0)
  196.         {
  197.             break;
  198.         }
  199.         nleft -= nread;
  200.         buf += nread;
  201.         if (*(buf - 1) == END_LINE)
  202.         {
  203.             break;
  204.         }
  205.     }
  206.     buf_len = buf_size - nleft;
  207.     if (buf_len > 0)
  208.     {
  209.         *(buf - 1) = '\0';
  210.     }
  211.  
  212.     return buf_len;
  213. }
  214.  
  215. void logit(FILE *fp, char *client, char *message)
  216. {
  217.     fprintf(fp, "%s", client);
  218.     fprintf(fp, message);
  219.     fprintf(fp, "\n");
  220.     fflush(fp);
  221. }
  222.  
  223. void reverse(char *dest, const char *source)
  224. {
  225.     int len, i;
  226.     len = strlen(source);
  227.     i = 0;
  228.     while (len > 0)
  229.     {
  230.         dest[i++] = source[--len];
  231.     }
  232.     dest[i] = '\0';
  233. }
  234.  
  235. #ifdef _WIN32
  236. void winsock_init()
  237. {
  238.     static WSADATA wsaData;    
  239.     int wsaret;
  240.  
  241.     if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
  242.     {
  243.         fprintf(stderr, "Couldn't start winsock\n");
  244.         WSACleanup();
  245.         exit(1);
  246.     }
  247. }
  248. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement