论坛: 黑客进阶 标题: [转贴]有关实现windows98下的远程shell的问题 复制本贴地址    
作者: BrideX [bridex]    论坛用户   登录
主题 有关实现windows98下的远程shell的问题  « 上一主题 | 下一主题 »

liwashington  发表于:2005-04-08 13:36 

发帖: 11
积分: 0
注册: 2003-11-24
在NT类的系统里面实现远程SHELL的代码在网上很常见,但把在NT类系统里正常工作的代码放到98下打死都不能正常工作,为什么呢,希望高手大侠指点一二!这里先多谢!!!

代码的实现就是利用98下的command.com文件,通过两个匿名管道接到command.com进程的输入输出上,然后通过管道与SOCK相接.现在的工作情况是管道与SOCK间的通信没问题,但是command.com到管道的输出除了开头的版本信息以外,没有任何东西,输入的命令会在管道处原样得到输出,但就是没有得到命令处理的有关输出.(代码中已考虑了API支持的不同)

是不是command.com不能这样实现呢?如果不能这样,那如何实现在98下的SHELL? 
glacier  发表于:2005-04-08 15:04 

发帖: 1608
积分: 32
注册: 2001-03-04
把命令结尾处的‘\n’换成‘\r\n’

glacier 编辑于 2005-04-08 15:10
---
浮生事,苦海舟,荡去漂来不自由
kexin  发表于:2005-04-10 10:01 

发帖: 43
积分: 0
注册: 2004-08-19
多打几个回车不行吗?另外,接收通出的管道应该接收到输入管道对command的输出吗?
---
QQ:6180058    E-Mail:kexin732@sohu.com   
爱好操作系统/编程/网络安全测试/交朋友。
liwashington  发表于:2005-04-11 09:32 

发帖: 11
积分: 0
注册: 2003-11-24
首先感谢两位大侠的指点。下面我把情况说得具体一点:
测试是在windows 98 SE虚拟机上做的,远程连接客户端是在windows 2003上的netcat,结果情况为连接后在客户端出现标准的command.com的版本等信息和提示符,这和cmd.exe的差不多,随后客户端打入命令,如dir,之后客户端会再回显一次dir,经测试这确是从command.com的输出管道读出来的。但是并没有出现dir显示的列目录信息,问题就在这里了!!!

以下是简化过的(原程序中通过SOCK)代码:
typedef struct ThreadParam
{
    SOCKET    sSoc;            //端口
    HANDLE    hHandle;        //管道的句柄
}THREADPARAM, *PTHREADPARAM;

DWORD WINAPI ReadThread(LPVOID lpParam);
DWORD WINAPI WriteThread(LPVOID lpParam);

