Slide 1

Slide 1 text

4.#ϑΝΠϧڞ༗Λ4XJGUͰ࣮૷ ͢Δ LJTIJLBXBLBUTVNJ !LJTIJLBXBLBUTVNJ!IBDIZEFSNJP LJTIJLBXBLBUTVNJ

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

r .BD΍8JOEPXTͷϑΝΠϧڞ༗ʹ͸4.#ϓϩτίϧ͕࢖ΘΕ͍ͯΔ r 4FSWFS.FTTBHF#MPDLͷུ r -"/಺ͷϑΝΠϧڞ༗΍ϓϦϯλڞ༗ʹར༻͞ΕΔ௨৴ϓϩτίϧ r *#.͕։ൃɺޙʹ.JDSPTPGU͕֦ு͠ɺ8JOEPXT؀ڥʹ͓͚ΔϑΝΠϧڞ༗ͷ ඪ४ϓϩτίϧͱͯ͠࢖༻͞Ε͍ͯΔ r .BDͰ͸.BWFSJDLT͔ΒϝΠϯͷϑΝΠϧڞ༗ϓϩτίϧͱͯ͠࠾༻ 8IBUJT4.# 4.#ͱ͸Կ͔

Slide 4

Slide 4 text

r <.44.#>4FSWFS.FTTBHF#MPDL 4.# 1SPUPDPM7FSTJPOTBOE IUUQTMFBSONJDSPTPGUDPNFOVTPQFOTQFDTXJOEPXT@QSPUPDPMTNTTNCBEFFBFD )PXUP*NQMFNFOU4.#1SPUPDPM 4.#ϓϩτίϧΛ࣮૷͢Δʹ͸

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

r <.44.#>4FSWFS.FTTBHF#MPDL 4.# 1SPUPDPM7FSTJPOTBOE IUUQTMFBSONJDSPTPGUDPNFOVTPQFOTQFDTXJOEPXT@QSPUPDPMTNTTNCBEFFBFD r 5$14PDLFU$POOFDUJPO r #JOBSZ4FSJBMJ[F%FTFSJBMJ[F )PXUP*NQMFNFOU4.#1SPUPDPM &TTFOUJBM 5PPMTBOE.BUFSJBMT

Slide 8

Slide 8 text

r <.44.#>4FSWFS.FTTBHF#MPDL 4.# 1SPUPDPM7FSTJPOTBOE IUUQTMFBSONJDSPTPGUDPNFOVTPQFOTQFDTXJOEPXT@QSPUPDPMTNTTNCBEFFBFD r 5$14PDLFU$POOFDUJPO r #JOBSZ4FSJBMJ[F%FTFSJBMJ[F )PXUP*NQMFNFOU4.#1SPUPDPM &TTFOUJBM 5PPMTBOE.BUFSJBMT

Slide 9

Slide 9 text

r <.44.#>4FSWFS.FTTBHF#MPDL 4.# 1SPUPDPM7FSTJPOTBOE IUUQTMFBSONJDSPTPGUDPNFOVTPQFOTQFDTXJOEPXT@QSPUPDPMTNTTNCBEFFBFD r 5$14PDLFU$POOFDUJPO r #JOBSZ4FSJBMJ[F%FTFSJBMJ[F )PXUP*NQMFNFOU4.#1SPUPDPM &TTFOUJBM 5PPMTBOE.BUFSJBMT 8FCαʔϏεʹ͓͚Δ"1*

Slide 10

Slide 10 text

r <.44.#>4FSWFS.FTTBHF#MPDL 4.# 1SPUPDPM7FSTJPOTBOE IUUQTMFBSONJDSPTPGUDPNFOVTPQFOTQFDTXJOEPXT@QSPUPDPMTNTTNCBEFFBFD r 5$14PDLFU$POOFDUJPO r #JOBSZ4FSJBMJ[F%FTFSJBMJ[F )PXUP*NQMFNFOU4.#1SPUPDPM &TTFOUJBM 5PPMTBOE.BUFSJBMT

Slide 11

Slide 11 text

r <.44.#>4FSWFS.FTTBHF#MPDL 4.# 1SPUPDPM7FSTJPOTBOE IUUQTMFBSONJDSPTPGUDPNFOVTPQFOTQFDTXJOEPXT@QSPUPDPMTNTTNCBEFFBFD r 5$14PDLFU$POOFDUJPO r #JOBSZ4FSJBMJ[F%FTFSJBMJ[F )PXUP*NQMFNFOU4.#1SPUPDPM &TTFOUJBM 5PPMTBOE.BUFSJBMT 8FCαʔϏεʹ͓͚Δ63-4FTTJPO

Slide 12

Slide 12 text

r <.44.#>4FSWFS.FTTBHF#MPDL 4.# 1SPUPDPM7FSTJPOTBOE IUUQTMFBSONJDSPTPGUDPNFOVTPQFOTQFDTXJOEPXT@QSPUPDPMTNTTNCBEFFBFD r 5$14PDLFU$POOFDUJPO r #JOBSZ4FSJBMJ[F%FTFSJBMJ[F )PXUP*NQMFNFOU4.#1SPUPDPM &TTFOUJBM 5PPMTBOE.BUFSJBMT 8FCαʔϏεʹ͓͚Δ+40/$PEBCMF

Slide 13

Slide 13 text

r 1BDLFU$BQUVSFT ‣ UDQEVNQ ‣ 8JSFTIBSL )PXUP*NQMFNFOU4.#1SPUPDPM 6TFGVM5PPMT

Slide 14

Slide 14 text

