MUSICONICA
Páginas: [1]   Ir Abajo
  Imprimir  
Autor Tema: Scylla - Creación de Modulos  (Leído 1160 veces)
0 Usuarios y 1 Visitante están viendo este tema.
flacman
Administrador
Vago degenerado
*
Desconectado Desconectado

Mensajes: 2.897


Trabajar, trabajar y trabajar! . Uribe


Ver Perfil WWW
« en: 01 de Julio de 2009, 09:23:36 »

Buenas, pos pa los chismosos los primeros SS de la posible GUI definitiva xD







Bueno y ahora para todo aquel que quiera colaborar con el proyecto:
Cada módulo se divide en 3 partes básicas, GUI, Documentación y modulo, y cada una de estas tiene una forma de implementarse.

GUI

Las interfaces tienen 3 partes, una parte básica que aplica para todos los módulos que es "host name", user y password. El usuario y password puede ser uno solo (un usuario o un password), una lista (un usuario-password por renglon) o ninguno (campos en blanco, por ejemplo en FTP lo uso cuando el usuario decide solo probar el usuario anónimo). La segunda parte, que es obligatoria implementarla así esté vacia, es un IModuleOption, es decir, una clase que implementa la clase abstracta IModuleOptions definida a continuación:

Código:
    /// <summary>
    /// IMPORTANTE: Es OBLIGATORIO seguir un modelo SINGLETON!
    /// </summary>
    public abstract class IModuleOptions : UserControl
    {
        /// <summary>
        /// This method is called after loading user-defined User & password list
        /// </summary>
        /// <param name="users">Reference to the user list</param>
        /// <param name="passwords">Reference to the password list</param>
        public abstract void onListsLoad(ref List<string> users, ref List<string> passwords);
        /// <summary>
        /// Gets the cipher level defined by SecurityProviderProtocol (i.e, SSLv2, SSLv3, ServerDefined SSLversion (definded in openssl as SSLv23), no cipher, or other (used to defined other module-implemented ciphers, like sftp or ssh)
        /// </summary>
        /// <returns>a cipher type definition</returns>
        public abstract SecurityProviderProtocol getCipher();
        /// <summary>
        /// Gets the number of threads to use, implemented here cus of protocols like smb (only 1 thread used)
        /// </summary>
        /// <returns>Number of threads</returns>
        public abstract int getThreadNumber();
        /// <summary>
        /// Get the port number, implemented here cus most standard protocols have a default port asignation (e.g ssh-22)
        /// </summary>
        /// <returns>The port number</returns>
        public abstract int getPort();
        /// <summary>
        /// Gets other options (i.e, in MySQL, i give the chance to select certificates for making a secure connection
        /// </summary>
        /// <returns>a Polimorfic object (Coder-defined)</returns>
        public abstract object getOtherOptions();
        /// <summary>
        /// IMPORTANTE: Es OBLIGATORIO seguir un modelo SINGLETON!
        /// C# no permite implemetación de metodos static pero se deja comentado
        /// </summary>
        /// <returns></returns>
        //public abstract static IModuleOptions getPanelSingleton();
    }

Es importante Y NECESARIO que sea implementada como un SINGLETON! lastimosamente ni .Net, java, y creo q hasta ni C++ deja definir metodos estaticos abstractos o virtuales. Como pueden ver en la definición, esta clase abstracta ya hereda de UserControl, por lo que no hay que hacer doble herencia en la GUI.

La tercera parte, es el "Reporte", el reporte es un Control como se muestra en la tercera imagen que implementa la Interfaz IReportPanel, que a su vez, igual que IModuleOptions, hereda de UserControl, por lo que no es necesario hacer la herencia por aparte. Cada control es de tamaño 594, 362 o menos (según decida el usuario pero se recomienda usar ese tamaño). Este control se muestra en rojo en la imagen 3.
La forma que contiene estos reportes contiene 2 listas, la lista de módulos y la lista de hosts, cuando se elije un módulo, aparecen los hosts que se han probado con ese módulo, y al mismo tiempo se llama al constructor por defecto del control y se muestra. Cuando el usuario elija un host, se llama al método setData del control, el cual se encarga de llenar los datos del reporte de ese módulo y ese host específico.
Código:
public abstract class IReportPanel : UserControl
    {
/// <summary>
        /// Sets the data into the Report panel depending on the parameters passed to this method
        /// </summary>
        /// <param name="id">Session id (used to identify the actual session)</param>
        /// <param name="module">Module ID (used to identify the actual module)</param>
        /// <param name="host">host (dotted notation) (used to identify the host)</param>
        internal abstract void setData(int id, int module, string host);

    }

