Let’s put all the components from Part1, Part2, and Part3 together and execute the PowerShell script to see what will happens and how the Telegram Messenger client can interact with PowerShell Telegram Bot. Note that you can use -Verbose to see a detailed log on console on what is going on.

Required Parameters for Telegram PowerShell bot

The Telegram PowerShell bot script requires the following parameter to start interacting with the Telegram APIs, if you don’t know where these parameters come from, maybe you can go and check the previous posts.

  • Token: the HTTP API Token
  • PassPhase: A text that will be send from the Telegram Messenger client to authenticate. Consider it as the password.
  • FirstName: The Telegram messenger client user first name.
  • Lastname: The Telegram messenger client last name.
  • AllowedCommands: A text file contains all the allowed whitelist PowerShell commands.

You can get the first name and the last name information by sending a message to your bot and check the /getUpdate endpoint.

.\Telegram.ps1 -Token -PassPhrase  -FirstName -LastName  -Verbose 
#I did not use the -AllowedCommands Yet, will use it later
Starting Telegram PowerShell Bot
Starting Telegram PowerShell Bot

Hit enter and let the fun begin. You will notice that the application start a loop of checking incoming message with a No authentication made, or Auth Failure. This is OK as the script is waiting for the authentication message, which is the pass-phrase we set.

The first message in the session must be the passphrase.

Not Authenticated yet.
Not Authenticated yet.

Let’s try to send a dummy message and see what will happen.

Sending a normal message, not the passphrase
Sending a normal message, not the passphrase

You will notice that there is no response at all, and even in the console the No Authentication made, or auth Failure… will continue to loop as the first message must be the passphrase we set, don’t forget other parameters which also should match such the first name and last name.

Authentication success

let’s send the correct passphrase $uperM@n and see what will happens.

The Passphrase stored in the memory and passed through the parameter

Authentication success
Yeaaaaaa, Authenticated, let’s send some PS commands

let’s try to send some commands. For example, Get-Process explorer

PowerShell Console output
PowerShell Console output

The command was executed, and the result is prepared in JSON format and sent to the Client

Keep in mind that there is a limit of 4K Characters send or receive per message, don’t exceed this otherwise you will get an error. So try to limit your command result by using filters ( Select, Where, Filter…).

Using the AllowedCommands PowerShell parameter

Now we need to set a limit on which commands are considered as safe and its OK for the script to execute after authentication.

.\Telegram.ps1 -Token '1418701162:AAEIklEHZowjxorXL6VNfgzV54CmnPoUa3c' -PassPhrase '$uperM@n' -FirstName Faris -LastName Malaeb -AllowedCommands C:\Telegram\AllowedCommands.txt -Verbose

The Content of the C:\Telegram\AllowedCommands.txt is just a list of cmdlets that its OK to execute, for this example I will use only 2 commands.

Whitelist commands
Whitelist commands

Lets start the script again and perform the required authentication and try to run PowerShell cmdlets outside the AllowedCommands scope

Not Accepted command
Not Accepted command

The user who sends the message won’t get a response back, no need.

Feel free to send /Disconnect any time to end the session and un-authenticate yourself, aka Logoff :).

You can get the script from my Github repo, and also if you want you can send PR for updates.

Telegram PowerShell Bot Script

[cmdletbinding()]
param(
[parameter(Mandatory=$true)]$Token,
[parameter(Mandatory=$true)]$PassPhrase,
[parameter(Mandatory=$true)]$FirstName,
[parameter(Mandatory=$true)]$LastName,
[parameter(Mandatory=$false)]$AllowedCommands

)
#region Variables
$URL='https://api.telegram.org/bot{0}' -f $Token
$AcceptedSession=""
$LastUnAuthenticatedMessage=""
$lastexecMessageID=""
#endregion Variables

#region Function
Function FixTheStream {
    param(
    $Stream
    )
    Write-Verbose -Message "Fixing the stream, Text is stored in $($env:TMP)\TGPSMessages.txt"
        $FixedResult=@()
        $Stream | Out-File -FilePath (Join-Path $env:TMP -ChildPath "TGPSMessages.txt") -Force
        $ReadAsArray= Get-Content -Path (Join-Path $env:TMP -ChildPath "TGPSMessages.txt") | where {$_.length -gt 0}
        foreach ($line in $ReadAsArray){
            $ArrObj=New-Object psobject
            $ArrObj | Add-Member -MemberType NoteProperty -Name "Line" -Value ($line).tostring()
            $FixedResult +=$ArrObj
        }
        Write-Verbose -Message "Done fixing the message, the return will be $($FixedResult)"
        return $FixedResult


}