r /FUXPSLGSBNFXPSL r /44USFBN r 4XJGU/*0 5$14PDLFU$POOFDUJPO 5$14PDLFU௨৴

Slide 15

Slide 15 text

r "QQMF1MBUGPSN ‣ /FUXPSLGSBNFXPSL ‣ /44USFBN r "QQMF-JOVY0UIFST ‣ 4XJGU/*0 5$14PDLFU$POOFDUJPO 5$14PDLFU௨৴

Slide 16

Slide 16 text

r "QQMF1MBUGPSN ‣ /FUXPSLGSBNFXPSL J04cNBD04cUW04cWJTJPO04cXBUDI04 ‣ /44USFBN r "QQMF-JOVY0UIFST ‣ 4XJGU/*0 5$14PDLFU$POOFDUJPO 5$14PDLFU௨৴

Slide 17

Slide 17 text

5$14PDLFU$POOFDUJPO /FUXPSLGSBNFXPSL import Network

Slide 18

Slide 18 text

5$14PDLFU$POOFDUJPO /FUXPSLGSBNFXPSL import Network let endpoint = NWEndpoint.hostPort( host: NWEndpoint.Host("198.51.100.50"), port: NWEndpoint.Port(integerLiteral: 445) )

Slide 19

Slide 19 text

5$14PDLFU$POOFDUJPO /FUXPSLGSBNFXPSL import Network let endpoint = NWEndpoint.hostPort( host: NWEndpoint.Host("198.51.100.50"), port: NWEndpoint.Port(integerLiteral: 445) )

Slide 20

Slide 20 text

5$14PDLFU$POOFDUJPO /FUXPSLGSBNFXPSL import Network let endpoint = NWEndpoint.hostPort( host: NWEndpoint.Host("198.51.100.50"), port: NWEndpoint.Port(integerLiteral: 445) ) let connection = NWConnection(to: endpoint, using: .tcp)

Slide 21

Slide 21 text

5$14PDLFU$POOFDUJPO /FUXPSLGSBNFXPSL import Network let endpoint = NWEndpoint.hostPort( host: NWEndpoint.Host("198.51.100.50"), port: NWEndpoint.Port(integerLiteral: 445) ) let connection = NWConnection(to: endpoint, using: .tcp)

Slide 22

Slide 22 text

5$14PDLFU$POOFDUJPO /FUXPSLGSBNFXPSL import Network let endpoint = NWEndpoint.hostPort( host: NWEndpoint.Host("198.51.100.50"), port: NWEndpoint.Port(integerLiteral: 445) ) let connection = NWConnection(to: endpoint, using: .tcp) connection.start(queue: .global(qos: .userInitiated))

Slide 23

Slide 23 text

5$14PDLFU$POOFDUJPO /FUXPSLGSBNFXPSL import Network let endpoint = NWEndpoint.hostPort( host: NWEndpoint.Host("198.51.100.50"), port: NWEndpoint.Port(integerLiteral: 445) ) let connection = NWConnection(to: endpoint, using: .tcp) connection.stateUpdateHandler = { (state) in } connection.start(queue: .global(qos: .userInitiated))

Slide 24

Slide 24 text

5$14PDLFU$POOFDUJPO /FUXPSLGSBNFXPSL import Network let endpoint = NWEndpoint.hostPort( host: NWEndpoint.Host("198.51.100.50"), port: NWEndpoint.Port(integerLiteral: 445) ) let connection = NWConnection(to: endpoint, using: .tcp) connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: // TCP connection established @unknown default: break } } connection.start(queue: .global(qos: .userInitiated))

Slide 25

Slide 25 text

5$14PDLFU$POOFDUJPO /FUXPSLGSBNFXPSL import Network let endpoint = NWEndpoint.hostPort( host: NWEndpoint.Host("198.51.100.50"), port: NWEndpoint.Port(integerLiteral: 445) ) let connection = NWConnection(to: endpoint, using: .tcp) connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: // TCP connection established @unknown default: break } } connection.start(queue: .global(qos: .userInitiated))

Slide 26

Slide 26 text

import Network ... connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let data = ... connection.send(content: data, completion: .contentProcessed() { (error) in ... }) @unknown default: break } } connection.start(queue: .global(qos: .userInitiated)) 5$14PDLFU$POOFDUJPO /FUXPSLGSBNFXPSL

Slide 27

Slide 27 text

/FHPUJBUJOH4.# $MJFOUOFHPUJBUJOH4.#XJUI4.#/FHPUJBUF3FRVFTU IUUQTMFBSONJDSPTPGUDPNFOVTPQFOTQFDTXJOEPXT@QSPUPDPMTNTTNCDFGFDBGGECGCFBCECE

Slide 28

Slide 28 text

/FHPUJBUJOH4.# $MJFOU 4FSWFS /FHPUJBUF3FRVFTU /FHPUJBUF3FTQPOTF 4FTTJPO4FUVQ3FRVFTU $MJFOUOFHPUJBUJOH4.#XJUI4.#/FHPUJBUF3FRVFTU ʜ 4FTTJPO4FUVQ3FTQPOTF

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

sudo tcpdump -p -i en7 -w smb.pcap host 198.51.100.50 1BDLFU$BQUVSF UDQEVNQ ύέοτΩϟϓνϟ͸ωοτϫʔΫΠϯλʔϑΣʔεʹΞΫηε ͢Δඞཁ͕͋ΔͷͰSPPUݖݶ͕ඞཁ

Slide 42

Slide 42 text

sudo tcpdump -p -i en7 -w smb.pcap host 198.51.100.50 1BDLFU$BQUVSF UDQEVNQ ϓϩϛεΩϟεϞʔυʢ͢΂ͯͷύέοτΛΩϟϓνϟʣ ʹ͠ͳ͍

Slide 43

Slide 43 text

sudo tcpdump -p -i en7 -w smb.pcap host 198.51.100.50 1BDLFU$BQUVSF UDQEVNQ ΩϟϓνϟΛߦ͏ωοτϫʔΫΠϯλʔϑΣʔε

Slide 44

Slide 44 text

sudo tcpdump -p -i en7 -w smb.pcap host 198.51.100.50 1BDLFU$BQUVSF UDQEVNQ อଘઌͷϑΝΠϧ໊

Slide 45

Slide 45 text

sudo tcpdump -p -i en7 -w smb.pcap host 198.51.100.50 1BDLFU$BQUVSF UDQEVNQ ϑΟϧλͷࢦఆɻͱͷૹड৴ύέοτͷΈ Ωϟϓνϟ͢Δ

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

r #JH&OEJBO ‣ ࠷্ҐόΠτ͕ઌʹདྷΔ ‣ 0xfe534d42 fe 53 4d 42 r -JUUMF&OEJBO ‣ ࠷ԼҐόΠτ͕ઌʹདྷΔ ‣ 0xfe534d42 42 4d 53 fe &OEJBOOFTT #ZUF0SEFS

Slide 57

Slide 57 text

r /FUXPSL#ZUF0SEFS ‣ #JH&OEJBO r )PTU#ZUF0SEFS ‣ %FQFOETPO"SDIJUFDUVSF ‣ .BDͱJ1IPOF͸-JUUMF&OEJBO &OEJBOOFTT #ZUF0SEFS

Slide 58

Slide 58 text

r جຊతʹ-JUUMF&OEJBO r #JH&OEJBOͳͷ͸߲̎໨ͷΈ r .BDͱJ1IPOF-JUUMF&OEJBO 4.#1SPUPDPM #ZUF0SEFS

Slide 59

Slide 59 text

%BUB4USVDUVSF /BNF 4J[F 7BMVF 1SPUPDPM*E CZUFT 0x424D53FE 4USVDUVSF4J[F CZUFT 64 $SFEJU$IBSHF CZUFT 0 4UBUVT CZUFT 0 $PNNBOE CZUFT 0x0000 (SMB2 NEGOTIATE) $SFEJU3FRVFTU CZUFT 0 'MBHT CZUFT 0x00000000 /FYU$PNNBOE CZUFT 0 ʜ ʜ ʜ 4.#1BDLFU)FBEFS

Slide 60

Slide 60 text

%BUB4USVDUVSF /BNF 4J[F 7BMVF 1SPUPDPM*E CZUFT 0x424D53FE 4USVDUVSF4J[F CZUFT 64 $SFEJU$IBSHF CZUFT 0 4UBUVT CZUFT 0 $PNNBOE CZUFT 0x0000 (SMB2 NEGOTIATE) $SFEJU3FRVFTU CZUFT 0 'MBHT CZUFT 0x00000000 /FYU$PNNBOE CZUFT 0 ʜ ʜ ʜ 4.#1BDLFU)FBEFS

Slide 61

Slide 61 text

%BUB4USVDUVSF /BNF 4J[F 7BMVF 1SPUPDPM*E CZUFT 0x424D53FE 4USVDUVSF4J[F CZUFT 64 $SFEJU$IBSHF CZUFT 0 4UBUVT CZUFT 0 $PNNBOE CZUFT 0x0000 (SMB2 NEGOTIATE) $SFEJU3FRVFTU CZUFT 0 'MBHT CZUFT 0x00000000 /FYU$PNNBOE CZUFT 0 ʜ ʜ ʜ 4.#1BDLFU)FBEFS

Slide 62

Slide 62 text

%BUB4USVDUVSF /BNF 4J[F 7BMVF 1SPUPDPM*E CZUFT 0x424D53FE 4USVDUVSF4J[F CZUFT 64 $SFEJU$IBSHF CZUFT 0 4UBUVT CZUFT 0 $PNNBOE CZUFT 0x0000 (SMB2 NEGOTIATE) $SFEJU3FRVFTU CZUFT 0 'MBHT CZUFT 0x00000000 /FYU$PNNBOE CZUFT 0 ʜ ʜ ʜ 4.#1BDLFU)FBEFS

Slide 63

Slide 63 text

%BUB4USVDUVSF /BNF 4J[F 7BMVF 1SPUPDPM*E CZUFT 0x424D53FE 4USVDUVSF4J[F CZUFT 64 $SFEJU$IBSHF CZUFT 0 4UBUVT CZUFT 0 $PNNBOE CZUFT 0x0000 (SMB2 NEGOTIATE) $SFEJU3FRVFTU CZUFT 0 'MBHT CZUFT 0x00000000 /FYU$PNNBOE CZUFT 0 ʜ ʜ ʜ 4.#1BDLFU)FBEFS

Slide 64

Slide 64 text

%BUB4USVDUVSF /BNF 4J[F 7BMVF 4USVDUVSF4J[F CZUFT 36 %JBMFDU$PVOU CZUFT 2 4FDVSJUZ.PEF CZUFT 0x0001 (SMB2_NEGOTIATE_SIGNING_ENABLED) 3FTFSWFE CZUFT 0 $BQBCJMJUJFT CZUFT 0x0000 $MJFOU(VJE CZUFT UUID $MJFOU4UBSU5JNF CZUFT 0 %JBMFDUT WBSJBCMF [0x0202, 0x0210] 1BEEJOH WBSJBCMF 00 00 00 00 4.#/&(05*"5&3FRVFTU

Slide 65

Slide 65 text

%BUB4USVDUVSF /BNF 4J[F 7BMVF 4USVDUVSF4J[F CZUFT 36 %JBMFDU$PVOU CZUFT 2 4FDVSJUZ.PEF CZUFT 0x0001 (SMB2_NEGOTIATE_SIGNING_ENABLED) 3FTFSWFE CZUFT 0 $BQBCJMJUJFT CZUFT 0x0000 $MJFOU(VJE CZUFT UUID $MJFOU4UBSU5JNF CZUFT 0 %JBMFDUT WBSJBCMF [0x0202, 0x0210] 1BEEJOH WBSJBCMF 00 00 00 00 4.#/&(05*"5&3FRVFTU

Slide 66

Slide 66 text

import Network ... connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let data = ... connection.send(content: data, completion: .contentProcessed() { (error) in ... }) @unknown default: break } } connection.start(queue: .global(qos: .userInitiated))

Slide 67

Slide 67 text

import Network ... connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let data = Data([0xfe, 0x53, 0x4d, 0x42, 0x40, 0x00, ...]) connection.send(content: data, completion: .contentProcessed() { (error) in ... }) @unknown default: break } } connection.start(queue: .global(qos: .userInitiated))

Slide 68

Slide 68 text

import Network ... connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let data = Data("00000100fe534d4240000000...6e6f7265")! connection.send(content: data, completion: .contentProcessed() { (error) in ... }) @unknown default: break } } connection.start(queue: .global(qos: .userInitiated))

Slide 69

Slide 69 text

extension Data { init?(_ hex: String) { let len = hex.count / 2 var data = Data(capacity: len) for i in 0..

Slide 70

Slide 70 text

extension Data { init?(_ hex: String) { let len = hex.count / 2 var data = Data(capacity: len) for i in 0..

Slide 71

Slide 71 text

extension Data { init?(_ hex: String) { let len = hex.count / 2 var data = Data(capacity: len) for i in 0..

Slide 72

Slide 72 text

No content

Slide 73

Slide 73 text

import Network ... connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let data = Data("00000100fe534d4240000000...6e6f7265")! connection.send(content: data, completion: .contentProcessed() { (error) in ... }) @unknown default: break } } connection.start(queue: .global(qos: .userInitiated)) let data = Data("00000100fe534d4240000000...6e6f7265")! connection.send( content: data, completion: .contentProcessed() { (error) in ... } )

Slide 74

Slide 74 text

import Network ... connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let data = Data("00000100fe534d4240000000...6e6f7265")! connection.send(content: data, completion: .contentProcessed() { (error) in ... }) @unknown default: break } } connection.start(queue: .global(qos: .userInitiated)) let data = Data("00000100fe534d4240000000...6e6f7265")! connection.send( content: data, completion: .contentProcessed() { (error) in ... } )

Slide 75

Slide 75 text

import Network ... connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let data = Data("00000100fe534d4240000000...6e6f7265")! connection.send(content: data, completion: .contentProcessed() { (error) in ... }) @unknown default: break } } connection.start(queue: .global(qos: .userInitiated)) let data = Data("00000100fe534d4240000000...6e6f7265")! connection.send( content: data, completion: .contentProcessed() { (error) in ... } )

Slide 76

Slide 76 text

import Network ... connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let data = Data("00000100fe534d4240000000...6e6f7265")! connection.send(content: data, completion: .contentProcessed() { (error) in ... }) @unknown default: break } } connection.start(queue: .global(qos: .userInitiated)) let data = Data("00000100fe534d4240000000...6e6f7265")! connection.send( content: data, completion: .contentProcessed() { (error) in connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (content, contentContext, isComplete, error) in guard let content else { return } print(content.hex) } } )

Slide 77

Slide 77 text

import Network ... connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let data = Data("00000100fe534d4240000000...6e6f7265")! connection.send(content: data, completion: .contentProcessed() { (error) in ... }) @unknown default: break } } connection.start(queue: .global(qos: .userInitiated)) connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (content, contentContext, isComplete, error) in guard let content else { return } print(content.hex) }

Slide 78

Slide 78 text

import Network ... connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let data = Data("00000100fe534d4240000000...6e6f7265")! connection.send(content: data, completion: .contentProcessed() { (error) in ... }) @unknown default: break } } connection.start(queue: .global(qos: .userInitiated)) connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (content, contentContext, isComplete, error) in guard let content else { return } print(content.hex) }

Slide 79

Slide 79 text

No content

Slide 80

Slide 80 text

No content

Slide 81

Slide 81 text

No content

Slide 82

Slide 82 text

public struct Header { public let protocolId: UInt32 public let structureSize: UInt16 public let creditCharge: UInt16 public let status: UInt32 public let command: UInt16 public let creditRequestResponse: UInt16 public let flags: Flags public let nextCommand: UInt32 public let messageId: UInt64 public let reserved: UInt32 public let treeId: UInt32 public let sessionId: UInt64 public let signature: Data } $POTUSVDU4.#%BUB4USVDUVSF 4.#1BDLFU)FBEFS

Slide 83

Slide 83 text

$POTUSVDU4.#%BUB4USVDUVSF 4.#1BDLFU)FBEFS 1SPUPDPM*E CZUFT 4USVDUVSF4J[F CZUFT .FTTBHF*E CZUFT 6*OU 6*OU 6*OU

Slide 84

Slide 84 text

$POTUSVDU4.#%BUB4USVDUVSF CZUFT CZUFT CZUFT 6*OU 6*OU 6*OU CZUF 6*OU 66*% CZUFT %BUB 4USJOH WBSJBCMF %BUB 65'-&

Slide 85

Slide 85 text

let header = Header( creditCharge: 1, command: .negotiate, creditRequest: 0, flags: [], messageId: 0, treeId: 0, sessionId: 0 ) $POTUSVDU4.#%BUB4USVDUVSF 4.#1BDLFU)FBEFS

Slide 86

Slide 86 text

No content

Slide 87

Slide 87 text

let header = Header( creditCharge: 1, command: .negotiate, creditRequest: 0, flags: [], messageId: 0, treeId: 0, sessionId: 0 ) $POTUSVDU4.#%BUB4USVDUVSF 4.#1BDLFU)FBEFS

Slide 88

Slide 88 text

let header = Header( creditCharge: 1, command: .negotiate, creditRequest: 0, flags: [], messageId: 0, treeId: 0, sessionId: 0 ) $POTUSVDU4.#%BUB4USVDUVSF 4.#1BDLFU)FBEFS

Slide 89

Slide 89 text

public enum Command: UInt16 { case negotiate = 0x0000 case sessionSetup = 0x0001 case logoff = 0x0002 case treeConnect = 0x0003 case treeDisconnect = 0x0004 case create = 0x0005 case close = 0x0006 case flush = 0x0007 case read = 0x0008 case write = 0x0009 case lock = 0x000A case ioctl = 0x000B case cancel = 0x000C case echo = 0x000D case queryDirectory = 0x000E case changeNotify = 0x000F case queryInfo = 0x0010 case setInfo = 0x0011 case oplockBreak = 0x0012 case serverToClientNotification = 0x0013 }

Slide 90

Slide 90 text

let header = Header( creditCharge: 1, command: .negotiate, creditRequest: 0, flags: [], messageId: 0, treeId: 0, sessionId: 0 ) $POTUSVDU4.#%BUB4USVDUVSF 4.#1BDLFU)FBEFS

Slide 91

Slide 91 text

let header = Header( creditCharge: 1, command: .negotiate, creditRequest: 0, flags: [], messageId: 0, treeId: 0, sessionId: 0 ) $POTUSVDU4.#%BUB4USVDUVSF 4.#1BDLFU)FBEFS

Slide 92

Slide 92 text

public struct Flags: OptionSet, Sendable { public let rawValue: UInt32 public init(rawValue: UInt32) { self.rawValue = rawValue } public static let serverToRedir = Flags(rawValue: 0x00000001) public static let asyncCommand = Flags(rawValue: 0x00000002) public static let relatedOperations = Flags(rawValue: 0x00000004) public static let signed = Flags(rawValue: 0x00000008) public static let priorityMask = Flags(rawValue: 0x00000070) public static let dfsOperation = Flags(rawValue: 0x10000000) public static let replayOperation = Flags(rawValue: 0x20000000) }

Slide 93

Slide 93 text

public struct NegotiateRequest { public let header: Header public let structureSize: UInt16 public let dialectCount: UInt16 public let securityMode: SecurityMode public let reserved: UInt16 public let capabilities: Capabilities public let clientGuid: UUID public let clientStartTime: UInt64 public let dialects: [Dialects] public let padding: Data public let negotiateContextList: Data } 4.#/&(05*"5&3FRVFTU $POTUSVDU4.#%BUB4USVDUVSF

Slide 94

Slide 94 text

let negotiateRequest = NegotiateRequest( messageId: 0, securityMode: [.signingEnabled], dialects: [.smb202, .smb210] ) 4.#/&(05*"5&3FRVFTU $POTUSVDU4.#%BUB4USVDUVSF

Slide 95

Slide 95 text

let negotiateRequest = NegotiateRequest( messageId: 0, securityMode: [.signingEnabled], dialects: [.smb202, .smb210] ) // => fe534d42400000000000000000000000... 4.#/&(05*"5&3FRVFTU $POTUSVDU4.#%BUB4USVDUVSF

Slide 96

Slide 96 text

public func encoded() -> Data { var data = Data() var protocolId = protocolId data += withUnsafeBytes(of: &protocolId) { Data($0) } var structureSize = structureSize data += withUnsafeBytes(of: &structureSize) { Data($0) } var creditCharge = creditCharge data += withUnsafeBytes(of: &creditCharge) { Data($0) } var status = status data += withUnsafeBytes(of: &status) { Data($0) } ... 4FSJBMJ[F4.#1BDLFU 4.#1BDLFU)FBEFS

Slide 97

Slide 97 text

extension Data { init(from value: T) { var value = value self = Swift.withUnsafeBytes(of: &value) { Data($0) } } } 4FSJBMJ[F4.#1BDLFU *OUFHFSUP%BUB

Slide 98

Slide 98 text

protocol BinaryConvertible { static func +(lhs: Data, rhs: Self) -> Data static func +=(lhs: inout Data, rhs: Self) } extension BinaryConvertible { static func +(lhs: Data, rhs: Self) -> Data { lhs + Data(from: rhs) } static func +=(lhs: inout Data, rhs: Self) { lhs = lhs + rhs } } 4FSJBMJ[F4.#1BDLFU *OUFHFSUP%BUB

Slide 99

Slide 99 text

extension UInt8: BinaryConvertible {} extension UInt16: BinaryConvertible {} extension UInt32: BinaryConvertible {} extension UInt64: BinaryConvertible {} 4FSJBMJ[F4.#1BDLFU *OUFHFSUP%BUB

Slide 100

Slide 100 text

public func encoded() -> Data { var data = Data() data += protocolId data += structureSize data += creditCharge data += status data += command data += creditRequestResponse data += flags.rawValue data += nextCommand data += messageId data += reserved data += treeId data += sessionId data += signature return data }

Slide 101

Slide 101 text

public func encoded() -> Data { var data = Data() data += protocolId data += structureSize data += creditCharge data += status data += command data += creditRequestResponse data += flags.rawValue data += nextCommand data += messageId data += reserved data += treeId data += sessionId data += signature return data }

Slide 102

Slide 102 text

public func encoded() -> Data { var data = Data() data += header.encoded() data += structureSize data += UInt16(dialects.count) data += securityMode.rawValue data += reserved data += capabilities.rawValue data += Data(from: clientGuid) data += clientStartTime for dialect in dialects { data += dialect.rawValue } data += padding data += negotiateContextList return data }

Slide 103

Slide 103 text

connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let data = Data("00000100fe534d4240000000...6e6f7265")! connection.send(content: data, completion: .contentProcessed() { (error) in ... }) @unknown default: break } } connection.start(queue: .global(qos: .userInitiated))

Slide 104

Slide 104 text

connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let negotiateRequest = NegotiateRequest( messageId: 0, securityMode: [.signingEnabled], dialects: [.smb202, .smb210] ) let data = negotiateRequest.encoded() connection.send(content: data, completion: .contentProcessed() { (error) in ... }) @unknown default: break } } connection.start(queue: .global(qos: .userInitiated))

Slide 105

Slide 105 text

No content

Slide 106

Slide 106 text

No content

Slide 107

Slide 107 text

No content

Slide 108

Slide 108 text

No content

Slide 109

Slide 109 text

public struct DirectTCPPacket { public let zero: UInt8 public let streamProtocolLength: Data public let smb2Message: Data public init(smb2Message: Data) { zero = 0x00 let length = UInt32(truncatingIfNeeded: smb2Message.count) var data = Data(capacity: 3) let byte1 = UInt8((length >> 16) & 0x000000FF) let byte2 = UInt8((length >> 8) & 0x000000FF) let byte3 = UInt8(length & 0x000000FF) data.append(byte1) data.append(byte2) data.append(byte3) streamProtocolLength = data self.smb2Message = smb2Message } public func encoded() -> Data { var data = Data() data += zero data += streamProtocolLength data += smb2Message return data } }

Slide 110

Slide 110 text

public struct DirectTCPPacket { public let zero: UInt8 public let streamProtocolLength: Data public let smb2Message: Data public init(smb2Message: Data) { zero = 0x00 let length = UInt32(truncatingIfNeeded: smb2Message.count) var data = Data(capacity: 3) let byte1 = UInt8((length >> 16) & 0xFF) let byte2 = UInt8((length >> 8) & 0xFF) let byte3 = UInt8(length & 0xFF) data.append(byte1) data.append(byte2) data.append(byte3) streamProtocolLength = data self.smb2Message = smb2Message } public func encoded() -> Data { var data = Data() data += zero data += streamProtocolLength data += smb2Message return data } } public init(smb2Message: Data) { zero = 0x00 let length = UInt32(truncatingIfNeeded: smb2Message.count) var data = Data(capacity: 3) let byte1 = UInt8((length >> 16) & 0x000000FF) let byte2 = UInt8((length >> 8) & 0x000000FF) let byte3 = UInt8(length & 0x000000FF) data.append(byte1) data.append(byte2) data.append(byte3) streamProtocolLength = data self.smb2Message = smb2Message }

Slide 111

Slide 111 text

public struct DirectTCPPacket { public let zero: UInt8 public let streamProtocolLength: Data public let smb2Message: Data public init(smb2Message: Data) { zero = 0x00 let length = UInt32(truncatingIfNeeded: smb2Message.count) var data = Data(capacity: 3) let byte1 = UInt8((length >> 16) & 0xFF) let byte2 = UInt8((length >> 8) & 0xFF) let byte3 = UInt8(length & 0xFF) data.append(byte1) data.append(byte2) data.append(byte3) streamProtocolLength = data self.smb2Message = smb2Message } public func encoded() -> Data { var data = Data() data += zero data += streamProtocolLength data += smb2Message return data } } public init(smb2Message: Data) { zero = 0x00 let length = UInt32(truncatingIfNeeded: smb2Message.count) var data = Data(capacity: 3) let byte1 = UInt8((length >> 16) & 0x000000FF) let byte2 = UInt8((length >> 8) & 0x000000FF) let byte3 = UInt8(length & 0x000000FF) data.append(byte1) data.append(byte2) data.append(byte3) streamProtocolLength = data self.smb2Message = smb2Message }

Slide 112

Slide 112 text

public struct DirectTCPPacket { public let zero: UInt8 public let streamProtocolLength: Data public let smb2Message: Data public init(smb2Message: Data) { zero = 0x00 let length = UInt32(truncatingIfNeeded: smb2Message.count) var data = Data(capacity: 3) let byte1 = UInt8((length >> 16) & 0xFF) let byte2 = UInt8((length >> 8) & 0xFF) let byte3 = UInt8(length & 0xFF) data.append(byte1) data.append(byte2) data.append(byte3) streamProtocolLength = data self.smb2Message = smb2Message } public func encoded() -> Data { var data = Data() data += zero data += streamProtocolLength data += smb2Message return data } } public init(smb2Message: Data) { zero = 0x00 let length = UInt32(truncatingIfNeeded: smb2Message.count) var data = Data(capacity: 3) let byte1 = UInt8((length >> 16) & 0x000000FF) let byte2 = UInt8((length >> 8) & 0x000000FF) let byte3 = UInt8(length & 0x000000FF) data.append(byte1) data.append(byte2) data.append(byte3) streamProtocolLength = data self.smb2Message = smb2Message }

Slide 113

Slide 113 text

#JU.BTL#JU4IJGU #ZUFXJTF0QFSBUJPO 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 UInt8(length & 0x000000FF)

Slide 114

Slide 114 text

#JU.BTL#JU4IJGU #ZUFXJTF0QFSBUJPO 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 UInt8(length & 0x000000FF) ϏοτϚεΫ

Slide 115

Slide 115 text

#JU.BTL#JU4IJGU #ZUFXJTF0QFSBUJPO 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 UInt8(length & 0x000000FF) ԼҐόΠτ͕࢒Δ ্ҐͷϏοτ͸θϩʹͳΔ

Slide 116

Slide 116 text

#JU.BTL#JU4IJGU #ZUFXJTF0QFSBUJPO 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 UInt8((length >> 8) & 0x000000FF)

Slide 117

Slide 117 text

#JU.BTL#JU4IJGU #ZUFXJTF0QFSBUJPO 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 UInt8((length >> 8) & 0x000000FF) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Slide 118

Slide 118 text

public struct DirectTCPPacket { public let zero: UInt8 public let streamProtocolLength: Data public let smb2Message: Data public init(smb2Message: Data) { zero = 0x00 let length = UInt32(truncatingIfNeeded: smb2Message.count) var data = Data(capacity: 3) let byte1 = UInt8((length >> 16) & 0xFF) let byte2 = UInt8((length >> 8) & 0xFF) let byte3 = UInt8(length & 0xFF) data.append(byte1) data.append(byte2) data.append(byte3) streamProtocolLength = data self.smb2Message = smb2Message } public func encoded() -> Data { var data = Data() data += zero data += streamProtocolLength data += smb2Message return data } } public init(smb2Message: Data) { zero = 0x00 let length = UInt32(truncatingIfNeeded: smb2Message.count) var data = Data(capacity: 3) let byte1 = UInt8((length >> 16) & 0x000000FF) let byte2 = UInt8((length >> 8) & 0x000000FF) let byte3 = UInt8(length & 0x000000FF) data.append(byte1) data.append(byte2) data.append(byte3) streamProtocolLength = data self.smb2Message = smb2Message }

Slide 119

Slide 119 text

connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let negotiateRequest = NegotiateRequest( messageId: 0, securityMode: [.signingEnabled], dialects: [.smb202, .smb210] ) let data = negotiateRequest.encoded() let transportPacket = DirectTCPPacket(smb2Message: data) let packet = transportPacket.encoded() connection.send(content: packet, completion: .contentProcessed() { (error) in connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (content, contentContext, isComplete, error) in guard let content else { return } print(content.hex) } }) @unknown default: break } }

Slide 120

Slide 120 text

connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let negotiateRequest = NegotiateRequest( messageId: 0, securityMode: [.signingEnabled], dialects: [.smb202, .smb210] ) let data = negotiateRequest.encoded() let transportPacket = DirectTCPPacket(smb2Message: data) let packet = transportPacket.encoded() connection.send(content: packet, completion: .contentProcessed() { (error) in connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (content, contentContext, isComplete, error) in guard let content else { return } print(content.hex) } }) @unknown default: break } } let negotiateRequest = NegotiateRequest( messageId: 0, securityMode: [.signingEnabled], dialects: [.smb202, .smb210] ) let data = negotiateRequest.encoded() let transportPacket = DirectTCPPacket(smb2Message: data) let packet = transportPacket.encoded() connection.send(content: packet, completion: .contentProcessed() { (error) in connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (content, contentContext, isComplete, error) in guard let content else { return } print(content.hex) } })

Slide 121

Slide 121 text

connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let negotiateRequest = NegotiateRequest( messageId: 0, securityMode: [.signingEnabled], dialects: [.smb202, .smb210] ) let data = negotiateRequest.encoded() let transportPacket = DirectTCPPacket(smb2Message: data) let packet = transportPacket.encoded() connection.send(content: packet, completion: .contentProcessed() { (error) in connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (content, contentContext, isComplete, error) in guard let content else { return } print(content.hex) } }) @unknown default: break } } let negotiateRequest = NegotiateRequest( messageId: 0, securityMode: [.signingEnabled], dialects: [.smb202, .smb210] ) let data = negotiateRequest.encoded() let transportPacket = DirectTCPPacket(smb2Message: data) let packet = transportPacket.encoded() connection.send(content: packet, completion: .contentProcessed() { (error) in connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (content, contentContext, isComplete, error) in guard let content else { return } print(content.hex) } })

Slide 122

Slide 122 text

connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let negotiateRequest = NegotiateRequest( messageId: 0, securityMode: [.signingEnabled], dialects: [.smb202, .smb210] ) let data = negotiateRequest.encoded() let transportPacket = DirectTCPPacket(smb2Message: data) let packet = transportPacket.encoded() connection.send(content: packet, completion: .contentProcessed() { (error) in connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (content, contentContext, isComplete, error) in guard let content else { return } print(content.hex) } }) @unknown default: break } } let negotiateRequest = NegotiateRequest( messageId: 0, securityMode: [.signingEnabled], dialects: [.smb202, .smb210] ) let data = negotiateRequest.encoded() let transportPacket = DirectTCPPacket(smb2Message: data) let packet = transportPacket.encoded() connection.send(content: packet, completion: .contentProcessed() { (error) in connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (content, contentContext, isComplete, error) in guard let content else { return } print(content.hex) } })

Slide 123

Slide 123 text

connection.stateUpdateHandler = { (state) in switch state { case .setup, .waiting, .preparing, .failed, .cancelled: break case .ready: let negotiateRequest = NegotiateRequest( messageId: 0, securityMode: [.signingEnabled], dialects: [.smb202, .smb210] ) let data = negotiateRequest.encoded() let transportPacket = DirectTCPPacket(smb2Message: data) let packet = transportPacket.encoded() connection.send(content: packet, completion: .contentProcessed() { (error) in connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (content, contentContext, isComplete, error) in guard let content else { return } print(content.hex) } }) @unknown default: break } } let negotiateRequest = NegotiateRequest( messageId: 0, securityMode: [.signingEnabled], dialects: [.smb202, .smb210] ) let data = negotiateRequest.encoded() let transportPacket = DirectTCPPacket(smb2Message: data) let packet = transportPacket.encoded() connection.send(content: packet, completion: .contentProcessed() { (error) in connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (content, contentContext, isComplete, error) in guard let content else { return } print(content.hex) } })

Slide 124

Slide 124 text

No content

Slide 125

Slide 125 text

No content

Slide 126

Slide 126 text

No content

Slide 127

Slide 127 text

extension Data { init(from value: T) { var value = value self = Swift.withUnsafeBytes(of: &value) { Data($0) } } func to(type: T.Type) -> T { return self.withUnsafeBytes { $0.load(as: T.self) } } } %FTFSJBMJ[F4.#1BDLFU #JOBSZUP4USVDUVSF

Slide 128

Slide 128 text

class ByteReader { private let data: Data private(set) var offset: Data.Index var availableBytes: Int { return data.count - offset } init(_ data: Data) { self.data = data offset = data.startIndex } func read() -> T { let size = MemoryLayout.size let value = data[offset..<(offset + size)].to(type: T.self) offset += size return value } }

Slide 129

Slide 129 text

public struct NegotiateResponse { public let header: Header public let structureSize: UInt16 public let securityMode: SecurityMode public let dialectRevision: UInt16 public let negotiateContextCount: UInt16 public let serverGuid: UUID public let capabilities: Capabilities public let maxTransactSize: UInt32 public let maxReadSize: UInt32 public let maxWriteSize: UInt32 public let systemTime: UInt64 public let serverStartTime: UInt64 public let securityBufferOffset: UInt16 public let securityBufferLength: UInt16 public let negotiateContextOffset: UInt32 public let securityBuffer: Data }

Slide 130

Slide 130 text

public init(data: Data) { let reader = ByteReader(data) header = reader.read() structureSize = reader.read() securityMode = SecurityMode(rawValue: reader.read()) dialectRevision = reader.read() negotiateContextCount = reader.read() serverGuid = reader.read() capabilities = Capabilities(rawValue: reader.read()) maxTransactSize = reader.read() maxReadSize = reader.read() maxWriteSize = reader.read() systemTime = reader.read() serverStartTime = reader.read() securityBufferOffset = reader.read() securityBufferLength = reader.read() negotiateContextOffset = reader.read() securityBuffer = reader.read( from: Int(securityBufferOffset), count: Int(securityBufferLength) ) }

Slide 131

Slide 131 text

let negotiateRequest = NegotiateRequest( messageId: 0, securityMode: [.signingEnabled], dialects: [.smb202, .smb210] ) let data = negotiateRequest.encoded() let transportPacket = DirectTCPPacket(smb2Message: data) let packet = transportPacket.encoded() connection.send(content: packet, completion: .contentProcessed() { (error) in connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (content, contentContext, isComplete, error) in guard let content else { return } print(content.hex) } })

Slide 132

Slide 132 text

let data = negotiateRequest.encoded() let transportPacket = DirectTCPPacket(smb2Message: data) let packet = transportPacket.encoded() connection.send(content: packet, completion: .contentProcessed() { (error) in connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (content, contentContext, isComplete, error) in guard let content else { return } let transportPacket = DirectTCPPacket(response: content) let length = Int(transportPacket.protocolLength) let response = NegotiateResponse(data: transportPacket.smb2Message) print(response) } })

Slide 133

Slide 133 text

No content

Slide 134

Slide 134 text

No content

Slide 135

Slide 135 text

extension NegotiateResponse: CustomDebugStringConvertible { public var debugDescription: String { """ \(header) Negotiate Protocol Response (\(String(format: "0x%02x", header.command))) StructureSize: \(structureSize) Security mode: \(securityMode) Dialect: \(String(format: "0x%04x", dialectRevision)) NegotiateContextCount: \(negotiateContextCount) Server Guid: \(serverGuid) Capabilities: \(capabilities) Max Transaction Size: \(maxTransactSize) Max Read Size: \(maxReadSize) Max Write Size: \(maxWriteSize) Current Time: \(FileTime(systemTime)) Boot Time: \(FileTime(serverStartTime)) Blob Offset: \(securityBufferOffset) Blob Length: \(securityBufferLength) Security Blob: \(securityBuffer.hex) NegotiateContextOffset: \(String(format: "0x%08x", negotiateContextOffset)) """ } }

Slide 136

Slide 136 text

No content

Slide 137

Slide 137 text

No content

Slide 138

Slide 138 text

No content

Slide 139

Slide 139 text

No content

Slide 140

Slide 140 text

No content

Slide 141

Slide 141 text

r <.44.#>4FSWFS.FTTBHF#MPDL 4.# 1SPUPDPM7FSTJPOTBOE IUUQTMFBSONJDSPTPGUDPNFOVTPQFOTQFDTXJOEPXT@QSPUPDPMTNTTNCBEFFBFD r 5$14PDLFU$POOFDUJPO r #JOBSZ4FSJBMJ[F%FTFSJBMJ[F )PXUP*NQMFNFOU4.#1SPUPDPM &TTFOUJBM 5PPMTBOE.BUFSJBMT 8FCαʔϏεʹ͓͚Δ"1* 8FCαʔϏεʹ͓͚Δ63-4FTTJPO 8FCαʔϏεʹ͓͚Δ+40/$PEBCMF

Slide 142

Slide 142 text

r <.44.#>4FSWFS.FTTBHF#MPDL 4.# 1SPUPDPM7FSTJPOTBOE✅ IUUQTMFBSONJDSPTPGUDPNFOVTPQFOTQFDTXJOEPXT@QSPUPDPMTNTTNCBEFFBFD r 5$14PDLFU$POOFDUJPO✅ r #JOBSZ4FSJBMJ[F%FTFSJBMJ[F✅ )PXUP*NQMFNFOU4.#1SPUPDPM &TTFOUJBM 5PPMTBOE.BUFSJBMT

Slide 143

Slide 143 text

r /&(05*"5& r 4&44*0/@4&561 r -0(0'' r 53&&@$0//&$5 r 53&&@%*4$0//&$5 r $3&"5& r $-04& r '-64) r 3&"% 4.#.FTTBHFT r 83*5& r -0$, r &$)0 r $"/$&- r *0$5- r 26&3:@%*3&$503: r $)"/(&@/05*': r 26&3:@*/'0 r 4&5@*/'0

