Альтернативы LogonUser для сетевого олицетворения (C ++) - PullRequest
8 голосов
/ 20 июля 2009

Есть ли альтернативы LogonUser и для олицетворения данной учетной записи для доступа к сетевым ресурсам? Я ищу метод олицетворения, который позволил бы мне подключиться к машине в чужих доменах (или машинам рабочей группы для того же вопроса).

Для исходных данных у меня есть: имя машины, имя пользователя (или домен \ имя пользователя), пароль в виде открытого текста.

Я знаю, что есть способ установить соединение, используя WNetAddConnection с \\ machinename \ ipc $, тогда большинство сетевых функций будут работать в контексте этой учетной записи, однако win2008 добавил еще один поворот, и некоторые функции все еще используют учетную запись, этот поток работает под.

Я также знаю, что есть какой-то способ получить маркер олицетворения с помощью SSPI. Кто-нибудь экспериментировал с этими токенами, хороши ли они для доступа к общим ресурсам, SCM, удаленному реестру и тому подобному? Для чего используется WNetAddConnection?

РЕДАКТИРОВАТЬ: Чтобы уточнить, причина, по которой я не могу использовать LogonUser, заключается в том, что мне нужно выдать себя за пользователя в ненадежном домене или рабочей группе

EDIT2: Еще одно уточнение: элемент, который я пытаюсь реализовать, похож на psexec, например ::

  • программа не должна изменять конфигурацию хоста или активного каталога (например, создавать временных локальных пользователей и т. Д.). Более того, нельзя предположить, что он работает на постоянном токе или нет
  • Не может быть никаких предположений относительно того, какое программное обеспечение предварительно установлено на удаленном хосте, только при условии, что общий доступ к файлам Windows включен на цели
  • Известно, что учетная запись / пароль работают на целевом сервере, но целевой компьютер может находиться в локальном домене, чужом домене, а не в домене.

EDIT3: Мне бы очень хотелось узнать больше об опции SSPI InitializeSecurityContext / AcquireCredentialsHandle. Есть ли кто-нибудь, кто интенсивно работал с этим API? Можно ли использовать токены, возвращенные с олицетворением, чтобы поток мог обращаться к сетевым ресурсам, копировать файлы и т. Д.? Может кто-нибудь выложить рабочий фрагмент кода?

EDIT4: Благодаря Marsh Ray проблема решена. Если кто-то ищет код проверки концепции, он здесь

Ответы [ 4 ]

9 голосов
/ 29 июля 2009

Если вы хотите «получить доступ к сетевым ресурсам» за пределами своего леса, сделайте это с WNetAddConnection2 / 3, как вы упомянули, или используйте стандартные API-интерфейсы RPC с RPC_ C__ AUTHN__ GSS__ NEGOTIATE и явной структурой учетных данных.

Обычно "олицетворение" - это то, что происходит на стороне сервера. Серверная сторона сможет олицетворять соединение как учетную запись, которую вы подключаете как.

Но ключ заключается в следующем: олицетворение имеет смысл только для олицетворения учетной записи, к которой сервер может получить доступ в своем локальном каталоге SAM / domain / forest. Если клиент и сервер находятся в разных лесах, они явно не могут согласовать SID учетной записи для токена олицетворения (за исключением случая с хорошо известными SID, такими как Administrator, которые служат главным образом для запутывания такого рода вещей), и что необходимо проверить по DACL и т. д.

Возможно, вам нужно вызвать LogonUserEx с флагом LOGON32__ LOGON__ NEW__ CREDENTIALS. Это должно произойти (даже в другом лесу - на самом деле он не проверяет подлинность предоставленных вами учетных данных), давая вам токен с указанным вами именем пользователя / паролем. Возможно, вам придется использовать DuplicateToken, чтобы превратить это в токен олицетворения. Затем вы можете использовать SetThreadToken для замены токена в вашем потоке.

ИМХО, на самом деле это не "олицетворение", вы просто используете учетные данные напрямую, но оно позволяет вам прозрачно получать доступ к сетевым ресурсам в качестве произвольного имени пользователя / пароля, которое вы предоставляете.

Редактировать: О да, учтите, что в этом типе соединения нет защиты от человека посередине. Клиент особенно не может строго аутентифицировать сервер (если не считать героев, таких как IPSEC), поэтому теоретически вы не можете доверять всему, что сервер говорит вам.

4 голосов
/ 21 июля 2009

Теория гласит, что вы передаете учетные данные в виде структуры SEC_WINNT_AUTH_IDENTITY функции AcquireCredentialsHandle , которая создает дескриптор, используемый в InitializeSecurityContext . Я никогда не пробовал это на чужих доменах, хотя и не знаю, работает ли это.

0 голосов
/ 25 июля 2009

Вы можете открыть командную строку, сопоставить диск, используя имя пользователя и пароль в виде простого текста. Затем отключите диск:

net use m: \\machinename\share password /user:username
... do stuff ...
net use m: /delete

http://technet.microsoft.com/en-us/library/cc756153(WS.10).aspx

0 голосов
/ 23 июля 2009

Делать это напрямую и надежно через Windows API кажется практически невозможным, плюс Windows делает так много закулисной работы, чтобы сделать доступ к сети «просто работающим». Кроме того, сторона подражания действует только для одного потока, который называется API.

Но ... вы можете запустить целую программу под другим пользователем ... например, при запуске службы.

Таким образом, вы можете отредактировать реестр в своей основной программе, чтобы запускать различные службы под разными токенами безопасности, и использовать IPC / сокеты для связи с этими процессами из основного приложения. то есть. целая куча (или перезапуск и переконфигурирование одного и того же процесса) вспомогательных процессов, запущенных под разными пользователями, которыми злоупотребляет ваше основное приложение.

Я понимаю, что это хак, но это кажется жизнеспособным;)

...