邪恶八进制信息安全团队技术讨论组's Archiver

kiki 2006-9-21 11:37

[原创]一个网络工具(简单用户层实现添加进程信息网络嗅探端口查看等)

文章作者:kiki
信息来源:邪恶八进制信息安全团队

一个小程序,加了些乱七八糟的功能,在Winxp sp2下测试可以运行,主要功能如下:
1:查看进程列表以及进程模块信息
2:控制进程访问网络,允许/拒绝.
3:禁用/启用 当前网络适配器
4:利用嗅探查看当前网络数据流向
5:参考fport的一个端口与进程关联以及状态查看

以上功能都在用户层实现,界面做得比较丑,功能也很低,感兴趣的就下来看看吧.
没有加壳或者绑定其他程序,请放心测试使用...

adson 2006-9-22 13:19

下载测试了下,发现如下问题:
1。初始化时间长
2。点网络状态后弹出错误框(openProcess(WRITE_DAC) Error),关闭后反复弹出,得到任务管理器中结束PFW.exe进程才行。
3。在点过网络状态后退出程序,残留HookAll.exe进程,需手动结束。
4。导致一次xpsp2死机(不过不能确定就是初始化该程序所引起)

kiki 2006-9-22 13:39

这个查看进程与端口关联的部分,我在自己机器上测试也存在问题,一点击qq.exe就会发生错误并自动关闭,但是其他程序不会发生错误.我把这部分代码贴出来,大家看看吧(跟网上那个fport差不多):
[code]
#include <stdlib.h>
#include <Aclapi.h>
#include <iphlpapi.h>
#include <Psapi.h>

#pragma comment(lib, "psapi.lib")
#pragma comment(lib, "IPHlpApi.lib")
#pragma comment(lib, "ws2_32.lib")

char* GetNameByPid(DWORD pid, char * FilePath)
{
  HMODULE hmod;
  DWORD cb = 0;
  HANDLE hdl = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                    FALSE, pid);

  EnumProcessModules(hdl, &hmod, sizeof(hmod), &cb);
  GetModuleFileNameEx( hdl, hmod,  FilePath, MAX_PATH);
  return FilePath;

}


BOOL AdjustProcessPrivileges(LPCSTR szPrivilegesName)
{
  HANDLE hToken;
  TOKEN_PRIVILEGES tkp;

  if(!OpenProcessToken(GetCurrentProcess(),
    TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
  {
    return FALSE;
  }

  if(!LookupPrivilegeValue(NULL,szPrivilegesName,
                  &tkp.Privileges[0].Luid))
  {
    CloseHandle(hToken);
    return FALSE;
  }
  
  tkp.PrivilegeCount = 1;
  tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  
  if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp),NULL,NULL))
  {
    CloseHandle(hToken);
    return FALSE;
  }
  
  CloseHandle(hToken);
  return TRUE;
}


void GetUdpState(DWORD port,  char *temp, DWORD pid)
{
DWORD i;
PMIB_UDPTABLE pUdpTable;
char FilePath[MAX_PATH];

pUdpTable = (MIB_UDPTABLE*) malloc(sizeof(MIB_UDPTABLE));
DWORD dwSize = 0;

if (GetUdpTable(pUdpTable, &dwSize, TRUE) == ERROR_INSUFFICIENT_BUFFER)
{
  GlobalFree(pUdpTable);
  pUdpTable = (MIB_UDPTABLE*)malloc((UINT)dwSize);
}

GetUdpTable(pUdpTable, &dwSize, TRUE);
for(i = 0; i < pUdpTable->dwNumEntries; i++)
{
   struct in_addr ia;
   ia.S_un.S_addr = pUdpTable->table[i].dwLocalAddr;
   
   DWORD localport = pUdpTable->table[i].dwLocalPort;
   if(((localport<<16)>>24)+((localport<<24)>>16) == port)
   {
     wsprintf(temp, "UDP:%s:%d %s------------->%s\0", inet_ntoa(ia), port,  "LISTEN", GetNameByPid(pid, FilePath));
     GlobalFree(pUdpTable);
     return;
   }
   
}
return;

}



