Narzędzie do nieadmińskiego shadow podłączenia do sesji RDP użytkowników w WinServer 2012R2

Problem w okresie pracy przedsiębiorstwa w czasie kwarantanny był następujący: rzeczywiście należy zminimalizować liczbę wizyt w biurach specjalistów zajmujących się obsługą i doradztwem w zakresie oprogramowania aplikacyjnego, a szczerze mówiąc, użytkownicy często nadużywają pomocy specjalistów, nie chcąc zagłębiać się w sam problem, twierdząc „przyjdą - pomogą - zrobią, a ja w tym czasie zapalę papierosa / wypiję kawę itp.”. Konsultacja telefoniczna przy wspólnym dostępie do serwera jest bardziej efektywna, gdy jesteśmy w stanie przeglądać zdalny ekran.

Narzędzie do nieadmińskiego shadow podłączenia do sesji RDP użytkowników w WinServer 2012R2

Już po „wynalezieniu” naszego roweru pojawiły się sensowne informacje na temat artykułu: RDS Shadow – połączenie szeregowe z sesjami RDP użytkowników w Windows Server 2012 R2 lub Tryb shadow użytkownika bez uprawnień w systemie Windows Server lub Delegowanie zarządzania sesjami RDP. Wszystkie one zakładają korzystanie z konsoli, nawet z elementami prostego dialogu.

Wszystkie zamieszczone poniżej informacje są przeznaczone dla tych, którzy normalnie znoszą nienormalne wynaturzenia w celu osiągnięcia pożądanego rezultatu, wynajdując niepotrzebne sposoby.
Aby „nie ciągnąć kota za ogon”, zacznę od ostatniego: rower działa u zwykłego użytkownika za pomocą narzędzia AdmiLink, za co autorowi należy się podziękowanie.

I. Konsola i shadow RDP.

Ponieważ korzystanie z administratorskimi prawami w konsoli Menedżera Serwera -> QuickSessionCollection -> klikając na sesję interesującego użytkownika, wybierając w menu kontekstowym Shadow (Kopia cieniowa) dla personelu, instruującego w pracy z oprogramowaniem, — nie było to możliwe, rozważono inny „drewniany” sposób, a mianowicie:

1. Sprawdzamy RDP id sesji:

query user | findstr Administrator

lub:

qwinsta | findstr Administrator 

Przy czym "| findstr Administrator" było wygodne tylko wtedy, gdy wiesz, że akurat Administrator potrzebujesz, ewentualnie używać tylko pierwszej części do przeglądania wszystkich zalogowanych na serwerze.

Narzędzie do nieadmińskiego shadow podłączenia do sesji RDP użytkowników w WinServer 2012R2

2. Łączymy się z tą sesją, pod warunkiem, że w politykach grupowych domeny wskaźnik „Ustala zasady zdalnego zarządzania sesjami użytkowników w usługach zdalnych pulpitu” został wybrany ze wskaźnikiem przynajmniej „Obserwacja sesji za zgodą użytkownika” ( mstsc /shadow:127więcej informacji):

Proszę zwrócić uwagę, że na liście będą tylko loginy użytkowników.

Powtarzam, że bez uprawnień administratora otrzymasz następujący rezultat:

Ale do wstępnego debugowania programu, o którym mowa, korzystałem z konta z prawami administratora.

Narzędzie do nieadmińskiego shadow podłączenia do sesji RDP użytkowników w WinServer 2012R2

Jednak do wstępnego debugowania programu, o którym mowa, użyłem konta z uprawnieniami administratora.

II. Program

Zadanie: stworzenie prostego interfejsu graficznego do połączenia z użytkownikiem przy jego zgodzie oraz wysyłania wiadomości do użytkownika. Wybrano środowisko programistyczne Lazarus.

1. Uzyskujemy pełną listę domen użytkowników „login” – „pełne imię” od administratora lub ponownie za pomocą konsoli:

wmic useraccount get Name,FullName 

Nikt nie zabrania tak zrobić:

wmic useraccount get Name,FullName > c:testusername.txt

Zaraz powiem, że Lazarus miał problem z przetwarzaniem tego pliku, ponieważ domyślnie jego kodowanie to UCS-2, więc musiałem po prostu ręcznie przekształcić na zwykły UTF-8. W strukturze pliku jest dużo tabulacji, a właściwie wiele spacji, które postanowiliśmy przetworzyć programowo; prędzej czy później problem z kodowaniem zostanie rozwiązany, a plik będzie aktualizowany programowo.

Zatem w koncepcji jest folder dostępny dla użytkowników programu, na przykład c:test, w którym będą 2 pliki: pierwszy z loginem i pełnym imieniem, drugi z id_rdp i loginami użytkowników. Następnie przetwarzamy te dane jak potrafimy :).

Na razie, aby skojarzyć z listą sesji, przenosimy te (login i pełne imię) zawartości do tablicy:

