diff --git a/README.md b/README.md index 2bbc499..147a395 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ CIFS / SMB2 navel gazing, in 65816 assembly. 5/9/2015 - Current status: Connects on port 445, sends valid SMB Protocol Negotiation message, accepts and analyzes reply. Next step: Login, mount a share, read a file. +5/24/2015 - Current status: Connects on port 445, completes Protocol Negotiation, successfully sends login (on Setup_ANDX message), obsolete LM (DES) style password Build 'CMD.S' with Merlin32 and the included Library directory. diff --git a/latest_tcpdump.txt b/latest_tcpdump.txt new file mode 100644 index 0000000..2231da9 --- /dev/null +++ b/latest_tcpdump.txt @@ -0,0 +1,154 @@ +10.0.2.55 = Apple IIgs running Marinetti +10.0.2.1 = Raspberry Pi running A2SERVER, SMB credentials 'PI' / 'APPLE2' + +19:44:52.729775 IP (tos 0x0, ttl 60, id 437, offset 0, flags [none], proto TCP (6), length 91) + 10.0.2.55.1025 > 10.0.2.1.445: Flags [P.], cksum 0x9201 (correct), seq 1:52, ack 1, win 16384, length 51 +SMB PACKET: SMBnegprot (REQUEST) +SMB Command = 0x72 +Error class = 0x0 +Error code = 0 (0x0) +Flags1 = 0x8 +Flags2 = 0x1 +Tree ID = 0 (0x0) +Proc ID = 57005 (0xdead) +UID = 0 (0x0) +MID = 1 (0x1) +Word Count = 0 (0x0) +smb_bcc=12 +Dialect=NT LM 0.12 + + + 0x0000: 4500 005b 01b5 0000 3c06 64b1 0a00 0237 E..[....<.d....7 + 0x0010: 0a00 0201 0401 01bd 0b17 3b08 4197 ac10 ..........;.A... + 0x0020: 5018 4000 9201 0000 0000 002f ff53 4d42 P.@......../.SMB + 0x0030: 7200 0000 0008 0100 0000 0000 0000 0000 r............... + 0x0040: 0000 0000 0000 adde 0000 0100 000c 0002 ................ + 0x0050: 4e54 204c 4d20 302e 3132 00 NT.LM.0.12. + +19:44:52.730020 IP (tos 0x0, ttl 64, id 59985, offset 0, flags [DF], proto TCP (6), length 40) + 10.0.2.1.445 > 10.0.2.55.1025: Flags [.], cksum 0x1852 (incorrect -> 0x24dd), seq 1, ack 52, win 14600, length 0 + 0x0000: 4500 0028 ea51 4000 4006 3847 0a00 0201 E..(.Q@.@.8G.... + 0x0010: 0a00 0237 01bd 0401 4197 ac10 0b17 3b3b ...7....A.....;; + 0x0020: 5010 3908 1852 0000 P.9..R.. + +19:44:52.735280 IP (tos 0x0, ttl 64, id 59986, offset 0, flags [DF], proto TCP (6), length 141) + 10.0.2.1.445 > 10.0.2.55.1025: Flags [P.], cksum 0x975e (correct), seq 1:102, ack 52, win 14600, length 101 +SMB PACKET: SMBnegprot (REPLY) +SMB Command = 0x72 +Error class = 0x0 +Error code = 0 (0x0) +Flags1 = 0x88 +Flags2 = 0x3 +Tree ID = 0 (0x0) +Proc ID = 57005 (0xdead) +UID = 0 (0x0) +MID = 1 (0x1) +Word Count = 17 (0x11) +NT1 Protocol +DialectIndex=0 (0x0) +SecMode=0x3 +MaxMux=50 (0x32) +NumVcs=1 (0x1) +MaxBuffer=16644 (0x4104) +RawSize=65536 (0x10000) +SessionKey=0x76A1 +Capabilities=0x80F3FD +ServerTime=Sun May 24 19:44:54 2015 +TimeZone=240 (0xf0) +CryptKey=Data: (1 bytes) +[000] 08 \0x08 +smb_bcc=28 +[000] E1 F1 F5 61 E2 7C 34 34 57 00 4F 00 52 00 4B 00 \0xe1\0xf1\0xf5a\0xe2|44 W\0x00O\0x00R\0x00K\0x00 +[010] 47 00 52 00 4F 00 55 00 50 00 00 00 G\0x00R\0x00O\0x00U\0x00 P\0x00\0x00\0x00 + + + 0x0000: 4500 008d ea52 4000 4006 37e1 0a00 0201 E....R@.@.7..... + 0x0010: 0a00 0237 01bd 0401 4197 ac10 0b17 3b3b ...7....A.....;; + 0x0020: 5018 3908 975e 0000 0000 0061 ff53 4d42 P.9..^.....a.SMB + 0x0030: 7200 0000 0088 0340 0000 0000 0000 0000 r......@........ + 0x0040: 0000 0000 0000 adde 0000 0100 1100 0003 ................ + 0x0050: 3200 0100 0441 0000 0000 0100 a176 0000 2....A.......v.. + 0x0060: fdf3 8000 f7ae 6fa1 7b96 d001 f000 081c ......o.{....... + 0x0070: 00e1 f1f5 61e2 7c34 3457 004f 0052 004b ....a.|44W.O.R.K + 0x0080: 0047 0052 004f 0055 0050 0000 00 .G.R.O.U.P... + +19:44:52.789776 IP (tos 0x0, ttl 60, id 438, offset 0, flags [none], proto TCP (6), length 40) + 10.0.2.55.1025 > 10.0.2.1.445: Flags [.], cksum 0x1d80 (correct), seq 52, ack 102, win 16384, length 0 + 0x0000: 4500 0028 01b6 0000 3c06 64e3 0a00 0237 E..(....<.d....7 + 0x0010: 0a00 0201 0401 01bd 0b17 3b3b 4197 ac75 ..........;;A..u + 0x0020: 5010 4000 1d80 0000 0000 0000 0000 P.@........... + +19:44:53.037171 IP (tos 0x0, ttl 60, id 439, offset 0, flags [none], proto TCP (6), length 183) + 10.0.2.55.1025 > 10.0.2.1.445: Flags [P.], cksum 0xe588 (correct), seq 52:195, ack 102, win 16384, length 143 +SMB PACKET: SMBsesssetupX (REQUEST) +SMB Command = 0x73 +Error class = 0x0 +Error code = 0 (0x0) +Flags1 = 0x8 +Flags2 = 0x1 +Tree ID = 0 (0x0) +Proc ID = 57005 (0xdead) +UID = 0 (0x0) +MID = 1 (0x1) +Word Count = 13 (0xd) +Com2=0xFF +Res1=0x0 +Off2=0 (0x0) +MaxBuffer=16644 (0x4104) +MaxMpx=50 (0x32) +VcNumber=1 (0x1) +SessionKey=0x76A1 +CaseInsensitivePasswordLength=24 (0x18) +CaseSensitivePasswordLength=0 (0x0) +Res=0x0 +Capabilities=0x80F3FD +Pass1&Pass2&Account&Domain&OS&LanMan= +smb_bcc=78 +[000] F3 E1 2B C1 B9 1E F4 0B 7A E8 D5 93 F2 C6 56 11 \0xf3\0xe1+\0xc1\0xb9\0x1e\0xf4\0x0b z\0xe8\0xd5\0x93\0xf2\0xc6V\0x11 +[010] 2C 20 43 40 C5 58 11 C6 00 00 00 00 00 00 00 00 , C@\0xc5X\0x11\0xc6 \0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00 +[020] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00 \0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00 +[030] 50 49 00 57 4F 52 4B 47 52 4F 55 50 00 47 53 2F PI\0x00WORKG ROUP\0x00GS/ +[040] 4F 53 00 41 70 70 6C 65 20 49 49 67 73 00 OS\0x00Apple IIgs\0x00 + + + 0x0000: 4500 00b7 01b7 0000 3c06 6453 0a00 0237 E.......<.dS...7 + 0x0010: 0a00 0201 0401 01bd 0b17 3b3b 4197 ac75 ..........;;A..u + 0x0020: 5018 4000 e588 0000 0000 008b ff53 4d42 P.@..........SMB + 0x0030: 7300 0000 0008 0100 0000 0000 0000 0000 s............... + 0x0040: 0000 0000 0000 adde 0000 0100 0dff 0000 ................ + 0x0050: 0004 4132 0001 00a1 7600 0018 0000 0000 ..A2....v....... + 0x0060: 0000 00fd f380 004e 00f3 e12b c1b9 1ef4 .......N...+.... + 0x0070: 0b7a e8d5 93f2 c656 112c 2043 40c5 5811 .z.....V.,.C@.X. + 0x0080: c600 0000 0000 0000 0000 0000 0000 0000 ................ + 0x0090: 0000 0000 0000 0000 0050 4900 574f 524b .........PI.WORK + 0x00a0: 4752 4f55 5000 4753 2f4f 5300 4170 706c GROUP.GS/OS.Appl + 0x00b0: 6520 4949 6773 00 e.IIgs. + +19:44:53.039043 IP (tos 0x0, ttl 64, id 59987, offset 0, flags [DF], proto TCP (6), length 112) + 10.0.2.1.445 > 10.0.2.55.1025: Flags [P.], cksum 0x0d0a (correct), seq 102:174, ack 195, win 15544, length 72 +SMB PACKET: SMBsesssetupX (REPLY) +SMB Command = 0x73 +Error class = 0x0 +Error code = 0 (0x0) +Flags1 = 0x88 +Flags2 = 0x3 +Tree ID = 0 (0x0) +Proc ID = 57005 (0xdead) +UID = 100 (0x64) +MID = 1 (0x1) +Word Count = 3 (0x3) +Com2=0xFF +Off2=0 (0x0) +Action=0x1 +smb_bcc=27 +[000] 55 6E 69 78 00 53 61 6D 62 61 20 33 2E 36 2E 36 Unix\0x00Sam ba 3.6.6 +[010] 00 57 4F 52 4B 47 52 4F 55 50 00 \0x00WORKGRO UP\0x00 + + + 0x0000: 4500 0070 ea53 4000 4006 37fd 0a00 0201 E..p.S@.@.7..... + 0x0010: 0a00 0237 01bd 0401 4197 ac75 0b17 3bca ...7....A..u..;. + 0x0020: 5018 3cb8 0d0a 0000 0000 0044 ff53 4d42 P.<........D.SMB + 0x0030: 7300 0000 0088 0340 0000 0000 0000 0000 s......@........ + 0x0040: 0000 0000 0000 adde 6400 0100 03ff 0000 ........d....... + 0x0050: 0001 001b 0055 6e69 7800 5361 6d62 6120 .....Unix.Samba. + 0x0060: 332e 362e 3600 574f 524b 4752 4f55 5000 3.6.6.WORKGROUP. diff --git a/src/SMBDEMO.S b/src/SMBDEMO.S index 9a6e16b..75b04a6 100644 --- a/src/SMBDEMO.S +++ b/src/SMBDEMO.S @@ -6,6 +6,7 @@ * Friday, May 1, 2015 - Ported more code to Merlin32, set up Merlin32 equates * Saturday, May 2, 2015 - Formatting fixes, refactoring, rewritten SMB Negotiation code * Saturday, May 9, 2015 - Receive and interpret NEG_PROT reply and start login +* Sunday, May 24, 2015 - Some bugfixes, Tool128 and Tool129 requirement for hashing and DES, LM password hashing support * * REFERENCES * smb.c / smb.h from libOGC @@ -91,7 +92,7 @@ StartUpTools _TLStartUp pha pha - PushLong #$800 ; 8 pages of DP space + PushLong #$900 ; 9 pages of DP space PushWord AppMMID PushWord #$C005 ; Fixed, Page-Aligned, Locked, Unpurgeable PushLong #$000000 ; in Bank $00, $0000 @@ -185,11 +186,21 @@ StartUpTools _TLStartUp clc adc #$100 pha + pha _SoundStartUp jsr CheckError _TCPIPStartUp jsr CheckError + + Tool $280 ; HashStartUp + jsr CheckError + + pla + clc + adc #$100 + pha + Tool $281 ; CryptoStartUp rts @@ -636,6 +647,13 @@ sendloop2 PushWord #0000 pla cmp #2 bne noevent3 + PushWord #0000 ; space for result + PushLong #00000000 ; nil filter procedure + _ModalDialog + pla + cmp #2 + bne noevent3 + jmp CTSClose3 noevent3 PushLong MySMBHandle jsr SMB_Negotiate_Poll @@ -647,7 +665,31 @@ login PushLong CTSWinPtr PushLong #CTSTextB _SetIText - jmp SMB_input_brk ; die so we can inspect things + PushLong MySMBHandle + jsr SMB_SetupAndX + +sendloop3 PushWord #0000 + PushWord #$0006 + PushLong #EventRec + _EventAvail + pla + beq noevent4 + PushWord #0000 + PushLong #00000000 + _ModalDialog + pla + cmp #2 + bne noevent4 + PushWord #0000 ; space for result + PushLong #00000000 ; nil filter procedure + _ModalDialog + pla + cmp #2 + bne noevent4 + jmp SMB_staging_brk + +noevent4 _TCPIPPoll + bra sendloop3 closed PushLong CTSWinPtr PushWord #1350 @@ -717,7 +759,7 @@ readbuf ds 4 ; rrBuffCount * * Tool List * -ToolList dw 13 ; Tool Count +ToolList dw 15 ; Tool Count dw 01,00 ; Tool Locator, any vers dw 02,00 ; Memory Manager, any vers dw 03,00 ; Misc Tools, any vers @@ -731,6 +773,8 @@ ToolList dw 13 ; Tool Count dw 20,00 ; Line Edit, any vers dw 21,00 ; Dialog Manager, any vers dw 54,00 ; Marinetti, any vers + dw 128,00 ; HashTool, any vers (MD2/MD4/MD5/SHA1 hashing for NTLMv2) + dw 129,00 ; Crypto tool, any vers (DES for NTLMv1) ToolListEnd * @@ -1083,6 +1127,11 @@ SMB_sess_domain ds 32 ; sloppy 32 byte buffer to hold SMB domain SMB_dialect asc 02'NT LM 0.12'00 ; the only dialect we're gonna speak SMB_os asc 'GS/OS'00 ; native Operating System SMB_lanman asc 'Apple IIgs'00 ; native LAN Manager +SMB_lm_username asc 'PI'00,00,00,00,00,00,00,00,00,00,00,00 ; lanman hash login username +SMB_lm_password asc 'APPLE2'00,00,00,00,00,00,00,00 ; lanman hash login password +SMB_lm_magic asc 'KGS!@#$%' ; lanman hash magic DES crypt string +SMB_lm_hash ds 21 ; LM Hash, actually 16 bytes but the extra zeroes make response easier to generate +SMB_lm_response ds 24 ; LM Response * SMB packet staging area * TODO these will probably be dynamically allocated too? @@ -1356,45 +1405,223 @@ SMB_SetupAndX plx ; return address ldy #SMB_sess_maxbuffer-SMB_sess_begin lda [SMB_sessid],y - sta SMB_staging+SMB_header_size+3 ; max buffer size + sta SMB_staging+SMB_header_size+5 ; max buffer size ldy #SMB_sess_maxmpx-SMB_sess_begin lda [SMB_sessid],y - sta SMB_staging+SMB_header_size+5 ; max MPX + sta SMB_staging+SMB_header_size+7 ; max MPX ldy #SMB_sess_maxvcs-SMB_sess_begin lda [SMB_sessid],y - sta SMB_staging+SMB_header_size+7 ; max VCS + sta SMB_staging+SMB_header_size+9 ; max VCS ldy #SMB_sess_skey-SMB_sess_begin lda [SMB_sessid],y - sta SMB_staging+SMB_header_size+9 ; session key + sta SMB_staging+SMB_header_size+11 ; session key lda #0 - sta SMB_staging+SMB_header_size+11 ; session key (upper, should always be zero?) + sta SMB_staging+SMB_header_size+13 ; session key (upper, should always be zero?) lda #24 - sta SMB_staging+SMB_header_size+13 ; password length (case insensitive) - - lda #24 - sta SMB_staging+SMB_header_size+15 ; password length (case sensitive) + sta SMB_staging+SMB_header_size+15 ; password length (case insensitive) + + lda #0 + sta SMB_staging+SMB_header_size+17 ; password length (case sensitive/NTLM) lda #0 - sta SMB_staging+SMB_header_size+17 ; reserved sta SMB_staging+SMB_header_size+19 ; reserved + sta SMB_staging+SMB_header_size+21 ; reserved ldy #SMB_sess_caps-SMB_sess_begin lda [SMB_sessid],y - sta SMB_staging+SMB_header_size+21 + sta SMB_staging+SMB_header_size+23 iny iny lda [SMB_sessid],y - sta SMB_staging+SMB_header_size+23 ; session capabilities + sta SMB_staging+SMB_header_size+25 ; session capabilities + jsr SMB_LM_Hash ; generate NTLMv1 Hash + jsr SMB_LM_Response ; generate NTLMv1 Response + lda #0 + sta SMB_tmp5 ; initialize pointer -* TODO copy username, password, native os, native lanmanager, update byte count, send result + ; Case Insensitive Password (LM Response) + PushLong #SMB_lm_response ; source + pea #^SMB_staging + lda #SMB_staging+SMB_header_size+29 + clc + adc SMB_tmp5 + pha + ldx #24 + jsr _strncpy + lda #24 + clc + adc SMB_tmp5 + sta SMB_tmp5 + + ; Case Sensitive Password (NTLM Response) + clc + adc #24 + sta SMB_tmp5 ; skip it / zero it for now + + ; Account + PushLong #SMB_lm_username ; source + pea #^SMB_staging ; destination + lda #SMB_staging+SMB_header_size+29 + clc + adc SMB_tmp5 + pha + jsr _strcpy + tya + clc + adc SMB_tmp5 + sta SMB_tmp5 + + ; Domain + PushLong #SMB_sess_domain ; source + pea #^SMB_staging ; destination + lda #SMB_staging+SMB_header_size+29 + clc + adc SMB_tmp5 + pha + jsr _strcpy + tya + clc + adc SMB_tmp5 + sta SMB_tmp5 + + ; OS + PushLong #SMB_os ; source + pea #^SMB_staging ; destination + lda #SMB_staging+SMB_header_size+29 + clc + adc SMB_tmp5 + pha + jsr _strcpy + tya + clc + adc SMB_tmp5 + sta SMB_tmp5 + + ; LanMan + PushLong #SMB_lanman + pea #^SMB_staging ; destination + lda #SMB_staging+SMB_header_size+29 + clc + adc SMB_tmp5 + pha + jsr _strcpy + tya + clc + adc SMB_tmp5 + sta SMB_tmp5 + + sta SMB_staging+SMB_header_size+27 ; update byte count + + clc + adc #SMB_header_size+29 + pha ; 'length' parameter for _SMB_Send + dec + dec + dec + dec + xba + sta SMB_staging+SMB_offset_tcplength+1 ; save length for naked-TCP dgram - jsr _SMB_Send + jsr _SMB_Send ; send our reply! + clc + rts + +* SMB_LM_Hash - operate on the SMB_lm_username and SMB_lm_password values to produce +* SMB_lm_hash, using V1 DES-based operation. Requires TOOL129 (Crypto Tool) +* +* The password has been uppercased and chopped to 14 bytes, with 0x00 padding +* We take it in two 7-byte pieces, add parity, and use each piece to DES-encrypt the string +* 'KGS!@#$%'. The result is the LM hash. +SMB_LM_Hash PushLong #SMB_tmp1 ; SMB_tmp1 will have our parity-enhanced key + PushLong #SMB_lm_password ; key to add parity to + Tool $0A81 ; DESAddParity + + PushLong #SMB_lm_hash ; where DES-encrypted data will go + PushLong #SMB_tmp1 ; parity-enhanced key + PushLong #SMB_lm_magic ; the magic string we're encrypting + PushWord #0000 ; operation: encrypt + Tool $0981 ; DESCipher + + ; now do the same thing with the second 7 bytes of the password + + PushLong #SMB_tmp1 + PushLong #SMB_lm_password+7 + Tool $0A81 ; DesAddParity + + PushLong #SMB_lm_hash+8 + PushLong #SMB_tmp1 + PushLong #SMB_lm_magic + PushWord #0000 + Tool $0981 + + ; SMB_lm_hash should now contain the NTLMv1 hash of the password + clc + rts + +* SMB_LM_Response - operate on SMB_lm_hash and 8-byte challenge to produce +* SMB_lm_response, using V1 DES-based operation. Requires TOOL129 (Crypto Tool) +* +* LM Hash is padded out to 21 bytes, each of which gets parity added and is +* used to DES encrypt the session challenge. The result is the LM response. +SMB_LM_Response + PushLong #SMB_tmp1 ; SMB_tmp1 will have our parity-enhanced key + PushLong #SMB_lm_hash ; key to add parity to + Tool $0A81 ; DESAddParity + + PushLong #SMB_lm_response ; where the DES-encrypted data will go + PushLong #SMB_tmp1 ; parity-enhanced key + ldy #SMB_sess_challenge-SMB_sess_begin + lda [SMB_sessid],y ; PushLong [SMB_sessid],y + pha + iny + iny + lda [SMB_sessid],y + pha + PushWord #0000 ; operation: encrypt + Tool $0981 ; DESCipher + + ; second 7 bytes of hash + + PushLong #SMB_tmp1 + PushLong #SMB_lm_hash+7 + Tool $0A81 ; DESAddParity + + PushLong #SMB_lm_response+8 + PushLong #SMB_tmp1 + ldy #SMB_sess_challenge-SMB_sess_begin + lda [SMB_sessid],y ; PushLong [SMB_sessid],y + pha + iny + iny + lda [SMB_sessid],y + pha + PushWord #0000 + Tool $0981 ; DESCipher + + ; third 7 bytes of hash + + PushLong #SMB_tmp1 + PushLong #SMB_lm_hash+14 + Tool $0A81 ; DesAddParity + + PushLong #SMB_lm_response+16 + PushLong #SMB_tmp1 + ldy #SMB_sess_challenge-SMB_sess_begin + lda [SMB_sessid],y + pha + iny + iny + lda [SMB_sessid],y + pha + PushWord #0000 + Tool $0981 ; DESCipher + clc rts @@ -1762,8 +1989,34 @@ _sclp lda [SMB_tmp3],y bra _sclp _scrt rep #$30 mx %00 + iny rts +* _strncpy - Copy a string somewhere, only n bytes +* Arguments: +* Pointer to source (two words, on stack) +* Pointer to destination (two words, on stack) +* X = number of bytes to copy +_strncpy txy + plx + PullLong SMB_tmp1 ; Destination + PullLong SMB_tmp3 ; Source + phx + tyx + ldy #00 + sep #$30 + mx %11 +_snclp lda [SMB_tmp3],y + sta [SMB_tmp1],y + dex + cpx #00 + beq _sncrt + iny + bra _snclp +_sncrt rep #$30 + mx %00 + rts + * _SMB_Check - Check to see if TCP received data is SMB _SMB_Check lda SMB_input+SMB_offset_proto cmp #SMB_proto1 diff --git a/src/smbdemo b/src/smbdemo index 0004a96..9d5e884 100644 Binary files a/src/smbdemo and b/src/smbdemo differ