Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: alicia19es en 28 Diciembre 2013, 02:11 am



Título: Interceptar borrado de archivo
Publicado por: alicia19es en 28 Diciembre 2013, 02:11 am
Hola a todos, estoy dando los ultimos toques a una aplicación realizada en vb.net.
La aplicación detecta la introducción de usb en el pc y realiza una copia en el disco de archivos segun unos filtros determinados, comprobando previamente que ya no exista mediante codificacion md5.
Pero quiero ir un poco más allá, y he pensado en que se realice una copia del fichero que el usuario intente eliminar, ya que esta eliminacion puede deberse a dos motivos:
  • 1. A que el archivo no le valga
  • 2. Que el archivo sea digámoslo "comprometido" y le interese eliminarlo
He estado haciendo pruebas con el systemfilewatcher, pero solo detecta los eventos una vez producidos, por lo que cuando intento copiar el archivo, este ya no existe.
La pregunta es, ¿Existe alguna forma de interceptar ese intento de borrado para realizar una copia previa de dicho archivo?

Gracias.


Título: Re: Interceptar borrado de archivo
Publicado por: alicia19es en 28 Diciembre 2013, 13:08 pm
Bueno, no consigo encontrar nada por ahí referente al tema.
Pienso que quizás podría intentar algo como capturar el proceso y los argumentos que utiliza Windows cuando recibe la orden de borrado de archivos.
Pero ¿como se llama ese proceso?¿Cómo interceptarlo?, etc...
Si alguien tiene alguna idea, por favor, que lo postee.
Gracias y saludos


Título: Re: Interceptar borrado de archivo
Publicado por: Eleкtro en 28 Diciembre 2013, 14:26 pm
No es nada facil, debes crear o bien un Hook Global (API Hook), o bien un driver (File System Filter Driver).

La función (indocumentada) NtSetFileInformation de la WinAPI es llamada para eliminar un archivo, con la estructura FileDispositionInformation ,
aunque también debes mirar la función DeleteFile, y no se si habrá otras, y luego está el uso de la interface ICopyHook que exclusívamente previene de la eliminación mediante la Shell.

Para intentar hookear la API puedes utilizar la librería Deviare, o EasyHook, mhook (c++), u otras. Hay varios ejemplos en Google tanto para VBNET como C#, aunque parece que todas las librerías tienen sus desventajas y bugs.

