Pipe control Telnet

Source: Internet
Author: User
Tags exit in readfile

Objective

The previous essay describes how to control a program through a pipeline, but this one was accidentally invalidated when the telnet was controlled, and Telnet flashed after CreateProcess execution.

Problem analysis

If the standard input and output is not modified, the program can be executed normally after CreateProcess, which can be judged by modifying the standard input and output handle. For more information, open Telnet analysis with IDA and find the statement that causes the program to flash back.

此处有图

The main logic of the Mian function is as above, the program first calls the GetStdHandle () and determines whether to exit the program by the return value, which is critical

//Retrieves a handle to the specified standard device (standard input, standard output, or standard error).HANDLE WINAPI GetStdHandle(  _In_ DWORD nStdHandle);

The function returns the current standard input and output handle, because we have replaced it with a pipe, so the return should be the handle of our pipe, by writing a test program that can be tested to the return handle is indeed our pipe handle.
So the program does not exit at the beginning of the judgment.
To locate the error faster, use GetExitCodeProcess () to get the value returned by the program. (However, it was later found that the next function was tested directly faster)

//Retrieves the termination status of the specified process.BOOL WINAPI GetExitCodeProcess(  _In_  HANDLE  hProcess,  _Out_ LPDWORD lpExitCode);

When the program runs, it returns 259, the rest of the values are the return value when the program exits, and the error return value of Telnet is-1. Back to the program code, return in main 1 words only left the Getconsolescreenbufferinfo () function return 0 This one possibility, of course, the program can also be in other places through exit (-1) to make the program exit and return-1, Searching for exit in Ida did not find anything suspicious, so let's be bold to guess. Write a test program to discover that Getconsolescreenbufferinfo () does not recognize the pipe handle that was passed in.

//Retrieves information about the specified console screen buffer.BOOL WINAPI GetConsoleScreenBufferInfo(  _In_  HANDLE                      hConsoleOutput,  _Out_ PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);

On the function's introduction page, there is no way to see why the pipe handle is not working, but in the introduction of Writeconsole () it is found that writeconsole () fails when the handle passed in is redirected to a handle of another file, which is the guess. Because Telnet takes a sequence of write and read operations to the console, CMD takes a similar writefile operation.

Writeconsole fails if it is used with a, standard handle, is redirected to a file. If an application processes multilingual output so can be redirected, determine whether the output handle is a console h Andle (one method is to call the Getconsolemode function and check whether it succeeds). If The handle is a console handle, call Writeconsole. If The handle is not a console handle, the output was redirected and you should call WriteFile to perform the I/O. Be sure To prefix a Unicode plain text file with a byte order mark. For more information, see Using Byte Order Marks.

It is also said that the standard input and output handle can be returned by CreateFile, so

Solutions 1

The general idea is to stop creating the pipeline, and to control telnet by creating a file that returns a standard input and output handle by createfile, which resolves two issues: 1) Having telnet not rejecting the handle (2) can be controlled by a handle

Let Telnet accept

When I first set the handle of Telnet back to the handle returned by the CreateFile, it's amazing to be rejected, no reason, in the test program can be accepted, is it not the program is called? Then I stumbled upon the addition of a flag create_new_console to CreateProcess.

This place actually did not understand why, but also for the back to bury the foreshadowing.

Control

It does not seem possible to use the standard return handle with WriteFile and ReadFile, but querying MSDN can be found through Writeconsoleinput () and Readoutputbuffercharacters () To implement similar functions for write and read-out pipelines. Readoutputbuffercharacters () personally tested to be able to return, but was immersed in meditation before testing writeconsoleinput ().

It's strange that I passed the new handle to the callee, but it would still grab the input and output on the console of the control program. MSDN says that if you don't create a new console, you're going to grab the input and output, but I don't accept my handle with my new console, as if things got harder, and with cop thoughts, I gave up this path.

If you are interested, you can follow my path, or you have an insight into the console and you can tell me where my problem is.

Solutions 2

(This road is the way the teacher wants us to go.) still is the incoming pipe handle through the pipeline control, through the hook WIN32 API way, the console-based operation into file-based.
There are many ways to do this, and I give a thought: 1 hook all the write and read related APIs, redirect to the pipe up to 2) Hook GetStdHandle let him return CreateFile the new handle is used to cope with other console-related functions, However, because write and read need to get the pipe handle, but the pipe handle is returned by GetStdHandle, the different handle are returned according to the order in which the getstdhandle is called. Search found in Telnet only the first call to GetStdHandle, then very simple, the second time after the function works, the first time the second time to call CreateFile created.
Emmm is easy to say, but it takes a little time to think about the logic, such as starting with a global variable that stores handle.
Hook tool Use