Slide 144

Slide 144 text

r /&(05*"5& r 4&44*0/@4&561 r -0(0'' r 53&&@$0//&$5 r 53&&@%*4$0//&$5 r $3&"5& r $-04& r '-64) r 3&"% r 83*5& r -0$, r &$)0 r $"/$&- r *0$5- r 26&3:@%*3&$503: r $)"/(&@/05*': r 26&3:@*/'0 r 4&5@*/'0 ϩάΠϯ ϩάΦϑ μ΢ϯϩʔυ Ξοϓϩʔυ σΟϨΫτϦҰཡ 4.#.FTTBHFT

Slide 145

Slide 145 text

-JTU%JSFDUPSZ /BNF 4J[F 7BMVF 4USVDUVSF4J[F CZUFT 33 'JMF*OGPSNBUJPO$MBTT CZUFT Ϩεϙϯεʹؚ·ΕΔ৘ใ 'MBHT CZUFT 0x01 'JMF*OEFY CZUFT 0 'JMF*E CZUFT ਌σΟϨΫτϦͷ*% 'JMF/BNF0GGTFU CZUFT ݕࡧύλʔϯͷ 'JMF/BNF-FOHUI CZUFT ݕࡧύλʔϯจࣈྻͷόΠτ਺ 0VUQVU#VGGFS-FOHUI CZUFT ҰճͰฦͬͯ͘ΔϨεϙϯεͷ࠷େαΠζ #VGGFS WBSJBCMF ݕࡧύλʔϯจࣈྻʢྫʣ* 4.#26&3:@%*3&$503:3FRVFTU

Slide 146

Slide 146 text

4FTTJPO4FUVQ3FRVFTU "VUIFOUJDBUJPO 1BTTXPSE MD4 /5-.)BTI 6TFSOBNF %PNBJO HMAC-MD5 3FTQPOTF,FZ/5 HMAC-MD5 4FSWFS$IBMMFOHF $MJFOU$IBMMFOHF /51SPPG4US

Slide 147

Slide 147 text

public class Connection { let host: String var onDisconnected: (Error) -> Void private let connection: NWConnection public func connect() async throws { return try await withCheckedThrowingContinuation { (continuation) in connection.stateUpdateHandler = { (state) in switch state { ... case .ready: continuation.resume() self.connection.stateUpdateHandler = stateUpdateHandler case .failed(let error): continuation.resume(throwing: error) self.connection.stateUpdateHandler = nil ... } } connection.start(queue: .global(qos: .userInitiated)) } } }

Slide 148

Slide 148 text

public class Connection { let host: String var onDisconnected: (Error) -> Void private let connection: NWConnection public func connect() async throws { return try await withCheckedThrowingContinuation { (continuation) in connection.stateUpdateHandler = { (state) in switch state { ... case .ready: continuation.resume() self.connection.stateUpdateHandler = stateUpdateHandler case .failed(let error): continuation.resume(throwing: error) self.connection.stateUpdateHandler = nil ... } } connection.start(queue: .global(qos: .userInitiated)) } } }

Slide 149

Slide 149 text

public class Connection { let host: String var onDisconnected: (Error) -> Void private let connection: NWConnection public func connect() async throws { return try await withCheckedThrowingContinuation { (continuation) in connection.stateUpdateHandler = { (state) in switch state { ... case .ready: continuation.resume() self.connection.stateUpdateHandler = stateUpdateHandler case .failed(let error): continuation.resume(throwing: error) self.connection.stateUpdateHandler = nil ... } } connection.start(queue: .global(qos: .userInitiated)) } } }

Slide 150

Slide 150 text

public class Connection { let host: String var onDisconnected: (Error) -> Void private let connection: NWConnection public func connect() async throws { return try await withCheckedThrowingContinuation { (continuation) in connection.stateUpdateHandler = { (state) in switch state { ... case .ready: continuation.resume() self.connection.stateUpdateHandler = stateUpdateHandler case .failed(let error): continuation.resume(throwing: error) self.connection.stateUpdateHandler = nil ... } } connection.start(queue: .global(qos: .userInitiated)) } } }

Slide 151

Slide 151 text

public func send(_ data: Data) async throws -> Data { let transportPacket = DirectTCPPacket(smb2Message: data) let content = transportPacket.encoded() return try await withCheckedThrowingContinuation { (continuation) in connection.send(content: content, completion: .contentProcessed() { (error) in if let error { continuation.resume(throwing: error) return } connection.receive( minimumIncompleteLength: 0, maximumLength: 65536) { (content, contentContext, isComplete, error) in if let error = error { continuation.resume(throwing: error) return } continuation.resume(returning: content) } }) } }

Slide 152

Slide 152 text

public func send(_ data: Data) async throws -> Data { let transportPacket = DirectTCPPacket(smb2Message: data) let content = transportPacket.encoded() return try await withCheckedThrowingContinuation { (continuation) in connection.send(content: content, completion: .contentProcessed() { (error) in if let error { continuation.resume(throwing: error) return } connection.receive( minimumIncompleteLength: 0, maximumLength: 65536) { (content, contentContext, isComplete, error) in if let error = error { continuation.resume(throwing: error) return } continuation.resume(returning: content) } }) } }

Slide 153

Slide 153 text

public func send(_ data: Data) async throws -> Data { let transportPacket = DirectTCPPacket(smb2Message: data) let content = transportPacket.encoded() return try await withCheckedThrowingContinuation { (continuation) in connection.send(content: content, completion: .contentProcessed() { (error) in if let error { continuation.resume(throwing: error) return } connection.receive( minimumIncompleteLength: 0, maximumLength: 65536) { (content, contentContext, isComplete, error) in if let error = error { continuation.resume(throwing: error) return } continuation.resume(returning: content) } }) } }

Slide 154

Slide 154 text

4XJGU$PODVSSFODZ "TZOD"XBJU 3FTQPOTF )FBEFS #PEZ

Slide 155

Slide 155 text

4XJGU$PODVSSFODZ "TZOD"XBJU 3FTQPOTF CZUF )FBEFS #PEZ CZUF

Slide 156

Slide 156 text

4XJGU$PODVSSFODZ "TZOD"XBJU 3FTQPOTF CZUF )FBEFS #PEZ CZUF