Para el manejo de sesiones, se tiene la clase Session (singleton) que se encarga del manejo de la base de datos donde es posible realizar todo tipo de consultas para conseguir información sobre el módulo. La clase Session cuenta actualmente con los siguientes métodos (no está completo; solo nombraremos los relevantes):

Código:
        /// <summary>
        /// Gets an instance of this singleton
        /// </summary>
        /// <returns>an instance of Session</returns>
        public static Session getInstance();
/// <summary>
        /// Gets Messages objects from de specified query. This query must be made to the Message Table. E.g:
        /// "SELECT * FROM Messages WHERE id = " + id + " AND module = " + actualModule + " AND host_ = '" + host + "' AND username = '" + name + "'";
        /// </summary>
        /// <pre> The query MUST be correct. Thie method would ONLY execute it and converte de parameters to a "Message" Object</pre>
        /// <param name="query">the SQL query to execute</param>
        /// <returns>A list of Messages</returns>
        public List<Messages> getMessages(string query);
/// <summary>
        /// gets a list of 2 strings from the specified query. The query SHOULD only select two items of the table and the items must be an string. E.g:
        /// "SELECT username, pass FROM USER_PASS WHERE id = " + id + " AND module = " + module + " AND host_ = '" + host__ + "'";
        /// </summary>
        /// <pre> The query MUST be correct. Thie method would ONLY execute it and converte de parameters to a "Message" Object</pre>
        /// <param name="query">the query to execute</param>
        /// <returns>a list of DoubleString objects</returns>
        public List<DoubleString> get2Strings(string query);
/// <summary>
        /// gets a list of strings from the specified query. The query SHOULD only select one item of the table and the item must be an string. E.g:
        /// "SELECT usename FROM USER_PASS WHERE id = " + id + " AND module = " + p + " AND host_ = '" + p_3 + "'";
        /// </summary>
        /// <pre> The query MUST be correct. Thie method would ONLY execute it and converte de parameters to a "Message" Object</pre>
        /// <param name="query">the query to execute</param>
        /// <returns>a list of strings from the specified query</returns>
        public List<string> getStrings(string query);
/// <summary>
        /// Gets only one string (the first) from the specified query. E.g:
        /// "SELECT pass FROM USER_PASS WHERE id = " + id + " AND module = " + actualModule + " AND host_ = '" + host + "' AND username = '" + listBox1.SelectedItem.ToString() + "'";
        /// </summary>
        /// <pre> The query MUST be correct. Thie method would ONLY execute it and converte de parameters to a "Message" Object</pre>
        /// <param name="query">The query to execute</param>
        /// <returns>The first item of the query (it sould be an string)</returns>
        public string getString(string query);