EDITO: En este ejemplo (http://stackoverflow.com/questions/19997011/hooking-ntcreatefile-api-from-ntdll-dll-with-easyhook-c) puedes hacerte una idea del modo de empleo de Easyhook junto a lo necesario para hookear dicha functión NtSetFileInformation.

Saludos.


Título: Re: Interceptar borrado de archivo
Publicado por: ThinkByYourself en 28 Diciembre 2013, 14:31 pm
Puedes hacerloo bien... o puedes buscar el camino corto.

No sé si se podrá pero a lo mejor puedes listar (en un bucle infinito) los ficheros del directorio que se supone que tiene que guardar lo que haya en el usb, y cuando se liste algo diferente que nada PUM!!!!!!!! Bacap al canto, cifrado y ocultamiento. Dime si te sirve, no sería la primera vez que lo he pensado! Un saludo!


Título: Re: Interceptar borrado de archivo
Publicado por: alicia19es en 28 Diciembre 2013, 17:18 pm
Muchas gracias a los dos.
En principio quiero hacerlo bien, pero me parece Elektrosoft que eso puede sobrepasar mi nivel de conocimientos. De todas formas lo miraré.
Una pregunta: ¿Con kernel.dll y user32.dll no podría conseguir algo? Por ejemplo con las deletefile, etc...?
Gracias


Título: Re: Interceptar borrado de archivo
Publicado por: Eleкtro en 28 Diciembre 2013, 19:12 pm
user32.dll ... deletefile ...

Esa es precísamente una de las funciones que nombré: http://msdn.microsoft.com/en-us/library/windows/desktop/aa363915%28v=vs.85%29.aspx

Iguálmente deberías hookear esa función para interceptar cuando el SO llama a la función, pero ya puestos mejor prueba con NtSetFileInformation (se encuentra en la ntdll.dll) porque según he leido es la función por la que pasa cualquier método de eliminación (y otros), aunque está indocumentada así que mucha información no tengo, pero DeleteFile ahora que lo leo la documentación es posible que no tenga nada que ver con tu propósito puesto que no tiene parámetros para enviar a la papelera, es una función que debe estar limitada a la Shell (supongo).

Saludos


Título: Re: Interceptar borrado de archivo
Publicado por: alicia19es en 28 Diciembre 2013, 21:00 pm
Hola ElectroSoft, gracias por la ayuda.
En principio voy a descartar el hacerlo mediante la interface ICopiHook y el DeleteFile del kernel.dll, ya que si solo intercepta el borrado mediante shell, pues creo que no me vale.
Mi intención es que intecepte los eventos habituales de un borrado de archivo, seleccionarlo y pulsa la tecla suprimir, quizás se pueda inteceptar esas pulsaciones y actuar en consecuencia, aunque tendría que realizar un bucle infinito, algo que no me gusta demasiado.
He estado un par de hora  investigando sobre la función NtSetFileInformation, pero la verdad es que hay bien poco.
Alguna orientación más que me puedas dar. Tus consejos son bienvenidos, gracias a ellos voy viendo por donde tirar.
Saludos y gracias de nuevo.



He localizado este enlace donde se puede extraer alguna informacion, ahora es necesario descifrarlo  :rolleyes:
http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/NtDeleteFile.html (http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/NtDeleteFile.html)



[MOD]: No hagas doble post, utiliza el botón 'MODIFICAR'.


Título: Re: Interceptar borrado de archivo
Publicado por: Eleкtro en 29 Diciembre 2013, 01:34 am
No se si te das cuenta de la cantidad de conocimientos que se requieren para llevar a cabo esta tarea, además de la experiencia en intentos fallidos, si ...porque hookear APIS es lo que tiene, que por alguna chorrada insignificante un hook puede ir perféctamente en Windows XP, pero no funcionar en otra versión de Windows, y lo mismo con las arquitecturas, además entre las diferentes versiones de windows pueden modificar los parámetros de "X" funciones. Fíjate si es dificil que resulta necesario utilizar librerías de terceros para realizar estos hooks de forma decente los cuales ya se encargan de inyectar y etc...

Este campo no lo he tocado prácticamente nada, no vayas a pensar que soy un experto en el tema, los únicos hooks que he realizado han sido de bajo nivel con las funciones que la WinAPI proporciona para instalar los hooks, pero a lo que voy ...implementar ICopyHook sería una manera más limpia (y estable) sin necesidad de Hookear, y te permitiria tener control sobre los archivos eliminados desde el Explorer, pero sigue siendo una pesadilla llevarlo a cabo.

Ahora bien, hay otra alternativa mucho más facil que se me ha ocurrido, sirviéndote del FileSystemWatcher. No pongo la mano en el fuego de haberlo dejado 100% efectivo, deberías testear en profundidad lo que sucede cuando eliminas dos archivos/carpetas con el mismo nombre pero con distinta fecha de modificación para comprobar si se restaura la que se debe restaurar, yo solo te dejo la idea:

EDITO: Para proceder a usar el siguiente código necesitas referenciar Microsoft Shell Controls And Automation.
EDITO2: Le añadí un par de cosas más, y también lo documenté un poco mejor...
Código
  1. Imports System.IO
  2. Imports Shell32
  3.  
  4. Public Class Test
  5.  
  6.    Private SH As New Shell
  7.    Private RecycleBin As Folder = SH.NameSpace(ShellSpecialFolderConstants.ssfBITBUCKET)
  8.    Private WithEvents FSW As New FileSystemWatcher
  9.  
  10.    Private Shadows Sub Load() _
  11.    Handles MyBase.Load
  12.  
  13.        ' Seteo las propiedades del objeto 'FileSystemWatcher'.
  14.        With FSW
  15.            .Path = "C:\Test"
  16.            .IncludeSubdirectories = True
  17.            .Filter = "*"
  18.            .NotifyFilter = NotifyFilters.FileName Or NotifyFilters.DirectoryName
  19.            .EnableRaisingEvents = True
  20.        End With
  21.  
  22.    End Sub
  23.  
  24.    Private Sub OnItemDeleted(sender As FileSystemWatcher, e As FileSystemEventArgs) _
  25.    Handles FSW.Deleted
  26.  
  27.        ' Almacenamos una colección de los items de la papelera de reciclaje.
  28.        ' Tanto archivos, carpetas, y accesos directos .lnk (que no se tratan como archivos ni carpetas),
  29.        ' cuyo nombre sea el mismo nombre que el elemento que se acaba de eliminar.
  30.        ' Y los ordenamos por su fecha de modificación.
  31.        Dim DeletedItems As IEnumerable(Of FolderItem) =
  32.            RecycleBin.Items.Cast(Of FolderItem).
  33.                             Where(Function(Item) Item.Name = e.Name).
  34.                             OrderBy(Function(Item) Item.ModifyDate)
  35.  
  36.        ' Si hubiera más de un elemento con el mismo nombre,
  37.        ' seleccionamos el último elemento que se eliminó (o al menos, eso se supone que debería suceder.)
  38.        Dim LastDeletedItem As Shell32.FolderItem = DeletedItems.LastOrDefault
  39.  
  40.        If LastDeletedItem IsNot Nothing Then
  41.  
  42.            ' Esto es un simple checkeo por prevención,
  43.            ' considero que solo hay un 0,00001% de posibilidades de que se de la condición...
  44.            ' Esto podría deberse a que el usuario haya desecho manuálmente la acción de borrado (CTRL+Z),
  45.            ' en un tiempo menor del que la aplicación ha procesado los elementos de la papelera.
  46.            '
  47.            ' También está el caso de las incontrolables acciones de terceros,
  48.            ' Como por ejemplo el editor de texto 'Sublime Text', que al modificar un archivo,
  49.            ' lo elimina dando un falso positivo.
  50.            If (LastDeletedItem.IsFolder AndAlso Directory.Exists(e.FullPath)) _
  51.               OrElse (Not LastDeletedItem.IsFolder AndAlso File.Exists(e.FullPath)) Then
  52.  
  53.                Throw New Exception(String.Format("¿ El elemento ha sido restaurado ?: {0}", e.FullPath))
  54.                Exit Sub
  55.  
  56.            End If
  57.  
  58.            ' Invocamos el verbo "undelete" para deshacer la acción de borrado sin necesidad de escribir más isntrucciones.
  59.            ' Otros verbos que se pueden usar por ejemplo "delete" para eliminar el elemento de forma permanente,
  60.            ' u "open" para abrir las propiedades del elemento.
  61.            LastDeletedItem.InvokeVerb("undelete")
  62.  
  63.            ' O bien hacemos otra cosa distinta, como por ejemplo un backup del archivo/directorio eliminado...
  64.            '
  65.            'Dim BackupPath = String.Format("C:\Backup\{0}", e.Name)
  66.            '
  67.            'Select Case LastDeletedItem.IsFolder
  68.            '
  69.            '    Case True
  70.            '        FileIO.FileSystem.CopyDirectory(LastDeletedItem.Path, BackupPath,
  71.            '                                        FileIO.UIOption.AllDialogs, FileIO.UICancelOption.ThrowException)
  72.            '
  73.            '    Case False
  74.            '        FileIO.FileSystem.CopyFile(LastDeletedItem.Path, BackupPath,
  75.            '                                   FileIO.UIOption.AllDialogs, FileIO.UICancelOption.ThrowException)
  76.            '
  77.            'End Select
  78.  
  79.        End If
  80.  
  81.    End Sub
  82.  
  83. End Class

Saludos


Título: Re: Interceptar borrado de archivo
Publicado por: alicia19es en 29 Diciembre 2013, 12:03 pm
ElectroZoider (¿Te has cambiado el nick?, te has salido.
Vaya tela, la clase que me acabas de ofrecer. Voy a analizarla un poco y ya te cuento. De verdad muchas gracias. Yo no tengo ese nivel todavía, algunas cosas se me escapan, sobre todo a la hora de buscar las declaraciones correctas, funciones de las namespaces, tipo de atributos segun su estructura....
En fin poco a poco voy aprendiendo con gente como tú.
Muchas gracias, en cuanto lo pruebe te lo comento.

-----------------------------------------------------------------------------
Ya he hecho las comprobaciones.  Me da error en la declaración que realizas en la línea 38:
         Dim LastDeletedItem As Shell32.FolderItem = DeletedItems.LastOrDefault me dice:

'LastOrDefault' no es un miembro de 'System.Collections.Generic.IEnumerable(Of Shell32.FolderItem)'.   

y si le doy a ignorar errores y lo ejecuto, una vez elimino un archivo se rompe el programa mostrándome lo siguiente:

No se controló MissingMemberException

No se encuentra el miembro público 'Cast' en el tipo 'FolderItems3'.

Alguna idea del porqué? Saludos y gracias.


Título: Re: Interceptar borrado de archivo
Publicado por: Eleкtro en 29 Diciembre 2013, 16:41 pm
No se controló MissingMemberException
No se encuentra el miembro público 'Cast' en el tipo 'FolderItems3'.

Alguna idea del porqué? Saludos y gracias.

En el código de arriba utilizo algunos métodos de LINQ (.Cast, .Last), para utilizarlos es necesario utilizar la versión Framework 3.5 como mínimo, entonces tienes que actualizar la versión del objetivo de Framework en las propiedades de tu proyecto e importa LINQ:
Código
  1. Imports System.Linq

http://msdn.microsoft.com/en-us/library/system.linq.enumerable_methods%28v=vs.100%29.aspx



ElectroZoider (¿Te has cambiado el nick?).
Si jeje, es posible que me vuelva a cambiar de nick antes de acabar el año

Saludos


Título: Re: Interceptar borrado de archivo
Publicado por: alicia19es en 29 Diciembre 2013, 23:04 pm
 ;-) ;-) ;-)Jajajaja, qué mákina, estaba utilizando el 3.0