Sticker code, huh?

Control

#include <iostream>#include <Windows.h>#include <cstdio>#include <detours.h>using namespaceStdBOOLCreateshell (HANDLE * readh, HANDLE * writeh, process_information * pi) {security_attributes sa = {0}; Sa.nlength =sizeof(SA);    Sa.lpsecuritydescriptor = NULL;    Sa.binherithandle = TRUE; HANDLE Rh1, WH1, RH2, WH2;if(! CreatePipe (&AMP;RH1, &AMP;WH1, &sa,1024x768)) {//outputpipe        return false; }if(! CreatePipe (&AMP;RH2, &AMP;WH2, &sa,1024x768)) {//input Pipe        return false;    } *readh = Rh1;    *writeh = WH2;    Startupinfoa si; memset (&si,0,sizeof(SI)); Si.dwflags = Startf_useshowwindow |    Startf_usestdhandles;    Si.wshowwindow = Sw_hide; Si.hstdinput = RH2;//RH2Si.hstdoutput = WH1;//wh1Si.hstderror = WH1;if(! Detourcreateprocesswithdlla (NULL,"C:\\Users\\Hasee\\Desktop\\tellnet\\Telnet.exe ", NULL, NULL, TRUE, normal_priority_class| Create_new_console, NULL, NULL, &AMP;SI, PI,"D:\\visual_studio_test\\virusexcercise\\fortelnet\\DetoursTest3\\Debug\\DetoursTest3.dll ", NULL)) {cout <<"CreateProcess error!"<< Endl;return false; }return true;}BOOLPrintmsg (HANDLE readh) {WCHAR output[1024x768] = {' /'}; CHAR outputa[1024x768] = {' /'};unsigned LongN for(inti =0; I <Ten; i++) { while(1) {if(! Peeknamedpipe (Readh, NULL,0, NULL, &n, NULL)) {cout <<"Cannot get msg"<< Endl;return false; }if(n = =0)             { Break; }if(! ReadFile (readh, Output, N, &n, NULL)) {cout <<"Cannot read file"<< Endl;return false;            } Output[n] = NULL; WideCharToMultiByte (CP_ACP,0, Output,-1, Outputa, N, NULL, FALSE);        cout << Outputa; } Sleep ( -); }return 1;}intMain () {HANDLE input = GetStdHandle (Std_input_handle);    HANDLE Readh, Writeh; CHAR output[1024x768]; output[1023] =' /';    U_long N2; Process_information Pi;if(!createshell (&readh, &writeh, &pi)) {System ("Pause");return 1;    } printmsg (Readh); WCHAR * cmd =Newwchar[1024x768]; U_long N;intEcode;    COORD A; a.x =0; A.Y =0; WCHAR *tempb[1024x768]; while(1) {Readconsolew (input, cmd,1024x768, &AMP;N2, NULL);//readconsoleWriteFile (Writeh, CMD, n2*2, &n, NULL);//write Pipe        if(!printmsg (Readh)) {TerminateProcess (pi.hprocess,0); System"Pause");return 1; }} System ("Pause");return 0;}

Dll

