| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- package smb
- import (
- "github.com/izouxv/logx"
- "imuslab.com/smb/driver/mod/smb/encoder"
- )
- // Function属性
- const (
- FSCTL_DFS_GET_REFERRALS = 0x00060194
- FSCTL_PIPE_PEEK = 0x0011400C
- FSCTL_PIPE_WAIT = 0x00110018
- FSCTL_PIPE_TRANSCEIVE uint32 = 0x0011C017
- FSCTL_SRV_COPYCHUNK = 0x001440F2
- FSCTL_SRV_ENUMERATE_SNAPSHOTS = 0x00144064
- FSCTL_SRV_REQUEST_RESUME_KEY = 0x00140078
- FSCTL_SRV_READ_HASH = 0x001441bb
- FSCTL_SRV_COPYCHUNK_WRITE = 0x001480F2
- FSCTL_LMR_REQUEST_RESILIENCY = 0x001401D4
- FSCTL_QUERY_NETWORK_INTERFACE_INFO = 0x001401FC
- FSCTL_SET_REPARSE_POINT = 0x000900A4
- FSCTL_DFS_GET_REFERRALS_EX = 0x000601B0
- FSCTL_FILE_LEVEL_TRIM = 0x00098208
- FSCTL_VALIDATE_NEGOTIATE_INFO = 0x00140204
- )
- // Flags属性
- const (
- SMB2_0_IOCTL_IS_IOCTL = 0x00000000
- SMB2_0_IOCTL_IS_FSCTL = 0x00000001
- )
- func init() {
- commandRequestMap[CommandIOCtl] = func() DataI {
- return &IOCTLRequest{}
- }
- }
- // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/5c03c9d6-15de-48a2-9835-8fb37f8a79d8
- type IOCTLRequest struct {
- Header
- StructureSize uint16
- Reserved uint16
- Function uint32
- GUIDHandle GUID //GUIDHandle []byte `smb:"fixed:16"`
- InputOffset uint32 `smb:"offset:Buffer"`
- InputLength uint32 `smb:"len:Buffer"`
- MaxInputSize uint32
- OutputOffset uint32
- OutputLength uint32
- MaxOutputSize uint32
- Flags uint32
- Reserved2 uint32
- Buffer []byte
- //Buffer interface{}
- }
- // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/f70eccb6-e1be-4db8-9c47-9ac86ef18dbb
- type IOCTLResponse struct {
- Header
- StructureSize uint16 //always 49
- Reserved uint16
- Function uint32 //CtlCode
- GUIDHandle GUID //FileId []byte `smb:"fixed:16"`
- BlobOffset uint32 //InputOffset
- BlobLength uint32 //InputCount
- BlobOffset2 uint32 //OutputOffset
- BlobLength2 uint32 //OutputCount
- Flags uint32
- Reserved2 uint32
- Buffer []byte
- }
- func (data *IOCTLRequest) ServerAction(ctx *DataCtx) (interface{}, error) {
- data.Header.Flags = SMB2_FLAGS_RESPONSE
- if data.Flags != SMB2_0_IOCTL_IS_FSCTL {
- return ERR(data.Header, STATUS_NOT_SUPPORTED)
- }
- if !data.GUIDHandle.IsSvrSvc(ctx.session) {
- return ERR(data.Header, STATUS_NOT_SUPPORTED)
- }
- var pdudata []byte
- /*
- if data.Flags == SMB2_0_IOCTL_IS_FSCTL {
- decoded, _ := hex.DecodeString("980000000f000000000000000000000000e1f505000000001700000000000000fe8000000000000000ebcb3570ade0f20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
- pdudata = decoded
- log.Println(pdudata)
- }
- */
- switch data.Function {
- case FSCTL_PIPE_WAIT:
- piple := FSCTLPIPEWAITRequestStruct{}
- if err := encoder.Unmarshal(data.Buffer, &piple); err != nil {
- }
- nameStr := string(piple.Name)
- logx.Debug("Unmarshalling Ioctl stdin pipe response ["+nameStr+"]", nil)
- case FSCTL_PIPE_TRANSCEIVE:
- _, err := DcerpcWrite(ctx, &WriteRequest{Data: data.Buffer})
- if err != nil {
- return ERR(data.Header, STATUS_UNSUCCESSFUL)
- }
- pdudata, err = DcerpcReadRaw(ctx)
- if err != nil {
- return ERR(data.Header, STATUS_UNSUCCESSFUL)
- }
- }
- resp := IOCTLResponse{
- Header: data.Header,
- StructureSize: 0x31,
- Function: data.Function,
- GUIDHandle: data.GUIDHandle,
- BlobOffset2: 0x70,
- BlobLength2: uint32(len(pdudata)),
- Buffer: pdudata,
- }
- return &resp, nil
- }
- // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/f030a3b9-539c-4c7b-a893-86b795b9b711
- // 请求服务器等待连接
- type FSCTLPIPEWAITRequestStruct struct {
- Timeout uint64 // 毫秒单位
- NameLength uint32
- TimeoutSpecified uint8 // 一个布尔值,指定是否忽略Timeout参数
- Padding uint8
- Name []byte // 命名管道名称的Unicode字符串,名称不得包含“\pipe\”
- }
- func (c *SessionC) NewFSCTLPIPEWAITRequest(pipename string) FSCTLPIPEWAITRequestStruct {
- pipeName := encoder.ToUnicode(pipename)
- return FSCTLPIPEWAITRequestStruct{
- NameLength: uint32(len(pipeName)),
- TimeoutSpecified: 1,
- Padding: 0,
- Name: pipeName,
- }
- }
- /*
- // 连接并绑定命名管道,并拿到管道句柄
- func (c *Session) ConnectAndWriteStdInPipes(pipename string) (treeid uint32, pipehandle []byte, err error) {
- timeout := uint64(500000)
- treeId, err := c.TreeConnect("IPC$")
- if err != nil {
- c.Debug("", err)
- return 0, nil, err
- }
- IOCTLRequest := c.NewIOCTLRequest(treeId)
- // 使用FSCTL_PIPE_WAIT,FileId必须为0xFFFFFFFFFFFFFFFF
- IOCTLRequest.Function = FSCTL_PIPE_WAIT
- IOCTLRequest.Flags = SMB2_0_IOCTL_IS_FSCTL
- IOCTLRequest.GUIDHandle = []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
- // 连接管道
- FSCTLPIPEWAITRequestIn := c.NewFSCTLPIPEWAITRequest(pipename)
- FSCTLPIPEWAITRequestIn.Timeout = timeout
- IOCTLRequest.Buffer = FSCTLPIPEWAITRequestIn
- c.Debug("Sending Ioctl stdin pipe request ["+pipename+"]", nil)
- buf, err := c.Send(IOCTLRequest)
- if err != nil {
- c.Debug("", err)
- return 0, nil, err
- }
- res := NewIOCTLResponse()
- c.Debug("Unmarshalling Ioctl stdin pipe response ["+pipename+"]", nil)
- if err = encoder.Unmarshal(buf, &res); err != nil {
- c.Debug("Raw:\n"+hex.Dump(buf), err)
- return 0, nil, err
- }
- // 创建管道请求
- pipeHander, err := c.CreatePipeRequest(treeId, pipename)
- if err != nil {
- return 0, nil, err
- }
- // 将数据写入管道
- err = c.WritePipeRequest(treeId, []byte("cmd"), pipeHander)
- if err != nil {
- return 0, nil, err
- }
- return treeId, pipeHander, nil
- }
- // 拿到stdin、out、err句柄
- func (c *Session) ConnectAndBindNamedPipes(pipename string) (stdinpipe, stdoutpipe, stderrpipe []byte, err error) {
- var stdIn, stdOut, stdErr []byte
- timeout := uint64(500000)
- treeId, err := c.TreeConnect("IPC$")
- if err != nil {
- c.Debug("", err)
- //return nil, err
- }
- IOCTLRequest := c.NewIOCTLRequest(treeId)
- // 使用FSCTL_PIPE_WAIT,FileId必须为0xFFFFFFFFFFFFFFFF
- IOCTLRequest.Function = FSCTL_PIPE_WAIT
- IOCTLRequest.Flags = SMB2_0_IOCTL_IS_FSCTL
- IOCTLRequest.GUIDHandle = []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
- // 连接输入管道
- pipeIn := pipename + "_in"
- FSCTLPIPEWAITRequestIn := c.NewFSCTLPIPEWAITRequest(pipeIn)
- FSCTLPIPEWAITRequestIn.Timeout = timeout
- IOCTLRequest.Buffer = FSCTLPIPEWAITRequestIn
- c.Debug("Sending Ioctl stdin pipe request ["+pipeIn+"]", nil)
- buf, err := c.Send(IOCTLRequest)
- if err != nil {
- c.Debug("", err)
- //return nil, err
- }
- res := NewIOCTLResponse()
- c.Debug("Unmarshalling Ioctl stdin pipe response ["+pipeIn+"]", nil)
- if err := encoder.Unmarshal(buf, &res); err != nil {
- c.Debug("Raw:\n"+hex.Dump(buf), err)
- }
- stdIn = res.GUIDHandle
- c.Debug("Completed Ioctl stdin pipe ["+pipeIn+"]", nil)
- // 连接输出管道
- pipeOut := pipename + "_out"
- FSCTLPIPEWAITRequestOut := c.NewFSCTLPIPEWAITRequest(pipeOut)
- FSCTLPIPEWAITRequestOut.Timeout = timeout
- IOCTLRequest.Buffer = FSCTLPIPEWAITRequestOut
- c.Debug("Sending Ioctl stdout pipe request ["+pipeOut+"]", nil)
- buf, err = c.Send(IOCTLRequest)
- if err != nil {
- c.Debug("", err)
- //return nil, err
- }
- res = NewIOCTLResponse()
- c.Debug("Unmarshalling Ioctl stdout pipe response ["+pipeOut+"]", nil)
- if err = encoder.Unmarshal(buf, &res); err != nil {
- c.Debug("Raw:\n"+hex.Dump(buf), err)
- }
- c.Debug("Completed Ioctl stdout pipe ["+pipeOut+"]", nil)
- // 创建
- // 连接错误管道
- pipeErr := pipename + "_err"
- FSCTLPIPEWAITRequestErr := c.NewFSCTLPIPEWAITRequest(pipeErr)
- FSCTLPIPEWAITRequestErr.Timeout = timeout
- IOCTLRequest.Buffer = FSCTLPIPEWAITRequestErr
- c.Debug("Sending Ioctl stderr pipe request ["+pipeErr+"]", nil)
- buf, err = c.Send(IOCTLRequest)
- if err != nil {
- c.Debug("", err)
- //return nil, err
- }
- res = NewIOCTLResponse()
- c.Debug("Unmarshalling Ioctl stderr pipe response ["+pipeErr+"]", nil)
- if err = encoder.Unmarshal(buf, &res); err != nil {
- c.Debug("Raw:\n"+hex.Dump(buf), err)
- }
- c.Debug("Completed Ioctl stderr pipe ["+pipeErr+"]", nil)
- return stdIn, stdOut, stdErr, nil
- }
- func NewIOCTLRequest(treeId uint32) IOCTLRequestStruct {
- // smb2Header := NewSMB2Header()
- // smb2Header.Command = smb.SMB2_IOCTL
- // smb2Header.CreditCharge = 1
- // smb2Header.MessageId = c.GetMessageId()
- // smb2Header.SessionId = c.GetSessionId()
- // smb2Header.TreeId = treeId
- // smb2Header.Credits = 127
- return IOCTLRequestStruct{
- Header: Header{
- Command: CommandIOCtl.INT(),
- Credits: 127,
- CreditCharge: 1,
- },
- StructureSize: 57,
- GUIDHandle: make([]byte, 16),
- }
- }
- */
|