void GetPortState(DWORD port,  char *temp, DWORD pid)
{
DWORD i;
PMIB_TCPTABLE pTcpTable;
char FilePath[MAX_PATH];

pTcpTable = (MIB_TCPTABLE*) malloc(sizeof(MIB_TCPTABLE));
DWORD dwSize = 0;

if (GetTcpTable(pTcpTable, &dwSize, TRUE) == ERROR_INSUFFICIENT_BUFFER)
{
  GlobalFree(pTcpTable);
  pTcpTable = (MIB_TCPTABLE*)malloc((UINT) dwSize);
}

GetTcpTable(pTcpTable, &dwSize, TRUE);


    for(i = 0; i < pTcpTable->dwNumEntries; i++)
    {
      struct in_addr ia;
      ia.S_un.S_addr = pTcpTable->table[i].dwLocalAddr;
      struct in_addr ib;
      ib.S_un.S_addr = pTcpTable->table[i].dwRemoteAddr;

      DWORD localport = pTcpTable->table[i].dwLocalPort;
      DWORD remoteport = pTcpTable->table[i].dwRemotePort;

      if(((localport<<16)>>24)+((localport<<24)>>16) == port)
      {

        switch(pTcpTable->table[i].dwState)
        {
        case MIB_TCP_STATE_CLOSED:
          wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "CLOSED", GetNameByPid(pid, FilePath));
//          MessageBox(NULL, temp, "PFW", 0);
          GlobalFree(pTcpTable);
          return;
        case MIB_TCP_STATE_CLOSING:
          wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "CLOSING", GetNameByPid(pid, FilePath));
//          MessageBox(NULL, temp, "PFW", 0);
          GlobalFree(pTcpTable);
          return;
        case MIB_TCP_STATE_CLOSE_WAIT:
          wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "CLOSE_WAIT", GetNameByPid(pid, FilePath));
//          MessageBox(NULL, temp, "PFW", 0);
          GlobalFree(pTcpTable);
          return;
        case MIB_TCP_STATE_DELETE_TCB:
          wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s--%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "DELETE_TCB", GetNameByPid(pid, FilePath));
//          MessageBox(NULL, temp, "PFW", 0);
          GlobalFree(pTcpTable);
          return;
        case MIB_TCP_STATE_ESTAB:
          wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "ESTAB", GetNameByPid(pid, FilePath));
//          MessageBox(NULL, temp, "PFW", 0);
          GlobalFree(pTcpTable);
          return;
        case MIB_TCP_STATE_FIN_WAIT1:
          wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "FIN_WAIT1", GetNameByPid(pid, FilePath));
//          MessageBox(NULL, temp, "PFW", 0);
          GlobalFree(pTcpTable);
          return;
        case MIB_TCP_STATE_FIN_WAIT2:
          wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "FIN_WAIT2", GetNameByPid(pid, FilePath));
//          MessageBox(NULL, temp, "PFW", 0);
          GlobalFree(pTcpTable);
          return;
        case MIB_TCP_STATE_LAST_ACK:
          wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "LAST_ACK", GetNameByPid(pid, FilePath));
//          MessageBox(NULL, temp, "PFW", 0);
          GlobalFree(pTcpTable);
          return;
        case MIB_TCP_STATE_LISTEN:
          wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16), "LISTEN", GetNameByPid(pid, FilePath));
//          MessageBox(NULL, temp, "PFW", 0);
          GlobalFree(pTcpTable);
          return;
        case MIB_TCP_STATE_SYN_RCVD:
          wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16),  "SYN_RCVD", GetNameByPid(pid, FilePath));
//          MessageBox(NULL, temp, "PFW", 0);
          GlobalFree(pTcpTable);
          return;
        case MIB_TCP_STATE_SYN_SENT:
          wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16),  "SYN_SENT", GetNameByPid(pid, FilePath));
//          MessageBox(NULL, temp, "PFW", 0);
          GlobalFree(pTcpTable);
          return;
        case MIB_TCP_STATE_TIME_WAIT:
          wsprintf(temp, "TCP:%s:%d %s:%d %s-------------%s\0", inet_ntoa(ia), port, inet_ntoa(ib),((remoteport<<16)>>24)+((remoteport<<24)>>16),  "TIME_WAIT", GetNameByPid(pid, FilePath));
//          MessageBox(NULL, temp, "PFW", 0);
          GlobalFree(pTcpTable);
          return;
        }
      }
   
    }
    return;

}





int GetSystemVersion(void)
{
  OSVERSIONINFO OsVersionInfo = {sizeof(OSVERSIONINFO)};
  GetVersionEx(&OsVersionInfo);
  if(OsVersionInfo.dwMajorVersion == 5)
  {
    if(OsVersionInfo.dwMinorVersion == 0)
      return 2; //win2000
    if(OsVersionInfo.dwMinorVersion == 1)
      return 1; //winxp
    else
      return 0; //win2003
  }

  else
    return 0; //others
}





BYTE ObjectType = 0;

void SetObjectBySystem(void)
{
  if(GetSystemVersion() == 2)
  {
    ObjectType = 0x1A;
    return;
  }

  if(GetSystemVersion() == 1)
  {
    ObjectType = 0x1C;
    return;
  }

  MessageBox(NULL, "需要2000或者Xp系统!", "PFW", 0);
  return;
}

// NtQuerySystemInformation record type 16