#include "stdafx.h"#include <Windows.h>#include <WinBase.h>#include <detours.h>HANDLE (winapi* old_getstdhandle) (DWORD nstdhandle) = GetStdHandle; BOOL (WINAPI * old_writeconsolew) (HANDLE hconsoleoutput,ConstVOID *lpbuffer, DWORD nnumberofcharstowrite, Lpdword Lpnumberofcharswritten, lpvoid lpreserved) = WriteConsoleW; BOOL (WINAPI * old_readconsoleinputw) (HANDLE hconsoleinput, Pinput_record lpbuffer, DWORD nlength, Lpdword Lpnumberofeventsread) = READCONSOLEINPUTW; BOOL (WINAPI * old_readconsoleinputa) (HANDLE hconsoleinput, Pinput_record lpbuffer, DWORD nlength, Lpdword Lpnumberofeventsread) = Readconsoleinputa; BOOL (WINAPI * old_readconsolew) (HANDLE hconsoleinput, LPVoid lpbuffer, DWORD nnumberofcharstoread, Lpdword LPNUMBEROFC Harsread, Pconsole_readconsole_control pinputcontrol) = Readconsolew;intc =0; HANDLE WINAPI new_getstdhandle (DWORD nstdhandle) {HANDLE ret =0;if(C <2) {security_attributes sa; Sa.nlength =sizeof(SA);        Sa.lpsecuritydescriptor = NULL; Sa.binherithandle = TRUE;if(Nstdhandle = = Std_input_handle) {ret = Createfilea ("conin$", Generic_read |        Generic_write, File_share_read, &sa, open_existing, NULL, NULL); }Else{ret = Createfilea ("conout$", Generic_read |        Generic_write, File_share_write, &sa, open_existing, NULL, NULL); } C + +;returnRet }Else{ret = Old_getstdhandle (nstdhandle);returnRet }}bool WINAPI New_writeconsolew (HANDLE hconsoleoutput,ConstVOID *lpbuffer, DWORD nnumberofcharstowrite, Lpdword Lpnumberofcharswritten, LPVoid lpreserved) {HANDLE WPip = GetS    Tdhandle (Std_output_handle); WriteFile (Wpip, lpbuffer, nnumberofcharstowrite*2, Lpnumberofcharswritten, NULL);returnTRUE;} BOOL WINAPI new_readconsoleinputw (HANDLE hconsoleinput, Pinput_record lpbuffer, DWORD nlength, Lpdword    Lpnumberofeventsread) {HANDLE Rpip = GetStdHandle (Std_input_handle);    ReadFile (Rpip, Multibytes, Nlength, Lpnumberofeventsread, NULL); *lpnumberofcharsread/=2;returnTRUE;} BOOL WINAPI New_readconsoleinputa (HANDLE hconsoleinput, Pinput_record lpbuffer, DWORD nlength, Lpdword Lpnumberofeventsread) {Charwidechar[1024x768];    HANDLE Rpip = GetStdHandle (Std_input_handle);    ReadFile (Rpip, Widechar, Nlength, Lpnumberofeventsread, NULL); DWORD dwnum = MultiByteToWideChar (CP_ACP,0, Widechar,-1Null0); MultiByteToWideChar (CP_ACP,0, Widechar,-1, lpbuffer, Dwnum); *lpnumberofcharsread *=2;returnTRUE;} BOOL WINAPI New_readconsolew (HANDLE hconsoleinput, LPVoid lpbuffer, DWORD nnumberofcharstoread, Lpdword Lpnumberofchar    Sread, Pconsole_readconsole_control pinputcontrol) {HANDLE Rpip = GetStdHandle (Std_input_handle);    ReadFile (Rpip, lpbuffer, Nnumberofcharstoread, Lpnumberofcharsread, NULL); *lpnumberofcharsread/=2;returnTRUE;}voidHook () {detourrestoreafterwith ();    Detourtransactionbegin ();    Detourupdatethread (GetCurrentThread ());    Detourattach ((PVOID *) &old_writeconsolew, New_writeconsolew);    Detourattach ((PVOID *) &AMP;OLD_READCONSOLEINPUTW, NEW_READCONSOLEINPUTW);    Detourattach ((PVOID *) &old_readconsoleinputa, New_readconsoleinputa);    Detourattach ((PVOID *) &old_readconsolew, New_readconsolew);    Detourattach ((PVOID *) &old_getstdhandle, new_getstdhandle); Detourtransactioncommit ();}voidUnhook () {detourtransactionbegin ();    Detourupdatethread (GetCurrentThread ());    Detourdetach ((PVOID *) &old_writeconsolew, New_writeconsolew);    Detourdetach ((PVOID *) &AMP;OLD_READCONSOLEINPUTW, NEW_READCONSOLEINPUTW);    Detourdetach ((PVOID *) &old_readconsoleinputa, New_readconsoleinputa);    Detourdetach ((PVOID *) &old_readconsolew, New_readconsolew);    Detourdetach ((PVOID *) &old_getstdhandle, new_getstdhandle); Detourtransactioncommit ();} BOOL apientry DllMain (hmodule hmodule, DWORD ul_reason_for_call, LPVOID lpre Served) {Switch(Ul_reason_for_call) { CaseDll_process_attach:hook (); Break; CaseDll_thread_attach: Break; CaseDll_thread_detach: Break; CaseDll_process_detach:unhook (); Break; }returnTRUE;}

Pipe control Telnet

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.