Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.

Temas - DtxdF

Páginas: [1] 2 3 4
1
Seguridad / Configuración de un proxy en LAN/WLAN
« en: Marzo 02, 2021, 11:44:23 pm »
Un proxy es, en el más sentido estricto de la palabra, un intermediario, si suponemos que es un programa o dispositivo que actúa de intermediario (en una red de ordenadores) entre un servidor, siendo éste el objetivo de la otra parte, en este caso, el cliente.

Suponiendo el caso que tengamos tres máquinas, vamos a acuñar el nombre de máquina A al cliente, B para el Proxy y C para el servidor. El cliente (A) desea conectarse al servidor (C) como normalmente se haría, pero antes de que la petición pueda llegar a su destinatario, ésta pasa hacia el Proxy (B) y de este último al servidor.



Esquema de un proxy

Sus usos son relativos a cada cliente, pero entre los más caprichosos podríamos mencionar necesidades de lo más variopintas:

  • Cortafuegos: Se podría decir de cierta forma, que este uso es muy habitual si se desea bloquear tráfico indeseado o prevenir ataques perpetuados por el malware. Además que de esta medida también se podría usar como filtro para sitios publicitarios.
  • Filtración del contenido: En una empresa regularmente se dispone de este tipo de uso para bloquear el tráfico saliente generado por los empleados. Esto puede ser muy útil para prevenir cualquier tipo de distracción o, inclusive, se podría decir que podría mejorar la seguridad.
  • Aceleración y ahorro de ancho de banda: Ya sea que estemos usando un navegador o cualquier otro software que tenga la posibilidad de conectarse a otra máquina (a través de Internet o Intranet, por ejemplo), es muy útil guardar datos como imágenes, vídeos, y misceláneas, como lo pueden ser los archivos usados mayormente en los sitios web: HTML, CSS, JS, etc.; esta característica para ahorrar y acelerar la trae con sí cualquier navegador decente, pero muy útil igualmente cuando no, o es otro software de diferente índole.
  • Control de acceso: En la administración de ordenadores en una empresa, instituciones y sitios gubernamentales, es muy útil ser permisivos con determinados usuarios o restringir el uso de cada quien, para regular la información que se comparte entre sí. No obstante, la regulación de la información no es el único fin, se podría decir que para usar que sean provistos ciertos servicios es necesario el uso de un proxy.
  • Anonimato y privacidad: En algunos países donde la información que se comparte puede ser restringida de forma arbitraria, ya sea por un gobierno o un ISP, los proxies son muy útiles para evadir la censura.

Dante & Stunnel:

SOCKS es un protocolo de Internet para el intercambio de paquetes a través de un servidor proxy. La naturaleza del protocolo brinda versatilidad para crear todo tipo de herramientas de enrutamiento, y también es muy útil para otros objetivos, como ser una precisa herramienta para la elusión, que permite evadir el filtrado de Internet para acceder a contenidos bloqueados por gobiernos, lugares de trabajo, escuelas y dependiendo del caso, acceder a servicios específicos de una nación.

Dante es eso, un servidor proxy que usa SOCKS como protocolo. Este software es muy simple, pero totalmente funcional, y si se combina con Stunnel aumentaría el poderío de cualquier individuo que busque un buen equilibrio entre privacidad y seguridad.


Instalación de Dante:

Usando nuestro gestor de paquetes apt, y aclarando que el sistema se debe encontrar actualizado, vamos a instalar el paquete dante-server.

Código: (bash) [Seleccionar]
sudo apt-get install dante-server

Instalación de dante-server

Una vez finalizado, debemos configurarlo.

Configuración de Dante


Editando el archivo de configuración de danted

Primero que nada, vamos a editar el archivo de configuración de danted, pero para simplificar aún más este artículo, vamos a agregar el siguiente extracto de configuración muy elemental:

Código: (text) [Seleccionar]
logoutput: /var/log/socks.log
internal: 127.0.0.1 port = 1080
external: eth0
clientmethod: none
socksmethod: none
user.privileged: root
user.notprivileged: nobody

# Permitir conexiones localhost (stunnel)
client pass {
        from: 127.0.0.1/32 to: 127.0.0.1/32
}

# Bloquear y registrar el resto de intentos de conexión
client block {
        from: 0.0.0.0/0 to: 0.0.0.0/0
        log: connect error
}

# Bloquear el acceso de los clientes a los servicios localhost
socks block {
        from: 0.0.0.0/0 to: lo
        log: connect error
}

# Permitir a los clientes acceso al exterior - tcp 80 utilizando el método "connect"
socks pass {
        from: 127.0.0.1/32 to: 0.0.0.0/0 port = 80
        command: connect
        protocol: tcp
}

# Permitir a los clientes acceso al exterior - tcp 443 utilizando el método "connect"
socks pass {
        from: 127.0.0.1/32 to: 0.0.0.0/0 port = 443
        command: connect
        protocol: tcp
}

# Bloquear y registrar todos los demás intentos de clientes
socks block {
        from: 0.0.0.0/0 to: 0.0.0.0/0
        log: connect error
}

logoutput

Este valor controla la salida del servidor de los registros.

internal

Toda dirección y sólo en esta dirección, que provenga de ésta o una interfaz, será aceptada.

external

Esta será la dirección o la interfaz de salida, y es importante que, si es que lo deseamos, nos brinde la conexión a Internet.

clientmethod

Exigir que la conexión se "autentique" utilizando uno de los métodos apropiados.

socksmethod

Si el cliente ofrece más de un método de autenticación, Dante seleccionará el método a utilizar en función del orden en que los métodos son listados aquí.

user.privileged

Nombre de usuario para realizar ciertas operaciones con privilegios.

user.notprivileged

Usuario que el servidor ejecuta la mayor parte del tiempo. Éste debe tener un ID con tan pocos privilegios como sea posible.


Si es necesario realizar operaciones mucho más complejas de las que se muestran acá se pueden apreciar mejor en la propia documentación de Dante.


Uso de dante:

Ya concluida su configuración, es necesario activar el servicio, que si resulta satisfactoria su ejecución, podremos conectarnos a él por el puerto 1080, que, si no se es sabido, es el puerto estándar de los servidores proxy SOCKS.

Código: (bash) [Seleccionar]
sudo service danted start

Iniciando el servicio danted

Una el servicio se inicia, es hora de probarlo, y para ello, podemos usar la herramienta CURL, que si bien, en la mayoría de distribuciones se tiene preinstalada, puede que esta o la del lector no, así que con el siguiente comando es posible instalarlo:

Código: (bash) [Seleccionar]
sudo apt-get install curl

Instalación del paquete CURL

En mi distribución está la versión más reciente de CURL.

Una vez que se ha instalado, es posible ver nuestra dirección IP pública, aunque aclarando que sin importar (para este caso) si se usa o no un proxy, se obtendrá la misma, pero el objetivo de esto es verificar si podemos conectar con el proxy que hemos configurado.


Código: (bash) [Seleccionar]
curl -x "socks5h://127.0.0.1:1080" https://ifconfig.me && echo

Probando la conectividad del proxy

Nota: No hace falta aclarar el porqué de ocultar la dirección IP pública.

Si bien, y como se aclaró, usando o no el proxy se obtendrá el mismo resultado, pero suponiendo el caso de que el servicio no se haya iniciado por cualquier situación, podríamos comprobarlo de la siguiente manera.


Código: (bash) [Seleccionar]
sudo service danted stop
curl -x "socks5h://127.0.0.1:1080" https://ifconfig.me && echo


Fallo de la conexión

Como se puede apreciar, no indica que ifconfig.me ha fallado, más bien indica que el proxy lo ha hecho, por lo que para cerciorarnos es de esta manera.


No todo es color de rosas, y es que con un sniffer decente es todavía posible observar el contenido que se comparte entre el cliente y el servidor SOCKS, como se puede apreciar en la siguiente figura usando Wireshark.



Usando Wireshark para ver el contenido que se comparte un cliente y un servidor

Esto es sumamente peligroso si se desea compartir datos confidenciales, pero afortunadamente hay soluciones.

Instalación de Stunnel:

Stunnel se utiliza mayormente para proveer conexiones seguras a clientes que no propician TLS o SSL de forma nativa. Es posible ejecutarlo en una variedad de sistemas, usa criptografía clave pública y entre otras características igual de excelentes que las antes mencionadas.

Al inicio de su ejecución puede presentar un puerto externo seguro que es mapeado a un puerto TCP o UDP no seguro perteneciente a la aplicación objetivo.

Suponiendo el primer caso más trivial donde se desee implementar una conexión SSL segura a una conexión hacia un servidor inseguro, siendo éste un servidor SMTP, Stunnel mapeará el puerto 443 al puerto 25 del servidor de correo. Inicialmente el tráfico generado por los clientes que se conecten a través del proxy deberá pasar a través del puerto 443 y a su vez Stunnel lo redireccionará al 25. Stunnel puede ser ejecutado en el mismo servidor donde se mantenga en ejecución a la aplicación de correo, que aunque esta última no disponga de protección concienzuda, los dos programas serán ejecutados en un firewall interno seguro, además que todo este proceso será transparente.

Para poder instalar Stunnel, con un simple comando es posible:


Código: (bash) [Seleccionar]
sudo apt-get install stunnel4

Instalación del paquete stunnel4

Configuración de Stunnel:

Antes de iniciar la configuración, debemos agregar la marca de orden de bytes, algo requerido por el mismo dante, y para aclarar un poco más, se especificará que la codificación unicode en este caso será en UTF-8, como lo indica la siguiente figura.


Marca de orden de bytes

Para ello, es necesario primero cambiar de el usuario actual al usuario root.

Código: (bash) [Seleccionar]
sudo su
echo -e '\xef\xbb\xbf; BOM composed of non printable characters. It is here, before the semicolon!' > /etc/stunnel/stunnel.conf
exit # Salimos


Iniciando la configuración de stunnel

Es indispensable escribir en la línea 2 del archivo de configuración, y si el lector es olvidadizo, ese es el objetivo del comentario «BOM composed of non printable characters. It is here, before the semicolon!».

Simplificando, aquí una configuración para el correcto y básico funcionamiento de Stunnel:


Código: (text) [Seleccionar]
setuid = stunnel4
setgid = stunnel4

[trivial server]
accept      = 1081
connect     = 127.0.0.1:1080
ciphers     = PSK
debug       = 3
PSKsecrets  = /etc/stunnel/psk.txt
setuid      = stunnel4
setgid      = stunnel4


Configuración de stunnel

setuid

Como opción global: setgid() al grupo especificado en modo daemon y borrar todos los demás grupos.

Como opción de nivel de servicio: establezca el grupo del socket Unix especificado con "accept". setuid = USER (solo Unix)

setgid

Como opción global: setuid() al usuario especificado en modo daemon.

Como opción de nivel de servicio: establezca el propietario del socket Unix especificado con "accept".

accept

Aceptar conexiones en la dirección especificada.

Si no se especifica ningún host, el valor predeterminado es todas las direcciones IPV4 para el host local.

Para escuchar en todas las direcciones IPV6 se debe utilizar:


Código: (text) [Seleccionar]
accept = :::PORT
connect

conectarse a una dirección remota

Si no se especifica ningún host, el valor predeterminado del host es localhost.

Se permiten varias opciones de conexión en una sola sección de servicio.

Si el host se resuelve en varias direcciones y/o si se especifican varias opciones de conexión, la dirección remota se elige mediante un algoritmo round robin.

ciphers

seleccionar cifrados TLS permitidos (TLSv1.2 y inferiores)

Esta opción no afecta a los cifrados TLSv1.3.

Una lista delimitada por dos puntos de los cifrados para permitir en la conexión TLS, por ejemplo DES-CBC3-SHA:IDEA-CBC-MD5.

debug

El nivel es uno de los nombres o números de nivel syslog o números, emerg(0), alert(1), crit(2), err(3), warning(4), notice(5), info(6) o debug(7). Se mostrarán todos los registros para el nivel especificado y todos los niveles numéricamente inferiores a los que se mostrarán. Utilice debug = debug o debug = 7 para la mayor salida de depuración. El valor predeterminado es notice(5).

PSKsecrets

archivo con identidades PSK y claves correspondientes

Cada línea del archivo en el siguiente formato:


Código: (text) [Seleccionar]
IDENTITY:KEY
Las claves hexadecimales se convierten automáticamente en forma binaria. Las claves deben tener al menos 16 bytes de longitud, lo que implica al menos 32 caracteres para claves hexadecimales. El archivo no debe ser legible en para todo el mundo ni grabable para cualquiera.


Todo lo mostrado en esta sección es lo elemental, pero si se requiere ir más allá y extrapolar conceptos, no hay mejor que leer la propia documentación.


Uso de Stunnel:

Es necesario primero, generar la clave precompartida, cosa posible con openssl, que podría o no estar instalado, de cualquier modo, es sencillamente instalable con el siguiente comando:

Código: (bash) [Seleccionar]
sudo apt-get install openssl
Acto seguido, vamos a generar la susodicha clave:

Código: (bash) [Seleccionar]
sudo su
openssl rand -base64 -out /etc/stunnel/psk.txt 180
sed --in-place '1s/^/psk:/' /etc/stunnel/psk.txt
cat /etc/stunnel/psk.txt | tr -d "\n" > /etc/stunnel/psk.1.txt
mv /etc/stunnel/psk.1.txt /etc/stunnel/psk.txt
chmod 600 /etc/stunnel/psk.txt
exit

La explicación es sumamente sencilla: primero generamos 180 bytes de números pseudo aleatorios codificados a base64, acto seguido, le agregamos como prefijo psk a la cadena anteriormente generada, siendo en realidad un valor arbitrario, luego se eliminan todos los caracteres de nueva línea, pero el archivo resultante será nombrado como psk.1.txt para que no quede vacío por un conflicto entre dos flujos, aunque después éste remplaza al original, se le asignan los permisos correctos (en este caso, 600) y salimos.

A partir de este momento, es necesario, primero, compartir la clave precompartida a los clientes, e iniciar el servicio stunnel4.

Para seguir con el ejemplo, se usará Arch Linux como cliente. Aunque como no se desea que terceros puedan ver la clave, es mejor usar herramientas parecidas a scp, o el mismísimo en este caso:


Código: (bash) [Seleccionar]
sudo scp /etc/stunnel/psk.txt [email protected]:/tmp

Transfiriendo la clave de forma segura

Código: (bash) [Seleccionar]
sudo mv /tmp/psk.txt /etc/stunnel
Luego el cliente debe agregar el archivo de configuración de stunnel para poder realizar la conexión con el servidor, y los diversos servicios.

Código: (text) [Seleccionar]
; BOM composed of non printable characters. It is here, before the semicolon!

setuid = stunnel
setgid = stunnel

[trivial client]
client     = yes
accept     = 127.0.0.1:1080
connect    = 192.168.1.106:1081
debug      = 3
PSKsecrets = /etc/stunnel/psk.txt
setuid     = stunnel
setgid     = stunnel

Cabe aclarar que, al igual que el servidor, se debe agregar al inicio del archivo el BOM.

Por supuesto, que la configuración cambia entre sistemas, pero para este caso será de la manera plasmada anteriormente. Una vez que se han escrito los cambios del archivo de configuración, se debe iniciar el servicio, que en Arch es llamado sockd:


Código: (bash) [Seleccionar]
sudo systemctl start stunnel

Iniciando stunnel en la máquina cliente

No podemos ultimar esta sección sin antes haber probado y verificado que el resultado es digno de agradecimiento.

Código: (bash) [Seleccionar]
curl -x "socks5h://127.0.0.1:1080" http://ifconfig.me && echo

Wireshark analizando tráfico encriptado

No importa qué paquete veamos, todo está encriptado, por lo que nuestra configuración ha sido satisfactoriamente ejecutada.

Autenticación segura con Stunnel y Dante:

Un efecto posiblemente indeseado sea el de no querer que todo el mundo use del proxy, por lo que agregando una medida extra podría evitar éso. Efectivamente se haría con un simple cambio en la configuración y reiniciando el servicio.

Código: (bash) [Seleccionar]
socksmethod: username
¡Listo! Ya se podría usar la autenticación, que, si no se sabe ni cómo generar usuarios, pues vienen siendo los mismos del sistema. Y que lo diga mejor el código:

Código: (bash) [Seleccionar]
sudo adduser proxy_user
sudo passwd proxy_user


Agregando al usuario proxy_user

El cliente ahora, si desea ingresar, debe iniciar sesión desde su programa-cliente, en este caso CURL.

Código: (bash) [Seleccionar]
curl -x "socks5h://proxy_user:[email protected]:1080" http://ifconfig.me && echo
Aumentando la privacidad, seguridad y evadiendo restricciones: Tor:

La red Tor, esa fascinante red que nos provee una capa extra de seguridad en nuestras comunicaciones. Una red capaz de evadir la censura más torturadora para una persona que reside en un país donde la libertad de expresión es nula o inimaginable. Tor (siglas de The Onion Router), es un proyecto cuyo principal objetivo es desarrollar una red distribuida de baja latencia, superpuesto sobre Internet donde el encaminamiento de mensajes no revela la identidad del usuario.


La red tor

Tor implementa una técnica llamada encaminamiento cebolla, o del inglés, onion routing, técnica usada conseguir que las redes preserven su privacidad de forma transparente con los individuos de la red, por ende, es viable realizarlo de forma pública.

Por lo general, cuando un cliente desea conectarse a un servidor de la manera tradicional, la petición pasa a través del router, a su vez ésta a los enrutadores del ISP, y por último, al servidor objetivo.

Por supuesto, que es posible que un tercero puede leer lo que transferimos, y aunque lo cifraramos desde el origen, podrían residir datos que nos puedan identificar.

La solución ante tal hecho, es usar la susodicha técnica. En vez de que el paquete pase por una vía directa, es mejor que viaje por una no directa y más o menos aleatoria a través de los nodos de la red.



La red tor

Usando un directorio donde residan las claves de los nodos, la petición A cifrará el contenido para C, y luego se lo enviará a B, luego ésta cifrará ese contenido al penúltimo nodo, y finalmente, cuando se finalice toda esta transacción, se le enviará la respuesta descifrada al destinatario.

La red en diseño tiene sus pros y contras, y entre uno de sus contras está, que el último nodo es capaz de ver el contenido tal cual como lo envió A, solo sí no se cifró desde el origen.


Instalación de tor:

Para hacer uso de Tor, es necesario el paquete, por suerte en la mayoría de distribuciones de diferente índole, el nombre es invariable.

Código: (bash) [Seleccionar]
sudo apt-get install tor
Uso:

Tanto su uso puede ser perfectamente ejecutado como un daemon o iniciándolo como un aplicativo más, pero para ser más organizados, vamos a hacerlo de la manera tradicional.

Código: (bash) [Seleccionar]
sudo service tor start
El uso de Tor es aun más sencillo que los anteriores aplicativos, ya que como está por defecto, su uso, es perfecto.

Código: (bash) [Seleccionar]
curl -x "socks5h://127.0.0.1:9050" http://ip-api.com/json | jq

Viajando a través de la red

Como se puede apreciar nos encontramos en los Países Bajos en un santiamén.

Configuración automática en LAN/WLAN:

Cualquiera que esté en sus cabales, puede notar lo excesivo que puede ser esto para un usuario promedio en un ambiente doméstico: instalar la aplicación correspondiente, procurar que no se quejará por algún error o un sinfín de vicisitudes que se puedan presentar en determinado contexto, y luego, si se tiene éxito, conectar a la aplicación. ¿Y si se pudiera adelantar todos esos pasos de forma transparente al usuario? Afortunadamente sí es posible, y el usuario lo único que tiene que hacer es conectarse, ya sea por medio de Ethernet o WIFI, a nuestro pequeño punto de acceso (o usando el cable de ethernet, si es por esta vía).

En aras a la simplicidad, vamos a usar por el resto de las subsecciones, scripts que nos ayuden a configurar de forma amena toda la infraestructura. Claro está que es necesario instalar un par de paquetes que se irán nombrando a lo largo del artículo.


Instalación de redsocks:

Según, desde el repositorio oficial de redsocks, es:

Citar
Una herramienta que permite redirigir cualquier conexión TCP a SOCKS o proxy HTTPS utilizando su firewall, por lo que la redirección puede ser en todo el sistema o en toda la red.

Esta herramienta, con un par de configuraciones, es posible que cumpla con éxito el objetivo de esta sección, pero antes, es necesario instalarla:

Código: (bash) [Seleccionar]
sudo apt-get install redsocks
Ya instalado, es ahora indispensable ejecutar ciertos scripts que hacen uso de iptables para configurarlo junto con redsocks.

Uso de redsocks:

Antes que nada, he aquí los archivos:


Archivos necesarios para configurar redsocks

init.sh:
Código: (bash) [Seleccionar]
# Crear una nueva cadena
sudo iptables -t nat -N REDSOCKS
# Ignorar LANS y otras dirección reservadas (https://es.wikipedia.org/wiki/Anexo:Direcciones_IP_reservadas).
sudo iptables -t nat -A REDSOCKS -d 0.0.0.0/8 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 10.0.0.0/8 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 127.0.0.0/8 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 169.254.0.0/16 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 172.16.0.0/12 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 192.168.0.0/16 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 224.0.0.0/4 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 240.0.0.0/4 -j RETURN
# Cualquier otra cosa debería ser redirigida al puerto 12345
sudo iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-ports 12345

redsocks.conf:
Código: (text) [Seleccionar]
base {
        log_debug = on;
        log_info = on;
        log = "file:/tmp/redsocks.log";
        daemon = on;
        redirector = iptables;
}

redsocks {
       /*
        * Por defecto es 127.0.0.1 por razones de seguridad,
        * pero si deseamos escuchar en todas las interfaces,
        * usamos la dirección no especificada, 0.0.0.0. El
        * puerto es arbitrario igualmente.
        */
        local_ip = 0.0.0.0;
        local_port = 12345;

        // Dirección IP y puerto del servidor proxy
        ip = <Dirección IP>;
        port = <Puerto>;

        // Los tipos conocidos son: socks4, socks5, http-connect, http-relay
        type = <Tipo>;
}

restore.sh:
Código: (bash) [Seleccionar]

sudo iptables -F
sudo iptables -X
sudo iptables -Z
sudo iptables -t nat -F
sudo iptables -t nat -X
sudo iptables -t nat -Z
killall redsocks

El primer archivo (init.sh) como su mismo nombre lo indica, serán las reglas para iptables, así redsocks funcionará correctamente; el segundo (redsocks.conf) es la configuración de redsocks, que se hablará en breve; y, el tercero y último, pero no menos importante, es la contraparte de init.sh, ya que es el encargado de restaurar las cadenas y reglas de iptables y terminar (si está en ejecución) el proceso redsocks.


Pasemos directo a la acción ejecutando el primer archivo, no sin antes permitir la redirección de paquetes, y, especificar nuestra interfaz de salida:


Código: (bash) [Seleccionar]
sudo sysctl net.ipv4.ip_forward=1
sudo iptables --table nat --append POSTROUTING --out-interface ppp0 --jump MASQUERADE

Para mi caso, la interfaz del sistema de salida es ppp0. Ahora sí, se deberá ejecutar el script anteriormente mencionado.

Código: (bash) [Seleccionar]
sudo sh init.sh
A su vez, aunque es opcional y se le deja en libertad al lector, vamos a crear una función para agregar reglas que serán redirigidas a la cadena REDSOCKS, anteriormente creada con el script init.sh.

Código: (bash) [Seleccionar]
function add_redsocks_rule() {
    local is_extern=$1
    local port=$2
    local chain

    if [ "$#" -lt 2 ];then
        echo "Sintaxis: add_redsocks_rule <0|1> <PUERTO>"
        return 1
    fi

    if [ "$is_extern" -eq 1 ];then
        chain="PREROUTING"
    elif [ "$is_extern" -eq 0 ];then
        chain="OUTPUT"
    else
        echo "No se puede saber si la regla es externa o no."
        return 1
    fi

    sudo iptables -t nat -A "$chain" -p tcp --dport "$port" -j REDSOCKS
}

Y, para el gozo de los perezosos u olvidadizos, vamos a agregar dos alias.

Código: (bash) [Seleccionar]
alias add_redsocks_rule_internal="add_redsocks_rule 0"
alias add_redsocks_rule_external="add_redsocks_rule 1"

Una vez se ha realizado con diligencia el prologo de nuestra operación, es momento de configurar redsocks.conf, siendo elemental configurar sólo la dirección de nuestro servidor proxy, que, si bien, no es recomendable hacer la práctica que se citará a continuación, se eligió uno al azar por la web, siendo su localización: Brasil.


Configurando la dirección del proxy

Es momento de ejecutar redsocks.

Código: (bash) [Seleccionar]
sudo redsocks -c redsocks.conf
Y, se deberá probar si funcionó, ya sea comparando nuestra dirección IP pública original con la del servidor proxy, o viendo la localización del ISP, pero antes de continuar, es importante que usemos la función que se creó hace unos momentos para poder agregar los puertos a los que se deberá redirigir.

Código: (bash) [Seleccionar]
add_redsocks_rule_internal 80
add_redsocks_rule_internal 443

Esto lo que hará será aplicar la cadena REDSOCKS a los puertos TCP especificados. Y como paso final, se prueba su eficacia:

Código: (bash) [Seleccionar]
curl http://ip-api.com/json | jq

Proxy en Brasil

Como es posible apreciar por las ilustraciones, no es necesario especificar, con el parámetro de CURL -x, la dirección, ni el puerto, ni el tipo del proxy, sino que será sigilosamente ejecutado.

LAN:

Ya es sabido lo sencillo que es configurar un proxy tanto si se desea usar con configuraciones implícitas o explícitas, pero no se puede obviar el hecho de que algunos usuarios se vean en la necesidad de disponer de un proxy sin tener que configurarlo, como puede ser en LAN.

Para que eso sea posible, es necesario propiciar de un servidor DHCP, cosa que nos la puede facilitar mucho dnsmasq.


Instalación de dnsmasq:

dnsmasq proporciona tanto un servidor DNS, un servidor DHCP, y entre otras cosas muy interesantes. Es adecuado para maquinarias de escasos recursos, ya que es liviano y tiende a consumir muy poco. Además, una característica muy relevante en este software es, que puede almacenar las consultas en caché, lo que aumentaría la búsqueda de los sitios almacenados con anterioridad.

Su instalación, al igual que los demás paquetes no pasa de un comando:


Código: (bash) [Seleccionar]
sudo apt-get install dnsmasq
Configuración de dnsmasq:

Su configuración es simple, pero se ha comentado diligentemente cada detalle debido a la largura de las descripciones.

Código: (text) [Seleccionar]
# Los navegadores antiguos tenían una barra que era específica para las búsquedas en los
# buscadores, pero el usuario por ignorancia usaba la que era para los dominios, lo que
# provocaba que se perdiera tiempo resolviendo dominios inexistentes, lo que acarreaba
# en una respuesta DNS "NXDOMAIN". Con esta instrucción se evita eso (aunque los navega-
# dores actuales ya solucionarón ese inconveniente), pero esto hace referencia a los
# antiguos.
domain-needed

# Evitar que se haga una consulta DNS inversa a una dirección local o en el espacio de
# direcciones.
bogus-priv

# No usar el fichero 'resolv.conf'
no-resolv

# Definimos los servidores DNS, que, a conveniencia se usan los de OpenDNS.
server=208.67.222.222
server=208.67.220.220

# Configuramos el servidor DHCP para asignar el rango de direcciones en 24h(oras) en las
# interfaces wlan0 (la tarjeta de red inalámbrica) y eth0 (la de ethernet).
# wlan0 tendrá el siguiente rango: 192.168.0.2 a 192.168.0.254, mientras que el punto de
# acceso (nosotros) tendrá la dirección 192.168.0.1
# eth0 tendrá el siguiente rango: 10.42.0.2 a 10.42.0.254, mientras que la máquina local
# tendrá la siguiente dirección 10.42.0.1
#
# Nota #1: Tienen que usar sus propias interfaces.
# Nota #2: Recuerden que su tarjeta de red inalámbrica debe admitir el modo AP para que
# sea posible crear un punto de acceso.
dhcp-range=eth0,192.168.0.2,192.168.0.254,24h
dhcp-range=wlan0,10.42.0.2,10.42.0.254,24h

# Registramos las consultas y demás (opcional, pero altamente recomendable para la depuración)
log-queries
log-dhcp
log-facility=/var/log/dnsmasq.log

La ubicación donde se debe escribir es en /etc/dnsmasq.conf. A continuación se reinicia dnsmasq.

Código: (bash) [Seleccionar]
sudo service dnsmasq restart
Asimismo como hicimos para agregar reglas internas, ahora debemos agregar reglas externas.

Código: (bash) [Seleccionar]
add_redsocks_rule_external 80
add_redsocks_rule_external 443

Y, por motivos de prueba, usamos la máquina cliente para ver si hemos tenido o no éxito, que, se debe hacer de forma parecida al examen que hicimos localmente.

Código: (bash) [Seleccionar]
curl http://ip-api.com/json | jq

Probando el proxy sin necesidad de configurarlo en el cliente

WLAN:

Se aumenta paulatinamente la complejidad, pero estas palabras no son ni de lejos ciertas. Ya habiendo configurado exitosamente el proxy, tanto de forma local como en LAN, ahora pasamos al siguiente nivel, que sería la conectividad inalámbrica, algo que a día de hoy, es muy bien recibido.

Para ello, vamos a crear un punto de acceso, pero para el cliente será como conectarse a cualquier router doméstico, además, si le sumamos que navegará por un proxy sin necesidad de instalar ni configurar nada, es en serio, muy útil.


Instalación de hostapd:

hostapd es un software gratuito y de código abierto, que está diseñado para facilitar la creación de puntos de acceso. En caso de verse en la necesidad de no contar con un router, pero sí con una tarjeta de red inalámbrica compatible con el modo AP, esta herramienta es muy útil, y muy configurable, además tiene diferentes características que, de solo mencionarlas, sería quedarse corto. Entre sus características son:

  • Soporte WPA/WPA2, WEP, entre otros.
  • Es posible crear redes ocultas.
  • Estadísticas muy detalladas de los datos.
  • Entre otras tantas.

Primero para explotar todas las características, hay que tener instalado dicho paquete, que se puede hacer con el siguiente comando:

Código: (bash) [Seleccionar]
sudo apt-get install hostapd
Configuración de hostapd:

Ahora es necesario configurarlo, para ello, se deja aquí mismo el archivo ya comentado, no sin antes repetir que se debe verificar si la tarjeta de red tiene soporte para el modo AP, por suerte se puede ver con el comando iw, pero si no se tiene instalado:

Código: (bash) [Seleccionar]
sudo apt-get install iw
Para ver cuántas tarjetas de red inalámbricas tenemos:

Código: (bash) [Seleccionar]
iw dev

Listado de interfaces de redes

Donde dice phy#0, es el índice de hardware, y es importante saberlo para poder ver la información con el siguiente comando, aunque para no complicar su visualización, solo se mostrará parte del resultado, que son los modos soportados, que es lo que nos interesa.

Código: (bash) [Seleccionar]
iw phy0 info

Modos soportados

Se ve claramente que entre los modos soportados está el que nos interesa: AP, pero en caso de que no esté y se intente crear un punto de acceso con hostapd puede ser muy inestable o ni siquiera se crearía.

Ahora que ya se ha comprobado si nuestra tarjeta de red tiene ese poder, he aquí la tan esperada configuración:


Código: (bash) [Seleccionar]
# El nombre de la red
ssid=DtxdF

# El canal
channel=5

# Esta opción, que depende de la tarjeta, significando así, junto con la
# compatibilidad 'N', la tecnología que admite.
hw_mode=g

# 1 = WPA; 2 = WEP; 3 = Ambos
auth_algs=3

# Compatibilidad con la tecnología 'IEEE 802.11n'
ieee80211n=1

# QoS
wmm_enabled=1

# La interfaz de la tarjeta de red inalámbrica
interface=wlan0

# Versión 2 de WPA
wpa=2

# Una contraseña super segura
[email protected]

# (AES) Counter Mode CBC-MAC Protocol
rsn_pairwise=CCMP

Está perfectamente comentado, por lo que lo único que faltaría es aclarar que algunos valores como el de hw_mode, ieee80211n, y rsn_pairwise, depende de las posibilidades de nuestra tarjeta de red, y para poder ver esa información, el compañero ideal será iw, aunque si éste no muestra detalles útiles o específicos, tal vez sea necesario instalar el paquete lshw, o usar el viejo iwconfig.

Ya guardado el archivo de configuración en /etc/hostapd/hostapd.conf, es hora de reiniciar el daemon hostapd:


Código: (bash) [Seleccionar]
sudo service hostapd restart
Mientras tanto en el cliente, y ya habiendo accedido vía WIFI a nuestro punto de acceso, es posible ver si la magia ha hecho efecto al corroborar la ubicación.


Uso del proxy en Android a través de WIFI

The Onion Router Access Point (Tor-ap):

Si el lector no ha quedado satisfecho con usar un proxy común y corriente, de formal local, por LAN y WLAN, entonces quizá le atraiga la idea de usar la red Tor.

Uso:

tor-ap es un script simple que permitirá redirigir todas las conexiones hacia la red Tor. Tal script se puede encontrar en las siguientes líneas:

Código: (bash) [Seleccionar]
#!/usr/bin/env sh

# El identificador del usuario de Tor.
TOR_UID=$(id -u debian-tor)

# Las destinos que no se enrutarán a través de Tor.
NON_ROUTE="127.0.0.1/8"

# El puerto DNS local, que, por defecto es el 53.
LOCAL_DNS=53

# Esta sección es para la máquina local.
#
# L_TOR_DNS: El puerto DNS de Tor para la máquina local.
# L_TRANS_PORT: El puerto del proxy transparente para la máquina local.
L_TOR_DNS=5353
L_TRANS_PORT=9040

# Esta sección es para las máquinas remotas (cliente conectados vía LAN/WLAN).
#
# No hace falta explicación, es lo mismo que la anterior sección, pero
# aplicado a las máquinas remotas.
R_TOR_DNS=5354
R_TRANS_PORT=9041

iptables --flush
iptables --table nat --flush

iptables --table nat --append OUTPUT --match owner --uid-owner $TOR_UID --jump RETURN
iptables --table nat --append OUTPUT --protocol udp --dport $LOCAL_DNS --jump REDIRECT --to-ports $L_TOR_DNS
iptables --table nat --append PREROUTING --protocol udp --dport $LOCAL_DNS --jump REDIRECT --to-ports $R_TOR_DNS

for NET in $NON_ROUTE;do
        iptables --table nat --append OUTPUT --destination $NET --jump RETURN

done

iptables --table nat --append OUTPUT --protocol tcp --syn --jump REDIRECT --to-ports $L_TRANS_PORT
iptables --table nat --append PREROUTING --protocol tcp --syn --jump REDIRECT --to-ports $R_TRANS_PORT

Damos los correspondientes permisos de ejecución:

Código: (bash) [Seleccionar]
chmod +x tor-ap
Y, configuramos Tor:

/etc/tor/torrc:
Código: (bash) [Seleccionar]
# Cuando Tor necesita asignar una dirección virtual (no utilizada) debido a un comando
# MAPADDRESS del controlador o la función AutomapHostsOnResolve, Tor elige una
# dirección no asignada de este rango. Más en 'man 1 tor'.
VirtualAddrNetwork 10.192.0.0/10
# Cuando esta opción está habilitada y recibimos una solicitud para resolver una dirección que termina
# con uno de los sufijos en AutomapHostsSuffixes, asignamos una dirección virtual no utilizada a esa
# dirección y devolvemos la nueva dirección virtual. Esto es útil para hacer que las direcciones
# ".onion" funcionen con aplicaciones que resuelven una dirección y luego se conectan a ella.
# Más en 'man 1 tor'
AutomapHostsOnResolve 1

# Esto es necesario para la máquina local.
#
# El puerto del proxy transparente
TransPort 9040
# El puerto del servidor DNS UDP de Tor
DNSPort 5353

# Esto es necesario para los clientes remotos.
TransPort 0.0.0.0:9041
DNSPort 0.0.0.0:5354

Ahora se reinicia Tor:

Código: (bash) [Seleccionar]
sudo service tor restart
Antes de ejecutar CURL, debemos, con una instancia de Tor en ejecución, ejecutar tor-ap.

Código: (bash) [Seleccionar]
sudo ./tor-ap
Ahora comprobamos:

Código: (bash) [Seleccionar]
curl http://ip-api.com/json | jq

Finalización de tor-ap

La ventaja más llamativa de tor-ap frente a la tradicional configuración de este austero artículo, es, que no es necesario especificar los puertos específicos, ni hacer malabares para que funcione Tanto local, como en LAN y WLAN, con la simple ejecución del script es posible realizar todo esto, y con la segunda ventaja, pero igual de grandiosa, y es que si realizamos una prueba de fuga de DNS, los resultados serán magníficos.


DNS Leak Test

No hay fugas.


No está demás decir, antes de concluir, que, no es necesario aplicar una regla a iptables para indicarle al sistema qué interfaz será la de salida (en otras palabras, la que brindará al usuario conexión a Internet) y tampoco es necesario habilitar la redirección de paquetes (con sysctl), eso es otra ventaja.


Nyx & Tor:


Circuitos de Tor usando Nyx

Nyx es un monitor de línea de comandos para Tor. Con él es posible obtener información sumamente detallada en tiempo real sobre los circuitos que hacen uso los usuarios, como el uso de ancho de banda, las conexiones, los registros, y muchísimo más.

Para usar la imprescindible herramienta, podremos instalarla de la siguiente manera:


Código: (bash) [Seleccionar]
python3.7 -m pip install nyx
Es importante que seleccionen su versión de Python correspondiente, ya que en algunas distribuciones el comando sin especificar su versión implica ejecutar la versión 2.7, ya vieja y descontinuada.

Ya instalado, no es necesario configurar Nyx, pero sí a Tor


Configuración de Tor para su uso con Nyx:

Antes de hacer nada, vamos a generar una clave para aumentar la seguridad en el control de Tor, para ello con el siguiente comando, que se comentará en breve, es posible hacerlo.

Código: (bash) [Seleccionar]
tor --hash-password 123

HASH que se deberá usar en la configuración de Tor

Anotando la salida de ese comando, y pegándola en la configuración de Tor de la siguiente manera:

/etc/tor/torrc:
Código: (bash) [Seleccionar]
ControlPort 9051
HashedControlPassword 16:A2A0C4D4E718EBE8600E129DB98AA1C3459069F221E8BDC73063CC4EF6

Allí especificamos el HASH de la contraseña 123, y además, con ControlPort damos a entender que es el puerto para habilitar el control del proceso Tor.

Ahora ejecutamos nyx y por motivos de seguridad se nos preguntará la contraseña.



Inicio de sesión con nyx

Una vez tecleamos la contraseña correspondiente, e ingresamos exitosamente, nos encontramos con el gráfico del ancho de banda, tanto de bajada como de subida.


Gráfico del ancho de banda

Presionamos la flecha derecha de nuestro teclado y obtenemos otra vista: ahora podremos ver los circuitos.


Circuitos de Tor

Si se presiona ENTER veremos información en pantalla.


Circuitos de Tor mejor detallados

Una muy útil forma de usar nyx es para obtener una nueva identidad. Simplemente presionando la tecla n se nos cambiará.

Código: (bash) [Seleccionar]
for i in {1..3};do
    curl -x "socks5://127.0.0.1:9050" -s http://ip-api.com/json | jq ".query" | tr -d '"'
done
# Después de requerir una nueva identidad.
curl -x "socks5://127.0.0.1:9050" -s http://ip-api.com/json | jq ".query" | tr -d '"'


Cambiando de identidad

Proxychains:


En ciertas ocasiones cuando una aplicación tiene la habilidad de conectarse, ya sea a Internet o un sucedáneo, no trae con sí el poder de configurar un proxy, afortunadamente existe una herramienta capacitada para este fin.

Proxychains es ideal para situaciones como las anteriormente planteadas, ya que permite, dependiendo de su configuración, encadenar una lista de proxies.


instalación:

Código: (bash) [Seleccionar]
sudo apt-get install proxychains
Uso:

Proxychains es fácil de configurar, ya que consta de un solo archivo de configuración, y dentro de él, tiene tres formas de funcionar, sumando a las diversas opciones.

  • Dinámico o Dynamic: Cada conexión se realizará a través de proxies encadenados, tal y como estén en la lista, omitiendo a los muertos.
  • Estricto o Strict: Igual que Dynamic, pero es necesario que todos los proxies encadenados estén en línea.
  • Aleatorio o Random: Cada conexión se realizará a través de un proxy aleatorio.

Es necesario antes de ejecutar a proxychains, definir la cadena de proxies a utilizar, los cuales, para este artículo, serán:

Código: (text) [Seleccionar]
socks5 135.181.39.13  1080  # Finland
socks5 151.106.34.139 1080  # France
socks4 127.0.0.1      1212  # Este no existe (!)
socks5 192.252.215.5  16137 # Canada

Suponiendo que el tercer proxy no exista, en teoría igualmente debería funcionar, salvo que ningún otro funcione, pero este no es el caso (al menos no en el momento de escribir estas palabras).

Código: (bash) [Seleccionar]
proxychains curl http://ip-api.com/json && echo

Modo dinámico de proxychains

Como se puede observar, aunque algunas conexiones fallen, sigue su ejecución con prontitud.

Ya habiendo probado el modo dinámico, por supuesto que para ver otro tipo de funcionamiento, vayamos con el estricto, que, según la descripción, es igual a dynamic, pero falla si alguna conexión falla. Así que lo que se debe hacer para cambiar el modo, es, comentar dynamic_chain en el archivo de configuración y a su vez, descomentar strict_chain, dejando intacto lo demás. Ejecutando el mismo comando, aquí su resultado.



Modo estricto en proxychains

Falló exactamente como se tenía en mente, pero ahora comentando el proxy que no existe, debería funcionar tal y como se está maquinando en nuestra mente.


Modo estricto sin fallar en proxychains

Obtenemos un resultado grato, y es porque se eliminó el proxy muerto o inexistente.

Faltaría entonces un modo, siendo uno de los más interesantes: random. Su mismo nombre ilustra lo que hará. Pasamos comentado strict_chain y descomentando random_chain, a su vez, ejecutamos nuevamente el mismo comando, pero esta vez en un bucle for, siendo su límite hasta tres veces para ver qué obtenemos.



Modo aleatorio de proxychains

Sin tocar absolutamente nada, se percibe tácitamente el cambio que proxychains hace entre las cadenas de proxies, concluyendo así las modalidades.

Opciones misceláneas de proxychains:

  • chain_len: Esto determinará cuántas de las direcciones IP de la cadena se utilizarán en la creación de la nueva cadena de proxies aleatoria.
  • quit_mode: No muestra la salida verbosa. Muy útil si se quiere combinar con otros programas usando tuberías, por ejemplo.
  • proxy_dns: Usar los proxies para realizar una petición DNS. Lo positivo es que no habrá filtrado de datos, y lo negativo, es que el servidor de tener habilitada implementada esta característica.
  • tcp_read_time_out: El tiempo de espera para la lectura en milisegundos.
  • tcp_connect_time_out: El tiempo de espera para conectar en milisegundos.

El archivo de configuración de proxychains está muy bien documentado, así que en caso de duda, es buena idea acudir a él también.

Conclusión:

Desde el preludio de este austero artículo que tuvo el principal objetivo de inculcar, tanto a los novicios como a los más versados en la materia, las diferentes maneras de las que se podría o, implementar, o, usar un proxy en plataformas Gnu/Linux y compatibles, con el propósito, ya sea de aumentar la privacidad, la seguridad, evadir las restricciones que impone un gobierno, o para englobar, acceder a ciertos recursos que no son posibles de llevar a cabo en tal nación determinada. Espero sea de verdad muy útil para el que esté leyendo las siguientes líneas.


Este artículo es una especie de segunda versión de otro artículo que se hizo hace mucho tiempo, puliendo algunos detalles y agregando otros, es por eso que algunas características pueden tener cierto parentesco.


~ DtxdF

2
Trustword es un programa muy simple para la firma, el cifrado y el mantenimiento de claves para facilitar y fortalecer una comunicación segura. Usa internamente (gracias a libsodium) para el cifrado XSalsa20, y en el caso de la criptografía asimétrica, se complementa con el intercambio de claves X25519. Y para la firma digital Ed25519ph con SHA512. En el caso del almacenamiento de contraseñas usa argon2id.


Dependencias:

Usando el gestor de paquetes de nuestro sistema, podremos instalar las siguientes dependencias que harán funcionar a trustword:

  • gcc (recomendado) o clang (no probado)
  • cmake
  • openssl
  • libsodium
  • argon2
  • sqlite3

Arch Linux:

Código: (bash) [Seleccionar]
sudo pacman -S base-devel cmake openssl libsodium argon2 sqlite3
Debian:

Código: (bash) [Seleccionar]
sudo apt-get install libssl-dev libsqlite3-dev libsodium-dev libargon2-dev cmake make gcc
FreeBSD:

Código: (bash) [Seleccionar]
doas pkg install gcc cmake openssl libsodium libargon2 sqlite3
Instalación:

Ya habiendo instalado las dependencias correspondientes para nuestro sistema, es hora de realizar la instalación:

Código: (bash) [Seleccionar]
git clone https://github.com/UltraTesla/trustword.git
cd trustword
chmod +x dependences.sh
./dependences.sh
sudo chown <Tu nombre de usuario>:<Tu grupo> ~/.trustword
trustword --help

Tutorial:

Antes que nada es necesario generar nuestro par de claves, o en otras palabras, la clave pública, la secreta, la del firmado, y la de verificación. Afortunadamente es tan fácil como ejecutar un comando con la información necesaria:

Código: (bash) [Seleccionar]
trustword -g --user [Nombre de usuario] --password [Contraseña]
Recordando que si no se ajustara un nombre de usuario conveniente, trustword usaría el valor de la variable de entorno USER.


Resultado de generar las claves

Una vez generadas, es posible, nuevamente con un simple comando, visualizar todas las claves de nuestro sistema:

Código: (bash) [Seleccionar]
trustword -l

Las claves que están en nuestro sistema

Algo peculiar de trustword es que no almacena los nombres de usuarios tal cual se escriben, más bien guarda la suma de verificación (SHA3_224(), específicamente) con el propósito de agregar un extra de confidencialidad. La contra de este método de almacenamiento es que se necesita conocer de antemano el nombre de usuario del remitente y del destinatario, por lo que podría dificultar el mantenimiento.

Pero qué mejor forma de demostrar lo que digo que importando la clave pública y de nuestro compañero @Kirari:


Código: (bash) [Seleccionar]
trustword -i [Ruta de la clave] --hash [Huella dactilar]

Importando la clave de nuestro compañero

Una vez le compartimos nuestra clave pública (y de verificación, en caso de ser necesario) tendremos la posibilidad de comunicarnos de forma segura con la otra parte a tratar, pero primero hay que exportar nuestra clave pública correspondiente, ya sea en binario, o en formato hexadecimal (usando el parámetro -h), siendo este último una muy buena opción en caso de no poder distribuir la clave como un archivo.

Código: (bash) [Seleccionar]
trustword -e --user [Nombre de usuario]

Exportando mi clave pública

Para importar una clave en trustword es necesario indicar, además de la clave, su huella dactilar. Una muy útil forma de verificar que la clave a importar sea la del usuario correspondiente y también verifica que no se haya modificado en el transcurso.

Una vez hecho el apretón de manos con nuestra otra parte, es posible cifrar.


Código: (bash) [Seleccionar]
./trustword -C [Nombre del archivo a cifrar] --from [Nombre de usuario - origen] --to [Nombre de usuario - destino] --password [Contraseña de la clave secreta del usuario de origen]

Cifrando el mensaje para nuestro compañero

Tal vez surga la duda de por qué trustword necesita de la contraseña que usamos en la generación del par de claves. Pues es una sencilla cuestión: trustword almacena la clave secreta y de firmado cifrada para que un atacante al obtener la base de datos, en caso de un ataque, no pueda obtener su contenido.


Descifrando el mensaje de nuestro compañero

Siguiendo con el tema de cifrado. Si el usuario no desea generar su par de claves, está la posibilidad de usar el cifrado simétrico, lo cual implica que las dos partes sepan de antemano la contraseña para el cifrado y descifrado.

Código: (bash) [Seleccionar]
./trustword -k [Nombre del archivo a cifrar] --password [Contraseña]

Vídeo:

Nuestro compañero @Kirari realizó un vídeo para el que desee ver una demostración visual de la herramienta:


~ DtxdF

3

A veces necesitamos descargar una carpeta o un único archivo que esté siendo hospedado por un servicio de alojamientos de archivos muy famoso, aunque en la actualidad muy poco se usa, éste tuvo su brillantez en una época, y por si se lo preguntan, ese servicio es, Mediafire, el cual nos da un extra en nuestro tiempo, que podría considerarse, desperdiciado:


Lo que pasa al presionar el botón Download folder

Pero no hay necesidad de mostrar preocupación, ya que la solución es más fácil de lo que parece, pero si algo es mejor para este sencillo tutorial, son los detalles empíricos. Y como extra para los flojillos, pueden ir a la sección "El script" donde pueden ver su instalación, y su uso sin necesidad de ver qué hay detrás de él.

Obteniendo los enlaces manualmente:

Primero que nada, y ya con el enlace del archivo en cuestión, que en este caso será una carpeta. Debemos ver el siguiente patrón en la URI:

Código: (text) [Seleccionar]
https://www.mediafire.com/folder/[Identificador]
Una vez que lo deducimos, usaremos la API de mediafire, pero adicionando su correspondiente Identificador:

Código: (text) [Seleccionar]
https://www.mediafire.com/api/1.4/folder/get_content.php?r=rgfa&content_type=files&filter=all&order_by=name&order_direction=asc&chunk=1&version=1.5&folder_key=[IDENTIFICADOR]&response_format=json

Respuesta en formato JSON

Como se puede apreciar, es realmente sencillo, y cabe aclarar que para el caso de los archivos no se hace nada más especial, ni siquiera hace uso de la API, más bien realiza Web scraping para obtener el correspondiente enlace de descarga.

El script:

Antes que nada, aquí se enumeran los requerimientos si queremos que su ejecución sea plena:

  • lxml
  • bs4
  • requests

Claro está que tenemos la oportunidad de escoger entre usar pip y el gestor de paquetes de nuestro sistema, pero sería más recomendable optar por la segunda opción por las ventajas que tiene, como la actualización que se lleva a cabo al actualizar el sistema. Sin embargo, para no complicar el tutorial, usaremos pip y cada cual puede hacer una equivalencia con los nombres respectivos en los repositorios de su sistema.

Código: (bash) [Seleccionar]
pip install lxml
pip install bs4
pip install requests

Nota: Cabe aclarar que es mejor verificar su versión de pip correspondiente (que sea apto para python3.6 en adelante)

Luego, clonamos el repositorio:


Código: (bash) [Seleccionar]
git clone https://github.com/DtxdF/mediafire2links.git
cd mediafire2links
python3 mediafire2links.py

Pasos para la obtención:

Si ya hemos llegado hasta acá es porque hemos pasado lo peor. Pero ahora, y para ultimar el tutorial, vamos a lo que vinimos: obtener enlaces de las descargas de los archivos.

Debemos, ante nada, tener un enlace de algún archivo o carpeta que deseemos. En el caso de una carpeta es algo más especial en las instrucciones, ya que no necesitamos completamente la URL, más bien su identificador, que se puede obtener siguiendo el siguiente patrón:


Código: (text) [Seleccionar]
https://www.mediafire.com/folder/[Identificador]
Mayormente es una secuencia inhumana de caracteres, pero será fácilmente deducible.


La localizaciones de los archivos de una carpeta

Nota: Se ofuscuraron las direcciones para evitar su descarga.

He aquí el correspondiente comando:

Código: (bash) [Seleccionar]
python3 mediafire2links.py d [Identificador]
Y aquí la explicación: en el caso de querer obtener los correspondientes enlaces de los archivos en una carpeta se debe colocar como tipo de archivo una 'D' sin importar si ésta es mayúscula o minúscula, al igual que si desea descargar un archivo, siendo su letra correspondiente, una 'F', y aquí su correspondiente ejemplo:


Obteniendo un archivo individualmente

Y como no puede faltar, su correspondiente comando:

Código: (bash) [Seleccionar]
python3 mediafire2links.py f https://mediafire.com/file/[Identificador]/[Nombre de archivo]
Por lo general, es irrelevante el nombre de archivo; su identificador y por supuesto, su URL es más que suficiente para el script.

Uso con wget:

Se tiene la libertad de escoger alguna herramienta para descargar los archivos, pero para este caso es recomendable wget que es una excelente herramienta, especialmente cuando queremos descargar una carpeta entera.

Código: (bash) [Seleccionar]
python3 mediafire2links.py d [Identificador] > links.txt
wget -c -vv -i links.txt

Conclusión:

Este script fue pensado para darselo a un compañero que me lo pidió, pero también quise compartirlo por si a alguno le era de agrado. Quiero aclarar que si surge un error o cualquier incongruencia, no está demás informarlo. Espero les haya gustado.

~ DtxdF

4

Calculadora con notación polaca inversa

En la anterior parte pudimos aprender la instalación de FreeDOS en QEMU, pero hacía falta varias cosas, que más allá de su uso, tienen que ver con el mantenimiento, instalación de paquetes y una de las cosas más esenciales de todo, las redes.

Paquetes necesarios:


Esto es simple. Abrimos QEMU con las opciones pre-configuradas en la parte anterior y ejecutaremos el comando fdimples, el cual nos muestra una interfaz TUI. Los controles pueden ser resumidos como lo siguiente:

*.- 🡡, 🡢, 🡣, 🡠: Moverse entre los diferentes elementos. Ya sea que estés en la lista de grupos de paquetes o de los paquetes mismos, las flechas hacia arriba y hacia abajo te ayudarán a desplazarte; si necesitas moverte entre grupo de paquetes o los paquetes que éstos contengan, las flechas hacia la derecha o la izquierda, son los de utilidad. En caso de que se necesite ver la descripción de un paquete, cuando se le esté apuntando (ver imagen, paquete FDNET) presione la flecha derecha y las flechas hacia arriba y hacia abajo expandirán o disminuirán la descripción y los programas que el paquete contenga.
*.- SPACE o ENTER: Misma funcionalidad. Seleccionar o confirmar una opción. En caso de querer seleccionar todo el grupo completo (ver imagen, grupo de paquete Networking), se necesita apuntar hacia él, y luego presionar ENTER o SPACE para seleccionar/deseleccionar todos los paquetes a instalar/desinstalar, o si simplemente se desea instalar un paquete, es necesario moverse hasta él y realizar el mismo procedimiento.

Así de sencillas son las instrucciones, ahora que se sabe la forma de instalar paquetes desde el CD-ROM (la misma imagen ISO, en nuestro caso) pasemos a instalar los paquetes necesarios para obtener Internet. En nuestro caso deben ser los siguientes:

*.- FDNET: paquete de soporte de red básico para FreeDOS para varias configuraciones de hardware y plataformas de máquinas virtuales.
*.- MTCP: Colección de herramientas TCP/IP para DOS de 16 bits, tales como: DHCP, IRC, FTP, Telnet, Netcat, HTGet, Ping, SNTP.
*.- Opcionalmente, aunque encarecidamente, se recomienda instalar también: curl, wget, ping

Como último paso para esta sección, reiniciamos.

Nota: Es necesario seguir con la siguiente sección para completar este paso.


Configuración de QEMU:

No solo es necesario instalar los paquetes para darle compatibilidad a FreeDOS para las máquinas virtuales y el hardware en sí, además es necesario configurar QEMU (o la máquina virtual que se esté usando) para que las configuraciones automatizadas y demás, pueden hacer efecto.

En nuestro caso ejecutaremos el siguiente comando:


Código: (bash) [Seleccionar]
qemu-system-i386 -net nic,model=pcnet -net user -k es -smp $(($(nproc)+1)) -m 32M -drive file=freedos.img,media=disk,format=raw -drive file=FD12CD.iso,media=cdrom -boot order=d

Resultado :D

El gestor de paquetes:

Sí, FreeDOS tiene un gestor de paquetes :D, y muy bueno, el cual nos permite instalar paquetes que no estén incluidos en el CD-ROM (la imagen ISO). En nuestro caso instalaremos los paquetes necesarios para programar en el mismo.

Antes de usar el gestor de paquetes necesario, para no perder tanto tiempo verificamos que no tengamos los paquetes deseados en la imagen ISO, los cuales son: DJGPP, i16butil, i16gcc, i16newli, i16budoc, i16gcdoc

En mi caso el único que tengo en la imagen ISO es DJGPP, por lo que paso a instalarlo usando fdimples:



Mientras que los demás, usaré fdnpkg para buscarlos y si son encontrados, instalarlos:


fdnpkg search i16

Ahora, instalamos:

Código: (dos) [Seleccionar]
fdnpkg install i16butil
fdnpkg install i16gcc
fdnpkg install i16newli
fdnpkg install i16budoc
fdnpkg install i16gcdoc

Una vez cuncluímos el proceso de instalación de los paquetes necesarios, necesitamos definir la variable que se mostrará en unos instantes en el archivo AUTOEXEC.BAT que se encuentra en C:

Código: (dos) [Seleccionar]
set DJGPP=c:\devel\djgpp\djgpp.env
Pese a que tenemos y podríamos usar perfectamente el comando EDIT para editar archivos y hasta programar con él, es recomendable usar otro editor de texto que se adhiera a sus necesidades y preferencias. En mi caso, usaré simplemente pico, aunque fed tampoco está mal, desde luego, es posible ejecutar el siguiente comando y se mostrará todos los editores, o también se puede ingresar a los repositorios.

Código: (dos) [Seleccionar]
fdnpkg search edit

Editores válidos por el momento

Programación en C:

Para concluir este pequeño artículo, vamos a escribir dos programas en C; uno que imprima 'Hello World!' y otro que será una calculadora con notación polaca inversa.

hello.c
Código: (c) [Seleccionar]
#include <stdio.h>
#include <stdlib.h>

int main(void) {
printf("Hello World!\n");
return EXIT_SUCCESS;

}

Código: (dos) [Seleccionar]
i16gcc -o hello.exe -O2 hello.c
hello.exe


Ya compilamos nuestro hello world, pero ahora vamos a compilar un programa con más funcionalidades.

polish.c
Código: (c) [Seleccionar]
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <math.h>
#include <stdbool.h>
#include "calculator.h"
 
#define MAX_NUMBERS 30
 
int main(int argc, char **argv) {
   long double *array = (long double *)malloc(sizeof(long double)*MAX_NUMBERS);
   long double *result = array;
   long double aux;
   char *endstr = NULL;
   int operator;
   int max_numbers, count;
   bool check = false;
 
   if (!array) {
  if (errno != 0)
perror("malloc");
  else
fprintf(stderr, "Possibly no memory\n");

  return EXIT_FAILURE;
 
   }
 
   max_numbers = MAX_NUMBERS;
   count = 0;
   while (--argc) {
  if (count++ >= max_numbers) {
max_numbers *= 2;
array = (long double *)realloc(array, sizeof(long double)*max_numbers);
 
if (!array) {
if (errno != 0)
   perror("realloc");
else
   fprintf(stderr, "Possibly no memory\n");
 
free(array);
return EXIT_FAILURE;
 
}
 
  }
 
  if (isdigit(**++argv)) {
errno = 0;
aux = strtold(*argv, &endstr);
 
if (errno != 0) {
perror("stdtold");
free(array);
return EXIT_FAILURE;

}
 
*result++ = aux;
 
continue;
 
  }
 
  if (!check)
check = true;
 
  result -= 2;
 
  if (isnan(*result) || isnan(*(result+1))) {
fprintf(stderr, "Invalid syntax!\n");
return EXIT_FAILURE;
 
  }
 
  operator = *argv[0];
  errno = 0;
  *result = calculate(*result, *(result+1), operator);
  result++;
 
  if (errno != 0) {
free(array);
return EXIT_FAILURE;
 
  }
 
   }
 
   if (check)
  printf("%Lg\n", *--result);
   else
  fprintf(stderr, "Invalid syntax!\n");
 
   free(array);
 
   return EXIT_SUCCESS;
 
}

calculator.c
Código: (c) [Seleccionar]
#include <stdio.h>
#include <errno.h>

long double calculate(long double n1, long double n2, int operator) {
long double result;

result = 0.0f;
switch (operator) {
case '+':
result = n1 + n2;
break;

case '-':
result = n1 - n2;
break;

case '*':
result = n1 * n2;
break;

case '/':
if (n2 == 0.0f) {
errno = EINVAL;
fputs("Zero divisor!\n", stderr);
} else
result = n1 / n2;
break;

default:
errno = EINVAL;
fprintf(stderr, "Invalid operator: '%c'\n", operator);

}

return result;

}

calculator.h
Código: (c) [Seleccionar]
long double calculate(long double n1, long double n2, int operator);
El proceso de compilación es sumamente sencillo:

Código: (dos) [Seleccionar]
i16gcc -o polish.exe -O2 polish.c calculator.c
polish.exe 2 2 +
polish.exe 4 2 *
polish.exe 2.5 2.5 +


Reto:

Aquí no acaba. Vamos a realizar una serie de retos para ver si los pueden completar. Básicamente consta de agregar nuevas funcionalidades a la calculadora:

  • Agregue más operadores binarios (que requieran de dos números) como el módulo, la potencia, etc
  • Sabiendo que los operadores lógicos no funcionan con el tipo de dato long double, agregue operadores, como AND, OR, XOR, etc.
  • Agregue operadores de relaciones, para determinar si dos números son iguales, uno es menor o igual, uno es mayor o igual, uno es mayor, uno es menor, uno es distinto del otro, etc

¿Cuántos puedes resolver? 3:)

Notas futuras:

Desde que empecé a hacer estos pequeños artículos no he querido usar QEMU; traté sin éxito de usar FreeDOS (no el pre-configurado) con DosEMU, que me pareció mucho mejor en cuanto a rendimiento y usabilidad, pero luego de error tras error, mejor lo dejaré para otra ocasión.

Material de referencia y altamente recomendada:

*.- www.freebsd.org/cgi/man.cgi?query=qemu&sektion=1&apropos=0
*.- www.freedos.org/books/cprogramming
*.- wiki.freedos.org/wiki/index.php/Networking_FreeDOS_-_Quick_Networking_HowTo
*.- wiki.qemu.org/index.php/Documentation/Networking
*.- wiki.archlinux.org/index.php/QEMU_(Espa%C3%B1ol)
*.- wiki.archlinux.org/index.php/Network_bridge

~ DtxdF

5
GNU/Linux / doas: Una alternativa a sudo, simple, ligera y segura
« en: Noviembre 01, 2020, 07:13:30 pm »
doas es un programa para ejecutar comandos como otro usuario. El administrador del sistema puede configurarlo para otorgar privilegios a usuarios específicos para ejecutar comandos específicos. Es gratuito y de código abierto bajo la licencia ISC y está disponible en Unix y varios sistemas Unix-like.


Fuente: NixCraft

doas es lo más simple que puedes conseguir teniendo muchas características del veterano sudo, no obstante a pesar de que éste último sea prácticamente un estándar de facto en la mayoría de sistemas, hay otros como OpenBSD que ya lo traen por defecto. Y no es por nada, doas es realmente fácil de usar y de configurar, ciertamente éso es debido a los patrones que contiene que analizaremos en brevedad.

Instalación:

Para la instalación en Gnu/Linux se usará debian, pero son libres de usar cualquier distribución de preferencia y que sea compatible. En el caso de FreeBSD, simplemente se instalará desde los repositorios.

Debian:

Código: (bash) [Seleccionar]
sudo apt install build-essential make bison flex libpam0g-dev
git clone https://github.com/slicer69/doas.git
cd doas
sudo make install

FreeBSD:

Código: (bash) [Seleccionar]
su
pkg install doas

Nota: Al concluir la instalación de doas en FreeBSD tendremos un archivo de configuración de ejemplo en '/usr/local/etc/doas.conf.sample'. Si se desea usar ese y modificarlo según nuestros datos, mucho mejor, como lo haremos en este caso.

Configuración:

Como se comentó anteriormente, doas provee patrones muy fáciles de aprender y comprender. El patrón es: permit|deny [options] identity [as target] [cmd command [args ...]]

permit|deny: permit, permite la opción o el comando de doas escrito en la configuración; deny, es la contraparte de permit, por lo que deniega la opción o el comando escrito en la configuración.
[options]: Las opciones del comando u opción a tratar. Ya se describirá mejor este apartado en unos instantes.
identity: El nombre de usuario o gropo que está ejecutando el comando. En el caso de un usuario, se coloca una cadena de caracteres (como: dtxdf), pero en el caso de un grupo se colocan dos puntos y una cadena de caracteres como se mencionó (como: :wheel).
[as target]: Ejecutar una opción o comando como un usuario o grupo en específico.
[cmd command [args ...]]: Ejecutar el comando siguiendo las opciones especificadas anteriormente.

Nota: Todo lo que esté en | significan que se pueden ejecutar una de esas opciones (como en: permit|deny). Todo lo que esté entre corchetes, es opcional (como en: [options]).

[options] tienes una variedad de opciones que permiten cambiar el comportamiento de cada comando. Entre ellas están:

*- nopass: No se requiere que el usuario ingrese una contraseña
*- persist: Después de que el usuario se autentica con éxito, no vuelva a solicitar una contraseña durante algún tiempo. Funciona en OpenBSD solamente, La opción persist no está disponible en Linux o FreeBSD.
*- keepenv: Mantener el entorno de usuario por defecto. Para poder ejecutar la mayoría de aplicaciones GUI, el usuario debe tener la palabra clave keepenv especificada, ya que en caso de que no sea así, puede bloquear la aplicación de forma indefinida debido a una mala información que se le proporcione.
*- setenv {[variable ...] [variable=value ...]}: Se pueden especificar variables de entorno arbitrarias o incluso se pueden eliminar las ya definidas usando un guion (-) al inicio del nombre de ella.

Ahora siguiendo el archivo de configuración de ejemplo que está en '/usr/local/etc/doas.conf.sample', vamos a copiarlo a '/usr/local/etc/doas.conf' y empecemos a configurar:


Código: (text) [Seleccionar]
# Archivo de ejemplo para doas
# Por favor consulte la página de manual de doas.conf(5) para obtener información sobre
# cómo configurar un archivo doas.conf.

# Permitir a los miembros del grupo wheel ejecutar acciones como root
permit :wheel

# Permitir al usuario alice ejecutar comandos como el usuario root.
permit alice as root

# Permita que el usuario bob ejecute programas como root, manteniendo las variables de entorno. Útil para aplicaciones GUI.
permit keepenv bob as root

# Permita que el usuario cindy ejecute solo el administrador de paquetes pkg como root para realizar actualizaciones de paquetes.
permit cindy as root cmd pkg update
permit cindy as root cmd pkg upgrade

Otro ejemplo que podría resultar interesante en caso de no deseas ejecutar poweroff o reboot sin requerir contraseña es:

Código: (text) [Seleccionar]
permit nopass user as root cmd poweroff
permit nopass user as root cmd reboot

O también podríamos denegar el acceso a una operación:

Código: (text) [Seleccionar]
deny user cmd poweroff
Esto resultaría:

Código: (text) [Seleccionar]
doas poweroff
doas: Operation not permitted

Nota: user debe ser reemplazado por tu nombre de usuario.

¿Cuál es mejor?

Ninguno. sudo por un lado es complejo, y tiene muchas opciones de configuración que le ofrece a un administrador de sistemas versatibilidad, pero doas es perfecto para la mayoría de usuarios que solo requieren ejecutar una tarea con privilegios.

Material de referencia y recomendado:

*- www.freebsd.org/cgi/man.cgi?query=doas.conf&sektion=5&manpath=freebsd-release-ports
*- en.wikipedia.org/wiki/Doas

~ DtxdF

6
GNU/Linux / Instalación de FreeDOS en QEMU + Alternativas
« en: Noviembre 01, 2020, 05:05:50 am »
FreeDOS es un sistema operativo completo, gratuito, de código abierto y compatible con DOS que se puede utilizar para jugar juegos DOS clásicos, ejecutar software empresarial heredado o desarrollar sistemas integrados. Cualquier programa que funcione en MS-DOS también debería ejecutarse en FreeDOS.


FreeDOS es mucho más que una aplicación para revivir algunas aplicaciones y juegos clásicos, además de ser muy útil en entornos donde haya sistemas heredados pero obsoletos, los cuales mayormente son usados en el sistema operativo MSDOS. FreeDOS además de ser compatible con las míticas aplicaciones de aquella época, hacen que cualquier aficionado veterano o curioso por aprender, le dé 5 estrellas a este proyecto que se ha mantenido por decadas.

Descarga:

En nuestro caso elegiremos la versión estándar que puede ser encontrada aquí.

Código: (bash) [Seleccionar]
wget -c -vv http://www.freedos.org/download/download/FD12CD.iso
Instalación:

Se usará QEMU sin un frontend gráfico, y será usado en FreeBSD, aunque el resultado no será diferente a otros sistemas. Si se desea usar un frontend gráfico en debian se puede leer este artículo. En el caso de Arch Linux, es recomendable este artículo de la misma wiki.

También se tiene la libertad de elegir otros virtualizadores compatibles...


Antes de empezar, es necesario crear una imagen usando qemu-img(1):


Código: (bash) [Seleccionar]
qemu-img create freedos.img 200M
El formato por defecto es crudo (raw, en inglés) que permite ser simple y fácilmente exportable a otros emuladores. También asignamos 200 Megabytes de espacio (suficiente para la mayoría de cosas, incluso puede ser una exageración).

Ahora ejecutamos FreeDOS:


Código: (bash) [Seleccionar]
qemu-system-i386 -smp cores=$(nproc) -m 32 -drive file=freedos.img,media=disk,format=raw -drive file=FD12CD.iso,media=cdrom -boot order=d
Nota: Para los usuarios de FreeBSD, deben crear un alias para nproc, mientras que en Gnu/Linux ya existe el comando como tal. Como por ejemplo:

Código: (bash) [Seleccionar]
alias nproc="sysctl -n hw.ncpu"
Explicación breve:

qemu-system-i386: Usaremos QEMU para emular un sistema con el juego de instrucciones del i386
-smp cores=$(nproc): Configura algunas opciones para el invitado, como el número de núcleos a utilizar
-m 32: Le asignamos 32 megabytes de memoria (aunque 16 también funcionaría, me gusta exagerar :D)
-drive file=freedos.img,media=disk,format=raw: file=... define la imagen del disco virtual; media=... define el tipo de medio (disk o cdrom); format=... define el formato del disco virtual, que en nuestro caso es en crudo (raw, en inglés).
-boot order=d: El orden de las unidades. a y b para el disquete 1 y 2; c para el primer disco duro; d para el primero cdrom

Nota: Es recomendable leer el manual de qemu


Ahora, una vez comprendemos cada parámetro y opción ajustada, lo ejecutaremos para pasar a instalarlo:



Ya hemos configurado correctamente nuestra máquina virtual, ahora seleccionamos la primera opción (Install to harddisk)


Ahora seleccionamos nuestro idioma de preferencia.


Presionamos: Sí - Continúe con la instalación


Presionamos: Sí - Crear tabla de particiones en la unidad C:


Citar
Free FDISK es capaz de usar soporte de disco grande para permitirle crear particiones mayores a 2.048 MB usando particiones FAT32. Si habilita la compatibilidad con discos grandes, cualquier partición o unidad lógica de más de 512 MB se creará utilizando FAT32.

IMPORTANTE: si habilita la compatibilidad con discos grandes, algunos sistemas operativos podrán acceder a las particiones y unidades lógicas que tengan más de 512 MB de tamaño.

Si estás de acuerdo, presiona Y, que en nuestro caso será así.


Nos aparecerán varias opciones interesantes, pero la más relevante para este tutorial será la primera: Crear partición DOS o unidad lógica DOS (Create DOS partition or logical DOS drive, en inglés). Presionamos enter.


Ahora presionamos la primera opción, ya que nos interesa crear una partición primaria con el fin de instalar un sistema operativo en ella (FreeDOS, en nuestro caso).


Ahora nos pregunta si queremos usar el tamaño máximo de la partición disponible, que en nuestro caso será: Y


Finalizado la creación de la partición, terminemos el proceso saliendo con ESC.


Nos devolverá a este menú nuevamente, pero lo ignoraremos y presionaremos otra vez ESC


Ahora presionamos otra vez ESC para salir y que los cambios hagan efecto.


Reiniciamos presionando: Sí - Por favor, reiniciar ahora


Nos aparecerá el mismo menú del principio, y debemos presionar nuevamente la primera opción.


Otra vez seleccionamos el idioma de preferencia.


Presionamos: Sí - Continúe con la instalación


Le damos formato a la unidad presionando: Sí - Por favor, borrar y dar formato a la unidad C:.





Seleccionamos la distribución del teclado de nuestra preferencia, que en nuestro caso será: Español.


En esta parte se tiene la libertad de elegir cuántos paquetes instalar y si incluir con ellos, el código fuente. Solo paquetes básicos es una opción perfecta si solo queremos el software que está en MSDOS, pero Todos los paquetes es si queremos los paquetes básicos y el software que ha creado la comunidad FreeDOS con el tiempo. En nuestro caso la opción que está en la imagen es perfecta.


Presionamos: Sí - Por favor, instale FreeDOS 1.2.





Una vez finalizada la instalación, reiniciamos.


Ahora iniciamos el sistema.


Ya tenemos FreeDOS instalado en QEMU :D

Alternativas:

Dosbox:

DOSBox es un emulador que recrea un entorno similar al sistema DOS con el objetivo de poder ejecutar programas y videojuegos originalmente escritos para el sistema operativo MS-DOS.

Existe dosbox-staging el cual es mantenido por los fanáticos de este emulador y tiene mejoras sutiles respecto a Dosbox. La instrucciones pueden variar dependiendo de la distribución, así que lo dejaré en manos de los mismo autores: Instalación de dosbox-staging en Gnu/Linux.

FreeBSD ya tiene incluido el paquete:


Código: (bash) [Seleccionar]
doas pkg install dosbox-staging
Con dosbox podemos hacer exactamente lo mismo que FreeDOS, pero no tendremos a disposición todo el software en comparación.


Jugando Ace of the Pacific

Antes de continuar, es recomendable ajustar un pequeño valor en el archivo de configuración de dosbox/dosbox-staging.

Código: (bash) [Seleccionar]
vim ~/.config/dosbox/dosbox-staging.conf
Cambiamos 'keyboardlayout' de 'auto' a 'es' para que tengamos preconfigurado la distribución del teclado.

Una vez iniciado dosbox:



Montamos un directorio que deseamos, como Games


Otro pequeño consejo es que para aumentar el rendimiento de los programas en dosbox, debemos aumentar la velocidad del CPU. Con CTRL + F11 lo disminuimos y con CTRL + F12 lo aumentamos. Es recomendable aumentarlo hasta donde sea coherente.

MSDOS:

Sí, hasta él se puede usar nuevamente pero hay que recordar que ya no está mantenido, aunque FreeDOS es caso contrario, pero en caso de que eso no importe, se puede descargar el código fuente mismo desde el repositorio o desde Computer History Museum.

Juegos clásicos:

Podemos conseguir juegos clásicos en las siguientes páginas:


Lectura recomendada:


~ DtxdF

7
Python / Nueva versión de Ultra Tesla: Más rápido, seguro y eficiente.
« en: Octubre 01, 2020, 11:43:05 am »
Ultra Tesla es un proyecto de código abierto para crear redes distribuidas de servicios fácil, rápido y seguro, usando el poder de computo de múltiples ordenadores. El proyecto permite unificar los distintos servidores en una única interfaz que es proporcionada para el mismo usuario creando una sensación de transparencia.


Este proyecto lo llevo haciendo desde hace algún tiempo en mis tiempos libres. En esta nueva versión le he dedicado más esfuerzo que a la primera e incluso he estudiado algunas cosas nuevas para poder llevarlo a cabo, espero les guste y les sea de utilidad.

¿Qué hay de nuevo?:

En la última versión se hicieron grandes cambios, se arreglaron varios errores y se mejoraron muchas funcionalidades. Entre las más destacadas:

  • Posibilidad de transferir grandes cantidades de datos (probado con 3.5 GiB)
  • Eficiencia en cuanto a procesamiento y usabilidad en la memoria
  • Esquema de cifrado AES-GCM/RSA/SHA3 cambiado por uno más eficiente pero que ofrece la misma seguridad: x25519-xsalsa20-poly1305MAC y para la firma de los datos: ed25519.
  • UTeslaCLI ahora carga el triple de rápido y consume menos recursos.
  • Ya no se usa HTTP, ahora se usa simplemente TCP y en la capa de aplicación: ProtoTesla
  • Ahora es mucho más modular. Antes las funcionalidades que creaban la infraestructura de Ultra Tesla estaban en el mismo núcleo, lo cual hacía que fuera difícil de mantener a corto y largo plazo, por lo que se optó por transformar esas funcionalidades en servicios independientes.
  • Ya no se modifica el código en tiempo de ejecución (lo cual era catastrófico); se optó por usar composición.

Entre los fallos arreglados:

  • No se podía usar SSL en el cliente MySQL
  • No se podía usar un proxy
  • Cuello de botella en el núcleo
  • Se usaba reflexión sin una lista exclusiva de atributos permitidos
  • Condición de carrera cuando varios clientes se conectaban y usaban el mismo usuario
  • Ya no se autorecargan los módulos en tiempo de ejecución (lo cual era catastrófico y lento)

Wiki y documentación:


Wiki: github.com/UltraTesla/UTesla/wiki

TODO:

  • Probarlo en más sistemas unix-like y otros, como Windows.
  • Transferir mucho más rápido los datos de gran magnitud
  • Subirlo a AUR

Bugs:

Al momento de importar un módulo o librería ya sea en un servicio o un «plugin» se necesita asegurar que no ha sido importado anteriormente. Esto se puede saber de la siguiente manera:

Código: (python) [Seleccionar]
import sys
print("<módulo o librería>" in sys.modules)

Para recrear un ejemplo más realista de lo anteriormente mostrado usando una librería fictia llamada "foo":

Código: (python) [Seleccionar]
import sys
print("foo" in sys.modules)

Una incongruencia que estoy tratando de solucionar.

~ DtxdF

8
Cuando realizamos una auditoria o estamos en pleno ataque necesitamos ser rápidos y eficientes, además tener un kit de herramientas que demuestre todo nuestro potencial y conocimiento, el equipo de Error404Security nos trae una distribución que se une para hacer frente a ello. Más de 200 herramientas, eficiencia ante nada, estabilidad y personalización al 100%. Sin duda una distribución que fortalecerá las habilidades de todo pentester.


ReadOS es una distribución basada en Arch Linux diseñada principalmente para la auditoría y seguridad informática en general. Entre lo que destaca podemos mencionar las siguientes categorias con algunas herramientas muy conocidas:

*- Sniffing/Spoofing: Ettercap, Bettercap
*- Explotación: Metasploit-Framework,Yetsinia
*- Redes: Aircrack-NG, Wifiphisher, WiFi-Pumpkin
*- Ingeniería social: Beef-XSS, Delorian, Mydoom
*- MITM: Wireshark, mitmproxy
*- Scanners: Nmap, Nessus (si quiere acceder a la versión paga puede hacerlo manualmente)
*- OSINT: Error404-doxing, Maltego
*- Forense: Volafox, Foremost, Binwalk, Autopsy
*- Aplicaciones web: BurpSuite, OWASP
*- Cracking de contraseñas: John The Ripper, Hashcat, Crunch
*- Ingeniería inversa: Apktool, diStorm3

Solo es un ápice de todo lo que ofrece...


Instalación:

Enlace de descarga: error404security.com/iso/2020-08/ReadOS-i3-2020.08.06-x86_64.iso


Notas:

ReadOS cuenta con los repositorios oficiales de Arch Linux sumando los de la propia distribución. Por defecto no viene con una herramienta para gestionar los paquetes de AUR, aunque si se desea utilizarlo simplemente instalando 'Yay' solucionaría ese inconveniente.

Para facilitar las cosas y conservar mejor nuestro tiempo podemos usar los siguientes comandos para actualizar, instalar y remover paquetes:

*- ins <Nombre del paquete>: Instalar paquetes
*- rem <Nombre del paquete>: Remover paquetes
*- upgrade: Actualizar todo la distribución, incluyendo los paquetes que residen en AUR

Como ejemplo práctico:


Código: (bash) [Seleccionar]
ins yay
El comando anterior instalaría 'Yay' en un par de minutos

Actualización recomendada:

Es recomendable usar el comando 'upgrade' para además de actualizar el sistema, realiza cambios necesarios en la lista de servidores (mirrorlist)

Instalación en una máquina virtual:

Es obligatorio asignarle 2 CPUs o más a la máquina virtual para poder instalar el sistema con éxito, de lo contrario el instalador no se mostraría y a su vez podría acarrear con comportamientos inesperados o de funcionamiento con la distribución.

En el caso de Virtualbox, se recomienda utiizar el controlador VboxSVGA en la configuración 'Display/Pantalla.'

~ DtxdF

9
Hacking / Ataque por diccionario usando UTesla y Erica
« en: Julio 10, 2020, 07:13:14 am »
Un ataque por diccionario es considerado un tipo de ataque contra una contraseña (o una palabra que cause validez) usando una lista de posibles contraseñas, mayormente dado en un fichero de texto o una base de datos gigante. El ataque por diccionario (muchas veces confundido con fuerza bruta) usa una gran lista de contraseñas que pueden ser generadas por un generador automatizado, preferencias de la víctima, o incluso combinarse con la mismísima fuerza bruta para lograr el cometido.


Para saber más sobre Ultra Tesla pueden leer el artículo del mismo foro que hace algunos momentos lo he actualizado para que coincida con el README.md del repositorio. Sin embargo es recomendable que se haga una lectura del repositorio oficial ya que puede haber un cambio reciente que no esté en algún artículo de Internet.

Erica es un script para realizar un ataque por diccionario contra numerosas funciones Hash creado por nuestro compañero @Kirari. Para esta ocasión nosotros adaptaremos Erica para usarlo como un simple servicio en UTesla. Si quieres leer un tutorial sobre el script puedes leer un artículo que está en el mismo foro

Cabe aclarar que UTesla no está diseñado para soportar grandes cantidades de datos, pese a que se esté trabajando para mejorarlo cada día, uno de los muchos objetivos que se tienen en mente, es realizar de una forma diferente, APIs Webs siguiendo un formato no convencional. Para esta demostración usaremos un diccionario pequeño y unas pequeñas configuraciones para que funcione eficientemente


Esquema de la red:

Para este escenario se usarán tres máquinas, pero para que se tenga más rendimiento el plugin 'Erica' contiene un pequeño algoritmo que disminuye la carga "partiendo" el diccionario en mitades de longitud similar para cada parte (las partes son los servidores), incluso el límite de las líneas es un factor a tener en cuenta. Claro que todo esto estará automatizado por un plugin de UTeslaCLI

Comencemos:

Antes que nada, es importante que tengan actualizado (si es que lo tienen instalado, si no, pueden descargarlo) UTesla porque se han hecho varias actualizaciones arreglando errores y mejorandolo. Por lo que si han usado git, simplemente ejecuten:

Código: (bash) [Seleccionar]
git pull origin master
git submodule update --remote

O pueden descargarlo nuevamente, no tendrán que reinstalar las dependencias, así que será menos pesado  ;)

También es importante que usen la versión 3.8 de python, porque el plugin estará usando algunas nuevas sintaxis de ésta.

Si los repositorios de su distribución no tiene incluido la versión 3.8 de python, pueden instalarlo desde la fuente.

Es muy recomendable configurar las claves 'connect_timeout' y 'request_timeout' en la sección 'Client' del fichero 'config/UTesla.ini' según lo que se puede tardar, lo cual es relativo a la velocidad de conexión, la velocidad de procesamiento, la memoria, las líneas del archivos, entre otros.


Instalación del plugin 'Erica':

Debemos comenzar con un pequeño fichero para empezar a crear la estructura, el cual estará ubicado en 'complements/erica.py' con el siguiente contenido:

complements/erica.py:

Código: (python) [Seleccionar]
class Handler:
    pass

Ahora la estructura puede verse como '<Esquema>://<Dirección IP/Host>:<Puerto>/erica'

Por consiguiente necesitamos crear sub-servicios para organizar mejor el esquema, éso se hace creando la siguiente carpeta:


Código: (bash) [Seleccionar]
mkdir complements/erica-folder
Ahí podemos crear nuevos servicios que se verán reflejados como lo siguiente '<Esquema>://<Dirección IP/Host>:<Puerto>/erica/<Sub-servicio>'. Por ejemplo:

complements/erica-folder/get_job.py:

Código: (python) [Seleccionar]
import os
import tempfile
import secrets

class Handler:
    async def get(self):
        id = secrets.token_hex(16)
        workspace = '%s/erica_%s' % (
            tempfile.gettempdir(), id

        )

        os.makedirs(workspace, exist_ok=True)
       
        await self.write(id)

complements/erica-folder/write.py:
Código: (python) [Seleccionar]
import tempfile
import os

class Handler:
    async def post(self):
        wordlist = self.get_argument('wordlist')
        hash = self.get_argument('hash')
        hash_type = self.get_argument('hash_type')
        shake_length = str(self.get_argument('shake_length'))
        id = self.get_query_argument('id')
       
        workspace = '%s/erica_%s' % (
            tempfile.gettempdir(), id
       
        )
        hash_filename = '%s/hash.txt' % (workspace)
        hash_type_filename = '%s/hash_type.txt' % (workspace)
        wordlist_filename = '%s/wordlist.lst' % (workspace)
        shake_length_filename = '%s/shake_length.txt' % (workspace)
       
        response = {
            'error'   : False,
            'message' : None
               
        }

        if (os.path.isdir(workspace)):
            if not (os.path.isfile(hash_filename)):
                with open(hash_filename, 'w') as fd:
                    fd.write(hash)
                    fd.flush()
                    os.fsync(fd)

            if not (os.path.isfile(hash_type)):
                with open(hash_type_filename, 'w') as fd:
                    fd.write(hash_type)
                    fd.flush()
                    os.fsync(fd)

            if not (os.path.isfile(shake_length_filename)):
                with open(shake_length_filename, 'w') as fd:
                    fd.write(shake_length)
                    fd.flush()
                    os.fsync(fd)

            with open(wordlist_filename, 'a', buffering=1) as fd:
                fd.writelines(wordlist)
                os.fsync(fd)

        else:
            response['error'] = True
            response['message'] = 'El identificador de trabajo "%s" no existe' % (id)

        await self.write(response)

complements/erica-folder/crack.py:
Código: (python) [Seleccionar]
import tempfile
import os
import hashlib

def set_status(status, workspace):
    with open('%s/status.txt' % (workspace), 'w') as fd:
        fd.write(status)

def crack(hash, hash_type, wordlist, workspace, shake_length):
    result = False

    if not (hash_type in hashlib.algorithms_guaranteed):
        set_status('No se encuentra la función "%s"' % (hash_type), workspace)
        return

    set_status('running', workspace)

    with open(wordlist, 'r') as fd:
        for word in fd:
            word = word.strip()
            hashfunc = getattr(hashlib, hash_type)(word.encode())

            if (hash_type[:5] == 'shake'):
                hash2cmp = hashfunc.hexdigest(shake_length)

            else:
                hash2cmp = hashfunc.hexdigest()

            if (hash == hash2cmp):
                result = True
                break

    if (result):
        set_status('success:%s' % (word), workspace)

    else:
        set_status('fail', workspace)

class Handler:
    async def get(self):
        id = self.get_query_argument('id')
       
        workspace = '%s/erica_%s' % (
            tempfile.gettempdir(), id

        )
        hash_filename = '%s/hash.txt' % (workspace)
        hash_type_filename = '%s/hash_type.txt' % (workspace)
        wordlist_filename = '%s/wordlist.lst' % (workspace)
        shake_length_filename = '%s/shake_length.txt' % (workspace)

        response = {
            'error'   : False,
            'message' : None
               
        }

        if (os.path.isfile(hash_filename) and os.path.isfile(hash_type_filename) and os.path.isfile(wordlist_filename) and os.path.isfile(shake_length_filename)):
            with open(hash_filename, 'r') as fd:
                hash = fd.read().strip()

            with open(hash_type_filename, 'r') as fd:
                hash_type = fd.read().strip()

            with open(shake_length_filename, 'r') as fd:
                shake_length = int(fd.read())

            self.procs.create(crack, args=(hash, hash_type, wordlist_filename, workspace, shake_length))

        else:
            response['error'] = True
            response['message'] = 'Hay una incongruencia con los archivos del espacio de trabajo'

        await self.write(response)

complements/erica-folder/status.py:
Código: (python) [Seleccionar]
import os
import tempfile

class Handler:
    async def get(self):
        id = self.get_query_argument('id')

        workspace = '%s/erica_%s' % (
            tempfile.gettempdir(), id
           
        )
        response = {
            'error'   : False,
            'message' : None
               
        }

        status_file = '%s/status.txt' % (workspace)

        if (os.path.isfile(status_file)):
            with open(status_file, 'r') as fd:
                response['message'] = fd.read().strip()

        else:
            response['error'] = True
            response['message'] = 'No se puede leer el estado de la operación'

        await self.write(response)

Todos los servicios anteriormente mostrados irían en cada servidor que se desee usar para realizar el ataque por diccionario, quedando de la siguiente forma:

* - <Esquema>://<Dirección IP/Host>:<Puerto>/erica/get_job
* - <Esquema>://<Dirección IP/Host>:<Puerto>/erica/write
* - <Esquema>://<Dirección IP/Host>:<Puerto>/erica/crack
* - <Esquema>://<Dirección IP/Host>:<Puerto>/erica/status

Si parece tedioso repartir cada servicio para cada servidor, hay distintas modalidades. Se puede usar el comando scp para transportar los archivos facilmente, usar un USB al modo tradicional o usar el módulo de python 'http.server' el cual crearía un pequeño servidor web local según donde lo hayamos ejecutado.

Como último archivo que tendría que estar ubicado sólo en nuestra máquina local, sería el cliente para comunicarse con los servicios mostrados anteriormente.

modules/Cmd/erica.py:

Código: (python) [Seleccionar]
import os
import sys
import asyncio
import logging
import hashlib
import tempfile
import sqlite3
import multiprocessing

from modules.Infrastructure import client
from utils.General import parse_config
from utils.extra import create_pool

conf = parse_config.parse()
client_conf = conf['Client']
server_conf = conf['Server']
username = server_conf['user_server']
public_key = server_conf['pub_key']
private_key = server_conf['priv_key']
client.config = client_conf
db_name = '%s/erica.db' % (tempfile.gettempdir())
tmp_wordlist = '%s/erica-wordlist.lst' % (tempfile.gettempdir())