Voy a verlo y te comento.
Gracias de nuevo

--------------------------------------------------------------------------

Esto va de lujo Elektro, asombrada me dejas. Voy a modificar un poco para que se ajuste a mis intereses, a ver si no lo fastidio.
Por cierto, Electro, yo que vengo del vb 5 y 6, y me estoy metiendo poco a poco con el net. El tema de trabajar con las framework ¿es parecido a como se trabajaban las apis en las anteriores versiones?

Saludos.


Título: Re: Interceptar borrado de archivo
Publicado por: Eleкtro en 30 Diciembre 2013, 23:46 pm
Esto va de lujo Elektro, asombrada me dejas. Voy a modificar un poco para que se ajuste a mis intereses, a ver si no lo fastidio.

Me alegro de que te haya servido.


vengo del vb 5 y 6 ... El tema de trabajar con las framework ¿es parecido a como se trabajaban las apis en las anteriores versiones?

Yo en cambio fuí directo a VB.NET, aunque ya había tocado VB6 hace bastante tiempo ...pero fue muy poco, de todas formas la pregunta que formulas en mi opinión no tiene relación así que tampoco tiene mucho sentido contestarla con un "SI" o un "NO".

Como bien sabrás, VB6 no maneja Microsoft Framework, por lo tanto todas las classes de .NET es un mundo distinto que hay que aprender a usar. Y las APIS se declaran de forma distinta (al estilo .NET) pero se trabajan igual, cambian algunos tecnicismos como los datatypes Integer por Long, pero se usan básicamente de la misma manera... usando el código equivalente de VB6 a VBNET.