Si en caso dado, necesita otro método de consulta a la base de datos, porfavor haganoslo saber, en menos de una hora intentaremos tenerlo implementado.
Cabe aclarar 2 cosas, primero hay 2 clases de ayuda que se usan aquí, la primera es DoubleString que es muy sencilla (en realidad es una estructura), tiene 2 objetos de tipo string, s1 y s2 (uso: DoubleString 2string = new DoubleString(); 2string.s1; 2string.s2; 2string.s2 = "hola mundo"Wink. La segunda es una clase muy útil que contiene información sobre los mensajes, está definida de la siguiente forma:

Código:
    public class Messages
    {
        private string user;

        public string User
        {
            get { return user; }
            set { user = value; }
        }
        private string message;

        public string Message
        {
            get { return message; }
            set { message = value; }
        }
        private string host;

        public string Host
        {
            get { return host; }
            set { host = value; }
        }
        private int module;

        public int Module
        {
            get { return module; }
            set { module = value; }
        }
        private int id;

        public int Id
        {
            get { return id; }
            set { id = value; }
        }
        private int type;

        public int Type
        {
            get { return type; }
            set { type = value; }
        }
    }

Por otro lado está la estructura de la base de datos, la forma de crearla se define a continuación (incluida en el paquete del programa):
Código:
-- Lists table, used for identifing the lists used for the brute force attacks, ID refers to the type of list (not documented already) but it could be user, pass, user-list, user list or user/list. Path is the path where the list is.
CREATE TABLE Lists ( ID INT NOT NULL, PATH NVARCHAR(200) NOT NULL, PRIMARY KEY (ID, PATH) );
-- This table contains the messages of each module.
--ID = id of the Session;
--Module = id of the Module who stores the message;
--host_ = the attacked host;
--Type = the type of the message, defined by the module. the only not permitted codes are:
-- NoMessage = -1
--          USER_PASSWORD_FOUND = 0
--          ERROR_MESSAGE = 1
--Here is the OracleModule codes (used for an example)
--public enum OracleMessageType
--        {
--            //Defaults
--            NoMessage = -1,
--            USER_PASSWORD_FOUND = 0,
--            ERROR_MESSAGE = 1,
--            //Oracle
--            //username:created_time
--            USER = 2,
--            //version
--            VERSION = 3,
--            //sids
--            SID = 4,
--            //just role name
--            ROLE = 5,
--            //Profile:pwdPolicy
--            PASSWORD_POLICY = 6,
--            //username:status:profile
--            STATUS = 7,
--            //User:role
--            USER_ROLE = 8,
--            //Tables user can see
--            TABLES = 9,
--            //username:hash
--            HASHES = 10,
--            LINKS = 11,
--            //username:schemaname:osuser:machine:terminal:program:module:logon_time
--            AUDIT_INFO = 12
--        }
--UserName = the user who launches the attack (if it's a pre-hack it could be "");
CREATE TABLE Messages ( ID INT NOT NULL, Module INT NOT NULL, host_ NVARCHAR(300), Type INT, Message NVARCHAR(2048), UserName NVARCHAR(300), PRIMARY KEY (username,ID,Module,Type,Message) );
-- If a module is going to be attacked, it must me added to this table (ID = Session ID)
CREATE TABLE ModuleFound ( ID INT NOT NULL, Module INT NOT NULL, PRIMARY KEY (ID, Module) );
-- Sessions, ID = session ID, Comments = comments for this session, Name = name of the session, ActualModule = indicates which module was the user attacking after he quits
CREATE TABLE Session ( ID INT NOT NULL IDENTITY(1,1), Comments NVARCHAR(1000), Name NVARCHAR(100) NOT NULL, ActualModule INT, PRIMARY KEY (ID) );
-- Info about the thread state before the user quits. ThreadPos indicates the index of the list at which this thread was
CREATE TABLE ThreadInfo ( ID INT NOT NULL, ThreadPos INT NOT NULL, PRIMARY KEY (ID, ThreadPos) );
-- table that identifies the users (username) and passwords (pass) for the session ID, the module Module and the host host_
CREATE TABLE USER_PASS ( ID INT NOT NULL, Module INT NOT NULL, UserName NVARCHAR(70), Pass NVARCHAR(70) NOT NULL, host_ NVARCHAR(300), PRIMARY KEY (ID, Module, UserName, Pass) );
[code]

Cabe destacar que las únicas tablas que se usan en esta última GUI son USER_PASS y Message

[b]Modulo[/b]

Los modulos se definen basados en la Interfáz IOnlineModule

[code]    public interface IOnlineModule
    {
        /// <summary>
        /// Tests a username and password in the defined module
        /// </summary>
        /// <param name="user">Username to test</param>
        /// <param name="pass">Password to test</param>
        /// <param name="misc">unused - for further use if needed</param>
        /// <returns>the attempt was succesful?</returns>
        bool testPassword(String user, String pass, Object misc);
        /// <summary>
        /// Initiates the app, Please do not use, extend from the class OnlineModule
        /// </summary>
        void init();
        /// <summary>
        /// Makes pre-processing functions possibly needed befor making brute force
        /// </summary>
        /// <returns>returns false if module needs to stop</returns>
        bool preProcessing();

    }
Por lo general, en la estructura actual, siempre se hereda la clase OnlineModule (que a su vez extiende Module), Module se encarga del manejo de los threads y OnlineModule se encarga de las comunicaciones, por lo que se recomienda siempre heredar de OnlineModule y no implementar explicitamente el método init. Al hacer esto solo es necesario testiar cada password, sin preocuparse por el manejo de sockets, threads, SSL y errores.

OnlineModule presenta un API sencillo de manejar, y la clase en general maneja como contrato que Toda comunicación con sockets que se realice (es decir, creación y destrucción de sockets, envio y recepcion de mensajes, etc) se manejan con esta clase. Esto es solo para el manejo directo de sockets, por ejemplo en el módulo MySQUAL (jaja en honor al sena xD) llamo al api de MySQL directamente, por lo q no uso directamente sockets

Código:
/// <summary>
        /// gets the IPEndPoint from a Host host in the Port port
        /// </summary>
        /// <pre>if host is not valid, throws an exception</pre>
        /// <post>returns an end point resolving the host address</post>
        /// <param name="host">target host</param>
        /// <param name="port">target port</param>
        /// <returns>an IPEndPoint from a Host host in the Port port</returns>
public IPEndPoint getEndPoint(string host, int port);

///DEPRECATED, USER THE OTHER NOTIFY
/// <summary>
        /// notifies an error or a success
        /// </summary>
        /// <post>If error, manage the error, else prompt the success password</post>
        /// <param name="error">is an error?</param>
        /// uses both bools to manage cases like "maybe is valid"
        /// <param name="find">find a password?</param>
        /// <param name="message">Any message for the user?</param>
        /// <param name="pass">password used</param>
/// DEPRECATED
        public void notify(bool error, bool find, String message, String pass) //DEPRECATED
/// <summary>
        /// notifies an error, a success or a message
        /// </summary>
        /// <post>If error, manage the error, else prompt the password or message and add it to the data base</post>
        /// <param name="message">The message to prompt and to add to the database. If type == ERROR it MUST be password:message or password</param>
        /// <param name="username">the username who prompts the message</param>
        /// <param name="type">Type of the message. As an exaple, Oracle module message types are provided (note that the first 3 are obligatory</param>
        /// public enum OracleMessageType
        ///        {
        ///            //Defaults
        ///            //NO MESSAGE is stored in the DataBase
        ///            NoMessage = -1,
        ///            //Used when a user-password is found, the message MUST be the password
        ///            USER_PASSWORD_FOUND = 0,
        ///            //When an error happend
        ///            ERROR_MESSAGE = 1,
        ///           //Oracle
        ///           //username:created_time
        ///           USER = 2,
        ///           //version
        ///           VERSION = 3,
        ///           //sids
        ///           SID = 4,
        ///           //just role name
        ///           ROLE = 5,
        ///           //Profile:pwdPolicy
        ///           PASSWORD_POLICY = 6,
        ///           //username:status:profile
        ///           STATUS = 7,
        ///           //User:role
        ///           USER_ROLE = 8,
        ///           //Tables user can see
        ///           TABLES = 9,
        ///           //username:hash
        ///           HASHES = 10,
        ///           LINKS = 11,
        ///           //username:schemaname:osuser:machine:terminal:program:module:logon_time     
        ///           AUDIT_INFO = 12
        ///        }
public void notify(String message, string username, int type);
/// <summary>
        /// gets a socket from the socket pool
        /// </summary>
        /// <returns>a socket ready to use</returns>
        public Socket getSocket()

/// <summary>
        /// send data through the socket conn, manages the use of ssl
        /// </summary>
        /// <param name="data">data to send</param>
        /// <param name="conn">socket used to send data</param>
        protected void send(String data, ref Socket conn)

/// <summary>
        /// receives data through the socket conn and stores it in the buffer, manages the use of ssl if needed
        /// </summary>
        /// <param name="buffer">buffer to receive data</param>
        /// <param name="conn">socket from wich data is received</param>
        /// <returns>amount of data readed</returns>
        protected int receive(ref Byte[] buffer, ref Socket conn)

/// <summary>
        /// connects the socket conn, manages SSL if needed
        /// </summary>
        /// <param name="conn">socket to connect</param>
        protected void connectSocket(ref Socket conn)
         
        /// <summary>
        /// disconects a socket, also a ssl session if initiated
        /// </summary>
        /// <param name="socket"></param>
        protected void disconnectSocket(Socket socket);

Por otro lado, está el método bool preProcessing() que se encarga de hacer pre-procesamientos (o pre-hacks) antes de iniciar el ataque de fuerza bruta, estos pre-procesamientos dependen de cada módulo, como ejemplo se expone el módulo de Oracle. OracleModule realiza 3 hacks principales (no son todos) antes de iniciar el ataque de fuerza bruta (si el usuario decide), primero busca la versión del sistema usando las funciones de control del TNSListener (comando version), igualmente con los SIDs, usando el comando STATUS. Por otro lado realiza fuerza bruta sobre una lista de SIDs hasta encontrar uno, si el usuario no indica uno explicitamente se usa uno de los encontrados osino, por defecto usa ORCL. El tercer pre-hack es la realización de fuerza bruta sobre los usuarios por defecto de Oracle.

Documentación

Se espera la documentación de cada módulo MUY explicita sobre su funcionamiento, es maso filosofía MS, si no libero el código, por lo menos q la vaina esté bien documentada.

La documentación es un archivo XML definido de la siguiente forma
Código:
<Module>
<Name>Modulo FTP</Name>
<Protocols> FTP, FTPSv2, FTPSv3, SFTP</Protocols>
<Description>Modulo de fuerza bruta sobre el protocolo FTP y sus definiciones cifradas</Descripcion>
<Ports>21, 22, 990</Ports>
<Default>Connects over FTP through port 21 to the host especified using the list of users and passwords defined by user<Default>
<GUIUsage>
   <Cryptography>Uses SSLv2 or v3 ofer the FTP connection, or the protocol defined by SFTP</Cryptography>
   <Threads>Determine the number of threads to use in the Brute force atack</Threads>
   <TrySamePassAsUsername>Adds to the password list the list of usernames<TrySamePassAsUsername>
   <Port>Determines to which port make the connection</Port>
   <TryAnonymous>Adds the user Anonymous and password CutRulz to the user & password list respectively</TryAnonymous>
   <Other> If no user list or password list is defined, but anonymous user box is checked, just check for the existanse of an anonymous user</Other>
</GUIUsage>
<Hacks>
Try anonymous user
</Hacks>
</Module>

De este XML de ejemplo es obligatorio llenar los campos:
<Name> -> Nombre del modulo
<Protocols> -> Protocolos que implementa el modulo
<Description> -> descripcion del modulo
<Ports> -> puertos por defecto que usa
<Default> -> funcionamiento por defecto
<GUIUsage> -> descripcion DETALLADA de las opciones del modulo (cada opcion es un nuevo <NombreOpcion> </NombreOpcion>, por convencion siempre empieza por mayuscula y el nombre de cada opcion está definido por NombreOpcion, los espacion en el nombre se pueden definir con mayusculas, NombreOpcion o _, Nombre_opcion). Con detallada me refiero a por ejemplo, en el modulo ftp la opcion de usuario y pass anonimo NO prueba ese user y pass solamente, sino q añade a la lista de usuarios y passwords ese user y pass.
<Hacks> -> Hacks que realiza el módulo (funca igual q GUIUsage), por ejemplo revisar usuario anónimo; el modulo MySQL tiene los siguientes hacks:
Código:
<Hacks>
<TooManyConnections_TooManyUserConnections>If something cause this error, sleep 2 secs to wait for users to disconect and retry</TooManyConnections_TooManyUserConnections>
<CantGetHostname>If cant resolve hostname, sleep for 2 secs and retry, as hostname was previously resolved, it may be a network problem</CantGetHostname>
<PasswordHashShouldBeN-digitLong>if received message of "password to long must be hex", just try the passwords that meet: passLen LESSOREQUALTHAN #password AND !password.haveDigits </PasswordHashShouldBeN-digitLong>
<UserNameLenght>Just try usernames with less than 16 chars long</UserNameLenght>
<ShowDatabases>For each user, if option set, try to fetch for databases names<ShowDatabases>
</Hacks>

Espero todo haya quedado claro, cualqueir cosa me avisan.[/code][/code]
« Última modificación: 18 de Agosto de 2009, 05:58:15 por flacman » En línea

Posted by
flacman
Administrador
Vago degenerado
*
Desconectado Desconectado

Mensajes: 2.897


Trabajar, trabajar y trabajar! . Uribe


Ver Perfil WWW
« Respuesta #1 en: 03 de Julio de 2009, 04:36:53 »

Update: Anadido campo Hacks a la documentación
En línea

Posted by
flacman
Administrador
Vago degenerado
*
Desconectado Desconectado

Mensajes: 2.897


Trabajar, trabajar y trabajar! . Uribe


Ver Perfil WWW
« Respuesta #2 en: 17 de Agosto de 2009, 05:47:51 »

Update: Nueva arquitectura
En línea

Posted by
flacman
Administrador
Vago degenerado
*
Desconectado Desconectado

Mensajes: 2.897


Trabajar, trabajar y trabajar! . Uribe


Ver Perfil WWW
« Respuesta #3 en: 18 de Agosto de 2009, 05:58:36 »

Updatiado un poco mas Tongue
En línea

Posted by
Páginas: [1]   Ir Arriba
  Imprimir  
 
Ir a:  

Modify by RPM.
Página creada en 0.072 segundos con 20 queries.