Slide 157

Slide 157 text

4XJGU$PODVSSFODZ "TZOD"XBJU SFDFJWF )FBEFSͷ-FOHUIΛνΣοΫ #VGGFS-FOHUI ଓ͖Λड৴ ϨεϙϯεΛฦ͢

Slide 158

Slide 158 text

private func receive(completion: @escaping (Result) -> Void) { connection.receive( minimumIncompleteLength: 0, maximumLength: 65536) { (content, contentContext, isComplete, error) in if let error = error { completion(.failure(error)) return } let transportPacket = DirectTCPPacket(response: content) let length = Int(transportPacket.protocolLength) self.buffer.append(Data(transportPacket.smb2Message)) self.receive(upTo: length) { (result) in switch result { case .success: let data = Data(self.buffer.prefix(length)) self.buffer = Data(self.buffer.suffix(from: length)) completion(.success(data)) case .failure(let error): completion(.failure(error)) } } } }

Slide 159

Slide 159 text

private func receive(upTo byteCount: Int, completion: @escaping (Result<(), Error>) -> Void) { if self.buffer.count < byteCount { self.connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (data, _, isComplete, error) in if let error = error { completion(.failure(error)) return } guard let data else { if isComplete { completion(.failure(ConnectionError.disconnected)) } else { completion(.failure(ConnectionError.noData)) } return } self.buffer.append(data) self.receive(upTo: byteCount, completion: completion) } return } completion(.success(())) }