int main(int argc, char *argv[])
{
    STARTUPINFO            siInfo;
    PROCESS_INFORMATION    piInfo;
    SECURITY_ATTRIBUTES    saAttributes;
    HANDLE                hCmdIn = NULL;
    HANDLE                hCmdOut = NULL;
    HANDLE                hSockIn = NULL;
    HANDLE                hSockOut = NULL;
    HANDLE                hReadThread = NULL;
    HANDLE                hWriteThread = NULL;
    char                szCmdLine[MAX_PATH + 1];
    int                    iRet = 0;
    PTHREADPARAM        lpData = NULL;
    DWORD                dwTemp = 0;

    saAttributes.nLength = sizeof(saAttributes);
    saAttributes.lpSecurityDescriptor = NULL;
    saAttributes.bInheritHandle = true;

    //创建两个管道
    if (!CreatePipe(&hSockOut, &hCmdIn, &saAttributes, 0))
    {
        MessageBox(NULL, "CreatePipe1 error", "Pipe", MB_OK);
    }
    if (!CreatePipe(&hCmdOut, &hSockIn, &saAttributes, 0))
    {
        MessageBox(NULL, "CreatePipe2 error", "Pipe", MB_OK);
    }

    //把cmd.exe的输入输出重定向到指定的管道
    ZeroMemory(&siInfo, sizeof(siInfo));
    siInfo.cb = sizeof(siInfo);
    siInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    siInfo.wShowWindow = SW_HIDE;
    siInfo.hStdInput = hSockOut;
    siInfo.hStdOutput = hSockIn;
    if (!DuplicateHandle(GetCurrentProcess(), hSockIn, GetCurrentProcess(), &siInfo.hStdError, DUPLICATE_SAME_ACCESS, true, 0))
    {
        MessageBox(NULL, "DuplicatePipe error", "Pipe", MB_OK);
    }

    ZeroMemory(szCmdLine, sizeof(szCmdLine));
    GetWindowsDirectory(szCmdLine, sizeof(szCmdLine));
    lstrcat(szCmdLine, "\\command.com");
    //创建shell进程
    iRet = CreateProcess(
        NULL,
        szCmdLine,
        NULL,
        NULL,
        true,
        CREATE_NEW_CONSOLE | CREATE_DEFAULT_ERROR_MODE,
        NULL,
        NULL,
        &siInfo,
        &piInfo);
    //如果创建失败
    if (0 == iRet)
    {
        printf("CreateProcess error\r\n");
        return 1;
    }
   
    //创建读端口数据线程,并把读到的数据输出到cmd.exe进程
    lpData = (PTHREADPARAM)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(THREADPARAM));
    if (NULL == lpData)
    {
        MessageBox(NULL, "HeapAlloc1 error", "Error", MB_OK);
        return 1;
    }
    lpData->hHandle = hCmdIn;   
    hReadThread = CreateThread(
        NULL,
        0,
        ReadThread,
        lpData,
        0,
        &dwTemp);
    if (NULL == hReadThread)
    {
        HeapFree(GetProcessHeap(), 0, lpData);
        MessageBox(NULL, "CreateThread read error", "Error", MB_OK);
        return 1;
    }

    //创建写端口数据线程,并把从cmd.exe进程读到的数据输出到端口
    lpData = (PTHREADPARAM)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(THREADPARAM));
    if (NULL == lpData)
    {
        //DrvCtrl(2, iSockNum);
        MessageBox(NULL, "HeapAlloc2 error", "Error", MB_OK);
        return 1;
    }
    lpData->hHandle = hCmdOut;
    hWriteThread = CreateThread(
        NULL,
        0,
        WriteThread,
        lpData,
        0,
        &dwTemp);
    if (NULL == hWriteThread)
    {
        HeapFree(GetProcessHeap(), 0, lpData);
        MessageBox(NULL, "CreateThread write error", "Error", MB_OK);
        return 1;
    }


    //等待cmd.exe进程退出
    WaitForSingleObject(piInfo.hProcess, INFINITE);
    //结束读端口线程和写端口线程
    TerminateThread(hReadThread, 0);
    TerminateThread(hWriteThread, 0);

    return 0;
}

DWORD WINAPI ReadThread(LPVOID lpParam)
{
    PTHREADPARAM    pArguments = (PTHREADPARAM)lpParam;
    char            buf[1025];
    DWORD            dwLen = 0;

    while (1)
    {
        //从端口中读出数据
        ZeroMemory(buf, sizeof(buf));
        gets(buf);
        //把从端口读出的数据写入管道,即输入到cmd.exe进程
        WriteFile(pArguments->hHandle, buf, strlen(buf), &dwLen, NULL);
    }

    //释放资源
    HeapFree(GetProcessHeap(), 0, lpParam);
    lpParam = NULL;
    return 0;
}

/*
* 函数名称 : WriteThread
* 函数描述 : 把cmd.exe进程通过管道输出的数据读出来并写入到shell的端口。
* 参数 :
*        IN    lpParam    :    传递给线程的参数结构指针,这里是指向THREADPARAM结构的指
*                        针。
* 返回值 :
*        正常退返回0,否则为1。
* 备注 :
*       
*/
DWORD WINAPI WriteThread(LPVOID lpParam)
{
    PTHREADPARAM    pArguments = (PTHREADPARAM)lpParam;
    char            *pBuf = NULL;
    int                iCount = 0;
    DWORD            dwLen = 0;
    DWORD            dwSize = 0;

    while (1)
    {
        //从管道中读出cmd.exe进程输出的数据
        if (PeekNamedPipe(pArguments->hHandle, NULL, 0, NULL, &dwSize, NULL))
        {
            pBuf = (char *)HeapAlloc(GetProcessHeap(), 0, dwSize + 1);
            ZeroMemory(pBuf, dwSize + 1);
            ReadFile(pArguments->hHandle, pBuf, dwSize, &dwLen, NULL);
            if (dwLen > 0)
            {
                printf("%s\r\n", pBuf);
            }
            HeapFree(GetProcessHeap(), 0, pBuf);
            pBuf = NULL;
        }
    }

    //释放资源
    HeapFree(GetProcessHeap(), 0, lpParam);
    lpParam = NULL;
    return 0;
}


各位大侠看看问题出在哪里???

liwashington 编辑于 2005-04-11 09:35 


地主 发表时间: 05-04-11 09:35

论坛: 黑客进阶

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号