procedure Tf_rdp.UserF2Array;
var 
  F: TextFile;   i: integer;   f1, line1: String;   fL: TStringList;
begin  // f_d globalna ścieżka do lokalizacji plików
f1 := f_d + 'user_name.txt';  // zadanie polega na odczytaniu zawartości pliku do tablicy
fL := TStringList.Create;  // poddamy linię metamorfozom z separatorami
fL.Delimiter := '|'; fL.StrictDelimiter := True;
AssignFile(F, f1);
try  // Otwórz plik do odczytu
  reset(F); ReadLn(F, line1);
  i := 0;
while not eof(F) do  // Odczytuje wiersze, dopóki nie skończy się plik
begin
ReadLn(F, line1);
line1 := StringReplace(line1, '  ', '|', []);  // zamienia pierwszy napotkany 2 spacje na separator |
// usuwamy wszystkie podwójne spacje
while pos('  ', line1) > 0 do line1 := StringReplace(line1, '  ', ' ', [rfReplaceAll]);
begin
if (pos('|', line1) > 0) then
begin  // jeśli separator istnieje, zapisujemy go w tablicy
fL.DelimitedText := line1;  // dzielimy na kolumny
if (fL[0]  '') then  // jeśli konto ma nazwę
begin  // wpisujemy je do tablicy
 inc(i);  // pozbywamy się możliwych pojedynczych spacji w loginie
 fam[0, i] := StringReplace(fL[1], ' ', '', [rfReplaceall, rfIgnoreCase]);
 fam[1, i] := fL[0];
 end;end;end;end;  // Gotowe. Zamykamy plik.
 CloseFile(F);
 Fl.Free;
 except
 on E: EInOutError do ShowMessage('Błąd przetwarzania pliku. Szczegóły: ' + E.Message);
 end;end;

Przepraszam za „dużo kodu”, kolejne punkty będą bardziej zwięzłe.

2. W podobny sposób, jak w poprzednim punkcie, odczytujemy wynik przetwarzania listy do elementu StringGrid, przytaczając „istotny” fragment kodu:

2.1 Otrzymujemy aktualną listę sesji RDP w pliku:

f1:=f_d+'user.txt';
cmdline:='\/c query user >'+ f1;
if ShellExecute(0,nil, PChar('cmd'),PChar(cmdline),nil,1)=0 then;
Sleep(500); \/\/ można poczekać dłużej, aż plik zostanie utworzony do odczytu

2.2 Przetwarzamy plik (podane tylko istotne linie kodu):

StringGrid1.Cells[0,i]:=fL[1]; StringGrid1.Cells[2,i]:=fL[3]; \/\/ wrzucamy w pętli do StringGrid1
login1:=StringReplace(fL[1],' ','',[rfReplaceall, rfIgnoreCase]); \/\/ usuwamy spacje z logina
if (SearchArr(login1)>=0) then \/\/ szukamy w tablicy logina z p1. i zapisujemy w tabeli FIO
StringGrid1.Cells[1,i]:=fam[1,SearchArr(login1)]
else StringGrid1.Cells[1,i]:='+'; \/\/ albo zapisujemy plusa:)
.... \/\/ w zależności od wyboru użytkownika sortujemy i formatujemy dane
if (b_id.Checked=true) then SortGrid(0) else SortGrid(1);
StringGrid1.AutoSizeColumn(0);StringGrid1.AutoSizeColumn(1); StringGrid1.AutoSizeColumn(2);  

3. Bezpośrednie połączenie po kliknięciu na wiersz z użytkownikiem i numerem jego sesji:

  id:=(StringGrid1.Row);\/\/poznajemy numer wiersza  IntToStr(StringGrid1.Row)
  ids:=StringGrid1.Cells[2,id]; \/\/ uzyskujemy identyfikator rdp
  cmdline:='\/c mstsc \/shadow:'+ ids; \/\/ i łączymy się....
 if (b_rdp.Checked=True) then  if ShellExecute(0,nil, PChar('cmd'),PChar(cmdline),nil,1) =0 then;       

4. Dodano jeszcze kilka ulepszeń, takich jak sortowanie po kliknięciu na radiobutton, oraz wiadomości do użytkownika lub do wszystkich użytkowników.

Narzędzie do nieadmińskiego shadow podłączenia do sesji RDP użytkowników w WinServer 2012R2

→ Pełny kod źródłowy można zobaczyć tutaj

III. Zastosowanie AdminLink — co zauważyłem:

AdminLink rzeczywiście generuje skrót, który odnosi się do lokalizacji narzędzia admilaunch.exe, oraz osobistej kopii narzędzia uruchamiającego AdmiRun.Exe , która znajduje się w folderze użytkownika, na przykład vasya, w stylu C:UsersvasyaWINDOWS. W sumie nie jest tak źle: z prawami dostępu do pliku skrótu i innymi, można się pobawić, aby oczyścić sumienie.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster