20145319 《网络渗透》免考—任务栏隐藏

20145319 《网络渗透》免考—任务栏隐藏

概述

  • 本次实验在windows环境下实现,主要通过编写窗口程序并且修改程序中showWindows函数的参数来实现该窗口程序不显示窗口外形,也不在任务栏中显示从而达到隐藏目的
  • 主要知识如下
    • c++编程(与窗口相关的api函数)
    • 其他例如字符集和编译环境的一些知识

实验内容

  • 在实际生活中,攻击者将恶意代码植入被攻击主机中时,往往希望恶意代码能够隐藏自己,能够偷偷运行在后台中,让程序不弹出任何的窗口也不会在任务栏中现身。这就是恶意代码的任务栏隐藏,而如何实现这个功能,我们就需要从windows API中修改其中的函数参数来实现

编程基础

  • 在本次实验中,我们需要调用windowsAPI函数,编写windows系统应用程序,而非控制台程序,因此使用入口函数winMain初始化应用程序

  • WinMain函数的原型声明如下:

    int WINAPI WinMain(
    HINSTANCE hInstance, // handle to current instance
    HINSTANCE hPrevInstance, // handle to previous instance
    LPSTR lpCmdLine, // command line
    int nCmdShow // show state
    );

  • WinMain共四个参数,与main函数不同,这四个参数都在系统在调用函数时传给应用程序

  • hInstance:表示该程序当前运行的实例的句柄,作为一个实例的唯一标识(类似于进程和pid)。一个程序可以多个实例,但每运行一个实例就分配一个实例句柄,通过hInstance传参

  • hPrevInstance:在win32中无效,通常设为为NULL

  • lpCmdLine:传递给应用程序的一个命令行参数(类似于main函数中的argv)

  • nCmdShow:指定程序的窗口应该如何显示, 例如最大化、最小化以及我们这次要使用的隐藏等,这个可以由用户自由设定

  • 函数creatwindow和函数showWindow分别是用于创建窗口、设置指定窗口显示状态的函数,我们正是通过修改这两个函数的参数来实现任务栏隐藏功能

  • 函数creatwindow的函数原型声明:

    HWND CreateWindow(
    LPCTSTR lpClassName,
    LPCTSTR lpWindowName,
    DWORD dwStyle,
    int x,
    int y,
    int nWidth,
    int nHeight,
    HWND hWndParent,
    HMENU hMenu,
    HANDLE hlnstance,
    LPVOID lpParam);

  • lpClassName:指定窗口的类名

  • lpWindowName:窗口标题

  • dwStyle:窗口风格参数

  • x&y:分别代表了窗口初始的水平,垂直位置

  • nwidth&nHeight:窗口的宽度以及高度

  • hWndParent:被创建窗口的父窗口或者所有者窗口的句柄

  • hMenu:菜单句柄

  • hlnstance与窗口相关联的模块实例的句柄

  • lpParam

  • 函数showWindow的函数原型

    BOOL ShowWindow(HWND hWnd, int nCmdShow);

  • hwnd:对应窗口的句柄

  • ncmdShow:指定该窗口以何种状态显示(事实上我们正式通过修改这个参数实现了任务栏隐藏)

  • 其他类似于messagebox等函数以及方法就不再一一介绍

  • 通过查询到基本函数以及方法我们可以写一个自己的简单的窗口

    include "stdafx.h"

    include "windows.h"

    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//声明回调函数

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR szCmdLine, int iCmdShow){

    static TCHAR szAppName[] = _T("HelloWindow");

    HWND hwnd; //用来保存成功创建窗口后返回的句柄
    MSG msg; //定义消息结构体变量
    WNDCLASS wndclass; //窗体类

    wndclass.style = CS_HREDRAW | CS_VREDRAW; //指定窗口风格
    wndclass.lpfnWndProc = WndProc; ////函数指针,指向处理窗口消息的函数入口
    wndclass.cbClsExtra = 0; //结构体后附加的字节数,一般总为0
    wndclass.cbWndExtra = 0; //窗体实例附加的字节数,一般总为0
    wndclass.hInstance = hInstance; //模块句柄
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //图标句柄 任务栏显示的图标
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); //光标句柄
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //背景颜色COLOR_BACKGROUND
    wndclass.lpszMenuName = NULL; //菜单名的字符串
    wndclass.lpszClassName = szAppName; //自定义类名,不要与其他类名重复

    if (!RegisterClass(&wndclass))
    {
    MessageBox(NULL, TEXT("注册类失败!"), szAppName, MB_ICONERROR);
    return 0;
    }

    int x = ((GetSystemMetrics(SM_CXSCREEN) / 2) - 200); //水平方向居中
    int y = ((GetSystemMetrics(SM_CYSCREEN) / 2) - 200); //垂直居中

    hwnd = CreateWindow(szAppName, TEXT("window_test"), WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, x, y, 400, 200, NULL, NULL, hInstance, NULL);//创建窗体API

    //ShowWindow(hwnd, SW_HIDE);
    ShowWindow(hwnd, iCmdShow); //显示窗体的API 传入需要显示的窗体句柄和显示方式
    UpdateWindow(hwnd); //刷新窗体的API

    while (GetMessage(&msg, NULL, 0, 0) > 0){ //从系统的应用程序线程消息队列中取得一个消息
    DispatchMessage(&msg);
    }
    return msg.wParam;
    }

    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){

    HDC hdc; //句柄
    PAINTSTRUCT ps; //绘制信息
    RECT rect; //矩形
    HINSTANCE hInstance; //窗口实例
    static HWND hwndButton[2]; //按钮句柄

    switch (message){
    case WM_CREATE: //创建按钮
    {
    hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
    hwndButton[0] = CreateWindow(_T("BUTTON"), _T("hello"),
    WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
    140, 50, 100, 50, hwnd, NULL,
    (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);

    return 0;
    }
    case WM_PAINT: //绘制文字
    hdc = BeginPaint(hwnd, &ps);
    GetClientRect(hwnd, &rect);
    DrawText(hdc, TEXT("By:20145319"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_BOTTOM);
    EndPaint(hwnd, &ps);
    return 0;
    case WM_COMMAND: //响应按钮消息
    if ((HWND)lParam == hwndButton[0])
    {
    MessageBox(NULL, TEXT("你好,5319"), TEXT("问候"), MB_OK | MB_ICONQUESTION);
    }
    return 0;
    case WM_CLOSE: //关闭
    if (IDYES == MessageBox(hwnd, _T("是否关闭程序?"), _T("提示"), MB_YESNO | MB_ICONQUESTION))
    {
    DestroyWindow(hwnd);
    }
    return 0;
    case WM_DESTROY: //退出程序
    PostQuitMessage(0);
    return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
    }

  • 当程序正常运行时我们可以看到其界面,任务栏以及进程列表中的程序名均一切正常

  • 当我们修改showWindow函数中的参数为SW_HIDE,则结果如下,我们能在后台进程中看到相应程序,但是其界面和任务栏中都已经找不到该程序了

其他

编译中的问题

  • 在调用messageBox或者creatWindow之类的函数时,通常会输入中文字符串来作为对应的函数参数,那么就可能会出现编译报错(“const char*”类型的实参和LPCWSTR类型的形参不兼容)

  • 造成该错误的原因是字节编码问题,默认环境下的unicode编码并不支持多字节,使用_T函数可以转换编码

  • 当程序中并没有编译错误之后,我们尝试运行该程序,会出现如下错误

  • 这是因为,在最开始我们已经强调,winMain是windows系统应用程序的入口函数,当前环境下系统找不到main函数,从而报错,因此我们需要将编译环境从dos环境修改为windows环境

  • 点击菜单栏中项目菜单,打开项目的属性页面,将子系统参数由控制台(console)修改为窗口(windows)

  • 其实最近我才发现可以直接建立windows窗口程序。。。。

posted on 2017-06-18 12:16  20145319钟轲  阅读(234)  评论(0)    收藏  举报