information = {
    'description' : 'Realizar un ataque por diccionario',
    'commands'    : [
        {
            'argumentos principales' : [
                {
                    'args'     : ('-o', '--option'),
                    'help'     : 'El comando a ejecutar en el servidor',
                    'choices'  : ('get_job', 'write', 'crack', 'crack_local', 'status', 'reset'),
                    'default'  : 'get_job'

                }


            ]

        },
       
        {
            'argumentos requeridos por el comando \'write\'' : [
                {
                    'args' : ('-w', '--wordlist'),
                    'help' : 'La lista de palabras a usar'

                }

            ]

        },

        {
            'argumentos requeridos por el comando \'write\' y \'crack_local\'' : [
                {
                    'args'     : ('-H', '--hash'),
                    'help'     : 'La suma de verificación a atacar'

                },

                {
                    'args'     : ('-t', '--hash-type'),
                    'help'     : 'La función hash a usar'

                }

            ]

            },

        {
            'optionals'       : [
                {
                    'args'    : ('-l', '--lines'),
                    'help'    : 'Dividir el archivo en N líneas para cada servidor',
                    'default' : 1000000,
                    'type'    : int

                },

                {
                    'args'    : ('-i', '--interval'),
                    'help'    : 'El intervalo en segundos para comprobar si el trabajo a concluido',
                    'type'    : int,
                    'default' : 15

                },

                {
                    'args'    : ('-m', '--max-workers'),
                    'help'    : 'El máximo de procesos trabajando en la operación localmente',
                    'default' : multiprocessing.cpu_count(),
                    'type'    : int

                },

                {
                    'args'    : ('-L', '--shake-length'),
                    'help'    : 'La longitud del resultado en la función shake y derivados',
                    'default' : 32,
                    'type'    : int

                }

            ]

        }

    ],
    'version'     : '1.0.0'

}

def get_lines(filename):
    count = 0

    with open(filename, 'r') as fd:
        while (line := fd.readline()):
            count += 1

    return count

def crack(args):
    (wordlist, hash, hash_type) = args
    func = getattr(hashlib, hash_type)

    with open(wordlist, 'r') as fd:
        for i in fd:
            i = i.strip()
            hash2cmp = func(i.encode()).hexdigest()

            if (hash2cmp == hash):
                logging.info('Operación concluida localmente: %s (%s(%s))',
                             hash, hash_type.upper(), i)
                return True

        logging.warning('No se pudo satisfacer la operación localmente')

        return False

def chunk(fd, lines, parts):
    chunks = []

    index = 0
    count = 0

    for i in range(parts):
        chunks.append([])

    while (line := fd.readline()):
        if not (line.strip()):
            continue

        if (index == parts):
            index = 0

            yield chunks

            for i in range(parts):
                chunks[i] = []

        chunks[index].append(line)
           
        if (count == lines):
            index += 1
            count = 0

            continue
           
        count += 1

    if (chunks != []):
        yield chunks

def execute_sql_command(cmd, args=(), write=False):
    with sqlite3.connect(db_name) as sqlite_db:
        cursor = sqlite_db.cursor()
        cursor.execute('CREATE TABLE IF NOT EXISTS jobs(job VARCHAR(32) NOT NULL, network TEXT NOT NULL)')
        sqlite_db.commit()

        cursor.execute(cmd, args)

        if (write):
            sqlite_db.commit()

        else:
            return cursor.fetchall()

def getJob(net):
    result = execute_sql_command(
        'SELECT job FROM jobs WHERE network = ? LIMIT 1', (net,)

    )

    if (result != []):
        return result[0][0]

def writeControl(net, response):
    error = response['error']
    message = response['message']

    if (error):
        logging.warning('Ocurrió un error interno en el servidor "%s": %s', net, message)

    else:
        logging.info('Se ha escrito una parte del diccionario en el servidor %s', net)

def jobsControl(net, response):
    execute_sql_command('INSERT INTO jobs(job, network) VALUES (?, ?)', (response, net), True)

    logging.info('El trabajo "%s" se creó en el servidor "%s"', response, net)

def crackControl(net, response):
    error = response['error']
    message = response['message']

    if (error):
        logging.warning('Ocurrió un error interno en el servidor "%s": %s', net, message)

    else:
        logging.info('Se ha iniciado el ataque en el servidor "%s" 3:-)', net)

def statusControl(net, response):
    error = response['error']
    message = response['message']

    if (error):
        logging.warning('Ocurrió un error interno en el servidor "%s": %s', net, message)

    else:
        if (message == 'running'):
            logging.warning('La operación todavía se sigue efectuando')

        elif (message[:7] == 'success'):
            logging.info('Operación realizada con éxito, se ha obtenido la palabra correcta en la lista de palabras almacenada en el servidor "%s": %s', net, message[8:])

        elif (message == 'fail'):
            logging.warning('No se pudo obtener la palabra con éxito usando la lista de palabras almacenada en el servidor "%s" :-(', net)

        else:
            logging.warning('Estado desconocido en el servidor "%s": %s', net, message)

async def execute_command(net, cmd, data, callback, *args, method='POST', **kwargs):
    url = '%s/erica/%s' % (net, cmd)
    url_hash = hashlib.sha3_224(net.encode()).hexdigest()
    pub_key_file = '%s/servkeys/%s' % (
        server_conf['init_path'], url_hash
   
    )

    UClient = client.UTeslaClient(username)

    await UClient.set_user_keys(public_key, private_key)
    await UClient.set_server_key(pub_key_file)
   
    try:
        result = await UClient.fetch(
            url, data, method=method

        )

    except Exception as err:
        logging.warning('Ocurrió en la petición hacia el servidor "%s": %s', url, err)

        response = None

    else:
        response = UClient.get_message(result.body)

    if (response):
        return callback(net, response, *args, **kwargs)

    else:
        logging.warning('No se obtuvo ningún dato por parte del servidor %s...', net)

async def MainParser(args):
    hash = args.hash
    hash_type = args.hash_type
    wordlist = args.wordlist
    lines = args.lines
    interval = args.interval
    max_workers = args.max_workers
    option = args.option
    shake_length = args.shake_length

    db = await create_pool.create(server_conf['mysql_db'])
    networks = await db.get_networks(show_all=True)
    jobs = []
   
    if (option == 'get_job') and (os.path.isfile(db_name)):
        logging.warning('No se puede obtener nuevos trabajas hasta que se haga un reinicio para evitar alteraciones. Use el comando \'reset\' para permitir esta operación')
        return

    if (wordlist is None) and (option == 'write'):
        logging.warning('¡No se definió la ruta del diccionario a usar!')
        return

    if (hash is None or hash_type is None) and (option == 'write' or option == 'crack_local'):
        logging.warning('Falta definir el \'hash\' y/o la función a usar')
        return

    if (option == 'get_job' or option == 'status' or option == 'crack'):
        callbacks = {
            'get_job' : jobsControl,
            'crack'   : crackControl,
            'status'  : statusControl

        }

        for _, net, token in networks:
            data = {
                'token' : token

            }

            job = getJob(net)

            params = {
                'crack'   : '?id=%s' % (job),
                'status'  : '?id=%s' % (job)

            }

            jobs.append(
                execute_command(net, option + params.get(option, ''), data, callbacks[option], method='GET')

            )

    elif (option == 'write'):
        local_machine = '<Local Machine>'
        networks = networks + ((None, local_machine, None),)
        parts = len(networks)

        with open(wordlist, 'r') as fd:
            with open(tmp_wordlist, 'w', buffering=1) as tmp_fd:
                for words in chunk(fd, lines, parts):
                    for (_, net, token), chunk_val in zip(networks, words):
                        if (net == local_machine):
                            tmp_fd.writelines(chunk_val)

                        else:
                            data = {
                                'token'     : token,
                                'body'      : {
                                    'wordlist'  : chunk_val,
                                    'hash'      : hash,
                                    'hash_type' : hash_type,
                                    'shake_length'    : shake_length

                                }

                            }

                            cmd = 'write?id=%s' % (
                                getJob(net)

                            )

                            logging.warning('Escribiendo %d líneas en %s...', len(chunk_val)-1, net)
                            await execute_command(net, cmd, data, writeControl)

    elif (option == 'crack_local'):
        processes = multiprocessing.Pool(max_workers)
        processes.map(crack, [(tmp_wordlist, hash, hash_type)])
        processes.close()
        processes.join()

    elif (option == 'reset'):
        files2del = [
            tmp_wordlist,
            db_name

        ]

        for file in files2del:
            if (os.path.isfile(file)):
                os.remove(file)
                logging.warning('¡%s se ha eliminado!', file)

    await asyncio.gather(*jobs)

Preparando el escenario:

Para comenzar, necesitamos registrarnos en los diversos servidores que deseemos usar, pero la peculiaridad de todo esto es que usaremos el nombre de usuario de nuestro servidor local mas las claves de éste. Como se viene viendo en el primer tutorial de UTesla, para generar el par de claves del servidor se usaría el siguiente comando:

Código: (bash) [Seleccionar]
./UTesla
# Si se desea usar la versión 3.8 de python explícitamente
# python3.8 ./UTesla


Mi par de claves RSA O:)

Aquí lo importante es la clave pública que tendrá que ser transportada en los múltiples servidores que nos registraremos. En las anteriores secciones se explicó cómo transportar dichos archivos.

Una vez estamos en los otros servidores necesitamos ejecutar el siguiente comando para registrarnos:


Código: (bash) [Seleccionar]
./UTeslaCLI add -u utesla -p [email protected] -i /tmp/key.pub

Creando el usuario 'utesla' en Debian Buster


Creando el usuario 'utesla' en AntiX

Una vez se ha registrado el usuario correspondiente sin problemas en los distintos servidores de nuestra red, pasaremos a generar el token de acceso para agregar los servidores a posteriori.


Agregando 'http://192.168.0.1:17000' (Debian Buster) a la red


Agregando 'http://192.168.0.70:17000' (AntiX) a la red

Iniciando el ataque:

Una vez agregada las redes empecemos con el ataque, para ello simplemente ejecutemos:

Código: (bash) [Seleccionar]
./UTeslaCLI erica
./UTeslaCLI erica -w /tmp/wordlist.lst -t md5 -H 9d2b9e517b4c13d92a91472d1d1d4acb -o write -l 30000


Escribiendo un diccionario de 14MB en los servidores


El resultado de haber obtenido la palabra 'dtxdf' a partir de '9d2b9e517b4c13d92a91472d1d1d4acb'

Como ya hizo saber, el diccionario será dividido según las partes y el número de líneas proporcionado, en este se dividirá en tres partes; dos son de los servidores y la tercera es local, almacenada como '/tmp/erica-wordlist.lst'. Si los servidores no pudieron satisfacer la operación, se puede probar el ataque de manera local:


Intento por realizar el ataque de manera local

Como se puede observar se intentó realizar el ataque de manera local con el diccionario dividido, pero fue un intento fallido, aunque lo bueno es que el primer servidor (Debian Buster) si logró satisfacer la operación.

Notas:

* El contenido está hecho con fines demostrativos, en entornos reales y mejor preparados se usaría un cluster con buena maquinaria (en un futuro quizá haga un tutorial 3:-D)
* Tengo que aclarar nuevamente que UTesla aún no está diseñado para transportar grandes cantidades de datos eficientemente, se realizó un pequeño protocolo entre plugin/servicios para enviar por partes el archivo. Ya se está preparando la mejora para enviar cargas grandes con un buen rendimiento
* Espero hayan disfrutado y aprendido tanto como yo lo hice :D


~ DtxdF

10
Un administrador de sistema es el responsable de garantizar tanto el tiempo de actividad, rendimiento, uso de recursos, seguridad, monitorizar, configurar, implementar y muchas otras cosas en un sistema informático. El administrador se debería encargar de todo tipo de seguridad, tanto externa como interna, pero, ¿qué pasaría si el olvidadizo administrador no implementa un sistema de control contra dispositivos USB?...

Esquema SMS

Según la querida wikipedia:

El servicio de mensajes cortos o servicio de mensajes simples, más conocido como SMS (por las siglas del inglés Short Message Service), es un servicio disponible en los teléfonos móviles que permite el envío de mensajes cortos (con un límite de caracteres) entre teléfonos móviles. Por lo general las operadoras telefónicas cobran por cada mensaje enviado.

Una vez aclarado qué son los famosos SMS, imaginemos una situación en la que el administrador de sistemas protege con ímpetu cada sistema informático presente en una empresa, desde base de datos, hasta servidores convencionales, desde implementar sistemas de detección de intrusos hasta empezar a crear listas blancas, vigilar la tasa de paquetes y mucho más, pero... ¿qué pasaría si se le olvidara implementar un control contra dispositivos USB?.

Herramientas

Ya se ha aclarado que usaremos SMS para enviar comandos y recibir los resultados, pero ahora necesitamos saber las herramientas:

  • Un modem-USB (en mi caso un Bam Movistar): Será el que deberá estar conectado a la máquina víctima
  • Un sencillo programilla que está hecho para esta prueba de concepto: Será el encargado de enviar y recibir datos por medio del dispositivo

Descarga, configuración y compilación

Código: (bash) [Seleccionar]
git clone https://github.com/DtxdF/Spactra.git
cd Spactra
$EDITOR headers/info.h

Una vez descargado y hemos abierto el fichero de configuración, lo primordial sería solo configurar el número de teléfono del atacante (o sea el nuestro 3:D), aunque por los demás datos necesitaríamos hacer una investigación de acuerdo a las limitaciones de nuestro modem:

nvim headers/info.h

Una vez ajustado el número de teléfono del atacante, se debe pasar a la compilación:

Código: (bash) [Seleccionar]
gcc -O2 -o spactra spactra.c modem_control.c system_control.c -ggdb -Wall -pipe
Prueba de concepto

Ahora lo que el atacante debería hacer es introducir el modem-USB en la máquina que desea comprometer y ejecutar 'spactra', aunque ahí no acaba la cosa.

El puesto de control del atacante debe ser su propio teléfono y la aplicación, una aplicación típica de Android (por ejemplo) donde pueda recibir y enviar mensajes de texto. Pero qué mejor forma de decirlo que con una ilustración:


sudo ./spactra

Centro de mensajes de texto en Android

Ejecutando el comando 'id' remotamente

Notas

  • El programa está hecho para esta prueba de concepto, por lo que puede contener errores, no está hecho para situaciones reales o no mantiene una estabilidad con las respuestas a los comandos AT
  • Todas las pruebas se realizaron en Arch Linux
  • Espero les haya gustado  ;)

Conclusión

Aunque haya sido un artículo corto, espero les haya gustado y para concluir directamente, es recomendable mantener un control sobre los periféricos de nuestros equipos, implementar un pequeño sistema que informe cuando se inserta uno nuevo e inclusive, permitir a determinados usuarios que pertenezcan a un grupo para restringir el mismo uso.

~ DtxdF

11
Ultra Tesla es un proyecto de código abierto para crear redes distribuidas de servicios fácil, rápido y seguro, usando el poder de computo de múltiples ordenadores. El proyecto permite unificar los distintos servidores en una única interfaz que es proporcionada para el mismo usuario creando una sensación de transparencia.


Mi primer "Hello World":

Ultra Tesla utiliza servicios, que son básicamente mini-programas que se adhieren a la ejecución del servidor, siguiendo una sintaxis en HTTP como la siguiente: <scheme>://<netloc>/<Service>/<Sub-Service>/<...>

Donde <scheme> es 'http' o 'https' según la configuración del servidor; <netloc> es básicamente la dirección del servidor; <Service> es el nombre del servicio, que para este ejemplo será "hello_world" y los demás que son <Sub-Service> y <...> son básicamente otros mini-programas que se tendrán que usar anteponiendo el nombre del servicio anterior, por ejemplo, <Service>/<Sub-Service>/<Sub-Service 1>/<Sub-Service 2>/<...> y así según lo que el administrador haya propuesto.


Código: (python) [Seleccionar]
class Handler:
    async def get(self):
    await self.write('Hello World!')

Un ejemplo real con el servicio nombrado como complements/hello_world.py en una URL se vería como lo siguiente (suponiendo que la dirección del servidor sea localhost): http://localhost:17000/hello_world

Contactando al servidor:

Lo siguiente es un script simple para poder contactarse con el servidor y obtener la salida del servicio 'hello_world'

Código: (python) [Seleccionar]
import asyncio

from modules.Infrastructure import client

async def main():
    UTeslaClient = client.UTeslaClient('<Nombre de usuario>')
    await UTeslaClient.set_server_key('<Clave pública del servidor>')
    await UTeslaClient.set_user_keys('<Clave pública del usuario>', '<Clave privada del usuario>')

    cmd = {
        'token' : '<Token de acceso>'

    }

    Response = await UTeslaClient.fetch(
        'http://localhost:17000/hello_world',
        cmd,
        method='GET'

    )

    dec_body = UTeslaClient.get_message(Response.body)

    print(dec_body)

if __name__ == '__main__':
    asyncio.run(main())

Deberíamos obtener la siguiente respuesta:

Código: (text) [Seleccionar]
Hello World!
Creando un usuario:

El administrador será el encargado de crear los usuarios, aunque perfectamente se podría automatizar como un sistema de registro cualquiera con una interfaz de usuario cualquiera, para este ejemplo se usará el plugin 'add' de UTeslaCLI.

Código: (bash) [Seleccionar]
# Para requerir ayuda
./UTeslaCLI add --help
# Creamos el usuario
./UTeslaCLI add -u <Nombre de usuario> -p <Contraseña> -i <Ruta de la clave pública>

Creación del par de claves:

Tanto el servidor como el usuario deben tener sus par de claves para que la comunicación sea satisfactoria. Esto es un proceso inicial que deben hacer antes de hacer cualquier cosa (independientemente de si es un usuario o el administrador del servidor).

En el cliente:

El cliente va a requerir usar el plugin 'generate_keys' para la creación del par de claves

Código: (bash) [Seleccionar]
# Para requerir ayuda
./UTeslaCLI generate_keys --help
# Generamos el par de claves
./UTeslaCLI generate_keys -bit_size <Tamaño del par de claves en bits> -out-public-key <Nombre del archivo de la clave pública> -out-private-key <Nombre del archivo de la clave privada>

Si se ejecuta sin parámetros se generará con un tamaño de claves por defecto de 3072 bit's y las claves se mostrarán en la salida. Lo recomendable sería dejar el tamaño de claves pre-determinado y guardar el par de claves en un lugar seguro.

Ahora lo que tendría que hacer el usuario que desea registrarse es enviar la clave pública al administrador del servidor para que éste lo registre satisfactoriamente.


En el servidor:

El proceso para generar el par de claves en el lado del servidor será mucho más simple; se hará automáticamente cuando se ejecute.

Código: (bash) [Seleccionar]
./UTesla
El tamaño del par de claves estará definido en UTesla.ini, en la sección 'Crypt Limits' y en la clave 'rsa_key_length'.


Lo recomendable es dejar el tamaño de claves pre-determinado tanto del lado del cliente y del servidor, y se debe tener en cuenta que el tamaño de claves debe ser igual o equivalente en las dos partes.

Creación del token de acceso:

UTesla requiere de un token de acceso para realizar la mayoría de acciones, en este caso el cliente deseoso por obtener su token tiene que usar el plugin 'generate_token'

Código: (bash) [Seleccionar]
./UTeslaCLI generate_token <La URL del servidor> -u <El nombre de usuario> -p <La contraseña del usuario> -s <La clave pública del servidor> -i <La clave pública del usuario> -I <La clave privada del usuario>
Una vez hecho lo anterior y la petición haya sido satisfactoria, se mostrará el token de acceso, el cual debe ser almacenado en un lugar seguro para su posterior uso.

Uso de la distribución de servicios:

Supongamos que en el mundo haya dos servidores y los administradores se conozcan, uno de éstos contiene uno o más servicios que otro no tiene, pero un cliente que requiera el uso de ese servicio usando la URL del primer servidor (por ejemplo) no tendría ningún inconveniente, ya que si el servicio deseado no se encuentra en el primer servidor, éste hará una búsqueda en la red y determinará qué servidor es el que contiene ese servicio, posteriormente obtendría una respuesta como si fuera el mismo cliente y luego la redirige hacia el cliente mismo, por lo que todo sería transparente.

Lo anterior es muy útil si se desea separar ciertos servicios entre servidores, por cuestiones económicas, de recursos, una mejoría en la implementación o cualquier cosa que se desee, al fin y al cabo, el usuario es el que lo decide.

Para estos ejemplos el primer servidor será 'http://localhost:17000' y el segundo 'http://localhost:17001'. El segundo tiene un servicio llamado 'hello_friend', pero nosotros "los clientes" vamos a creer que el servicio está en el primer servidor, por lo cual lo usaremos para interactuar con éste.


complements/hello_friend.py:
Código: (python) [Seleccionar]
class handler:
    async def get(self):
        await self.write('hello friend!')

Por diseño, el administrador del segundo servidor debe crear un usuario como si fuera cualquier otro. Por lo que debe saber cómo crearlo, cosa que ya se hablo en anteriores secciones. En este caso nosotros lo llamaremos 'utesla'.

Además, como ya se aclaró en anteriores secciones, la mayoría de operaciones requieren de un token de acceso, por lo se va a suponer que se tiene hecho este paso para el nuevo usuario utesla.

