!C99Shell v. 1.0 pre-release build #13!

Software: Apache. PHP/5.5.15 

uname -a: Windows NT SVR-DMZ 6.1 build 7600 (Windows Server 2008 R2 Enterprise Edition) i586 

SYSTEM 

Safe-mode: OFF (not secure)

C:\dmz\FileZillaFTP\source\   drwxrwxrwx
Free 4.08 GB of 39.52 GB (10.32%)
Detected drives: [ a ] [ c ] [ d ] [ e ] [ f ]
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     AdminSocket.cpp (9.85 KB)      -rw-rw-rw-
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
// FileZilla Server - a Windows ftp server

// Copyright (C) 2002-2004 - Tim Kosse <tim.kosse@gmx.de>

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.

// 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

// AdminSocket.cpp: Implementierung der Klasse CAdminSocket.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "AdminSocket.h"
#include "AdminInterface.h"
#include "OptionTypes.h"
#include "misc\md5.h"
#include "iputils.h"
#include "Options.h"
#include "version.h"

#define BUFSIZE 4096

//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////

CAdminSocket::CAdminSocket(CAdminInterface *pAdminInterface)
{
    ASSERT(pAdminInterface);
    m_pAdminInterface = pAdminInterface;
    m_bStillNeedAuth = TRUE;

    m_pRecvBuffer = new unsigned char[BUFSIZE];
    m_nRecvBufferLen = BUFSIZE;
    m_nRecvBufferPos = 0;
    
    SYSTEMTIME sTime;
    GetSystemTime(&sTime);
    VERIFY(SystemTimeToFileTime(&sTime, &m_LastRecvTime));
}

CAdminSocket::~CAdminSocket()
{
    for (std::list<t_data>::iterator iter=m_SendBuffer.begin(); iter!=m_SendBuffer.end(); iter++)
        delete [] iter->pData;

    delete [] m_pRecvBuffer;
}

BOOL CAdminSocket::Init()
{
    char *buffer = new char[100];
    char *p = buffer;
    strcpy(buffer, "FZS");
    p += 3;

    *p++ = 0;
    *p++ = 4;
    memcpy(p, &SERVER_VERSION, 4);
    p += 4;
    
    *p++ = 0;
    *p++ = 4;

    memcpy(p, &PROTOCOL_VERSION, 4);
    p+=4;

    COptions options;
    CStdString pass = options.GetOption(OPTION_ADMINPASS);
    CStdString peerAddress;
    UINT port = 0;
    if (GetPeerName(peerAddress, port) && IsLocalhost(peerAddress) && pass == _T(""))
    {
        BOOL res = Send(buffer, p-buffer) == p - buffer;
        delete [] buffer;
        if (!res)
        {
            Close();
            return FALSE;
        }
        return FinishLogon();        
    }
    else
    {
        *p++ = 0;
        
        DWORD len = 20;
        memcpy(p, &len, 4);
        p += 4;

        *p++ = 0;
        *p++ = 8;
        
        int i;
        for (i = 0; i < 8; i++)
        {
            m_Nonce1[i] = (rand()*256)/(RAND_MAX+1);
            *p++ = m_Nonce1[i];
        }
        
        *p++ = 0;
        *p++ = 8;
        
        for (i = 0; i < 8; i++)
        {
            m_Nonce2[i] = (rand()*256)/(RAND_MAX+1);
            *p++ = m_Nonce2[i];
        }
    }

    int res = Send(buffer, p-buffer) == p-buffer;
    delete [] buffer;
    return res;
}

BOOL CAdminSocket::SendCommand(int nType, int nID, const void *pData, int nDataLength)
{
    if (m_bStillNeedAuth)
        return TRUE;

    t_data data;
    data.pData = new unsigned char[nDataLength + 5];
    *data.pData = nType;
    *data.pData |= nID << 2;
    data.dwOffset = 0;
    memcpy(data.pData + 1, &nDataLength, 4);
    if (pData)
        memcpy(data.pData+5, pData, nDataLength);

    data.dwLength = nDataLength + 5;

    m_SendBuffer.push_back(data);
    
    do
    {
        data = m_SendBuffer.front();
        m_SendBuffer.pop_front();
        int nSent = Send(data.pData + data.dwOffset, data.dwLength - data.dwOffset);
        if (!nSent)
            return FALSE;
        if (nSent == SOCKET_ERROR)
        {
            if (WSAGetLastError()!=WSAEWOULDBLOCK)
                return FALSE;
            m_SendBuffer.push_front(data);
            return TRUE;
        }
        
        if ((unsigned int)nSent < (data.dwLength-data.dwOffset))
        {
            data.dwOffset += nSent;
            m_SendBuffer.push_front(data);
        }
        else
        {
            delete [] data.pData;

            SYSTEMTIME sTime;
            GetSystemTime(&sTime);
            VERIFY(SystemTimeToFileTime(&sTime, &m_LastRecvTime));
        }
    } while (!m_SendBuffer.empty());

    return TRUE;
}