#define NT_HANDLE_LIST  16
//#define OBJECT_TYPE_SOCKET 0x1C //2000: 0x1A
#define MAX_HANDLE_LIST_BUF 0x200000


// 定义HanleInfo数据结构

typedef struct _HandleInfo
{
  USHORT dwPid;
  USHORT CreatorBackTraceIndex;
  BYTE  ObjType;
  BYTE  HandleAttributes;
  USHORT HndlOffset;
  DWORD  dwKeObject;
   ULONG  GrantedAccess;
}HANDLEINFO, *PHANDLEINFO;


// 申明NtQuerySystemInformation()函数
typedef DWORD (__stdcall* NTQUERYSYSTEMINFORMATION)( DWORD, PDWORD, DWORD, PVOID );

NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;

// 判断SOCKET类型的数组

char szSockType[6][6] = { "NUL", "TCP", "UDP", "RAW", "RDM", "SEQ" };


// AdjustDacl用来调整目标进程的DACL
void AdjustDacl( HANDLE hProcess )
{
  SID world = { SID_REVISION, 1, SECURITY_WORLD_SID_AUTHORITY, 0 };
  LPTSTR ptstrName = (LPTSTR)&world;
  EXPLICIT_ACCESS ea = {STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, SET_ACCESS,  NO_INHERITANCE,
  { 0,
  NO_MULTIPLE_TRUSTEE,
  TRUSTEE_IS_SID,
  TRUSTEE_IS_USER,
  ptstrName
  }
  };
  
  ACL * pdacl = 0;
  if ( SetEntriesInAcl(1, &ea, 0, &pdacl) != ERROR_SUCCESS )
    MessageBox(NULL, "SetEntriesInAcl Error", "PFW", 0);
  
  if ( SetSecurityInfo(hProcess,
                SE_KERNEL_OBJECT,
             DACL_SECURITY_INFORMATION,
             0,
             0,
             pdacl,
             0) != ERROR_SUCCESS )
    MessageBox(NULL, "SetSecurityInfo Error", "PFW", 0);
  LocalFree(pdacl);


}//end of AdjustDacl

BOOL FindNetHandle(HWND hwnd)
{
  SetObjectBySystem();
  int iRet;
  HANDLE hCurrentProc = GetCurrentProcess();
  HMODULE hNtdll = NULL;
  hNtdll = LoadLibrary( "ntdll.dll" );
  if ( !hNtdll )
  {
    MessageBox(NULL, "LoadLibrary( NTDLL.DLL ) Error", "PFW", 0);
    CloseHandle(hCurrentProc);
    return false;
  }
  
  NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtdll, "NtQuerySystemInformation");
  
  if ( !NtQuerySystemInformation )
  {
    MessageBox(NULL, "GetProcess( NtQuerySystemInformation ) Error", "PFW", 0);
    CloseHandle(hCurrentProc);
    FreeLibrary(hNtdll);
    return false;
  }
  
  DWORD dwNumBytes = MAX_HANDLE_LIST_BUF;
  PDWORD pdwHandleList = (PDWORD)malloc(dwNumBytes);
  if (!pdwHandleList)
  {
    MessageBox(NULL, "Malloc for Handle List Error", "PFW", 0);  
    CloseHandle(hCurrentProc);
    FreeLibrary(hNtdll);
    return false;
  }
  
  DWORD dwNumBytesRet = 0;
  
  iRet = NtQuerySystemInformation(NT_HANDLE_LIST,
                         pdwHandleList,
                    dwNumBytes,
                    &dwNumBytesRet);

  
  DWORD dwNumEntries;
  PHANDLEINFO pHandleInfo;
  if ( iRet )
  {
    MessageBox(NULL, "NtQuerySystemInformation return Error", "PFW", 0);  
    CloseHandle(hCurrentProc);
    FreeLibrary(hNtdll);
    return false;
  }
  else
  {
    HANDLE hProc;
    dwNumEntries = pdwHandleList[0];
    pHandleInfo = (PHANDLEINFO)( pdwHandleList + 1 );
    for ( DWORD i = 0; i < dwNumEntries; i++ )
    {
      
      if ((pHandleInfo->ObjType == ObjectType) && (pHandleInfo->dwPid))
      {
        hProc = OpenProcess(WRITE_DAC,false,pHandleInfo->dwPid);
        
        if ( hProc )
        {
          AdjustDacl( hProc );
          CloseHandle( hProc );
        }
        else
        {
          MessageBox(NULL, "OpenProcess(WRITE_DAC) Error", "PFW", 0);
          pHandleInfo++;
          continue;
        }
         
        
        HANDLE hMyHandle = NULL;
        hProc = OpenProcess(PROCESS_DUP_HANDLE, true, pHandleInfo->dwPid);
        if ( hProc )
        {  
          DuplicateHandle(hProc,
            (HANDLE)pHandleInfo->HndlOffset,
            hCurrentProc,
            &hMyHandle,
            STANDARD_RIGHTS_REQUIRED,
            true,
            0);
          CloseHandle( hProc );
        }
        else
        {
          MessageBox(NULL, "OpenProcess Error", "PFW", 0);
          pHandleInfo++;
          continue;
        }
        if ( !hMyHandle )
        {
          pHandleInfo++;
          continue;
        }
        else
        {
          sockaddr_in name = {0};
          name.sin_family = AF_INET;
          int namelen = sizeof(sockaddr_in);
          SOCKET s = (SOCKET)hMyHandle;
          iRet = getsockname( s,
            (sockaddr*)&name,
            &namelen );
          if ( iRet != SOCKET_ERROR )
          {
            int sockType = 0;
            int optlen = 4;
            iRet = getsockopt(s,
              SOL_SOCKET,
              SO_TYPE,
              (char*)&sockType,
              &optlen );
            if(iRet == 0)
            {
              char szPortInfo[128];
              char szFmr[] = "%s:0.0.0.0:%d-------------%s ";
//              wsprintf(szPortInfo, szFmr, pHandleInfo->dwPid,ntohs( name.sin_port ),szSockType[sockType]);
              if(sockType == 1)
              {
                GetPortState(ntohs(name.sin_port), szPortInfo, pHandleInfo->dwPid);
                SendMessage(GetDlgItem(hwnd,IDC_LIST1),LB_ADDSTRING,0,(LPARAM)szPortInfo);
              }
              if(sockType == 2)
              {
                GetUdpState(ntohs(name.sin_port), szPortInfo, pHandleInfo->dwPid);
                SendMessage(GetDlgItem(hwnd,IDC_LIST1),LB_ADDSTRING,0,(LPARAM)szPortInfo);
              }
              else
              {
                char FileName[MAX_PATH];
                GetNameByPid(pHandleInfo->dwPid, FileName);
                wsprintf(szPortInfo, szFmr,szSockType[sockType], ntohs(name.sin_port), FileName);
                SendMessage(GetDlgItem(hwnd,IDC_LIST1),LB_ADDSTRING,0,(LPARAM)szPortInfo);

              }
              memset(szPortInfo,0,128);
            }
          }
          CloseHandle(hMyHandle);
          closesocket(s);
        }
      }
      pHandleInfo++;
    }
  }
  
  free( pdwHandleList );
  CloseHandle( hCurrentProc );
  FreeLibrary(hNtdll);

  return 0;
}
[/code]