Slide 160

Slide 160 text

private func receive(upTo byteCount: Int, completion: @escaping (Result<(), Error>) -> Void) { if self.buffer.count < byteCount { self.connection.receive( minimumIncompleteLength: 0, maximumLength: 65536 ) { (data, _, isComplete, error) in if let error = error { completion(.failure(error)) return } guard let data else { if isComplete { completion(.failure(ConnectionError.disconnected)) } else { completion(.failure(ConnectionError.noData)) } return } self.buffer.append(data) self.receive(upTo: byteCount, completion: completion) } return } completion(.success(())) }

Slide 161

Slide 161 text

return try await withCheckedThrowingContinuation { (continuation) in connection.send(content: content, completion: .contentProcessed() { (error) in if let error { continuation.resume(throwing: error) return } self.receive() { (result) in switch result { case .success(let data): continuation.resume(returning: data) case .failure(let error): continuation.resume(throwing: error) } } }) } 4XJGU$PODVSSFODZ "TZOD"XBJU

Slide 162

Slide 162 text

public class Session { private var messageId = SequenceNumber() private let connection: Connection public init(host: String, port: Int) { connection = Connection(host: host, port: port) } public func connect() async throws { try await connection.connect() } public func negotiate( securityMode: Negotiate.SecurityMode = [.signingEnabled], dialects: [Negotiate.Dialects] = [.smb202, .smb210] ) async throws -> Negotiate.Response { let request = Negotiate.Request( messageId: messageId.next(), securityMode: securityMode, dialects: dialects ) let data = try await send(request.encoded()) let response = Negotiate.Response(data: data) return response } public func sessionSetup() async throws -> SessionSetup.Response { ... } }