No se si te habré aclarado la duda porque tampoco la he entendido bien xD,
Saludos.


Título: Re: Interceptar borrado de archivo
Publicado por: alicia19es en 2 Enero 2014, 01:37 am
Gracias Electro, de nuevo. XDDD, ¿Cuántas veces te vas a cambiar de nick?  :laugh: :laugh:
El código que me enviaste va estupendo. Ahora esoty intentando implementar que cuando se produzca el interceptado del borrado de archivo se envíe  por ftp a un alojamiento que tengo contratado.
Lo estoy haciendo con esto:

My.Computer.Network.UploadFile("c:\2.jpg", "ftp://miespacio.es/e.jpg", "nombreUsuario", "Contraseña", False, 1000)

Me sube el archivo al alojamiento, pero.... jejeje, y ahora vienen los peros:
1º Lo veo lento en relación con el cliente FileZilla que uso para mi web (provengo de php)
2º Aunque en principio esto que estoy haciendo es para aprender un poco y para una persona en particular que no tiene conocimiento informáticos alguno, mediante herramientas podrían ver mi alojamiento, usuario y clave en caso de investigación, aunque claro está qu en no voy a espiar a la nasa ni nada de eso.
3º He leído que se puede ofuscar el código, pero.. no encuentro ninguno gratuito fiable.
4º ¿Uso el código de arriba o es mejor utilizar la clase FtpWebRequest?