asm 2006-9-23 18:23

windows XP SP1测试通过

xiaocool 2006-9-23 18:56

运行之后,我qq自动关闭哦。。。。

kiki 2006-9-23 19:42

[quote][b]这里是引用第[/b][color=#ff0000][4 楼][/color][b]的[color=#000066]xiaocool[/color]于[/b]2006-09-23 18:56[b]发表的:[/b]
运行之后,我qq自动关闭哦。。。。[/quote]
这个问题我也不知道如何解决,具体处理的代码就是上面所帖的那部分,期待高手解答.
步骤:
NtQuerySysteminformation枚举所有HANDLE.
依次判断某句柄是否为SOCKET句柄
将该句柄转换成进程可处理的句柄变量(DuplicateHandle),t同时根据句柄信息结构中的Pid获取其所属进程信息.
然后用iphlpapi中的部分函数对该句柄操作获取其状态....

就这样一个过程,会造成qq程序无故地死掉,请知道的告知.

mikiyo 2006-9-23 19:50

[s:51] 测试一下,运行就有那么一点点卡!

kiki 2006-9-23 20:25

这个程序还是用轮询的方式来监视程序的,貌似
while(true)
{
    checkProcess();
    Sleep(n);
}
所以,效率很低...
如果采用前面我提到的监视NTCreateProcessEx的方法,则会好很多.写这个的时候,还没有写上面那个,所以,有机会就改吧.因为原理都清楚了,有时候懒得动手^_^

x8user 2006-10-4 14:52

[quote][b]这里是引用第[/b][color=#ff0000][1 楼][/color][b]的[color=#000066]adson[/color]于[/b]2006-09-22 13:19[b]发表的:[/b]
下载测试了下,发现如下问题:
1。初始化时间长
2。点网络状态后弹出错误框(openProcess(WRITE_DAC) Error),关闭后反复弹出,得到任务管理器中结束PFW.exe进程才行。
3。在点过网络状态后退出程序,残留HookAll.exe进程,需手动结束。
4。导致一次xpsp2死机(不过不能确定就是初始化该程序所引起)[/quote]

运行后
NetAcl.txt文件无法删除,郁闷~~

页: [1]
© 1999-2008 EvilOctal Security Team