Ataques man-in-the-browser (MitB)

Ya sabéis que un ataque man-in-the-middle (MiTM) el atacante intercepta el tráfico de la víctima, lo que le permite robar la información no protegida y manipular las respuestas. Sin embargo hoy vamos a ver los ataques man-in-the-browser (MitB) que se sitúan entre la víctima y su navegador. Normalmente lo suele implementar malware bancario y extensiones del navegador maliciosas ya que las protecciones como TLS y el segundo factor de autenticación no tienen ningún efecto contra ellos.

El agente de MitB espera hasta que la víctima visite un sitio web relevante y, cuando envía un formulario para realizar un nuevo pago, el agente cambia los valores enviados. Esto significa que en lugar de enviar, digamos, $1000 a un amigo, la víctima termina enviando $10,000 al atacante.


La principal mitigación contra estos ataques MiTB es utilizar mecanismos de autenticación "fuera de banda" en inglés out-of-band (OOB), es decir, utilizar otro medio externo al propio navegador del usuario como un SMS, si bien hay que tener en cuenta que también existe malware man-in-the-mobile (MitMo) en el teléfono móvil... xD

Un ejemplo práctico de un troyano que utiliza MitB

Una cadena de infección típica que incorpora un troyano que intentará realizar transacciones fraudulentas manipulando DOM es la siguiente:

  1. El troyano infecta el software de la computadora, ya sea el sistema operativo o la aplicación.
  2. El troyano instala una extensión en el navegador maliciosa para que se cargue la próxima vez que se inicie el navegador.
  3. Más tarde, el usuario reinicia el navegador.
  4. El navegador carga la extensión.
  5. La extensión registra un controlador para cada carga de página.
  6. Siempre que se carga una página, la extensión busca la URL de la página en una lista de sitios conocidos que son objeto de un ataque.
  7. El usuario inicia sesión de forma segura en, por ejemplo, https://www.banco.site/.
  8. Cuando el controlador detecta una carga de página para un patrón específico en su lista de destino (por ejemplo, https://www.banco.site/cuenta/FormularioPago), registra un controlador de eventos de botón.
  9. Cuando se presiona el botón enviar, la extensión extrae todos los datos de todos los campos del formulario a través de la interfaz DOM en el navegador y recuerda los valores.
  10. La extensión modifica los valores a través de la interfaz DOM.
  11. La extensión le dice al navegador que continúe enviando el formulario al servidor.
  12. El navegador envía el formulario, incluidos los valores modificados, al servidor.
  13. El servidor recibe los valores modificados en el formulario como una solicitud normal. El servidor no puede diferenciar entre los valores originales y los valores modificados, ni detectar los cambios.
  14. El servidor realiza la transacción y genera un recibo.
  15. El navegador recibe el recibo de la transacción modificada.
  16. La extensión detecta la URL https://www.banco.site/cuenta/confirmar, escanea el HTML en busca de los campos del recibo y reemplaza los datos modificados en el recibo con los datos originales que recordaba en el HTML.
  17. El navegador muestra el recibo modificado con los detalles originales.
  18. El usuario cree que la transacción original fue recibida por el servidor intacta y autorizada correctamente.

Sencilla protección contra ransomware mediante Raccine

Muchas familias de ransomware intentan mediante vssadmin borrar todas las shadow copies del sistema, ya sabéis, las instantáneas que va tomando Windows para poder volver a un punto de restauración en caso necesario. Es decir, intentan que la víctima no pueda tirar de ningún backup. ¿Qué pasaría si pudiéramos interceptar ese intento y terminar el proceso que lo invoca? Pues esto es lo que hace la herramienta Raccine del archifamoso Florian Roth aka Neo23x0.

Funcionamiento

  • Se intercepta la llamada a vssadmin.exe (y wmic.exe) y se pasa a raccine.exe como debugger (vssadmin.exe delete shadows se convierte en raccine.exe vssadmin.exe delete shadows)
  • Luego se procesan los argumentos de la línea de comandos y se buscan combinaciones maliciosas usando reglas de Yara.
  • Si no se puede encontrar una combinación maliciosa, se crea un nuevo proceso con los parámetros originales de la línea de comandos.
  • Si se encuentra una combinación maliciosa, se recopilan todos los PID de los procesos principales y comienza a matarlos. Raccine muestra una ventana de línea de comandos con los PID eliminados durante 5 segundos, lo loggea en el registro de eventos de Windows y luego sale.

Ventajas:

  • El método es bastante genérico.
  • No tenemos que reemplazar un archivo de sistema (vssadmin.exe o wmic.exe), lo que podría ocasionar problemas de integridad y podría romper nuestra vacuna cada vez que se parchee
  • Permite usar reglas YARA para buscar parámetros maliciosos en la línea de comandos
  • Los cambios son fáciles de deshacer
  • Se ejecuta en Windows 7/Windows 2008 R2 o superior
  • No se requiere un ejecutable en ejecución o un servicio adicional (sin agente)

Desventajas/Puntos ciegos

  • El uso legítimo de vssadmin.exe para eliminar shadow copies (o cualquier otra combinación blacklisteada) ya no es posible
  • Elimina todos los procesos que intentaron invocar vssadmin.exe, lo que podría ser un proceso de copia de seguridad (falso positivo)
  • Esto no detectará métodos en los que el proceso malicioso no sea uno de los procesos en el árbol que ha invocado vssadmin.exe (por ejemplo, a través de schtasks)

Tritium: una herramienta en go para password spraying

Hoy en día existen muchas herramientas para hacer password spraying mediante pre-autenticación de Kerberos, pero hoy he visto una escrita en Go llamada Tritium bastante interesante y una buena candidata para añadir al arsenal de todo buen pentester. 

Tal y como rezan en su Github incorporan las siguientes funcionalidades:

  • previene el bloqueo de usuarios del dominio
  • integra la enumeración de nombres de usuario con el proceso de spray de contraseñas (ambas son funcionalidades separadas)
  • capacidad de hacer spray de contraseñas de forma recursiva en lugar de ejecutar un simple spray
  • puede hacer resume/continuar el ataque e ignora las cuentas previamente comprometidas

Tritium permite lo mencionado anteriormente y más. Por ejemplo la enumeración de usuarios ya no desperdiciará un intento de login previo porque lo usará para generar un archivo de usuarios válidos. Tritium también le da al usuario la capacidad de pasarle un archivo de contraseñas para hacer spray de forma recursiva. Y sobretodo tiene la funcionalidad como comentábamos de que detecta si un dominio está bloqueando cuentas al guardar el estado y detiene el ataque si se bloquean 3 cuentas consecutivas.

Repo: https://github.com/S4R1N/Tritium
Instalación: go get S4R1N/Tritium

Uso:

 ./Tritium -h

        ___________      .__  __  .__               
        \__    ___/______|__|/  |_|__|__ __  _____  
          |    |  \_  __ \  \   __\  |  |  \/     \ 
          |    |   |  | \/  ||  | |  |  |  /  Y Y  \
          |____|   |__|  |__||__| |__|____/|__|_|__/ v 0.4
                                                                                          

          Author: S4R1N, alfarom256
 


 Required Params:

 -d            The full domain to use (-domain targetdomain.local)
 -dc           Domain controller to authenticate against (-dc washingtondc.targetdomain.local)
 -dcf          File of domain controllers to authenticate against 
 -u            Select single user to authenticate as (-user jsmith) 
 -uf           User file to use for password spraying (-userfile ~/home/users.txt)
 -p            Password to use for spraying (-password Welcome1)

 Optional: 

 -help         Print this help menu
 -o            Tritium Output file (default spray.json)
 -w            Wait time between authentication attempts [Default 1] (-w 0)    
 -jitter       % Jitter between authentication attempts      
 -rs           Enable recursive spraying 
 -ws           Wait time between sprays [Default 3600] (-ws 1800)
 -pwf          Password file to use for recursive 
 -res          Continue a password spraying campaign
 -rf           Tritium Json file 

CVE-2020-9484: RCE mediante deserialización en Apache Tomcat con PersistentManager

Hoy vamos a ver la explotación de la vulnerabilidad CVE-2020-9484 que publicó Jarvis Threedr3am, de pdd security research, a comienzos del verano pasado y que permite ejecución remota de código a través de deserialización en versiones de Apache Tomcat anteriores a abril de 2020. 

Eso sí, para que el servidor Tomcat objetivo sea vulnerable además los administradores tienen que haber configurado el uso de PersistentManager editando el archivo conf/context.xml, ya que por defecto Tomcat se ejecutará con StandardManager

  • StandardManager mantendrá las sesiones en la memoria. Si tomcat se cierra correctamente, almacenará las sesiones en un objeto serializado en el disco (llamado "SESSIONS.ser" por defecto). 
  • PersistentManager hace lo mismo, pero con un extra: hacer swapping de sesiones inactivas/idle. Si una sesión ha estado inactiva durante x segundos, se moverá al disco. Es una forma de reducir el uso de memoria. 

Cuando Tomcat recibe una solicitud HTTP con una cookie JSESSIONID, le pedirá al Manager que verifique si esa sesión ya existe. Como se controla el JSESSIONID ¿qué pasa por ejemplo si lo seteamos a un valor como "JSESSIONID=../../../../../../tmp/12345"? 

  • Tomcat solicita al Manager que verifique si existe una sesión con el ID de sesión "../../../../../../tmp/12345"
  • Primero verificará si tiene esa sesión en la memoria. 
  • Si no es así y está configurado PersistentManager verificará si tiene la sesión en el disco.
  • Verificará en el directorio + sessionid + ".session", por lo que se evalúa como “./session/../../../../../../tmp/12345.session“ 
  • Si el archivo existe, lo deserializará y analizará la información de la sesión.

Entonces, ya ha os habéis imaginado que necesitamos cargar un objeto serializado malicioso en un path interno de la máquina para que podamos recuperarlo a través de la cookie JSESSIONID y poder conseguir RCE. 

Taller de exploiting: ret2libc en Linux x64

Seguimos con exploiting en Linux, con el mismo código en la entrada anterior pero esta vez activando el bit NX (no-execute), es decir, la protección que nos marcará el stack como no ejecutable:
#include <stdio.h>
#include <unistd.h>

int vuln() {
    char buf[80];
    int r;
    r = read(0, buf, 400);
    printf("\nHas pasado %d bytes. buf es %s\n", r, buf);
    puts("No shell!");
    return 0;
}

int main(int argc, char *argv[]) {
    vuln();
    return 0;
}
Para ello compilamos el código esta vez sin '-z execstack':
$ gcc -fno-stack-protector ejercicio2x64.c -o ejercicio2x64
No nos olvidamos de desactivar ASLR (de momento) para realizar el ejercicio:
$ sudo sysctl -w kernel.randomize_va_space=0
Y cambiarle los permisos necesarios también:
$ sudo chown root ret2libc
$ sudo chmod 4755 ret2libc
Comprobamos las protecciones del programa compilado:
gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : ENABLED
PIE       : disabled
RELRO     : Partial

Ya tenemos el binario para trabajar con él, pero recordar que ya no podremos apuntar la dirección de retorno a nuestro shellcode directamente en la pila, por lo que tendremos que utilizar la técnica return to libc o ret2libc. 

¿Qué es ret2libc? 

Cada vez que escribimos un programa en C utilizamos funciones como printf, scanf, put, etc. y todas esas funciones estándar de C se han compilado en un solo archivo que es la librería estándar de C o libc, el cual es independiente del binario (programa compilado). 

Ret2libc es una técnica que se basa en ejecutar código que no se encuentra en la pila sino en un sector de la memoria de libc, que es ejecutable. Es decir, el código utilizado para vulnerar el programa son funciones dentro de esta librería. 

Resumiendo: podemos modificar la dirección de retorno para que apunte a libc, que cuenta con funciones muy útiles como system() para, por ejemplo, obtener una shell. 

El resumen del payload más común sería el siguiente: 

Junk + RET + POP RDI + shell + System Address 

Lo más visto del 2020 en Hackplayers

Último día del año y tradicional post con las 50 entradas del blog más leídas durante el año, este 2020 tildado como maldito por la pandemia de este infame virus que nos azota desde hace ya muchos meses.

Así que no puedo despedir este año sin desear que este nuevo que entra sea el de la recuperación y el principio de la vuelta a la normalidad. Sabemos que las próximas semanas serán duras y que probablemente nos enfrentaremos a un nueva ola así que a todos mucha precaución y paciencia.

Ya sabéis que a principios de año y ajenos todavía a lo que se venía, tuvimos la suerte de poder celebrar en condiciones normales y disfrutar nuestra conferencia h-c0n, pero que en 2021 no la podremos celebrar dadas las circunstancias.

Eso sí, diluiremos nuestra participación en otras actividades a lo largo del año: en otros eventos online con nuestros amigos, jugando a CTFs, debatiendo y compartiendo info en grupos y redes sociales, llorando o riendo... allí estaremos alguno de los locos de Hackplayers pues, como decía Goethe, la locura, a veces, no es otra cosa que la razón presentada bajo diferente forma.   

Cuidaros mucho.

  1. El "texto de la muerte" para los usuarios de WhatsApp en Android
  2. Crackear la contraseña de cualquier usuario de Windows sin ningún privilegio (cuenta de invitado incluida)
  3. Listado de códigos secretos de Android
  4. El abc para desproteger un Excel con contraseña
  5. Cómo fingir ser un hacker
  6. Grupos de Telegram sobre hacking y seguridad informática en español
  7. 100 grupos de hackers famosos
  8. 15 sitios para practicar hacking (legalmente) este verano
  9. Truco para *petar* un grupo de WhatsApp (bomba de emoticonos)
  10. 8 servicios proxy gratuitos para evitar restricciones y mantener el anonimato y la privacidad
  11. Introducción a Social-Engineering Toolkit (SET)
  12. WiFite: crackear redes wifi para dummies
  13. hackplayers: Blogroll en español
  14. Cómo clonar la tarjeta SD de la Raspberry Pi
  15. iDict, una herramienta de fuerza bruta para obtener contraseñas de usuarios de iCloud
  16. Tutorial para modificar un APK añadiéndole un payload msf
  17. Una lista de películas y series que todo hacker debe ver
  18. Recursos y herramientas para el descubrimiento de subdominios
  19. Bitcracker: la primera herramienta opensource para crackear volúmenes cifrados con BitLocker
  20. Cómo identificar el proceso que está usando un puerto TCP determinado
  21. hackplayers: Retos de Hackplayers
  22. Xencrypt: un crypter en PowerShell
  23. Descarga gratis los 100 mejores libros de hacking de Raj Chandel
  24. Listado de herramientas online para escanear sitios web potencialmente maliciosos
  25. Cómo hacerte un IMSI Catcher sencillo por sólo 11€
  26. androrat: un troyano RAT para Android
  27. SAD DNS: un nuevo ataque que puede hacer tambalear los cimientos de Internet
  28. HTTP-revshell: controla el equipo de la víctima a través de un canal encubierto
  29. Métodos para ocultar el historial de bash
  30. SearchOrg: script para obtener información de empresas mediante su dominio
  31. Principales vulnerabilidades en un Directorio Activo
  32. Aplicación Android para robar y leer chats de WhatsApp en Android (PoC)
  33. Zerologon desatado: la vulnerabilidad que permite comprometer cualquier controlador de dominio de Windows fácilmente
  34. hackplayers: Participa en Hackplayers
  35. El "texto de la muerte" para los usuarios de Apple
  36. Listado de sandboxes de análisis de malware gratuitos y online
  37. Algunos google dorks para espiar cámaras web en Internet
  38. De cómo colarse en el metro de forma elegante... (NFC hack)
  39. Comprometido por sólo copiar y pegar texto de una página maliciosa (obtención de una shell mediante pastejacking)
  40. SIGRed: vulnerabilidad crítica en el servidor DNS de Windows (CVE-2020-1350)
  41. Taller para escalar privilegios en Windows/Linux
  42. Ataques DoS "Slow HTTP" mediante SlowHTTPTest
  43. 13 herramientas para desofuscar código para reversers
  44. Hacking Wireless con Airgeddon (by @OscarAkaElvis #hc0n2019)
  45. Android Hacking 101 - Introducción
  46. Herramientas SQL Injection
  47. El viejo truco de las sticky keys sigue funcionado
  48. whatsapp-phishing o cómo robar la sesión de un usuario de WhatsApp Web
  49. Evadir un portal cautivo mediante un túnel DNS
  50. SIEM, ¿Durmiendo con el enemigo?

Taller de exploiting: baby BOF en Linux x64

Voy a retomar los ejercicios de exploiting en Linux, esta vez en arquitectura de 64 bits. Básicamente se trata de lo mismo que en 32 bits pero con unos "pequeños" cambios, principalmente:   

  • Los registros de propósito general se han ampliado a 64 bits. Así que ahora tenemos RAX, RBX, RCX, RDX, RSI y RDI. 
  • El puntero de instrucción (instruction pointer), el puntero de base (base pointer) y el puntero de pila (stack pointer) también se han ampliado a 64 bits como RIP, RBP y RSP respectivamente. 
  • Se han proporcionado registros adicionales: R8 a R15. 
  • Los punteros tienen un ancho de 8 bytes. 
  • Push/pop en la pila tienen 8 bytes. 
  • El tamaño máximo de dirección canonical/userspace es de 48bits, los menos significativos: 0x00007FFFFFFFFFFF. 
  • Los parámetros de las funciones se pasan a través de registros.   

Dicho ésto, vamos a empezar con el clásico smashing stack explotando el binario a partir del siguiente código:  

#include <stdio.h>
#include <unistd.h>

int vuln() {
    char buf[80];
    int r;
    r = read(0, buf, 400);
    printf("\nHas pasado %d bytes. buf es %s\n", r, buf);
    puts("No shell!");
    return 0;
}

int main(int argc, char *argv[]) {
    vuln();
    return 0;
}
 Lo compilamos sin las protecciones correspondientes:  
$ gcc -fno-stack-protector -z execstack ejercicio1x64.c -o ejercicio1x64
Le ponemos el SUID para obtener posteriormente una root shell:  
$ sudo chown root ejercicio1x64
$ sudo chmod 4755 ejercicio1x64
Y no olvidemos desactivar temporalmente ASLR para el ejercicio:  
echo 0 > /proc/sys/kernel/randomize_va_space 
Probamos la ejecución normal del programa:  
$ ./ejercicio1x64 
AAAAAAAAAAAAAAAAAAAAAAAAAAAa
 
Has pasado 29 bytes. buf es AAAAAAAAAAAAAAAAAAAAAAAAAAAa

Ya tenemos el binario así que vamos manos a la obra :-P

Sitúan a un hacker español como el mejor valorado de 2020

Alejandro Tapia Vacas (arriba en la foto) es español y posiblemente un desconocido para la prensa, pero ahí dónde lo veis ha estado en los puestos más altos de los CTFs más importantes del mundo: Defcon, NorthSec, VolgaCTF, Nuit du Hack, PHD, RuCTF y un largo etcétera... no ha faltado a las citas más importantes dónde los hackers compiten entre sí midiendo sus destrezas y en todas ellas ha ido sumando un score impresionante de 28 (https://ctftime.org), lo que ha hecho ponerse en cabeza de la clasificación global y ser reconocido internacionalmente por la UHA (United Hackers Association).

Autor de varios artículos, también en este blog, a sus 26 años ya trabaja en una multinacional reconocida como penetration tester a la vez que compagina su trabajo con la participación en competiciones de forma individual o con su grupo P1k0rd3p3l0t4$. Asiduo también en grupos de Telegram como el propio de Hackplayers y HTB hispano (donde le conocimos) ha tenido tiempo incluso de mejorar aún más su ranking en plataformas de bug bounty como HackerOne y Bugcrowd, a través de las cuales ya ha conseguido superar la barrera de los 150€. Sin duda y pese a la pandemia este ha sido su año así que sirva también este post como otro pequeño gran homenaje. ¡Enhorabuena Ale!


Este artículo fue publicado el día 28 de Diciembre de 2020, Día de los Santos Inocentes. Y no... nuestro amigo Jordi triunfa pero en otro tipo de industria...

 

¡Feliz navidad!

import turtle

def main():
    window = turtle.Screen()
    my_turtle = turtle.Turtle()
    screen = my_turtle.getscreen()
    screen.title("¡Feliz navidad!")
    screen.bgcolor("Blue")
    my_turtle.color("green")
    my_turtle.pensize(5)
    my_turtle.begin_fill()
    my_turtle.forward(100)
    my_turtle.left(150)
    my_turtle.forward(90)
    my_turtle.right(150)
    my_turtle.forward(60)
    my_turtle.left(150)
    my_turtle.forward(60)
    my_turtle.right(150)
    my_turtle.forward(40)
    my_turtle.left(150)
    my_turtle.forward(100)
    my_turtle.left(60)
    my_turtle.forward(100)
    my_turtle.left(150)
    my_turtle.forward(40)
    my_turtle.right(150)
    my_turtle.forward(60)
    my_turtle.left(150)
    my_turtle.forward(60)
    my_turtle.right(150)
    my_turtle.forward(90)
    my_turtle.left(150)
    my_turtle.forward(133)
    my_turtle.end_fill()
    my_turtle.color("red")
    my_turtle.pensize(1)
    my_turtle.begin_fill()
    my_turtle.right(90)
    my_turtle.forward(70)
    my_turtle.right(90)
    my_turtle.forward(33)
    my_turtle.right(90)
    my_turtle.forward(70)
    my_turtle.end_fill()
    my_turtle.speed(1)
    my_turtle.penup()
    my_turtle.color('yellow')
    my_turtle.goto(-28, 110)
    my_turtle.begin_fill()
    my_turtle.pendown()
    for i in range(5):
        my_turtle.forward(40)
        my_turtle.right(144)
    my_turtle.end_fill()
    def ball(trt, x, y, size=10, colour="red"):
        trt.penup()
        trt.setpos(x, y)
        trt.color(colour)
        trt.begin_fill()
        trt.pendown()
        trt.circle(size)
        trt.end_fill()
    ball(my_turtle, 95, -5)
    ball(my_turtle, -110, -5)
    ball(my_turtle, 80, 40, size=7, colour="yellow")
    ball(my_turtle, -98, 40, size=7, colour="yellow")
    ball(my_turtle, 70, 70, size=5)
    ball(my_turtle, -93, 70, size=5)
    def create_circle(turtle, x, y, radius, color):
        my_turtle.penup()
        my_turtle.color(color)
        my_turtle.fillcolor(color)
        my_turtle.goto(x, y)
        my_turtle.pendown()
        my_turtle.begin_fill()
        my_turtle.circle(radius)
        my_turtle.end_fill()
    create_circle(my_turtle, 230, 180, 60, "white")
    create_circle(my_turtle, 210, 180, 60, "#E731CE")
    my_turtle.speed(1)
    my_turtle.penup()
    msg = "¡Feliz navidad desde Hackplayers!"
    my_turtle.goto(0, -200)  
    my_turtle.color("white")
    my_turtle.pendown()
    my_turtle.write(msg, move=False, align="center", font=("Arial", 20, "bold"))
    my_turtle.hideturtle()
    window.mainloop()

if __name__ == "__main__":
    main()

 Ho ho ho! 2013 2014 2015 2016 2017 2018 2019 ...

CVE-2020-16875: ejecución remota de código en Microsoft Exchange

En septiembre de 2020 se publicó un parche para CVE-2020-16875 que afecta a Microsoft Exchange 2016 y 2019. La vulnerabilidad permite ejecución remota de código (RCE) a través de los cmdlets proporcionados por el endpoint HTTPS /ecp/DLPPolicy de un servidor Exchange.

La vulnerabilidad y la investigación originales fueron reportadas por Steven Seeley de Source Incite (@steventseeley):

https://srcincite.io/advisories/src-2020-0019/ (Aviso)
https://srcincite.io/pocs/cve-2020-16875.py.txt (PoC)

Para solucionar dicha vulnerabilidad se publicó el siguiente parche que filtraba los cmdlets correspondientes:

https://support.microsoft.com/en-us/help/4577352/security-update-for-exchange-server-2019-and-2016

Pero, como ya ha pasado otra veces, el análisis del parche condujo al bypass del mismo, y buena cuenta de ello dio el equipo de X41 D-Sec, que volvieron a conseguir inyectar cmdlets en un servidor remoto Exchange. Eso sí, recordar que se requiere un usuario válido con permisos para administrar las políticas de DLP.

El código del parche que previene la explotación es el siguiente:

internal static void ValidateCmdletParameters(string cmdlet,
    IEnumerable<KeyValuePair<string, string>> requiredParameters)
{
    if (string.IsNullOrWhiteSpace(cmdlet))
    {
        return;
    }
    Collection<PSParseError> collection2;
    Collection<PSToken> collection = PSParser.Tokenize(cmdlet,
        out collection2);
    if (collection2 != null && collection2.Count > 0)
    {
        throw new DlpPolicyParsingException(
            Strings.DlpPolicyNotSupportedCmdlet(cmdlet));
    }
    if (collection != null)
    {
        // #1 CHECKS IF THERE IS MORE THAN ONE COMMAND, BUT DOES NOT
        // RECOGNIZE .NET FUNCTIONS SUCH AS [Int32]::Parse("12")
        if ((from token in collection
        where token.Type == PSTokenType.Command 
        select token).ToList<PSToken>().Count > 1)
        {
            throw new DlpPolicyParsingException(
                Strings.DlpPolicyMultipleCommandsNotSupported(cmdlet));
        }
    }
    bool flag = false;
    foreach (KeyValuePair<string, string> keyValuePair in requiredParameters)
    {
        // #2 CHECKS IF THE cmdlet STRING(!!) STARTS WITH AN ALLOWED KEY
        if (cmdlet.StartsWith(keyValuePair.Key,
            StringComparison.InvariantCultureIgnoreCase))
        {
            // #3 CHECKS IF THE THE VALUES / PARAMETERS MATCH A CERTAIN
            // REGEX
            if (!Regex.IsMatch(cmdlet, keyValuePair.Value,
                RegexOptions.IgnoreCase))
            {
                throw new DlpPolicyParsingException(
                    Strings.DlpPolicyMissingRequiredParameter(cmdlet,
                        keyValuePair.Value));
            }
            flag = true;
        }
    }
    if (!flag)
    {
        throw new DlpPolicyParsingException(Strings.DlpPolicyNotSupportedCmdlet(
                                                                        cmdlet));
    }
}