void CAdminSocket::OnReceive(int nErrorCode)
{
    if (nErrorCode)
    {
        Close();
        m_pAdminInterface->Remove(this);
        return;
    }
    int numread = Receive(m_pRecvBuffer + m_nRecvBufferPos, m_nRecvBufferLen - m_nRecvBufferPos);
    if (numread > 0)
    {
        SYSTEMTIME sTime;
        GetSystemTime(&sTime);
        VERIFY(SystemTimeToFileTime(&sTime, &m_LastRecvTime));

        m_nRecvBufferPos += numread;
        if (m_nRecvBufferLen-m_nRecvBufferPos < (BUFSIZE/4))
        {
            unsigned char *tmp=m_pRecvBuffer;
            m_nRecvBufferLen *= 2;
            m_pRecvBuffer = new unsigned char[m_nRecvBufferLen];
            memcpy(m_pRecvBuffer, tmp, m_nRecvBufferPos);
            delete [] tmp;
        }
        int parseResult;
        while ((parseResult = ParseRecvBuffer()) > 0);

        if (parseResult == -1)
            return;
    }
    if (numread == 0)
    {
        if (ParseRecvBuffer() == -1)
            return;
        Close();
        m_pAdminInterface->Remove(this);
        return;
    }
    else if (numread == SOCKET_ERROR)
    {
        if (WSAGetLastError() != WSAEWOULDBLOCK)
        {
            if (ParseRecvBuffer() == -1)
                return;
            Close();
            m_pAdminInterface->Remove(this);
            return;
        }
    }
    while (ParseRecvBuffer() > 0);
}

void CAdminSocket::OnSend(int nErrorCode)
{
    if (nErrorCode)
    {
        Close();
        m_pAdminInterface->Remove(this);
        return;
    }

    while (!m_SendBuffer.empty())
    {
        t_data data=m_SendBuffer.front();
        m_SendBuffer.pop_front();
        int nSent = Send(data.pData+data.dwOffset, data.dwLength-data.dwOffset);
        if (!nSent)
        {
            Close();
            m_pAdminInterface->Remove(this);
            return;
        }
        if (nSent == SOCKET_ERROR)
        {
            if (WSAGetLastError() != WSAEWOULDBLOCK)
            {
                Close();
                m_pAdminInterface->Remove(this);
            }
            m_SendBuffer.push_front(data);
            return;
        }
        
        if ((unsigned int)nSent<(data.dwLength-data.dwOffset))
        {
            data.dwOffset+=nSent;
            m_SendBuffer.push_front(data);
        }
        else
            delete [] data.pData;
    }
}

int CAdminSocket::ParseRecvBuffer()
{
    if (m_nRecvBufferPos<5)
        return 0;

    if ((m_pRecvBuffer[0]&0x03) != 0)
    {
        SendCommand(_T("Protocol error: Unknown command type, closing connection."), 1);
        Close();
        m_pAdminInterface->Remove(this);
        return -1;
    }
    else
    {
        DWORD len;
        memcpy(&len, m_pRecvBuffer+1, 4);
        if (len > 0xFFFFFF)
        {
            SendCommand(_T("Protocol error: Invalid data length, closing connection."), 1);
            Close();
            m_pAdminInterface->Remove(this);
            return -1;
        }
        if (m_nRecvBufferPos < len+5)
            return 0;
        else
        {
            int nID = (m_pRecvBuffer[0]&0x7C) >> 2;
            if (m_bStillNeedAuth)
            {
                if (nID)
                {
                    SendCommand(_T("Protocol error: Not authenticated, closing connection."), 1);
                    Close();
                    m_pAdminInterface->Remove(this);
                    return -1;
                }
                if (len != 16)
                {
                    SendCommand(_T("Protocol error: Auth data len invalid, closing connection."), 1);
                    Close();
                    m_pAdminInterface->Remove(this);
                    return -1;
                }
                MD5 md5;
                md5.update(m_Nonce1, 8);
                COptions options;
                CStdString pass = options.GetOption(OPTION_ADMINPASS);
                if (pass.GetLength() < 6)
                {
                    SendCommand(_T("Protocol error: Server misconfigured, admin password not set correctly"), 1);
                    Close();
                    m_pAdminInterface->Remove(this);
                    return -1;
                }
                char* utf8 = ConvToNetwork(pass);
                if (!utf8)
                {
                    SendCommand(_T("Failed to convert password to UTF-8"), 1);
                    Close();
                    m_pAdminInterface->Remove(this);
                    return -1;
                }
                md5.update((unsigned char *)utf8, strlen(utf8));
                delete [] utf8;
                md5.update(m_Nonce2, 8);
                md5.finalize();
                unsigned char *digest = md5.raw_digest();
                if (memcmp(m_pRecvBuffer + 5, digest, 16))
                {
                    delete [] digest;
                    SendCommand(_T("Protocol error: Auth failed, closing connection."), 1);
                    Close();
                    m_pAdminInterface->Remove(this);
                    return -1;
                }
                delete [] digest;

                FinishLogon();
            }
            else
                m_pAdminInterface->ProcessCommand(this, nID, m_pRecvBuffer+5, len);
            memmove(m_pRecvBuffer, m_pRecvBuffer+len+5, m_nRecvBufferPos-len-5);
            m_nRecvBufferPos-=len+5;
        }
    }
    return 1;
}

BOOL CAdminSocket::SendCommand(LPCTSTR pszCommand, int nTextType)
{
    DWORD nDataLength;
    const char *utf8 = 0;

    if (!pszCommand)
        nDataLength = 0;
    else
    {
        utf8 = ConvToNetwork(pszCommand);
        nDataLength = strlen(utf8) + 1;
    }

    t_data data;
    data.pData = new unsigned char[nDataLength + 5];
    *data.pData = 2;
    *data.pData |= 1 << 2;
    data.dwOffset = 0;
    memcpy(data.pData + 1, &nDataLength, 4);
    *(data.pData+5) = nTextType;
    if (utf8)
        memcpy(reinterpret_cast<char *>(data.pData+6), utf8, nDataLength - 1);
    delete [] utf8;

    data.dwLength = nDataLength + 5;

    m_SendBuffer.push_back(data);
    
    do 
    {
        data = m_SendBuffer.front();
        m_SendBuffer.pop_front();
        int nSent = Send(data.pData + data.dwOffset, data.dwLength - data.dwOffset);
        if (!nSent)
            return FALSE;
        if (nSent == SOCKET_ERROR)
        {
            if (WSAGetLastError() != WSAEWOULDBLOCK)
                return FALSE;
            m_SendBuffer.push_front(data);
            return TRUE;
        }
        
        if ((unsigned int)nSent < (data.dwLength - data.dwOffset))
        {
            data.dwOffset += nSent;
            m_SendBuffer.push_front(data);
        }
        else
            delete [] data.pData;
    } while (!m_SendBuffer.empty());

    return TRUE;
}

BOOL CAdminSocket::CheckForTimeout()
{
    SYSTEMTIME sTime;
    FILETIME fTime;
    GetSystemTime(&sTime);
    VERIFY(SystemTimeToFileTime(&sTime, &fTime));
    
    _int64 LastRecvTime = ((_int64)m_LastRecvTime.dwHighDateTime << 32) + m_LastRecvTime.dwLowDateTime;
    _int64 CurTime = ((_int64)fTime.dwHighDateTime << 32) + fTime.dwLowDateTime;

    if ((CurTime - LastRecvTime) > 600000000) // 60 seconds
        return TRUE;

    return FALSE;
}

BOOL CAdminSocket::FinishLogon()
{
    m_bStillNeedAuth = FALSE;

    //Logon successful
    if (!SendCommand(1, 0, NULL, 0))
        return FALSE;
    return TRUE;
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ ok ]

:: Make Dir ::
 
[ ok ]
:: Make File ::
 
[ ok ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0156 ]--