Projektowanie stron WWW od podszewki

Artykuły na każdy temat

[PHP] Pobranie listy procesów i ubicie wybranych celów

Dodano 02.07.2011r. o 14:52
Skrypt umożliwia wyłączenie wybranych programów przy założeniu, że możemy wywoływać polecenia systemowe z poziomu PHP. Ponadto cała sytuacja dzieje się na Windowsie. Jeżeli będzie potrzeba zmodyfikowanie skryptu na inne OS'y to proszę o request wtedy pochylę się nad taką prośbą. Dodatkowym warunkiem, który musi zostać spełniony, aby skrypt działał jest włączona usługa RPC (domyślnie tak wlasnie jest) do wykonania zadania komendy systemowej tasklist oraz taskkill. Pierwsza z nich pobiera listę procesów na podstawie PROCESSENTRY32 jak mniemam. Drugie polecenie służy do zabijania wybranego procesu. Czyli mniej więcej coś jak taskmgr tylko w wersji konsolowej. Nie sprawdzałem, ale zgaduje, że aplikacje "ukryte" nie zostaną ujawnione na liście. W taki wypadku trzeba będzie napisać sterownik i odwołać się do EPROCESS. Przykładem narzędzia slużącego do chowania procesow jest np. HideToolz. Nie zmienia to jednak faktu, że i ukryte procesy da się wykryć. Pamiętam jak jakiś czas temu kłuciłem się z jakimś gościem, który twierdził, że używajac wyżej wymienionego narzędzia aplikacja staje się niewykrywalna. Sprawa rozbijała się o pewien antycheat do gry. Na dowód swoich słów, że da się wykryć ukryte procesy daje mały filmik demonstrujący aplikacje slużącą do listowania wszystkich procesów w systemie. Co ciekawe Microsoft wypuściło kiedyś narzędzie, które zwie się Process Explorer. Taki mix taskmgr i paru innych rzeczy w tym narzedzia slużącego do pokazywania procesów. Niestety zawiodłem się bo nie wykrywa ukrytych procesów.


I teraz ulubiona część artykułu czyli sedno sprawy. W tablicy $slaughter_list definiujemy PID'y albo nazwy procesów, które mają być ubite.
Kod:
<?php
// Lista procesów do ubicia
$slaughter_list['pid'] = array();
$slaughter_list['process_name'] = array('notepad.exe');
// Działania pożądane
$processes_list trim(shell_exec('tasklist /NH'));
$processes_list explode("\n"$processes_list);

if(empty($slaughter_list['pid']) && empty($slaughter_list['process_name']))
{
 echo 'Nie podałeś celów do ubicia';
 exit;
}

// Dla czystości sumienia
if(!empty($processes_list))
{
 // Przetwarzanie wyników i ubijanie celów, które w cale nie musi być w tym kawałku kodu
 foreach($processes_list as $key => $value)
 {
  // Niedoskonałe, dlatego trzeba nieco poprawić!
  preg_match("#([\s\w\.\-]+?)(\d+)#"$value$sub_information);
  $processes_list[$key] = array('process_name' => trim($sub_information[1]), 'pid' => (int)$sub_information[2]);

  // Sprawdzamy czy ten PID jest do ubicia
  if(in_array($processes_list[$key]['pid'], $slaughter_list['pid']))
  {
   // Można także użyć parametru /t odpowiedzialnego za zamkniecię procesów potomków
   exec('taskkill /pid '.$processes_list[$key]['pid'], $return$return_code);
   // $return_code > 0 = fail? $return_code = 128 oznacza nieudaną próbę ubicia procesu (nie znaleziono PID) - o ile dobrze pamiętam
   echo $processes_list[$key]['process_name'].' ('.$processes_list[$key]['pid'].') '.($return_code === '' 'nie ').'został ubity<br>';
  }

  // Dla czystości sumienia
  unset($return$return_code);

  // Sprawdzamy czy ta nazwa procesu jest do ubicia (uroki in_array() - wielkość liter nazwy procesu ma znaczenie! Rozwiązanie: array_map() + strtolower())
  if(in_array($processes_list[$key]['process_name'], $slaughter_list['process_name']))
  {
   // Można też użyć "taskkill /IM [nazwa procesu]"
   exec('taskkill /pid '.$processes_list[$key]['pid'], $return$return_code);
   // To samo co powyżej
   echo $processes_list[$key]['process_name'].' ('.$processes_list[$key]['pid'].') '.($return_code === '' 'nie ').'został ubity<br>';
  }

  // Dla czystości sumienia
  unset($return$return_code);
 }
}
else
{
 echo 'Lista procesów jest pusta';
}
?>
Przetwarzanie wyników i ubijanie celów niekoniecznie musi być w miejscu, które odpowiedzialne jest za listowanie procesów. Przykładowym wynikiem wykonania powyższego skryptu jest:

Cytat:

notepad.exe (1972) został ubity
notepad.exe (2860) został ubity
Zapytacie pewnie, po co to wszystko? W skrajnych przypadkach jest potrzeba zgaszenia aplikacji z poziomu strony WWW szczególnie jak się nie ma dostępu przez RDP (zdalny pulpit) albo inne badziewia.

Alternatywa dla komendy tasklist

Jeżeli nie znasz C++ i WinAPI to możesz na tym zakończyć czytanie artykułu. Troszkę kuriozalnie napisany jest ten tasklist, dlatego pomyślałem sobie, że lepiej samemu napisać program do listowania procesów. Głównie chodzi o filtrowanie potrzebnych informacji. Oczywiście można z poziomu poniższego aplikacji zabijać wybrany proces jednak pominąłem to.
Kod:
#include <iostream>
#include <windows.h>
#include <tlhelp32.h>

using namespace std;

int main()
{
    HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 pe = {0};
    pe.dwSize = sizeof(PROCESSENTRY32);

    if(Process32First(h, &pe))
    {
        do
        {
            cout << pe.szExeFile << " " << pe.th32ProcessID << endl;
        }
        while(Process32Next(h, &pe));
    }

    CloseHandle(h);

    system("PAUSE");
    return EXIT_SUCCESS;
}

Komentarze

Brak komentarzy

Dodaj komentarz

Zostaw komentarz jeżeli możesz! Nie bądź przysłowiowym botem! Nie bądź obojętny! Ciebie to nic nie kosztuje, a mi sprawi uśmiech na twarzy.
Zezwolono używać: BBCode
Zabroniono używać:
znaczników HTML

(Wymagany)

(Wymagany, niepublikowany)

(Nie wymagana)

Token:

Obrazek dla bota

(Przepisz tylko cyfry!)

(Wymagana)