Slide 163

Slide 163 text

public class Session { private var messageId = SequenceNumber() private let connection: Connection public init(host: String, port: Int) { connection = Connection(host: host, port: port) } public func connect() async throws { try await connection.connect() } public func negotiate( securityMode: Negotiate.SecurityMode = [.signingEnabled], dialects: [Negotiate.Dialects] = [.smb202, .smb210] ) async throws -> Negotiate.Response { let request = Negotiate.Request( messageId: messageId.next(), securityMode: securityMode, dialects: dialects ) let data = try await send(request.encoded()) let response = Negotiate.Response(data: data) return response } public func sessionSetup() async throws -> SessionSetup.Response { ... } }

Slide 164

Slide 164 text

public class Session { private var messageId = SequenceNumber() private let connection: Connection public init(host: String, port: Int) { connection = Connection(host: host, port: port) } public func connect() async throws { try await connection.connect() } public func negotiate( securityMode: Negotiate.SecurityMode = [.signingEnabled], dialects: [Negotiate.Dialects] = [.smb202, .smb210] ) async throws -> Negotiate.Response { let request = Negotiate.Request( messageId: messageId.next(), securityMode: securityMode, dialects: dialects ) let data = try await send(request.encoded()) let response = Negotiate.Response(data: data) return response } public func sessionSetup() async throws -> SessionSetup.Response { ... } }

Slide 165

Slide 165 text

public class Session { private var messageId = SequenceNumber() private let connection: Connection public init(host: String, port: Int) { connection = Connection(host: host, port: port) } public func connect() async throws { try await connection.connect() } public func negotiate( securityMode: Negotiate.SecurityMode = [.signingEnabled], dialects: [Negotiate.Dialects] = [.smb202, .smb210] ) async throws -> Negotiate.Response { let request = Negotiate.Request( messageId: messageId.next(), securityMode: securityMode, dialects: dialects ) let data = try await connection.send(request.encoded()) let response = Negotiate.Response(data: data) return response } public func sessionSetup() async throws -> SessionSetup.Response { ... } }

Slide 166

Slide 166 text

public class Session { private var messageId = SequenceNumber() private let connection: Connection public init(host: String, port: Int) { connection = Connection(host: host, port: port) } public func connect() async throws { try await connection.connect() } public func negotiate( securityMode: Negotiate.SecurityMode = [.signingEnabled], dialects: [Negotiate.Dialects] = [.smb202, .smb210] ) async throws -> Negotiate.Response { let request = Negotiate.Request( messageId: messageId.next(), securityMode: securityMode, dialects: dialects ) let data = try await connection.send(request.encoded()) let response = Negotiate.Response(data: data) return response } public func sessionSetup() async throws -> SessionSetup.Response { ... } }