Una vez aclarado todo lo que se tiene que hacer, vamos un paso más allá y obtengamos los servicios del segundo servidor (http://localhost:17001) para el primer servidor (http://localhost:17000)


Código: (bash) [Seleccionar]
./UTeslaCLI add_network http://localhost:17001 -s <Clave pública del segundo servidor> -p keys/key.pub -P keys/key.priv -u utesla -t <Token de acceso>
Como esto es un ejemplo, se usan las claves que por defecto se almacenan en la carpeta 'keys' del primer servidor; se usa el usuario 'utesla' que ya debe estar creado en el segundo servidor y nos contactamos con el servidor 'http://localhost:17001' para obtener sus servicios.

Como paso final, el cliente desea obtener el servicio 'hello_friend' y si todo ha salido bien, obtendrá su posterior salida, aunque lo peculiar de todo esto es que el cliente hará una petición al primer servidor en vez de al segundo.

Lo siguiente será muy parecido a lo que se observó en anteriores secciones, pero lo único que cambió es el nombre del servicio:


Código: (python) [Seleccionar]
import asyncio

from modules.Infrastructure import client

async def main():
    UTeslaClient = client.UTeslaClient('<Nombre de usuario>')
    await UTeslaClient.set_server_key('<Clave pública del servidor>')
    await UTeslaClient.set_user_keys('<Clave pública del usuario>', '<Clave privada del usuario>')

    cmd = {
        'token' : '<Token de acceso>'

    }

    Response = await UTeslaClient.fetch(
        'http://localhost:17000/hello_friend',
        cmd,
        method='GET'

    )

    dec_body = UTeslaClient.get_message(Response.body)

    print(dec_body)

if __name__ == '__main__':
    asyncio.run(main())

Deberíamos obtener la siguiente respuesta:

Código: (text) [Seleccionar]
Hello Friend!
Como se puede apreciar, es un proceso muy sencillo y lo mejor, es transparente para el usuario.

Sub servicios:

Ya se ha explicado anteriormente qué son los sub servicios, pero no se han explicado cómo crearlos. Al igual que la creación de plugins y servicios es muy sencillo.

Lo primero que hay que hacer es crear un servicio, como 'greeting' (complements/greeting.py).


Código: (python) [Seleccionar]
class Handler:
    pass

Se pueden colocar los métodos HTTP si se desea, pero para este caso no lo necesitamos

Ahora para la creación de sub servicios simplemente se crea una carpeta en 'complements' con el mismo nombre del servicio mas '-folder'.


Código: (bash) [Seleccionar]
mkdir complements/greeting-folder
En esa carpeta se tienen que agregar más archivos que sigan una estructura similar a la del servicio padre, como por ejemplo:

complements/greeting-folder/hello_friend.py:
Código: (python) [Seleccionar]
class Handler:
    async def get(self):
        await self.write('Hello Friend!')

Ahora un cliente puede hacer una petición usando una URL parecida a: <Scheme>://<netloc>/greeting/hello_friend y obtendría:

Código: (text) [Seleccionar]
Hello Friend!
Adentro de esa carpeta se crean más carpetas (si se desea), pero lo peculiar de todo esto es que no necesitan usar una sintaxis similar a "<Nombre del servicio>-folder", simplemente creando una carpeta e insertando nuevos servicios que sigan una estructura similar a los anteriores es más que suficiente.

Código: (bash) [Seleccionar]
mkdir complements/greeting-folder/farewell
complements/greeting-folder/farewell/bye.py:
Código: (python) [Seleccionar]
class Handler:
    async def get(self):
        await self.write('Bye!')

Y el cliente puede usar una estructura similar a: <scheme>://<netloc>/greeting/farewell/bye

Módulos:

Los módulos son muy útiles en caso de que se necesite integrar ficheros de python a los complementos, para que la escritura sea más limpia y siga mejores prácticas.

Para crear un módulo es necesario crear primero un servicio, en este caso 'math' (complements/math.py)


Código: (python) [Seleccionar]
class Handler:
    async def post(self):
        sum = self.modules.get('sum')
        num1 = self.get_argument('num1', 0)
        num2 = self.get_argument('num2', 0)

        await self.write('Result:' + str(sum.calculate(num1, num2)))

Ahora se debe crear una carpeta con el nombre del servicio mas '-modules' y ahí se agregan ficheros de python como cualquier otro; siguiendo lo que necesita el código anterior:

complements/math-modules/sum.py:

Código: (python) [Seleccionar]
def calculate(x, y):
    return x + y

Eso sería todo, muy sencillo y más modular.

Instalación:

Código: (bash) [Seleccionar]
git clone --recursive https://github.com/UltraTesla/UTesla.git
cd UTesla

Arch Linux:

Código: (bash) [Seleccionar]
sudo pacman -S mariadb
Debian:

Código: (bash) [Seleccionar]
sudo apt-get install mariadb-server libmariadb-dev python3-dev
Red Hat Enterprise Linux 8.2

Código: (bash) [Seleccionar]
sudo yum install python3-devel gcc mariadb mariadb-server mariadb-devel
General:

Código: (bash) [Seleccionar]
sudo systemctl start mariadb.server
python3 -m pip install -r requirements.txt
./UTesla

Es recomendable configurar primero antes de iniciar UTesla (como el nombre de usuario y la contraseña en MySQL)

Contribuyendo:

Al igual que cada proyecto nuevo creado, soy imperfecto y puedo equivocarme, pero con todo el gusto del mundo aceptaré tu contribución, ya sea por código o no, porque hay que recordar que se trata de abarcar muchos idiomas de distintas regiones del mundo y en éso puede haber múltiples defectos.

Notas:

  • No se ha probado en Windows u otro sistema operativo
  • El proyecto usa un protocolo propio y no uno estándar
  • El proyecto no está definido, de eso se encarga el mismo usuario
  • Todo el proyecto fue probado en la versión 3.8.2 y 3.7.3 de python

~ DtxdF

12
La red Tor, esa fascinante red que nos provee una capa extra de seguridad en nuestras comunicaciones. Una red capaz de evadir la censura más torturadora para una persona que reside en un país donde la libertad de expresión es nula o inimaginable. Tor (siglas de The Onion Router), es un proyecto cuyo principal objetivo es desarrollar una red distribuida de baja latencia, superpuesto sobre Internet donde el encaminamiento de mensajes no revela la identidad del usuario.


Un Tor-AP (The Onion Router Access Point), es un sencillo script para la creación de un punto de acceso inalámbrico con el fin de dirigir todas las conexiones a la red Tor, segurizando así nuestra integridad.

Importante: Recuerde siempre usar conexiones cifradas y seguras para evitar filtrado de datos ya sea por una vulnerabilidad en la misma red o en el nodo de salida.


Herramientas:

Las herramientas que usaremos para estos fines, serán las siguientes:

Requeridas:

  • tor: El software que creará el proxy transparente y nos permitirá segurizar nuestras conexiones
  • iptables (o la herramienta que controla nuestro firewall): El arma secreta de todo este plan lujurioso

Opcionales:

  • nyx: El monitor de la red Tor
  • dnsmasq (o un servidor DHCP y DNS): El que proporcionará una dirección IP a los clientes y resolverá los nombres de dominio a direcciones IP
  • hostapd: El que creará el AP en nuestro dispositivo

Instalación de dependencias:

Código: (bash) [Seleccionar]
#Requeridos
# Debian
sudo apt-get install tor
# Arch Linux
sudo pacman -S tor

#Opcionales
# Debian
sudo apt-get install dnsmasq dnsmasq-base nyx hostapd
# Arch Linux
sudo pacman -S dnsmasq nyx hostapd

Requerimientos de hardware:

Esta sección es especial, ya que depende de qué queramos o qué tengamos en nuestras manos para ampliar un poco la red.


  • Modo AP en nuestra tarjeta de red inalámbrica: Por si queremos crear un punto de acceso
  • Cables ethernet's y switches (o parecido): En caso de queramos crear la red en LAN en vez de WLAN, aunque pueden crear las dos infraestructuras.
  • Un modem: En mi caso un Modem USB, pero ustedes pueden usar el mismo que les ayuda a leer esto.

Creación:

Quiero aclarar que hace un par de semanas estaba jugando con iptables y tor y me propuse a crear un proxy transparente en mi propia laptop, nada del otro mundo; me puse a investigar para ver si alguien ya había hecho éso, y para mi suerte lo hizo mucho mejor. El usuario hasta tiene un repositorio llamado "tor-router".

Luego de leer un poco su código, quise agregarle y quitarle un par de líneas (que considero necesarias e innecesarias), también para no perder la conexión con otros equipos (en caso de de crear una red LAN/WLAN).

Aclarado lo anterior, aquí está el código:


Código: (bash) [Seleccionar]
#!/usr/bin/env sh

# Ya explicaré como obtener el ID de usuario para la variable TOR_UID
TOR_UID="<El identificar del usuario de tor>" # El Identificador de usuario de Tor
NON_ROUTE="127.0.0.1/8" # Los destinos que no desea enrutar a través de Tor
LOCAL_DNS=53 # El puerto DNS local, por defecto es '53'

# Esta parte se explicará mejor en la configuración de Tor
L_TOR_DNS=5353 # El puerto DNS de Tor para la máquina local
L_TRANS_PORT=9040 # El puerto del proxy transparente para la máquina local

R_TOR_DNS=5354 # El puerto DNS de Tor para las máquinas remotas (como los clientes conectados en LAN/WLAN)
R_TRANS_PORT=9041 # El puerto del proxy transparente para las máquinas remotas

iptables --flush
iptables --table nat --flush

iptables --table nat --append OUTPUT --match owner --uid-owner $TOR_UID --jump RETURN
iptables --table nat --append OUTPUT --protocol udp --dport $LOCAL_DNS --jump REDIRECT --to-ports $L_TOR_DNS
iptables --table nat --append PREROUTING --protocol udp --dport $LOCAL_DNS --jump REDIRECT --to-ports $R_TOR_DNS

for NET in $NON_ROUTE;do
        iptables --table nat --append OUTPUT --destination $NET --jump RETURN

done

iptables --table nat --append OUTPUT --protocol tcp --syn --jump REDIRECT --to-ports $L_TRANS_PORT
iptables --table nat --append PREROUTING --protocol tcp --syn --jump REDIRECT --to-ports $R_TRANS_PORT

Sobre la variable "TOR_UID", es el identificador del usuario de Tor (ya que el software Tor tiene un usuario). Para obtenerlo se hace lo siguiente:

Código: (bash) [Seleccionar]
# Para distribuciones basadas en Debian:
id -u debian-tor
# Para distribuciones basadas en Arch Linux o que tenga el mismo nombre de usuario:
id -u tor

El valor resultante es un número, el cual es el identificador de usuario del software Tor. En mi caso:


El valor (en mi caso) es '111' por lo que el valor de 'TOR_UID' es:

Código: (bash) [Seleccionar]
TOR_UID=111
Quedando de la siguiente manera:


Lo que tenemos que hacer, es darle permisos de ejecución una vez guardado los cambios:

Código: (bash) [Seleccionar]
chmod +x ./tor-ap
Ahora pasemos a la configuración de Tor (en /etc/tor/torrc):

Código: (text) [Seleccionar]
ControlPort 9051 # Opcional, es para que nyx se comunique con el controlador de tor
# Cuando Tor necesita asignar una dirección virtual (no utilizada) debido a un comando MAPADDRESS del controlador o la función AutomapHostsOnResolve, Tor elige una dirección no asignada de este rango. Más en 'man 1 tor'.
VirtualAddrNetwork 10.192.0.0/10
# Cuando esta opción está habilitada y recibimos una solicitud para resolver una dirección que termina con uno de los sufijos en AutomapHostsSuffixes, asignamos una dirección virtual no utilizada a esa dirección y devolvemos la nueva dirección virtual. Esto es útil para hacer que las direcciones ".onion" funcionen con aplicaciones que resuelven una dirección y luego se conectan a ella. Más en 'man 1 tor'
AutomapHostsOnResolve 1

#En las siguientes 'secciones' se asigna la dirección predeterminada (127.0.0.1) en la primera, mientras que en la segunda se asigna la dirección '0.0.0.0', con puertos diferentes (así es como funciona).

# Para el loopback
TransPort 9040 # El puerto del proxy transparente
DNSPort 5353 # El puerto del servidor DNS UDP de Tor

# Para la dirección no especificada
TransPort 0.0.0.0:9041
DNSPort 0.0.0.0:5354

Ejecución básica:

En esta sección veremos lo más básico de este tutorial: Hacer una prueba básica en nuestra misma máquina:

Código: (bash) [Seleccionar]
sudo -u debian-tor tor # si usas debian; si usas otro (como Arch Linux) el usuario es 'tor'; si usas otra distribución haz una investigación simple para saber cuál es el nombre del software 'tor'. Un pequeño comando que quizá le ayude a alguien: 'cat /etc/passwd | grep -i tor | cut -d':' -f1'.
sudo ./tor-ap # OJO, ya tienen que tener tor en ejecución, ya sea el daemon o el ejecutable en sí.
curl -i http://ip-api.com/json

La ilustración del resultado:


Ejecución avanzada:

Una vez visto los principios básicos para configurar el enrutamiento hacia tor, vamos a crear el punto de acceso con el fin de compartir la conexión.

Primero lo primero, configuremos algunas cosas de dnsmasq:


Código: (text) [Seleccionar]
domain-needed # Los navegadores antiguos tenían una barra que era específica para las búsquedas en los buscadores, pero el usuario por ignorancia usaba la que era para los dominios, lo que provocaba que se perdiera tiempo resolviendo dominios inexistentes, lo que acarreaba en una respuesta DNS "NXDOMAIN". Con esta instrucción se evita eso (aunque los navegadores actuales ya solucionarón ese inconveniente), pero me refiero a los antiguos.
bogus-priv # Evitar que se haga una consulta dns inversa a una dirección local o en el espacio de direcciones
no-resolv # No usar el fichero 'resolv.conf'
# Usar los siguientes nameservers
server=1.1.1.1
server=1.0.0.1
# Configuramos el DHCP para asignar el rango de direcciones en 24h(oras) en las interfaces wlp2s0b1 (la de mi tarjeta de red inalámbrica) y enp1s0f0 (la de ethernet).
# wlp2s0b1 tendrá el siguiente rango: 192.168.0.2 a 192.168.0.254, mientras que el punto de acceso (nosotros) tendrá la dirección 192.168.0.1
# enp1s0f0 tendrá el siguiente rango: 10.42.0.2 a 10.42.0.254, mientras que la máquina local tendrá la siguiente dirección 10.42.0.1
# Nota-1: Tienen que usar sus propias interfaces.
# Nota-2: Recuerden que su tarjeta de red inalámbrica debe admitir el modo AP para que lo puedan crear
dhcp-range=wlp2s0b1,192.168.0.2,192.168.0.254,24h
dhcp-range=enp1s0f0,10.42.0.2,10.42.0.254,24h
# Registramos las consultas y demás (opcional, pero recomendable para la depuración)
log-queries
log-dhcp
log-facility=/var/log/dnsmasq.log

Ahora se asigna las direcciones IPs:

Código: (bash) [Seleccionar]
sudo ip a add 192.168.0.1/24 dev wlp2s0b1
sudo ip a add 10.42.0.1/24 dev enp1s0f0

Quiero aclarar que dnsmasq es un daemon, pero para esta demostración y depurar un poco, mejor veamos las consultas que hacen los clientes, tanto DHCP con DNS.

Código: (bash) [Seleccionar]
# Desactivamos el servicio
sudo systecmtl stop dnsmasq.service
# Si no tienen systemctl, y usan SysV
sudo service dnsmasq stop

Ahora ejecutamos dnsmasq:

Código: (bash) [Seleccionar]
sudo dnsmasq -d -C /etc/dnsmasq.conf
# -d = No ejecutar en segundo plano
# -C = Especificar el archivo de configuración


Hasta aquí todo bien, ahora podemos conectar una PC (por ejemplo), usando ethernet al mini-router que estamos haciendo, asignarnos una dirección IP por medio de nuestro servidor DHCP y probamos nuevamente preguntando nuestros datos:


Expandiendo los horizontes...

Muy bien, hemos llegado sanos y salvos a esta sección, por lo que aumentemos un poco más la "dificultad". Creemos un punto de acceso  ;D

Para lograr nuestro cometido debemos configurar 'hostapd':


Código: (bash) [Seleccionar]
sudoedit /etc/hostapd/hostapd.conf
Código: (bash) [Seleccionar]
ssid=DtxdF # El nombre de mi red (¿Original? ¿No?)
channel=5 # El canal
hw_mode=g # Esta opción y la compatibilidad con 'N' (la veremos más abajo) depende de su tarjeta y significa la tecnología que admite su tarjeta
auth_algs=3 # 1=WPA; 2=WEP; 3=Ambos
ieee80211n=1 # Compatibilidad con la tecnología 'IEEE 802.11n'
wmm_enabled=1 # QoS
interface=wlp2s0b1 # La interfaz de la tarjeta de red inalámbrica
wpa=2 # La versión 2 de WPA
[email protected] # Una contraseña super segura
rsn_pairwise=CCMP # (AES) Counter Mode CBC-MAC Protocol

Lo ejecutamos:

Código: (bash) [Seleccionar]
sudo hostapd /etc/hostapd/hostapd.conf

Conclusión:


Ahora sabemos cómo crear un Tor-AP para agregar una capa de seguridad a nuestras conexiones, sin necesidad de configurar el navegador o el software que desea conectarse a Internet, sin anteponer un programa que remplaze funciones internas que crean incompatibilidades (como tsocks), sin limites, nada más que la imaginación...

Por cierto, para monitorear los circuitos, podemos usar nyx:


Código: (bash) [Seleccionar]
nyx -i 9051
~ DtxdF

13
GNU/Linux / DWM: ¡Un Window Manager de apenas 2149 líneas!
« en: Abril 24, 2020, 04:51:58 am »
Cuando hablamos de un Window Manager (Manejador de Ventanas, en español), no referimos de ese componente del sistema que proporciona al usuario una Interfaz gráfica de usuario (GUI, por sus siglas en Inglés). Pese a que la elección en su mayoría es el Entorno  de Escritorio, Un WM tiene muchas más ventajas en cuanto al ahorro de tiempo y recursos.


Fuente oficial: dwm.suckless.org

DWM (Dynamic Window Manager), es un administrador de ventanas dinámico para X, éste puede controlar la forma en que se expresan las ventanas en tiempo de ejecución de forma arbitraria según lo decida el mismo usuario. DWM, puede aplicar el diseño con los siguientes métodos:

  • Stacking (conocidos también como flotantes): Este gestor de ventanas representan un símil del escritorio tradicional del que venimos viendo en Sistemas Operativos como Windows y OS X. Éstos apilan cada ventana una delante de otra dando el aspecto a varias hojas de papel unidas.
  • Tiling (conocidos también como de tipo mosaico): Éstos no superponen las ventanas al contrario de su hermano anterior, además de que usan un catalogo extendidos de atajos en el teclado ahorrando más tiempo (e incluso recursos). Los gestores de ventanas tipo tiling se nota la exclusividad del uso del teclado, mientras que el ratón ya es opcional.
  • Dynamic: Es el caso de DWM que permite alternar entre tipo "Stacking" o "Tiling" a decisión del usuario.

Una vez aclarado los aspectos principales para adentrarnos más en estos mundos, pasemos a la práctica...

Descarga:

Antes que nada, debemos tener instalado 'git', 'gcc' y 'make' para poder clonar el repositorio e instalar todo parsimonioso:

Debian y derivados:


Código: (bash) [Seleccionar]
sudo apt-get install git build-essential
O en caso de no tener 'sudo' instalado

Código: (bash) [Seleccionar]
su
apt-get install git build-essential

Archlinux y derivados:

Código: (bash) [Seleccionar]
sudo pacman -S git gcc make
O en caso de no tener 'sudo' instalado

Código: (bash) [Seleccionar]
su
pacman -S git gcc make

Ahora clonamos el repositorio:

Código: (bash) [Seleccionar]
git clone http://git.suckless.org/dwm
cd dwm

Tutorial:

Quiero aclarar que este tutorial está enfocado a los usuarios noveles, los que desean aprender más sobre estos mundillos tan hermosos y llenos de libertad. Pese a que tocaremos código en C, trataré de no hacer mención de qué significa cada cosa, en su lugar dejaré textos enlazados a los conceptos para no embotar el tema principal y dedicarme a la configuración y uso de DWM.


Una vez hemos descargado DWM, pasemos a la configuración, pero antes necesitaremos instalar un lanzador de aplicaciones. Tenemos dos opciones: dmenu ó rofi (mi preferido).

Instalación en Archlinux y derivados:

Código: (bash) [Seleccionar]
# dmenu
sudo pacman -S dmenu
# rofi
sudo pacman -S rofi

Instalación en Debian y derivados:

Código: (bash) [Seleccionar]
# dmenu
sudo apt-get install suckless-tools
# rofi
sudo apt-get install rofi

Esos programas nos van a permitir poder ejecutar aplicaciones (estilo un menú de un Entorno de Escritorio, pero será invocado cuando deseemos).

En el caso de Debian a mí me faltaron instalar algunas dependencias, pero para Arch no fue el caso. Instalación de las depencias en Debian:

Código: (bash) [Seleccionar]
sudo apt-get install libx11-dev libxinerama-dev
Importante: Si faltaron mencionar dependencias o en el caso de Arch, te faltaron dependencias, hazmelo saber para editar este documento y mencionarlas, todos te lo agradeceríamos.

Ahora viene la parte buena, la configuración.

Para configurar DWM necesitamos abrir el archivo config.def.h con nuestro editor de texto preferido, En mi caso usaré Vim:

Código: (bash) [Seleccionar]
vim config.def.h

Comandos que se ejecutarán por defecto

Entre la línea 59-60 estarán los comandos que serán ejecutados por DWM y en unos momentos los empezaremos a cambiar.


Combinaciones del teclado

Entre la línea 62-97 encontraremos un listado de combincaciones del teclado. Mientras que en la imagen se aprecia tres dialogos de texto con unas flechas rojas, esas flechas específican lo siguiente:

  • Las primeras combinaciones: Con las "Primeras Combinaciones" me estoy refiriendo a las primeras teclas que llamarán a la variable. En la imagen apreciamos una Constante llamada MODKEY, ésa será la tecla principal y por defecto es "ALT" (más tarde veremos como cambiarla).
  • Las segundas combinaciones: Son las segundas teclas que usaremos, por ejemplo, si en la primera combinación se tiene solamente "MODKEY" (ALT) y en la segunda "XK_p", entonces sería básicamente "ALT+p"
  • La variable: Será el nombre que le pusimos en la imagen uno, a los comandos.

Agrego: también notamos que hay una extraña combinación de las "Primeras Combinaciones" en la fila dos, usando el carácter "Barra vertical". Éso se llama Operador OR, pero vamos a verlo mejor como un carácter para combinar teclas.

Agregando programas y combinaciones de teclas:

En la sección anterior pudimos entender un poco DWM, pero en esta sección aprenderemos a agregar programas con sus respectivas combinaciones de teclas. Comencemos.

Volvemos a las líneas 59-60 y modificamos la línea 59 sólo sí se desea cambiar dmenu por rofi (como fue mi caso). Quedando así:



dmenu cambiado a rofi

Cabe notar que cada vez que agregamos un comando necesitamos seguir la siguiente sintaxis:

Código: (c) [Seleccionar]
static const char *<nombre de la variable>[] = { "<programa>", NULL };
// o
static const char *<nombre de la variable>[] = { "<programa>", "<parámetro 3>", "<parámetro 2>", NULL };

Nota #1: Los signos '<' (menor qué) y '>' (mayor qué) no los usen, simplemente estoy indicando qué es lo que tienen que remplazar.
Nota #2: Los parámetros del programa pueden ser tantos como éste los requiera y deben ir separados por una ',' (coma) y entrecomillados.
Nota #3: Se debe colocar 'NULL' al final de la Cadena para indicar la finalización del array de caracteres.

Otra cosa, es modificar la Consola a ejecutar, que en mi caso será "URXVT":



URXVT

Compilamos:

Ahora para que nuestra configuración sea efectiva necesitamos copiar 'config.def.h' a 'config.h'. OJO, no es mover, sino copiar en la misma ruta:

Código: (bash) [Seleccionar]
cp -v config.def.h config.h
Antes de compilarlo, abrimos 'config.mk' y modificamos la última línea (la 38, para especificar). Cambiamos el valor de la MACRO 'CC', de 'cc' a 'gcc':


CC a GCC

Estamos cambiando el Compilador nativo a el Compilador GNU de C del GCC para evitar problemas, aunque no es necesariamente cierto lo que dije, ya que puede que compile perfectamente, pero para evitar incongruencias lo cambiamos. También puede que 'cc' sea un Enlace Simbólico a 'gcc', pero ya estas palabras se salen del tema.

Y por último, compilamos con las opciones que hemos hecho:


Código: (bash) [Seleccionar]
sudo make clean install

DWM compilado con éxto

Si no tenemos errores, tenemos compilado y listo para ser usado. Pero ahora falta un proceso más para poder usar DWM. Vamos a denominarlos: Método fácil y Método difícil.

Sobre el método fácil vamos a crear un archivo llamado ".xinitrc" en "$HOME" (nuestra carpeta de usuario) en el cual vamos a insertar el siguiente código:


Código: (bash) [Seleccionar]
exec dwm
Luego de hacer lo anterior, iniciamos las Xs e iniciando DWM ejecutando:

Código: (bash) [Seleccionar]
startx

Mi DWM con modificaciones :-)