Muchas gracias y saludos.
PD: Feliz Año.



Título: Re: Interceptar borrado de archivo
Publicado por: Eleкtro en 2 Enero 2014, 04:52 am
3º He leído que se puede ofuscar el código, pero.. no encuentro ninguno gratuito fiable.

Si buscas uno gratis, en ese caso Confuser es el mejor ~> http://confuser.codeplex.com/

My.Computer.Network.UploadFile("c:\2.jpg", "ftp://miespacio.es/e.jpg", "nombreUsuario", "Contraseña", False, 1000)

1º Lo veo lento en relación con el cliente FileZilla que uso para mi web (provengo de php)
4º ¿Uso el código de arriba o es mejor utilizar la clase FtpWebRequest?

Debes evitar en todo lo posible el uso de los métodos de My.Computer (aunque alguno que otro es excelente).

En MSND puedes encontrar un buen ejemplo con FtpWebRequest ~> How to: Upload Files with FTP (http://msdn.microsoft.com/en-us/library/ms229715%28v=vs.110%29.aspx)

Y te dejo otra alternativa, usando la librería FTPClient junto a un WebClient como puedes ver en el ejemplo de mi Helper Class ~> .:: By Elektro ::. Un ayudante para la librería FTPClient (http://foro.elhacker.net/net/libreria_de_snippets_posteen_aqui_sus_snippets-t378770.0.html;msg1899985#msg1899985)

Saludos


Título: Re: Interceptar borrado de archivo
Publicado por: Maurice_Lupin en 10 Enero 2014, 15:52 pm
Ummm interesante tema, lo que normalmente haria seria buscar un ejemplo en C++ utilizando la API e implementarlo en vb.net consultando http://www.pinvoke.net/

Por cierto cuando presionas Shift+Supr eliminas el archivo sin enviar a la papelera. Detecta ese evento el codigo posteado?

Aqui un ejemplo utilizando API en C++
http://reversecode.cubava.cu/2013/10/haciendo-nuestros-ficheros-imborrables/

Saludos.


Título: Re: Interceptar borrado de archivo
Publicado por: Eleкtro en 10 Enero 2014, 20:36 pm
Por cierto cuando presionas Shift+Supr eliminas el archivo sin enviar a la papelera. Detecta ese evento el codigo posteado?

Por desgracia para todos el evento del FileSystemWatcher no previene de eliminacion corriente ni de eliminación permanente, solámente detecta el cambio post-eliminación, pero no antes.

Saludos!