Slide 167

Slide 167 text

public class Session { private var messageId = SequenceNumber() private let connection: Connection public init(host: String, port: Int) { connection = Connection(host: host, port: port) } public func connect() async throws { try await connection.connect() } public func negotiate( securityMode: Negotiate.SecurityMode = [.signingEnabled], dialects: [Negotiate.Dialects] = [.smb202, .smb210] ) async throws -> Negotiate.Response { let request = Negotiate.Request( messageId: messageId.next(), securityMode: securityMode, dialects: dialects ) let data = try await connection.send(request.encoded()) let response = Negotiate.Response(data: data) return response } public func sessionSetup() async throws -> SessionSetup.Response { ... } }

Slide 168

Slide 168 text

public class Session { private var messageId = SequenceNumber() private let connection: Connection public init(host: String, port: Int) { connection = Connection(host: host, port: port) } public func connect() async throws { try await connection.connect() } public func negotiate( securityMode: Negotiate.SecurityMode = [.signingEnabled], dialects: [Negotiate.Dialects] = [.smb202, .smb210] ) async throws -> Negotiate.Response { let request = Negotiate.Request( messageId: messageId.next(), securityMode: securityMode, dialects: dialects ) let data = try await connection.send(request.encoded()) let response = Negotiate.Response(data: data) return response } public func sessionSetup() async throws -> SessionSetup.Response { ... } }

Slide 169

Slide 169 text

import XCTest @testable import SMBClient final class SessionTests: XCTestCase { func testNegotiate() async throws { let session = Session(host: "198.51.100.50", port: 445) try await session.connect() let response = try await session.negotiate() ... } 6OJU5FTU%SJWFO 9$5FTU

Slide 170

Slide 170 text

3FBM8PSME&YBNQMFT r $POOFDUUP4IBSFʢڞ༗υϥΠϒʹ઀ଓʣ r -JTU%JSFDUPSZʢσΟϨΫτϦҰཡʣ r 4USFBNJOH7JEFP'JMFʢϏσΦΛετϦʔϛϯά࠶ੜʣ r 6QMPBE%PXOMPBE'JMFʢΞοϓϩʔυɾμ΢ϯϩʔυʣ r 3FOBNF'JMFʢϑΝΠϧ໊ͷมߋʣ r %FMFUF'JMFʢϑΝΠϧͷ࡟আʣ r 6OJDPEF/PSNBMJ[BUJPOʢ6OJDPEFਖ਼نԽʣ Α͋͘ΔϢʔεέʔε

Slide 171

Slide 171 text

3FBM8PSME&YBNQMFT r $POOFDUUP4IBSFʢڞ༗υϥΠϒʹ઀ଓʣ r -JTU%JSFDUPSZʢσΟϨΫτϦҰཡʣ r 4USFBNJOH7JEFP'JMFʢϏσΦΛετϦʔϛϯά࠶ੜʣ r 6QMPBE%PXOMPBE'JMFʢΞοϓϩʔυɾμ΢ϯϩʔυʣ r 3FOBNF'JMFʢϑΝΠϧ໊ͷมߋʣ r %FMFUF'JMFʢϑΝΠϧͷ࡟আʣ r 6OJDPEF/PSNBMJ[BUJPOʢ6OJDPEFਖ਼نԽʣ Α͋͘ΔϢʔεέʔε

Slide 172

Slide 172 text

No content

Slide 173

Slide 173 text

/BNF 4J[F 7BMVF 4USVDUVSF4J[F CZUFT 49 1BEEJOH CZUFT 'MBHT CZUFT -FOHUI CZUFT 65536 0GGTFU CZUFT 131072 'JMF*E CZUFT 3FBEJOH'JMF 4.#3&"%3FRVFTU

Slide 174

Slide 174 text

4USFBNJOH7JEFP'JMF "7"TTFU3FTPVSDF-PBEFS%FMFHBUF func resourceLoader( _ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest ) -> Bool { ... if let dataRequest = loadingRequest.dataRequest { let fileSize = try await fileReader.fileSize let data = try await fileReader.read( offset: UInt64(dataRequest.requestedOffset), length: UInt32(truncatingIfNeeded: length) ) dataRequest.respond(with: data) loadingRequest.finishLoading() } return true }

Slide 175

Slide 175 text

6OJDPEF/PSNBMJ[BUJPO /'%/'$/',%/',$ B⤆ € à ͔⤆㿆 ͕ ߹੒ ෼ղ ߹੒ ෼ղ ߹੒ࡁΈจࣈ ݁߹จࣈྻ

Slide 176

Slide 176 text

6OJDPEF/PSNBMJ[BUJPO /'%/'$/',%/',$ ਆ ਆ ௩ ௩ ↄ Ṃ U+FA19 U+795E U+795E U+FA10 U+585A U+585A

Slide 177

Slide 177 text

No content

Slide 178

Slide 178 text

6OJDPEF/PSNBMJ[BUJPO /'%/'$/',%/',$

Slide 179

Slide 179 text

Data(" 神 ".utf8) == Data("ਆ".utf8) 6OJDPEF/PSNBMJ[BUJPO /'%/'$/',%/',$

Slide 180

Slide 180 text

6OJDPEF/PSNBMJ[BUJPO /'%/'$/',%/',$ ਆ 神󠄀 神󠄀 U+FA19 U+795E U+795E U+E0100 ਆ VS 17 == !=

Slide 181

Slide 181 text

4BNQMF$PEF ➡IUUQTHJUIVCDPNLJTIJLBXBLBUTVNJ4.#$MJFOU

Slide 182

Slide 182 text

8SBQ6Q r ௨৴ϓϩτίϧΛ࣮૷͢Δʹ͸ ‣ ࢓༷ॻΛಡΉ ‣ 5$16%14PDLFU$POOFDUJPO ‣ #JOBSZ4FSJBMJ[F%FTFSJBMJ[F r 4BNQMF$PEF IUUQTHJUIVCDPNLJTIJLBXBLBUTVNJ4.#$MJFOU

Slide 183

Slide 183 text

3FGFSFODFT r 4BNQMF$PEF IUUQTHJUIVCDPNLJTIJLBXBLBUTVNJ4.#$MJFOU r <.44.#>4FSWFS.FTTBHF#MPDL 4.# 1SPUPDPM7FSTJPOTBOE IUUQTMFBSONJDSPTPGUDPNFOVTPQFOTQFDTXJOEPXT@QSPUPDPMTNTTNCBEFFBFD r <.4/-.1>/5-"/.BOBHFS /5-. "VUIFOUJDBUJPO1SPUPDPM IUUQTMFBSONJDSPTPGUDPNFOVTPQFOTQFDTXJOEPXT@QSPUPDPMTNTOMNQCDFEBGGEEF r %$&3FNPUF1SPDFEVSF$BMM31$1%6&ODPEJOHT IUUQTQVCTPQFOHSPVQPSHPOMJOFQVCTDIBQIUN

Slide 184

Slide 184 text

3FGFSFODFT r 0QFO4PVSDF*NQMFNFOUBUJPOT ‣ TNCQSPUPDPM IUUQTHJUIVCDPNKCPSFBOTNCQSPUPDPM ‣ SVCZ@TNC IUUQTHJUIVCDPNSBQJESVCZ@TNC

Slide 185

Slide 185 text

3FGFSFODFT r จࣈ਺ͷ࿩ͷଓ͖ʙ6OJDPEFͷָ͘͠ͳ͍࿩ʙ IUUQTTQFBLFSEFDLDPNTIVOTIPCPOXFO[JTIVOPIVBOPTPLLJVOJDPEFOPMFTJLVOBJIVB TMJEF r ී௨ͷ6OJDPEF͸/'$ͳͷ͔ IUUQTUBNBTBODPNVOJDPEFOGD r )'4ͷςΩετΤϯίʔσΟϯά IUUQTUBNBTBODPNIGTQMVT