Quiero aclarar que cuando hagan todo esto por primera vez, no verán ningún fondo de pantalla, todo estará en negro, pero daré la explicación de cómo cambiar el fondo de pantalla en la sección 'avanzado'. Y por cierto, también verán una barra que indica los 'tags' de DWM.

Sobre el método "difícil", ya depende de nuestro gestor de sesiones, por suerte la mayoría de gestores los aceptaran (hablo del estándar de freedesktop.org), que en mi caso será LightDM. Lo único que debemos hacer es crear un "Archivo de Entrada de Escritorio" que irá ubicado en '/usr/share/xsessions':


Código: (text) [Seleccionar]
[Desktop Entry]
Encoding=UTF-8
Name=Dwm
Comment=Dynamic Window Manager
Exec=dwm-personalized
Icon=dwm.png
Type=XSession

Nota #1: El icono que nos trae el repositorio descargado llamado 'dwm.png'  lo copiamos a '/usr/share/pixmaps'
Nota #2: dwm-personalized es un script que crearemos a continuación.

Antes de iniciar DWM quizá queramos iniciar otras cosas, veamos mi archivo 'dwm-personalized':


Código: (bash) [Seleccionar]
#!/usr/bin/env sh

# No quiero la tecnología dpms (Display Power Management System)
xset -dpms
xset s off
xset s noblank

# Defino mi fondo de escritorio
nitrogen --set-centered /home/dtxdf/Pictures/BG-Desktop/bonito.jpg

# Remplazo el proceso actual por dwm
exec dwm

Yo lo tengo en '/usr/local/bin' que me parece ideal para este tipo de archivos:

Código: (bash) [Seleccionar]
sudo install --mode 755 dwm-personalized /usr/local/bin
Luego de hacer todo eso, al iniciar LightDM podremos cambiar la sesión a DWM para poder iniciarlo.

Combinaciones por defecto:

En esta sección les indicaré algunas combinaciones de teclas por defecto que quizá les sea de utilidad:

  • ALT+j y ALT+k: Desplazarse entre ventanas de izquierda o derecha
  • ALT+h y ALT+l: Aumentar/Disminuir el tamaño de las ventanas. El efecto se puede apreciar entre dos o más ventanas y se le aplica sólo a la ventana master.
  • ALT+SHIFT+q: Salir de DWM
  • ALT+p: Ejecutar dmenu o rofi
  • ALT+b: Mostrar u ocultar la barra de estado de DWM
  • ALT+[1-9]: Moverse entre tags (con [1-9] me refiero a un rango)
  • ALT+SHIFT+[1-9]: Mover la ventana a un tag específico
  • ALT+m: Modo monocle; coloca la ventana actual o master en pantalla completa
  • ALT+t: Modo mosaico
  • ALT+f: Modo flotante; Las vetanas nuevas se superponen como Windows, OS X o un Entorno de Escritorio
  • ALT+[Botón izquierdo del ratón]: Mantener presionado para que haga efecto; mover una ventana con el mouse, ésto coloca el orden en flotante
  • ALT+[Botón derecho del ratón]: Mantener presionado para que haga efecto; redimensionar una ventana
  • ALT+SHIFT+SPACE: Alternará al modo flotante de la ventana actual
  • ALT+SHIFT+c: Cerrar una ventana
  • ALT+SHIFT+d y ALT+SHIFT+i: Mover una ventana a master o stack
  • ALT+TAB: Desplazarse entre últimos tags que se haya indexado
  • ALT+ENTER: Alterna entre master o stack

Hay muchas combinaciones y pueden agregarle muchas más...

Trucos:

xev es una pequeña utilidad para imprimir los eventos de las X. Este programa nos ayudará a saber qué constante asignar a DWM. Manos a la obra:


xev en ejecución

Como se puede apreciar, en el apartado de 'state' podremos ver el código asignado a esa tecla, además de su constante, que en el último caso era 'Alt_L'.

Con este programa podremos saber qué clave asignar sin tener que buscar en los lugares más recónditos de la web o leer una documentación específica del mismo. Aunque una alternativa más rápida es:

Código: (bash) [Seleccionar]
xmodmap -pke


Mis tags

Podremos modificar los nombres de los tags (en la línea 25) a nuestro gusto (como es mi caso), no obstante si no se desea mover con los números del teclado, es mejor modificar el apartado de combinaciones de teclas.

Avanzado:

En esta sección les comparto unos scripts que uso con frecuencia para poder hacer mi vida más fácil, pero antes tengo que compartirles mi archivo de configuración para que puedan entender qué hace qué cosa:

Código: (text) [Seleccionar]
/* See LICENSE file for copyright and license details. */

/* appearance */
static const unsigned int borderpx  = 0;        /* border pixel of windows */
static const unsigned int snap      = 32;       /* snap pixel */
static const int showbar            = 0;        /* 0 means no bar */
static const int topbar             = 0;        /* 0 means bottom bar */
static const char *fonts[]          = { "Liberation Mono:size=10" };

static const char dmenufont[]       = "Liberation Mono:size=10";

static const char col_gray1[]       = "#222222";
static const char col_gray2[]       = "#444444";
static const char col_gray3[]       = "#bbbbbb";
static const char col_gray4[]       = "#eeeeee";
static const char col_cyan[]        = "#005577";

static const char *colors[][3]      = {
/*               fg         bg         border   */
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
[SchemeSel]  = { col_gray4, col_cyan,  col_cyan  },
};

/* tagging */
static const char *tags[] = { "UXVT", "Firefox", "Documentación" };

static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
/* class      instance    title       tags mask     isfloating   monitor */
{ NULL,     NULL,       NULL,       0,            0,           -1 }
};

/* layout(s) */
static const float mfact     = 0.55; /* factor of master area size [0.05..0.95] */
static const int nmaster     = 1;    /* number of clients in master area */
static const int resizehints = 1;    /* 1 means respect size hints in tiled resizals */

static const Layout layouts[] = {
/* symbol     arrange function */
{ "[]=",      tile },    /* first entry is default */
{ "><>",      NULL },    /* no layout function means floating behavior */
{ "[M]",      monocle },
};

/* key definitions */
#define MODKEY Mod1Mask
#define TAGKEYS(KEY,TAG) \
{ MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
{ MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} },

/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }

/* commands */
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
//static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
static const char *dmenucmd[] = { "rofi", "-show", "run", NULL };
static const char *termcmd[]  = { "urxvt", NULL };
static const char *firefox[] = { "firefox", NULL };
static const char *shutdown[] = { "power-script", "1", NULL }; // APAGAR
static const char *reboot[] = { "power-script", "2", NULL }; // REINICIAR
static const char *cancel[] = { "power-script", "3", NULL }; // CANCELAR
static const char *sessions[] = { "select-session", NULL }; // SELECCIONAR UNA SESIÓN DE TMUX
static const char *bam_connect[] = { "bam-connect", NULL }; // Para conectar el bam
static const char *bam_disconnect[] = { "bam-disconnect", NULL }; // Para desconectar el bam
static const char *screenshot[] = { "scrot-script", "mtpaint", NULL }; // Tomar una captura de pantalla