Function SendTGMessage{ #Send Message to Telegram Service
    param(
    $Messagetext,
    $ChatID
    )
    Write-Verbose -Message "Preparing to send TG Message" 
    $FixedText=FixTheStream -Stream $Messagetext
        $MessageToSend = New-Object psobject 
        $MessageToSend | Add-Member -MemberType NoteProperty -Name 'chat_id' -Value $ChatID
        $MessageToSend | Add-Member -MemberType NoteProperty -Name 'text' -Value $FixedText.line
        $JsonData=($MessageToSend | ConvertTo-Json)
        Write-Verbose -Message "----------------- Message that will be sent ----------------"
        Write-Verbose -Message $JsonData
        Write-Verbose -Message " ---------------- End of Message ---------------------------"
        Invoke-RestMethod -Method Post -Uri ($URL +'/sendMessage') -Body $JsonData -ContentType "application/json"
        Write-Verbose -Message "Message should be sent"
    }


Function ReadTGMessage{ #Read Incomming message 
    try{
        $inMessage=Invoke-RestMethod -Method Get -Uri ($URL +'/getUpdates') -ErrorAction Stop
        Write-Verbose -Message "Checking for new Messages $($inMessage.result[-1])"
        return $inMessage.result[-1]

    }
    Catch{
        Write-Host $_.exception.message -ForegroundColor red
        return "TGFail"
    }

}

Function IsAuthenticated{ 
param(
    $CheckMessage
)
    Write-Verbose -Message "Checking Authentication Function..."
    if (($messages.message.date -ne $LastUnAuthenticatedMessage) -and ($CheckMessage.message.text -like $PassPhrase) -and ($CheckMessage.message.from.first_name -like $FirstName) -and ($CheckMessage.message.from.last_name -like $LastName) -and ($CheckMessage.message.from.is_bot -like $false)){
    Write-Verbose -Message "Yes yes, Authenticated ...$($messages.message.chat.id)"
    $script:AcceptedSession="Authenticated"
    Write-Host "Auth Accepted..." -ForegroundColor Green
    return $messages.message.chat.id
    }
    Else{
    Write-Host "No Authentication made, or auth failure.." -ForegroundColor Red
    return 0

    }

}



Function CommandShouldBeExecuted {
    Param(
    $cmdlet
    )
    Write-Verbose -Message "Checking if the command is safe ..."
    try{
    if ($cmdlet -like "/disconnect"){
    Write-Host "Bye Bye ..." -ForegroundColor Green
    SendTGMessage -Messagetext "See You.. loging off" -ChatID $messages.message.chat.id
    $script:AcceptedSession=$null
        return 0
        
            }

    if (Test-Path $AllowedCommands){
        $commands=Get-Content -Path $AllowedCommands
        if (($commands |where {$_ -like ($cmdlet.split("")[0])}).count -gt 0) {
        Write-Verbose -Message "Command is safe and can be executed"
            return 1
            }
            Else{
             Write-Verbose -Message "Not Accepted Command.. "
            return 0
            }

        }
    }
    catch{
     Write-Verbose -Message "Allowed list not found.. executing anything is accepted."
    return 1
    }

}
#endregion Function

Write-Host "Script is activated and will require authentication..."
Write-Host "Waiting for Authentication phrase..."
while ($true){
sleep 1
    $messages=ReadTGMessage

    if ($messages -like "TGFail"){
    Write-Host "it seems we got a problem... lets wait for 10 seconds and then try again"
    Write-Host "Maybe you need to check the authentication Key..."
    sleep -Seconds 10
    }
    
     if (!($messages)){
     Write-Host "No data to parse ... will sleep for a while :)"
     }

     Else{

        if ($LastUnAuthenticatedMessage -like $null){
            $LastUnAuthenticatedMessage=$messages.message.date
           }

        if (!($AcceptedSession)){
            $CheckAuthentication=IsAuthenticated -CheckMessage $messages
            }
            Else{
            if (($CheckAuthentication -ne 0) -and ($messages.message.text -notlike $PassPhrase) -and ($messages.message.date -ne $lastexecMessageID)){
             Write-Verbose -Message "I got $($messages.message.text) and MessageID $($messages.message.message_id)"
                    
                    $DoOrDie=CommandShouldBeExecuted -cmdlet $messages.message.text
                    if ($DoOrDie -eq 1){

                        try{
                            $Result=Invoke-Expression($messages.message.text) -ErrorAction Stop
                            Write-Host "The Output of the command was the following" -ForegroundColor Green
                            $Result
                            Write-Host "End of Execution--------------" -ForegroundColor Green
                            SendTGMessage -Messagetext $Result -ChatID $messages.message.chat.id
                        }
                        catch {
                            SendTGMessage -Messagetext ($_.exception.message) -ChatID $messages.message.chat.id
                        }
                        Finally{
                            $lastexecMessageID=$messages.message.date
                        }
                    }
                                
            }
            

        }


        }
}

Yes, we made it, hope you like it, I might do a video which walks through all the components and details

<– Control your Infrastructure using… Telegram Messenger (Part 1 – Create the Bot)
<– Control your Infrastructure using… Telegram Messenger (Part 2 – Send and Receive.)
<– Control your Infrastructure using… Telegram Messenger (Part 3 – Basic Security)
Control your Infrastructure using… Telegram Messenger (Part 4 – Execution)

5/5 - (1 vote)