Introducción a bash -paso5- sed, awk, wc

[h]Introducción a bash : paso 5[/h]

https://www.wifi-libre.com/img/members/3/bash5_1.png

Recordatorio de los dos capítulos anteriores:

  • En nuestro primer curso ( Introducción a bash - paso 1: Bases, echo y “Hola mundo”) hemos visto;
    [list=*]
    ]Lo que es bash (el interprete de ordenes de las distribuciones GNU-Linux)/]
    ]Como redactar un script bash (un simple fichero de texto que se distingue por su primera liña, la famosa “bang-line!” : #!/bin/bash/]
    ]Como ejecutar un script bash (nos situamos en el directorio con nuestra consola y invocamos bash + el nombre del script)/]
    ]Hemos hecho nuestro pirmer script con el orden “echo” (que sirve para escribir en consola/]
    [/list]

  • En nuestro segundo curso Introducción bash, paso 2 : variables, expresion regular (grep) y pipe hemos visto:
    [list=]
    ]Lo que es una* variable** (ejemplo del cajón), como declarar la (<nombre_de_la_variable=valor_de_la_variable>) y como usar la ( con el simbolo $ para ver su valor) /
    ]
    ]Lo que es una **expresión regular **(una cadena cualquiera que definimos) y a que sirve (se usa para buscar coincidencias)/]
    ]Como usar básicamente el comando grep que permite definir y “jugar” con expresiones regulares/]
    ]El comando “cut” que nos permite recortar texto/]
    ]El* pipe** (“|”) que encadena dos comandos mandando el resultado del primero comando (su stdout) al segundo comando /*]
    [/list]

  • En nuestro tercero curso Introducción a bash -paso3- fichero de transición, cat, tee y read hemos visto:
    [list=*]
    ]La técnica del fichero de transición que consiste en guardar la salida de nuestras consolas para usarla posteriormente/]
    ]El comando “cat” que nos permite abrir un fichero de texto/]
    ]El comando “tee” que nos permite duplicar la salida de nuestra consola para guardar la en un fichero de texto /]
    ]El comando “read” que nos permite leer lo que entra el usuario en consola/]
    [/list]

  • En nuestro cuarto curso Introducción a bash -paso4- Condiciones “if-elif-else-fi” hemos visto:
    [list=*]
    ]Que es y como redactar una condición univoca simple “if-then-fi” ( si nuestra condición se cumple entonces se ejecuten ciertas ordenes) /]
    ]Los operadores lógicos sobre cadenas para redactar nuestras condiciones ( = condición se ejecuta si las expresiones son iguales; =! se jecuta sin son diferentes; -z se ejecuta si la cadena es vacila, -n si la cadena es nula )/]
    ]Las condiciones if-then-else-fi - Si (if) mi condición se cumple Entonces (then) se ejecutan ciertas ordenes; De lo contrario (else) se ejecutan otras ordenes (/]
    ]Por ultimo las condiciones múltiples" if-elif-else-fi" ( if - condición1 → orenes1 elif - condicón2 → ordenes2 elif condición 3 > orenes 3 etc…) /]
    ]De paso hemos conocido al comando whoami que pone en consola el nombre de usuario en acción, y el comando exit que nos permite salir de un script /]
    [/list]

    Habíamos acabado nuestro cuarto curso redactando una condición de control para poner en inicio de un script dedicado a pixie dust

#!/bin/bash if "$(whoami)" != 'root' ] # Abrimos nuestra condición con "if" . Nuestra condición verifica que el resultado de whoami sea diferente de "root" then # si es asi es que no podremos ejecutar reaver o pasar el mode monitor echo " This script requires root privileges Please run it with sudo ( sudo bash script.sh ) " # con "echo" escribimos en consola une mensaje de advertencia exit 1 # salimos en "estado de error" (1) elif "$(ls /usr/local/bin/pixiewps)" != '/usr/local/bin/pixiewps' ] # segunda condición a verifcar : la presencia de pixiewps en usr/local/bin then echo " This script requires pixiedust Please download and install pixiedust " # advertencia y exit 1 # salida en estado en error elif "$(ls /usr/local/bin/reaver)" != '/usr/local/bin/reaver' ] || "$(ls /usr/local/bin/pixiewps)" != '/usr/local/bin/pixiewps' ] # tercera condicion si no tenemos reaver o buly no podremos hacer el attaque asi que avortamos la misión then echo " This script requires a modified version of reaver or bully Please download or install one of this tool " exit 1 # salida en estado en error else # usamos else para escribir un mensage de exito (inecesario pero para hacer un bucle con todos los argumentos echo " It seems that your sytem is prepared for pixiedust atack :) Good luck!" fi # la necesaría instrucción de cierre "fi" que indica el "fi"nal de nuestra condición echo " Script under construction... See you in next chapter at www.wifi-libre.com" exit 0

Hoy seguiremos adelantando interesando nos a la selección de interfaz que vendría lógicamente en inicio de script.
Veremos para lograr un buen código como usar las condiciones vistas en el capitulo anterior y nos ayudaremos con nuevos comandos : awk, sed y la utilización de &&

Lo primero es hacer un plan de ataque.... el curso empieza en le post que sigue

[h]1) Prevenir los fallos : Añadir una condición para la versión de aircrack-ng[/h]

Sabemos que a partir de la versión** 1.2rc1 de aircrack-ng** el resultado de airmon-ng ha cambiado (obtenemos wlanXmon en mode monitor)
Como hay que mirar por adelante vamos a añadir en nuestro primero bucle elif una condición para verificar que aircracdk-ng sea en su ultima versión.
Lo que se me ocurre rápido es simplemente hacer un “grep” con expresión regular “Aircrack-ng 1.2 rc2”
Quitamos el “else” en final de nuestro script y añadimos la condición para la versión de aircrack-ng :

#!/bin/bash if "$(whoami)" != 'root' ] # Abrimos nuestra condición con "if" . Nuestra condición verifica que el resultado de whoami sea diferente de "root" then # si es asi es que no podremos ejecutar reaver o pasar el mode monitor echo " This script requires root privileges Please run it with sudo ( sudo bash script.sh ) " # con "echo" escribimos en consola une mensaje de advertencia exit 1 # salimos en "estado de error" (1) elif "$(ls /usr/local/bin/pixiewps)" != '/usr/local/bin/pixiewps' ] # segunda condición a verifcar : la presencia de pixiewps en usr/local/bin then echo " This script requires pixiedust Please download and install pixiedust " # advertencia y exit 1 # salida en estado en error elif "$(ls /usr/local/bin/reaver)" != '/usr/local/bin/reaver' ] || "$(ls /usr/local/bin/pixiewps)" != '/usr/local/bin/pixiewps' ] # tercera condicion si no tenemos reaver o buly no podremos hacer el attaque asi que avortamos la misión then echo " This script requires a modified version of reaver or bully Please download or install one of this tool " exit 1 # salida en estado en error elif -z "$( aircrack-ng | grep 'Aircrack-ng 1.2 rc2' )" ] # nueva condición para verificar que la versión de aircrack-ng es la ultima then echo "Please update to the last stable version of aircrack-ng (Aircrack-ng 1.2 rc2)" # mensaje de error fi

como veis la ultima condición es simplemente : 1 lanzar aircrack-ng
2 y con un pipe usar grep sobre la versión 1.2rc2 que es la que requiere nuestro programa.
Si no se “grepea” nada (operador -z, nuestra cadena es vaciá) = no tenemos a la 1.2rc2 y se sale del programa en estado de error exit(1)

[h]2) segundo paso : Un buen fichero de transición[/h]

Volvemos a usar la técnica del** fichero del transición**,
Pero vamos a “depurar” el resultado para tener un fichero con una interfaz por liña.
Asi, solo con contar las liñas de nuestro fichero de transición sabemos cuantas interfaces hay.
El stdout (la salida) de airmon-ng es así :

PHY Interface Driver Chipset < primera liña : no nos interesa < segunda liña : tampoco phy0 wlan0 ath9k Qualcomm Atheros QCA9565 / AR9565 Wireless Network Adapter (rev 01) phy1 wlan2 rtl8187 Realtek Semiconductor Corp. RTL8187 < ultima liña vacía : no nos interesa

¿Como quitar nuestras liñas que sobran? Es una ocasión perfecta para conocer al amigo sed…
SED es uno de los comandos mas peculiares de UNIX. Es un poco una mezcla entre “grep-cut” y otros comandos y nos ayuda a hacer muchas cosas.
Una de ellas es recortar liñas de un texto con el argumento “d”.
1 . Con sed ‘1,2d’ cortamos la primera y la segunda liña.
2 . Y para cortar la ultima se pude hacer así : ** sed ‘$d’**

Creamos un fichero de transición depurado…

airmon-ng | sed '1,2d' | sed '$d' >  /tmp/interfaces.txt

Notáis que para volcar el resultado de mi comando airmon-ng depurado en un fichero de transición he usado el símbolo "** >** " (dirigir la salida) seguido por la ruta hacía un fichero que llamo “interfaces.txt”.
Lo pongo en la carpeta para archivos temporales (tmp) porque como es un archivo de transición tiene vocación a desaparecer.
Con el comando cat podemos visualizar este archivo para ver si hemos depurado correctamente.
https://www.wifi-libre.com/img/members/3/bash5_2.jpg

ferrrrpecto :stuck_out_tongue:

[h]3) tercero paso : redactar un patrón[/h]

Para ello hay que pensar un poco las cosas…
Con el numero de linea que tiene nuestro fichero de transición podemos saber cuentas interfaces compatibles hay en el sistema.
Podemos distinguir entre tres casos mayores.
[list=1]
]Fichero con **0 **liinea, es decir que no hay interfaz reconocida y salimos del script/]
]Fichero con una liña : una sola interfaz que podemos pasar ne mode monitor y usar/]
]Fichero con varias liñas : varias interfaces - tendremos que proponer al usuario cual elegir/]
[/list]

Y esto lo sabemos hacer…

[quote]Si (if) No hay interfaz (0 lineas en el fichero de transición)
Entonces (then)
Salimos del script
Sino (elif) , si tenemos una sola linea en el texto de transición, es que hay una sola interfaz
Entonces (then)
podemos activar el mode monitor y guardar la interfaz en una variable para usar la con wash y reaver
Sino (else - porque no tenemos otra condición a añadir) es que tenemos mas de una interfaz
haremos un menu o pediremos con read que se elige una interfáz
fi <<<<<< instrucción de cierre[/quote]

¿Como contar el numero de linea? lo podemos hacer con el comando wc. (word count y no water closed :rolleyes: :D)
WC sirve para contar las liñas, las palabras o los bytes que componen un fichero
para contar las** llineas usaremos el argumento -l ** ejemplo:
https://www.wifi-libre.com/img/members/3/bash5_3.jpg
Notáis que lo hago de forma un poco rara, invoco primero wc -l que alimento después con
<
+ mi fichero de transición
Es un truco para obtener solo el numero de liña

[h]4) cuarto paso : awk en refuerzo[/h]

Es un buen momento para conocer a awk, uno de los mejores comandos UNIX… :cool:
AWK : permite seleccionar cadenas definiendo campos
Imaginamos que quiera seleccionar en nuestro fichero la segunda palabra

cat /tmp/interfaces.txt phy0 wlan0 ath9k Qualcomm Atheros QCA9565 / AR9565 Wireless Network Adapter (rev 01) phy1 wlan2 rtl8187 Realtek Semiconductor Corp. RTL8187
lo puedes hacer así

cat /tmp/interfaces.txt |  awk -F' ' '{ print $2 }'

[list=]
]-F : decretamos que vamos a definir y usar unos “campos” (field)/]
]’ ’ : ponemos un espacio entre dos serradores ’ ’ . significa que nuestros campos serán delimitados por los espacios/]
]* ‘{ print $2 }’** : Así indicamos de seleccionar el segundo campo, es decir la segunda palabra en nuestra linea/
]
[/list]
La ventaja de awk sobre** cut** es que awk mira varios espaciosa puestos al lado como un solo espacio.

[h]5) Añadir criterios con “&&” en nuestras condiciones[/h]

Muy a menudo habréis visto tutoriales dónde podéis ver cosas como

make && sudo make install

Se ejecuta make y con “&&” se ejecuta enseguida la orden que sigue (make intsall en este caso).
Es diferente de un pipe,
Se ejecuta la orden 1 y el resultado sale en consola como siempre, luego se ejecuta la orden 2 con la salida que se muestra consola y si ponemos otros && y una tercera orden se ejecutaría la orden que sigue etc…
Lo bueno es que podemos usar esto para añadir condiciones necesarias en nuestras lineas if, elif y else.

ahora hemos decidido hacer un bucle con tres condiciones:
0 liña en nuestro texto “interfaces” = 0 interfaces = salida del scirpt
1 liña en nuestro texto “interfaces” = 1 interfaces = activar o no activar el mode monitor
2 o más liñas en nuestro texto “interfaces” = varais interfaces = menú

con 0 adaptadores un solo comportamiento : salir del script.
con 1 adaptador 2 comportamientos : activar el mode monitor si no esta activado. NO activar el mode monitor si no esta activado
con más de 1 adaptador un comportamiento : llevar a un menú de selección. < próximo capitulo

Lo más aconsejable en este caso es añadir un criterio a nuestra liña elif.
Si la interfaz única esta en mode monitor va a tener un nombre tipo** wlanXmon**.
Si no esta en mode monitor tendrá un nombre tipo wlanX
- Lo que diferencia los dos es la cadena “mon” que vamos a elegir como expresión regular.
- Si hacemos un** grep **con expresión regular “mon” en una interfaz en mode monitor obtendremos una cadena (no será vacilá)
Entonces para identificar el estado de nuestra sola interfaz y seleccionar la si esta en mode monitor añadimos

&&  -n "$( cat /tmp/interfaces.txt | awk -F' ' '{ print $2 }' | grep mon )" ]

Hacemos un grep con expresión regular “mon” sobre nuestra liña única del fichero para interfaces (usamos “cat” para abrirlo).
Con awk hemos seleccionado el segundo campo con delimitador “espacio” para evitar errores y hacer que el grep se haga solo sobre el nombre de la interfaz.
Como la interfaz esta en mode monitor solo hay que recogerla en una variable para usar la con reaver. Lo que nos da:

airmon-ng | sed '1,2d' | sed '$d' > /tmp/interfaces.txt if "$( wc -l < /tmp/interfaces.txt )" = '0' ] then echo "0 interfaces" elif "$( wc -l < /tmp/interfaces.txt )" = '1' ] && -n "$( cat /tmp/interfaces.txt | awk -F' ' '{ print $2 }' | grep mon )" ] then echo " - One interface detected by airmon-ng" echo " - The interface is already in monitor mode" INTERFACE=$( cat /tmp/interfaces.txt | awk -F' ' '{ print $2 }') echo " - $INTERFACE ready to use for pixiedust!" fi
https://www.wifi-libre.com/img/members/3/bash5_4.jpg

[h]6) Condición múltiple para manejo automatizado de las interfaces[/h]

acabmos de hacer una condición que
[list=1]
]Sale del scirpt si nuestro fichero tiene 0 linea (no hay interfaces compatibles)/]
]Selecciona la interfaz si el fichero contiene una linea Y se enceuntra la expressión regular “mon” en el campo dos con delimitador espacio (segunda palabra, la interfaz)
Para tener una condición múltiple que abarque todas las situaciones debemos añadir dos casos más :confused:
]
]Pasar la interfaz en mode monitor si el fichero contiene una liña (una sola interfaz) Y no obtenemos nada buscando la expresión regular “mon” (interfaz tipo wlanX, sin mode monitor activado) /]
]Si tenemos varias interfaces llevaremos a un menú de selección (próxima lesión) /]
[/list]

En nuestro elif anterior utilizamos -n sobre el resultado de nuestro grep con expresión regular mon
con
-n
la condición se verifica si la cadena NO es nula (no es vacía)
con -z obtendremos el resultado opuesto ( la condición se verifica si la cadena es nula). Si nuestra interfaz no lleva la expresión “mon” no pilaremos nada con grep y tendremos una cadena nula.
En este caso activaremos el mode monitor y declararemos la variable $INTERFAZ.
Lo que nos da

elif  "$( wc -l < /tmp/interfaces.txt )" = '1' ] &&  -z "$( cat /tmp/interfaces.txt | awk -F' ' '{ print $2 }' | grep mon )" ]

(cambiamos el** -n** por** -z**)
Y con la liña siguiente activamos el mode monitor

airmon-ng start `cat /tmp/interfaces.txt | awk -F' ' '{ print $2 }'`

Hacemos airmon-ng sobre cat /tmp/interfaces.txt | awk -F’ ’ ‘{ print $2 }’ ; es decir nuestro pipe para sacar la segunda palabra de la liña del archivo de transición. (wlanX)

A continuación una condición completa (añadimos un else para los casos con varias interfaces)

[code]airmon-ng | sed ‘1,2d’ | sed ‘$d’ > /tmp/interfaces.txt
if “$( wc -l < /tmp/interfaces.txt )” = ‘0’ ]
then
echo “----------------------------------------------------------”
echo “WARNING :
No interface compatible with airmon-ng
Pxie dust requires mode monitor and injection
Exiting script…”
echo “----------------------------------------------------------”
exit 1
elif “$( wc -l < /tmp/interfaces.txt )” = ‘1’ ] && -n “$( cat /tmp/interfaces.txt | awk -F’ ’ ‘{ print $2 }’ | grep mon )” ]
then
echo “----------------------------------------------------------”
echo " - One interface detected by airmon-ng"
echo " - The interface is already in monitor mode"
echo “----------------------------------------------------------”
INTERFACE=$( cat /tmp/interfaces.txt | awk -F’ ’ ‘{ print $2 }’)
echo " - $INTERFACE ready to use for pixiedust!"
echo “----------------------------------------------------------”
elif “$( wc -l < /tmp/interfaces.txt )” = ‘1’ ] && -z “$( cat /tmp/interfaces.txt | awk -F’ ’ ‘{ print $2 }’ | grep mon )” ]
then
echo “----------------------------------------------------------”
echo " - One interface detected by airmon-ng"
echo " - The interface is in managed mode"
echo “----------------------------------------------------------”
echo " Monde Monitor is to be enabled,
WARNING :
Connexion will be impossible with the selected wireless interface
Untill you exit the script"

airmon-ng start `cat /tmp/interfaces.txt | awk -F' ' '{ print $2 }'`

echo “----------------------------------------------------------”
INTERFACE=$( echo “cat /tmp/interfaces.txt | awk -F' ' '{ print $2 }'mon” )
echo " - $INTERFACE ready to use for pixiedust! "
echo “----------------------------------------------------------”
else
echo “----------------------------------------------------------”
echo " SEVERAL INTERFACE : SCRIPT UNDER CONSTRUCTION"
echo " see you in next chapter ;)"
echo “----------------------------------------------------------”
fi[/code]

https://www.wifi-libre.com/img/members/3/bash5_5.jpg

podéis jugar con ella y veréis que cumple su oficio. Para acabarla en el próximo capitulo nos encargaremos de hacer un menú de selección para nuestro else (varias interfaces)
hasta entonces… May the bash with you !