static Key keys[] = {
/* modifier                     key        function        argument */
{ MODKEY,                       XK_Print,         spawn,          {.v = screenshot} },
{ MODKEY,                       XK_p,      spawn,          {.v = dmenucmd} },
{ MODKEY|ShiftMask,             XK_t,      spawn,          {.v = termcmd} },
{ MODKEY,              XK_F1,     spawn,        {.v = firefox} },
{ MODKEY|ShiftMask,             XK_s,      spawn,          {.v = shutdown} },
{ MODKEY|ShiftMask,             XK_r,      spawn,          {.v = reboot} },
{ MODKEY|ShiftMask,             XK_k,      spawn,          {.v = cancel} },
{ MODKEY,                       XK_s,      spawn,          {.v = sessions} },
{ MODKEY,                       XK_q,      spawn,          {.v = bam_connect} },
{ MODKEY,                       XK_w,      spawn,          {.v = bam_disconnect} },
{ MODKEY,                       XK_b,      togglebar,      {0} },
{ MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
{ MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
{ MODKEY,                       XK_i,      incnmaster,     {.i = +1 } },
{ MODKEY,                       XK_d,      incnmaster,     {.i = -1 } },
{ MODKEY,                       XK_h,      setmfact,       {.f = -0.05} },
{ MODKEY,                       XK_l,      setmfact,       {.f = +0.05} },
{ MODKEY,                       XK_Return, zoom,           {0} },
{ MODKEY,                       XK_Tab,    view,           {0} },
{ MODKEY|ShiftMask,             XK_c,      killclient,     {0} },
{ MODKEY,                       XK_t,      setlayout,      {.v = &layouts[0]} },
{ MODKEY,                       XK_f,      setlayout,      {.v = &layouts[1]} },
{ MODKEY,                       XK_m,      setlayout,      {.v = &layouts[2]} },
{ MODKEY,                       XK_space,  setlayout,      {0} },
{ MODKEY|ShiftMask,             XK_space,  togglefloating, {0} },
{ MODKEY,                       XK_0,      view,           {.ui = ~0 } },
{ MODKEY|ShiftMask,             XK_0,      tag,            {.ui = ~0 } },
{ MODKEY,                       XK_comma,  focusmon,       {.i = -1 } },
{ MODKEY,                       XK_period, focusmon,       {.i = +1 } },
{ MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
{ MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
TAGKEYS(                        XK_1,                      0)
TAGKEYS(                        XK_2,                      1)
TAGKEYS(                        XK_3,                      2)
TAGKEYS(                        XK_4,                      3)
TAGKEYS(                        XK_5,                      4)
TAGKEYS(                        XK_6,                      5)
TAGKEYS(                        XK_7,                      6)
TAGKEYS(                        XK_8,                      7)
TAGKEYS(                        XK_9,                      8)
{ MODKEY|ShiftMask,             XK_q,      quit,           {0} },
};

/* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = {
/* click                event mask      button          function        argument */
{ ClkLtSymbol,          0,              Button1,        setlayout,      {0} },
{ ClkLtSymbol,          0,              Button3,        setlayout,      {.v = &layouts[2]} },
{ ClkWinTitle,          0,              Button2,        zoom,           {0} },
{ ClkStatusText,        0,              Button2,        spawn,          {.v = termcmd } },
{ ClkClientWin,         MODKEY,         Button1,        movemouse,      {0} },
{ ClkClientWin,         MODKEY,         Button2,        togglefloating, {0} },
{ ClkClientWin,         MODKEY,         Button3,        resizemouse,    {0} },
{ ClkTagBar,            0,              Button1,        view,           {0} },
{ ClkTagBar,            0,              Button3,        toggleview,     {0} },
{ ClkTagBar,            MODKEY,         Button1,        tag,            {0} },
{ ClkTagBar,            MODKEY,         Button3,        toggletag,      {0} },
};

scrot-script

Dependencias: scrot zenity <programa extra para abrir la imagen> (en mi caso mtpaint)
Descripción: Tomar una captura de pantalla

Código: (bash) [Seleccionar]
#!/usr/bin/env sh

declare PROGRAM=$1
declare FILE_NAME=/tmp/scrot.png

if [ ${#*} -lt 1 ];then
    zenity --error --text="Debes seleccionar un programa para que interactúe con la captura de pantalla." --no-wrap
    exit 1

fi

if [ -z "$(which $PROGRAM)" ];then
    zenity --error --text="Ha ocurrido un error, \"$PROGRAM\" no existe" --no-wrap
    exit 2

fi

rm -f "$FILE_NAME";scrot -s "$FILE_NAME" && command "$PROGRAM" "$FILE_NAME"

bam-connect

Dependencias: wvdial
Descripción: Conectar a Internet utilizando el bam

Código: (bash) [Seleccionar]
#!/usr/bin/env sh

sudo wvdial

bam-disconnect

Dependencias: wvdial
Descripción: Enviar una señal SIGTERM a wvdial para apagar la conexión con el bam

Código: (bash) [Seleccionar]
#!/usr/bin/env sh

sudo killall wvdial

select-session

Dependencias: tmux zenity urxvt
Descripción: Permite seleccionar una sesión de tmux que esté oculta y en ejecución.

Código: (bash) [Seleccionar]
#!/usr/bin/env bash

declare -x aux
declare -x aux_sessions
declare -x session_name
declare -x session_info
declare -x execute
declare -x val
let n=0

IFS_BAK=$IFS
IFS="
"

show_sessions() {
for i in $(tmux ls);do
echo -n "$i;"

done

}

tmux ls > /dev/null 2> /dev/null

if [ $? -eq 1 ];then
zenity --text="Por ahora no tiene sesiones en tmux Sr. DtxdF :3" --no-wrap --info
exit 1

fi

aux_sessions=$(show_sessions)
execute='zenity --list --column="Session" --column="Information" --title="Seleccione una sesión Sr. DtxdF"'

while [ true ];do
let n+=1

aux=$(echo $aux_sessions | cut -d ";" -f $n)

if [ -z "$aux" ];then
break

fi

session_name=$(echo $aux | cut -d ":" -f 1)
session_info=$(echo $aux | cut -d ":" -f 2 | sed "s/^ //")

execute="$execute \"$session_name\" \"$session_info\""

done

IFS=$IFS_BAK
val=$(sh -c "$execute")

if [ $? -eq 0 ];then
urxvt -e sh -c "tmux attach -t \"$val\""

fi

power-script

Dependencias: zenity
Descripción: Permite apagar, reiniciar el equipo, aunque también podría cancelar las operaciones antes mencionadas.

Código: (bash) [Seleccionar]
#!/usr/bin/env bash

let option=$1 2> /dev/null
let timeout=10
let timetoshut=10
declare -x cancelfile="/tmp/noshut"

write_error_msg() {
zenity --text="$1" --error --no-wrap

}

check_noshut() {
if [ -f "$cancelfile" ];then
rm -f "$cancelfile"
exit 0

fi

}

if [ "$option" -eq 0 ];then
write_error_msg "¡Debes escribir una opción!"
exit 1

fi

if [ "$option" -eq 1 ];then
zenity --warning --text="Su equipo se apagará dentro de $timetoshut segundo(s) Sr. DtxdF, por favor sea paciente" --timeout=$timeout --no-wrap
sleep $timetoshut
check_noshut
poweroff

elif [ "$option" -eq 2 ];then
zenity --warning --text="Su equipo se reiniciará dentro de $timetoshut segundo(s) Sr. DtxdF, por favor sea paciente" --timeout=$timeout --no-wrap
sleep $timetoshut
check_noshut
reboot

elif [ "$option" -eq 3 ];then
touch $cancelfile
zenity --info --text="El equipo no se apagará Sr. DtxdF, no se preocupe ;-)" --timeout=$timeout --no-wrap

else
write_error_msg "¡Opción no encontrada!"
exit 3


fi

exit 0

simple-nmap-script

Dependencias: nmap zenity
Descripción: Escanea la red en busca de objetivos vivos
Estado: Próximamente...

wifi-scan-script

Estado: Próximamente...

Notas:

Para cambiar el tema por defecto de 'rofi', tendremos que ejecutar:

Código: (bash) [Seleccionar]
rofi-theme-selector
Se nos abrirá una ventana:


rofi-theme-selector

Presionamos ENTER para seleccionar un tema; ALT+A para ajustarlo como predeterminado; con ESC salimos y hasta podemos hacer una búsqueda de un tema por su nombre.


Si eres como yo y utiliza un Bam para comunicarse con el mundo exterior te recuerdo que hay un post para usar como alternativa a wvdial. Otra cosa, es que necesitamos agregar lo siguiente a el fichero sudoers para que no sea necesario requerir contraseña al conectarse al Modem USB:

Código: (text) [Seleccionar]
Host_Alias SRV_DTXDF = localhost, dtxdf # Nombre del host de la máquina

User_Alias USR_DTXDF = dtxdf # Nombre de usuario, en mi caso es 'dtxdf'

Cmnd_Alias WVDIAL       = /usr/bin/wvdial
Cmnd_Alias KILL_WVDIAL  = /usr/bin/killall wvdial

# Permitimos que se ejecute sudo sin contraseña a wvidlal y 'killall wvdial'
USR_DTXDF SRV_DTXDF = NOPASSWD:WVDIAL
USR_DTXDF SRV_DTXDF = NOPASSWD:KILL_WVDIAL


Si se desea cambiar la "clave modificadora" (ALT, por defecto) en DWM, se tiene que modificar 'config.def.h' (que luego será pasado a config.h), tendremos que irnos a la línea 47 y cambiar la constante simbólica 'MODKEY' con su valor 'Mod1Mask' por 'Mod4Mask', por ejemplo, sería asignar la tecla de Windows.

Podemos hacerlo con tantas teclas nos permita en 'xmodmap':


Código: (bash) [Seleccionar]
xmodmap


La razón por la que tengamos que copiar 'config.def.h' a 'config.h' es porque la comunidad de DWM realiza parches para mejorar mucho más la experiencia de éste, entonces si se modifica 'config.def.h' en vez de 'config.h', no estaríamos sobreescribiendo la configuración que le hayamos hecho.


En LightDM tuve que configurar algún par de cosas para que funcionara perfectamente, lo comentaré aquí por si a alguien le pasa:

En la sección de LightDM '[Seat:*]', descomentaremos 'session-wrapper' para que cargue el archivo Xsession; en la sección '[LightDM]' descomentaremos y nos aseguraremos de que las rutas que se colocan ahí sean correctas y existan, ya que permitirá leer los Archivos de Entrada de Escritorio.

Espero que a alguien le sirva ;)


Si se desean más temas para rofi, pueden ir al siguiente repositorio: https://github.com/davatorium/rofi-themes


Conclusión:


~ DtxdF

14
Un USB Dumper es una utilidad que copia (o extrae) todo los archivos que encuentre en un dispositivo (mayormente extraible, como un USB), una vez se conectó al ordenador. Éste tiene como primer objetivo el robo de información, pero puede darse un caso un tanto excepcional de un análisis o el respaldo de la información del mismo dispositivo.


La siguiente utilidad es un fork del usuario @Frijolito que acabo de terminar, y pueden encontrar el post aquí.

Repositorios:

  • Fork: github.com/DtxdF/UsbDumper
  • Original: github.com/MysteriusFat/UsbDumper

Características de esta versión

  • Eficiencia: Es realmente rápido
  • Recursividad: Además de copiar todos los archivos que pueda, también crea las carpetas según el nombre de éstas en el directorio de salida
  • El pingüino se asoma por la ventana: Funciona tanto para Windows como para GNU/Linux
  • Múltiples objetivos: Los objetivos se definen en config.h según el sistema operativo y se pueden colocar más de uno si se desea
  • Fácil: Es realmente fácil, simplemente ejecutando el nombre del ejecutable, el parámetro ( -t ) para seleccionar la ruta y listo, empiece a extraer todos esos datos del dispositivo víctima, mientras que para *nix si se desea se puede usar el script (que es copiado en la instalación a '/etc/init.d') para crear un daemon y ejecutarlo en segundo plano.

Instalación:

Decarga:

Código: (bash) [Seleccionar]
git clone https://github.com/DtxdF/UsbDumper.git
cd UsbDumper

GNU/Linux

Código: (bash) [Seleccionar]
sudo make -f linux.mk install
man UsbDumper # UsbDumper -h

Nota: Por defecto se instala e inicia el daemon en "/etc/init.d", si desea puede apagarlo y deshabilitarlo (o borrarlo)

Código: (bash) [Seleccionar]
systemctl disable UsbDumper
systemctl stop UsbDumper
# Para eliminarlo
rm -f /etc/init.d/UsbDumper

El daemon no es necesario, es para que se mantenga oculta, pero hay diferentes maneras de poder lograrlo, como usar cron, usar nohup o una variedad de herramientas de apoyo. ¡ES LIBRE DE USAR LA QUE DESEA!

Windows

Código: (bash) [Seleccionar]
mingw32-make -f windows.mk
UsbDumper.exe -h

Notas

  • El programa termina su ejecución cuando se haya completado la extración de cada dispositivo víctima
  • Debe tener en cuenta la primera nota para el daemon, el daemon es usado para ocultar lo que se está haciendo.
  • Cuando se termine de extraer todos los archivos, el programa tomará en cuenta la ruta como identificador para no volver a copiar los archivos
  • El archivo config.h es el encargado de verificar los dispositivos víctimas, y es el usuario el que decide qué dispositivos serán los que se desea extraer los archivos

Capturas de pantalla

Instalando

Copiando los archivos del dispositivo víctima

Terminando la extracción

Actualizado: El programa se ha actualizado para agregar soporte Unicode tanto para Windows como Linux, además de otros pequeños errores o inconvenientes.

~ DtxdF

15
En el día de hoy les presentare una fantástica herramienta que ha creado nuestro compañero @animanegra . Se hace llamar LeakChecker y su objetivo es mostrarnos si nuestras credenciales han sido filtradas a una base de datos, y lo mejor es que se puede hacer todo el proceso a través del teléfono.


La herramienta es de código abierto, pero nuestro compañero también nos proporcionó el APK e incluso, ésta no requiere permisos especiales para poder usarla. Dicho lo anterior tenemos dos opciones para descargarla: Clonar el repositorio o Descargar directamente el APK.

Clonando el repositorio:

Código: (bash) [Seleccionar]
git clone https://github.com/4nimanegra/LeakChecker.git
cd LeakChecker

En nuestro caso, usemos el APK:


Una vez ejecutada:


La instalamos y una vez finalizada, disponemos de un formulario, ahí es donde tenemos que colocar nuestra dirección de correo electrónico para verificar si nuestras credenciales fueron expuestas:


Como se puede observar mis credenciales no están expuestas  ;D. También se puede observar la facilidad de la herramienta y lo mejor, es que podemos transportarla en nuestro bolsillo.

Algo que se debe tener en consideración es que al igual que el creador, la herramienta es ética, no procura revelar información sensible, por lo que sólo se mostrarán algunos caracteres y tendrá un tiempo de espera de 60 segundos por cada solicitud, suficiente para verificar.


~ DtxdF

16
CLIConfig: Parsea tus archivos de configuración desde la terminal

CLIConfig es una utilidad para la línea de comandos, pero la verdadera estrella de esta película es la librería que usa "conf_parser.h" qué es la encargada de leer los archivos de configuración.CONF mientras que la herramienta antes mencionada hace mucho más.

Instalación

Código: (bash) [Seleccionar]
git clone https://github.com/DtxdF/CLIConfig.git
cd ./CLIConfig
sudo make install
man CLIConfig # o CLIConfig -h

Repositorio: github.com/DtxdF/CLIConfig

Ejemplos de CLIConfig

CLIConfig ayudará a la persona que esté haciendo scripting y necesite interactuar con los archivos de configuración del sistema. Por lo que siguiendo las pautas que se mostrarán a continuación quedará más que claro:

En mi caso yo usaré el archivo de configuración de DNSMASQ, pero antes haré una copia para esta demostración

Código: (bash) [Seleccionar]
cd /tmp
cp /etc/dnsmasq.conf .
CLIConfig dnsmasq.conf -s

CLIConfig no lee comentarios que tengan almuadillas antepuestas (#) por lo que en mi caso se mostraría lo siguiente:

Código: (text) [Seleccionar]
[Procesando: dnsmasq.conf]

domain-needed
bogus-priv
no-resolv
log-queries
log-dhcp
log-facility=/var/log/dnsmasq.log
server=1.1.1.1
server=1.0.0.1
dhcp-range=eth0,192.168.0.2,192.168.0.254,12h
interface=eth0

[Procesado: dnsmasq.conf]

Sí quisieramos eliminar el procesamiento se tendría que colocar el parámetro "-n" ó "--no-banner":

Código: (text) [Seleccionar]
domain-needed
bogus-priv
no-resolv
log-queries
log-dhcp
log-facility=/var/log/dnsmasq.log
server=1.1.1.1
server=1.0.0.1
dhcp-range=eth0,192.168.0.2,192.168.0.254,12h
interface=eth0

Sí quisieramos mostrar las claves "server" sería de la siguiente manera:

Código: (bash) [Seleccionar]
CLIConfig -k server -s dnsmasq.conf
El resultado sería el siguiente

Código: (text) [Seleccionar]
[Procesando: dnsmasq.conf]

server=1.1.1.1
server=1.0.0.1

[Procesado: dnsmasq.conf]

Quiero recordar que todo lo que no sea un parámetro o un argumento de un parámetro es un considerado un archivo

Código: (bash) [Seleccionar]
cp /etc/wvdial.conf .
CLIConfig -s dnsmasq.conf wvdial.conf

Resultado:

Código: (text) [Seleccionar]
[Procesando: dnsmasq.conf]

domain-needed
bogus-priv
no-resolv
log-queries
log-dhcp
log-facility=/var/log/dnsmasq.log
server=1.1.1.1
server=1.0.0.1
dhcp-range=eth0,192.168.0.2,192.168.0.254,12h
interface=eth0

[Procesado: dnsmasq.conf]
[Procesando: wvdial.conf]

[Dialer Defaults]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Modem Type = Analog Modem
Baud = 9600
New PPPD = yes
Modem = /dev/ttyUSB2
ISDN = 0
Phone = *99
Password = none
Username = none

[Procesado: wvdial.conf]

CLIConfig no le quita los espacios a las claves, por lo que en el caso de wvdial se tendría que colocar espacios.

Código: (bash) [Seleccionar]
CLIConfig -s /etc/wvdial.conf -k "Username "
Resultado:

Código: (text) [Seleccionar]
[Procesando: /etc/wvdial.conf]

Username = none

[Procesado: /etc/wvdial.conf]

Para modificar los servidores DNS de dnsmasq.conf haríamos los siguiente:

Código: (bash) [Seleccionar]
CLIConfig dnsmasq.conf -k server -v 8.8.8.8 -o
Código: (text) [Seleccionar]
[Procesando: dnsmasq.conf]

¡server ha sido modificado con éxito!

[Procesado: dnsmasq.conf]

Si vemos el archivo modificado:

Código: (bash) [Seleccionar]
cat dnsmasq.conf
Código: (text) [Seleccionar]
domain-needed
bogus-priv
no-resolv
log-queries
log-dhcp
log-facility=/var/log/dnsmasq.log
server=8.8.8.8
server=8.8.8.8
dhcp-range=eth0,192.168.0.2,192.168.0.254,12h
interface=eth0

No se ve tan bien... Y es por qué no le especificamos qué coincidencia deseamos modificar, por lo que lo hará con todos los que encuentre, para realizarlo:

Código: (bash) [Seleccionar]
CLIConfig dnsmasq.conf -k server -v 8.8.4.4 -o -p 2
...
cat dnsmasq.conf

Código: (bash) [Seleccionar]
...
server=8.8.8.8
server=8.8.4.4
...

NOTA: El parámetro "-o" ó "--overwrite" sobre-escribe el valor de la clave y el archivo, por lo que es mejor que hagamos un respaldo del anterior en casos reales

Para agregar una nueva clave:

Código: (bash) [Seleccionar]
CLIConfig dnsmasq.conf -k dhcp-range -v wlan0,10.42.0.2,10.42.0.254,5h -w
Código: (text) [Seleccionar]
[Procesando: dnsmasq.conf]

Escrito: dhcp-range=wlan0,10.42.0.2,10.42.0.254,5h

[Procesado: dnsmasq.conf]

Para eliminar todas las claves coincidentes:

Código: (bash) [Seleccionar]
CLIConfig dnsmasq.conf -d -k server
Eliminar sólo la segunda coincidencia:

Código: (bash) [Seleccionar]
CLIConfig dnsmasq.conf -d -k server -p 2
Ver la ayuda:

Código: (bash) [Seleccionar]
CLIConfig -h
Funcionamiento de cada parámetro

  • -h/--help: Muestra la ayuda
  • -s/--show: Muestra el archivo de configuración parseado
  • -k/--key: Coincidir con la clave
  • -w/--write: Agregar una clave y un valor a la configuración
  • -v/--value: El valor de la clave
  • -n/--no-banner: No mostrar el procesamiento de los que se está haciendo
  • -o/--overwrite: Sobre-escribe el valor de una(s) clave(s)
  • -E/--expression: Usar un valor como coincidencia en vez de la clave
  • -I/--init: Iniciar la interacción después de un número N
  • -O/--only: Sólo actuar con N filas
  • --offset: Lo mismo que --only
  • -i/--id: Actuar solamente cuando la llamada del callback número X sea igual a Y
  • -p/--pattern: Cuándo haya N coincidencias encontradas actuar con la que ajustó el usuario
  • -d/--delete: Borrar una clave

NOTA: Es necesario comprender el funcionamiento de cada parámetro que usa, ya que no todos funcionan de la misma manera y no todos se pueden combinar, además de los valores por defecto que fueron otorgados a éstos por el diseño del mismo programa.

Combinaciones:

  • -s/--show: -k/--key, -E/--expression, -O/--only, -i/--id, -p/--pattern, -I/--init
  • -k/--key: -v/--value, -w/--write, -s/--show, -o/--overwrite, -O/--only, -i/--id, -p/--pattern, -d/--delete, -I/--init
  • -w/--write: -k/--key, -v/--value
  • -v/--value: -k/--key, -w/--write, -o/--overwrite, -O/--only, -p/--pattern, -I/--init
  • -o/--overwrite: -k/--key, -v/--value, -E/--expression, -O/--only, -p/--pattern, -I/--init
  • -E/--expression: -s/--show, -v/--value, -o/--overwrite, -O/--only, -p/--pattern, -I/--init
  • -O/--only/--offset: -s/--show, -k/--key, -v/--value, -o/--overwrite, -E/--expression, -i/--id, -p/--pattern, -d/--delete, -I/--init
  • -i/--id: -s/--show, -O/--only
  • -I/--init: -s/--show, -k/--key, -v/--value, -o/--overwrite, -E/--expression, -p/--pattern, -d/--delete
  • -p/--pattern: -s/--show, -k/--key, -v/--value, -o/--overwrite, -E/--expression, -O/--only, -d/--delete, -I/--init

NOTA-#1: El parámetro -n/--no-banner no fue colocado en la tabla porque se puede combinar con todos

NOTA-#2: Sí se define el parámetro -k/--key al mismo tiempo que -E/--expression, el segundo no se tomara en cuenta, pero si el primero.

NOTA-#3: El valor por defecto de los siguientes parámetros es "0", lo que quiere decir que no se hará nada al menos que se le coloque un número mayor: -O/--only, -i/--id, -p/--pattern.

Sintaxis de los archivos de configuración

La sintaxis de un archivo de configuración se rige de la siguiente manera:

Código: (text) [Seleccionar]
clave=valor
Ejemplo de la librería

Primero compilamos la librería:

Código: (bash) [Seleccionar]
make conf_parser.o
Teniendo el siguiente archivo de configuración:

Código: (bash) [Seleccionar]
cat test.conf
Código: (text) [Seleccionar]
name=Josef
lastname=Naranjo
age=17
alias=DtxdF

Y teniendo el siguiente parser (test.c):

Código: (c) [Seleccionar]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include "conf_parser.h"

#define CMP(x,y) strcmp(x, y) == 0

struct configuration {
char * name;
char * lastname;
long age;
char * alias;

};

int parser(void * config, char * key, char * value) {
struct configuration * conf = (struct configuration *)config;
char *endstr;

if (CMP(key, "name")) {
conf->name = strdup(value);

} else if (CMP(key, "lastname")) {
conf->lastname = strdup(value);

} else if (CMP(key, "age")) {
conf->age = strtol(value, &endstr, 10);

if (errno != 0) {
return errno;

}

} else if (CMP(key, "alias")) {
conf->alias = strdup(value);

} else {
return 3; // Cuando una clave no es válida (Opcional)

}

return 0;

}

int main(void) {
struct configuration config;
FILE * file;

if ((file = fopen("test.conf", "rb")) == NULL) {
perror("Error abriendo el archivo de configuración");
               
      return errno;

}

if (ini_parse(file, &config, parser) != 0) {
perror("Ocurrio un error interpretando el archivo de configuración");

return errno;

}

printf("Información del sujeto:\n");
printf("----------------------\n\n");

printf("Nombre: %s\n", config.name);
printf("Apellido: %s\n", config.lastname);
printf("Edad: %ld\n", config.age);
printf("Alias: %s\n", config.alias);

free(config.name);
free(config.lastname);
free(config.alias);

fclose(file);

return EXIT_SUCCESS;

}

Lo compilamos y ejecutamos:

Código: (bash) [Seleccionar]
gcc -Wall -O2 -o program test.c conf_parser.o strip.o
./program

Y obtenemos:

Código: (text) [Seleccionar]
Información del sujeto:
----------------------

Nombre: Josef
Apellido: Naranjo
Edad: 17
Alias: DtxdF

TODO

  • Auto-completado de comandos
  • Manpage
  • Verificador de sintaxis

Gracias a

Ustedes lectores por otra oportunidad. Comentarios, Reportes o alguna interacción sería excelente  ;)

~ DtxdF

17
Underc0de / Índice de todos los "Tops Semanales"
« en: Marzo 28, 2020, 03:21:00 am »
El siguiente post está hecho con la intención de crear una forma de organizar todos los "Tops de la semana", además que será de mucha utilidad para los nuevos usuarios que ingresen en Underc0de. Cada vez que se cumplan cinco Tops, se editara este post actualizandolo con el resumen.


Temporada #1

  • underc0de.org/foro/underc0de/(aporte-semanal)-top-lo-mejor-de-lo-mejor-de-underc0de/
  • underc0de.org/foro/underc0de/(aporte-semanal)-top-lo-mejor-de-lo-mejor-de-underc0de-2/
  • underc0de.org/foro/underc0de/(aporte-semanal)-top-lo-mejor-de-lo-mejor-de-underc0de-3/
  • underc0de.org/foro/underc0de/(aporte-semanal)-top-lo-mejor-de-lo-mejor-de-underc0de-4/
  • underc0de.org/foro/underc0de/(aporte-semanal)-top-lo-mejor-de-lo-mejor-de-underc0de-5/

~ DtxdF

18
Mucho pentester por ahí, mucho hacker, mucho forense, pero nada de recopilación, nada de organización. Éso es lo que trata esta quinta pero hermosa entrega, que se adentrará en las entrañas de Underc0de a exhumar sobre herramientas para usos tan específicos para cada quién.

Top lo mejor de lo mejor de Underc0de

Top mejores Posts:


1.- Título: SMBMap: busca datos sensibles en recursos compartidos Windows desde Kali
     Autor: @Gabriela
     Enlace: underc0de.org/foro/gnulinux/smbmap-busca-datos-sensibles-en-recursos-compartidos-windows-desde-kali/
     Descripción: Una herramienta por excelencia, un post dotado de enseñanza, y una redactora excelente. Gabriela nos brinda su conocimiento con SMBMap, una herramienta que nos permitirá enumerar recursos compartidos Samba a lo largo de un dominio, pero no es todo lo que depara, enumera contenidos y permisos, así como soporta pass-the-hash, descarga y borra los ficheros, busca patrones de nombres de los archivos con la opción de autodescargarlos e incluso ejecuta comandos remotamente.


2.- Título: Dándole un vistazo a MDK3 - 1era Parte
     Autor: @Cl0udswX
     Enlace: underc0de.org/foro/wireless/t24210/
     Descripción: MDK3 es una herramienta para la seguridad inalámbrica (Wireless, en inglés) que tiene multitud de opciones para probar la seguridad de nuestro router. Herramienta que se aprovecha de vulnerabilidades en el estándar IEEE 802.11. Cl0udswX nos ilustra como es todo el proceso no en uno, sino en dos maravillosos artículos que no puedes dejar pasar.


3.- Título: CMSmap - Escáner de CMS (XML-RPC Brute Force en blog.underc0de.org)
     Autor: @HATI
     Enlace: underc0de.org/foro/hacking/t31022/
     Descripción: CMSmap es un escáner de gestores de contenido de código abierto que está escrito en Python. Esta herramienta se encarga de automatizar el proceso de búsqueda de vulnerabilidades más conocidas de los CMS, cómo Wordpress, Joomla y Drupal. HATI, nos hace una demostración perfecta contra una página web muy conocida...


4.- Título: myCompiler: práctica 16 lenguajes de programación desde el navegador
     Autor: @Denisse
     Enlace: underc0de.org/foro/programacion-general/t40398/
     Descripción: Emprenderas un viaje lejano, se te olvido el teléfono, la laptop, no tienes Tmux/Userland o cualquier método para probar ese código que está en tu mente, no hay problema que Denisse nos comparte una página un tanto interesante, que se da por seguro que a cualquier desarrollador va a saber aprovechar.


5.- Título: Navegar con Proxy "Tor" en GNU/Linux
     Autor: @Stiuvert
     Enlace: underc0de.org/foro/gnulinux/navegar-con-proxy-'tor'-en-gnulinux/
     Descripción: Todos nos hemos enfrentado a la triste realidad que hay una guerra constante entre la privacidad y los datos, pero no por ese aspecto negativo nos vamos a rendir y ser lo más servicial con lo que compartimos; desde nuestra ubicación, las páginas que visitamos, nuestros amigos, o básicamente todo lo que esté de algún modo relacionado. Stiuvert nos demuestra la importancia del afanado Tor, que pese a no ser 100% fiable, como su logo nos brindará una capa extra de seguridad.

Top mejores herramientas de la comunidad:


1.- Título: Underc0de Spy 1.1 LIBERADO AL FIN!!!!
     Autor: @CrazyKade
     Enlace: underc0de.org/foro/hacking/underc0de-spy-1-1-liberado-al-fin!!!!
     Descripción: Underc0de Spy es una herramienta hecha por CrazyKade y tiene como objetivo ser un escáner de hosts, puertos y además dejar un puerto a la escucha para posteriores análisis. Él se inspiró a partir de un punto de fatiga en su vida profesional por acudir a diferentes herramientas de diferentes empresas, cosa que vió muy tediosa, así que con todo el amor creó una fantástica herramienta para ese objetivo.


2.- Título: Underc0de Dorker
     Autor: @blackdrake
     Enlace: underc0de.org/foro/hacking/(tool)-underc0de-dorker/
     Descripción: Una vez más una herramienta que lleva el nombre de un conocido foro, pero algo que si se sale de esta rutina es lo que nos aporta blackdrake para facilitar el proceso de Google Hacking combinando Dorks nunca antes visto.


3.- Título: Lucrecia - Honeypot FTP
     Autor: @Kirari
     Enlace: underc0de.org/foro/hacking/lucrecia-honeypot-ftp-42032/
     Descripción: ¿Tienes un topo en la red? ¿Quieres sacarlo? ¿Qué...? ¿Por qué?, permitele entrar, ser lo más permisivo, no le denieges los paquetes, en su lugar usa la herramienta que nos brinda el hermano Kirari para espiar al espía.


4.- Título: Usb Dumper en C código y ejecutable
     Autor: @Frijolito
     Enlace: underc0de.org/foro/malware/usb-dumper-en-c-codigo-y-ejecutable/
     Descripción: Se pensará que un USB Dumper es un simple programa que se ejecuta en segundo plano a robar archivos y no tiene más objetivos, pero la realidad es que puede qué esté anexo a una simple conclusión de cuál fue ese virus que se adentró por las entrañas de tu Sistema Operativo, así cómo también puede robar información por supuesto...


5.- Título: Base64 Encode/Decode metodo mas veloz
     Autor: @79137913
     Enlace: underc0de.org/foro/scripting/(vbs)-base64-encodedecode-metodo-mas-veloz-(fud)/
     Descripción: Números nos da una razón increible para seguir usando sus herramientas, el aprendizaje. Con sólo pocos snippets de código que él nos deja les apuesto que en la manera que este profesor enseña aprenderan más de lo que se imaginan,

~ DtxdF

19
Python / Simple XML2JSON
« en: Marzo 21, 2020, 12:20:56 am »
Lo siguiente, será un pequeño código para parsear XML a JSON usando la librería BeautifulSoup. Un código que les servirá a las personas que estén dando su primeros pasos en el scraping.

Código: (python) [Seleccionar]
import sys
import os
import signal
from json import dumps
from bs4 import BeautifulSoup

def xml2json(data):
    xml_parser = []

    for _ in data:
        xml_parser.append({
            _.name:
            (_.attrs, _.text)

            })

    return dumps(xml_parser, indent=6)

if (__name__ == '__main__'):
    program = sys.argv[0]
    argv = sys.argv[1:]

    if (argv == []):
        print(f'Uso: {program} <file>.xml')
        sys.exit(1)

    xml_file = argv[0]

    if (xml_file[0] == '-'):
        xml_data = sys.stdin.read()

    else:
        if not (os.path.isfile(xml_file)):
            print('Error, el archivo XML no existe')
            sys.exit(2)

        with open(xml_file, 'rb') as _file_object:
            xml_data = _file_object.read()

    xml_data = BeautifulSoup(xml_data, 'xml').find_all()

    print(xml2json(xml_data))

PD-#1: No dejé nada de comentarios, para que hagan una investigación ardua sobre todo ello... Su compañero será help(...)
PD-#2: Ejecuten lo siguiente y verán una magia:

Código: (bash) [Seleccionar]
nmap -T5 -n localhost -oX - | python3 xml2json.py - | less
~ DtxdF

20
Hoy sacamos del baúl de Underc0de aportes que si se leen en la actualidad, seguro se tendrá un aire fresco y moderno a pesar de la longevidad de su publicación. Aportes, qué de seguro le caerá excelente a las personas que recien inician con GNU/Linux.

Top lo mejor de lo mejor de Underc0de

Top mejores Posts:


1.- Título: Trash-CLI, añade una papelera de reciclaje a la línea de comandos de Linux
     Autor: @Dragora
     Enlace: underc0de.org/foro/gnulinux/trash-cli-anade-una-papelera-de-reciclaje-a-la-linea-de-comandos-de-linux/
     Descripción: rm -rfd Trabajos_para_el_fin_del_semestre. Un comando tan simple puede causar una destrucción completa de algún trabajo o en casos de alerta, el sistema. Trash-CLI viene a prevenir esas "Equivocaciones" de nuestra parte.


2.- Título: Cheat-Sheet: GNU/LINUX - Hoja Guía para que no se me olvide
     Autor: @Denisse
     Enlace: underc0de.org/foro/gnulinux/cheat-sheet-gnulinux-hoja-guia-para-que-no-se-me-olvide/
     Descripción: ¿Cuántos usuarios noveles de GNU/Linux andan por ahí?, si se desea saber un número se puede apostar que más de 15, y se puede apostar más de 100$ que más de 15 tendrán dudas de su propia distro, tranquilos, guarden la calma que Denisse viene al rescate con un increible Cheat-Sheet para aquellas personas que consideren tener una memoria excepcionalmente espantosa.


3.- Título: Apache vs Nginx ¿Cúal es mejor?
     Autor: @facufangio
     Enlace: underc0de.org/foro/debates/apache-vs-nginx-cual-es-mejor/
     Descripción: Los dos son excelentes aplicativos, son queridos y odiados, son usados por muchos, pero ¿Cuál es mejor? ¿Cuál es la diferencia? ¿Quién se le puede personalizar más?. facufangio nos da una buena opinión objetiva de lo que estás buscando.


4.- Título: ¿Cómo eché a la gente de mi red WiFi para aumentar mi velocidad de internet?
     Autor: @puntoCL
     Enlace: underc0de.org/foro/hacking/como-eche-a-la-gente-de-mi-red-wifi-para-aumentar-mi-velocidad-de-internet/
     Descripción: Te vas a tu operadora más cercana,  contratas el mejor plan de Internet que nunca se ha visto y... no importará, ¿por qué?, simple, por ser una persona muy modesta e inocente compartiendo el WIFI a todo el mundo sin saber la consecuencia, pero no todo está perdido, puntoCL nos trae un excelente post sobre una herramienta para solucionar ese problema de conexión que no te deja navegar con tranqulidad.


5.- Título: Web Scraping con Python
     Autor: @ANTRAX
     Enlace: underc0de.org/foro/python/web-scraping-con-python/
     Descripción: ANTRAX nos trae un excelente post sobre cómo realizar scraping, que de seguro nos resultará fantástico a la hora de que ese amado servicio que tantas posibilidades trae, no cuente con una API.

Top mejores herramientas de la comunidad:


1.- Título: Cifrado Compresor
     Autor: @Azav
     Enlace: underc0de.org/foro/python/cifrado-compresor-(archivos)/
     Descripción: Azav nos trae una excelente herramienta para aprender cómo los famosos softwares de compresión actúan.


2.- Título: Generador de codigo basura
     Autor: @79137913
     Enlace: underc0de.org/foro/scripting/(source)generador-de-codigo-basura/
     Descripción: Números nos regala desde su arsenal una excelente herramienta para obfuscar mejor nuestros códigos.


3.- Título: VirusTotal Scanner 0.1
     Autor: @BigBear
     Enlace: underc0de.org/foro/perl/(perl)-virustotal-scanner-0-1/
     Descripción: Te descargas ese archivo tan inocente, pero tú sabes que puede traer una sorpresa con sí, por lo que tu primer pensamiento es pasarlo en un escaner online, pero no cuentas con un entorno gráfico o simplemente no quieras salirte de la comodidad de tu Terminal, no hay problema que BigBear nos trae un excelente script para el análisis desde ésta misma.


4.- Título: Computer-Kingdom: ¿Flojera de usar el navegador para buscar una palabra?
     Autores: @DtxdF y @Kirari
     Enlace: underc0de.org/foro/python/computer-kingdom-flojera-de-usar-el-navegador-para-buscar-una-palabra/
     Descripción: ¿Mala memoria? ¿Una nueva palabra?, no te preocupes que DtxdF y Kirari forman alianzas para regarlate un pequeño diccionario de palabras informáticas.


5.- Título: Algoritmo para Des/Codificar
     Autor: @noxonsoftwares
     Enlace: underc0de.org/foro/python/(py3)-algoritmo-para-descodificar/
     Descripción: noxonsoftwares sacá de su baúl un algoritmo interesante que resultará útil a personas que estén aprendiendo a proteger sus documentos con herramientas propias.

[Co-Autores]: DtxdF & Bartz

~ DtxdF

Páginas: [1] 2 3 4