Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wazuh-api.service.ps1 Invalid JSON primitive: System.Net.WebException. #387

Closed
jakko10 opened this issue May 17, 2019 · 13 comments
Closed
Assignees

Comments

@jakko10
Copy link

jakko10 commented May 17, 2019

when I run the script first time I get:
Getting agent key:
ConvertFrom-Json : Invalid JSON primitive: System.Net.WebException.
At C:\scripts\api-register-agent.ps1:89 char:70

  • ... -method "GET" -resource "/agents/$($agent_id)/key" | ConvertFrom-Json
  •                                                      ~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
    • FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand

when I run the script the second time then it's all good.

@AdriiiPRodri
Copy link
Contributor

Hi @jakko10 ,
Thank you for your time, I see that the error you tell us has to do with the version of Powershell that executes the script.

Can you tell me your Powershell version? That way I can help you better.
In any case you can try to make the following change on line 89:

$response = req -method "GET" -resource "/agents/$($agent_id)/key" | Out-String | ConvertFrom-Json

This error can occur in more parts of the script, in all of them the solution would be the same.

I hope I helped you, any question you have do not hesitate to ask

Best regards,
Adri

@jakko10
Copy link
Author

jakko10 commented May 21, 2019

@AdriiiPRodri thank you for your reply.
Yeah, sorry, I should have included powershell version info in my first post.

Major 5, Minor 1, Build 17763, Revision 503

..

Good thing is, your suggestion worked, I replaced line 89 with the code you provided and now it works like a charm every time.

PS! one thing that I see is every time I runs this script a line gets added to the end of ossec.conf if you make a typo for example in the IP then you'll end up with a typo on your conf file as well.

Thank you!

@AdriiiPRodri
Copy link
Contributor

You're welcome @jakko10 ,

I'm glad I solved your problem. As for what you're saying about the typo, currently the script doesn't have the capacity to know if what you're putting into it contains a typo error.

At the moment there is no intention to add that functionality since this is a script just for support. If this happens, you would have to modify the file ossec.conf stored in

C:\Program Files (x86)\ossec-agent\ossec.conf

Any question you have do not hesitate to ask

Best regards,
Adri

@jakko10
Copy link
Author

jakko10 commented May 21, 2019

@AdriiiPRodri maybe one idea how to "fix" this could also be that every time you run the script it will replace the line added by the script? Currently every time you run the script, it adds new line to the end of the file.
So you can end up with 10 different lines in the end of ossec.conf file. Yes usually you would never run the script more than once, but in my case, I am/was testing, so I ran it 10x already and later realized how the typo came to be :)

Looks like this one will do the trick.

Set-Content -Path "$config" -Value (get-content -Path "$config" | Select-String -Pattern '<ossec_config> <client> <server> <address>' -NotMatch)

@AdriiiPRodri
Copy link
Contributor

AdriiiPRodri commented May 21, 2019

We're going to try to solve that problem @jakko10, if you add this to the script by replacing lines 114 and 144 with:

$regex = '^<ossec_config>   <client>    <server>  <address>.*</address> </server>   </client> </ossec_config>'
If ($regex.Matches(Get-Content $config).Length > 0) {
    (Get-Content $config) -replace $regex, "<ossec_config>   <client>    <server>  <address>$($wazuh_manager)</address> </server>   </client> </ossec_config>" | Set-Content $config
}
Else {
    Add-Content $config "`n<ossec_config>   <client>    <server>  <address>$($wazuh_manager)</address> </server>   </client> </ossec_config>"
}

This will replace the added line, in your specific case will replace the 10 so you will have to remove them manually, in the following executions whenever there is the line this will be replaced by the new line with the IP chosen.

Tell me if this has worked for you, any doubt or problem do not hesitate to ask.

Regards

@jakko10
Copy link
Author

jakko10 commented May 22, 2019

@AdriiiPRodri looks like your suggested changes are still adding new line at the end of ossec.conf every time you execute the script.

@jakko10
Copy link
Author

jakko10 commented May 22, 2019

Interesting, looks like your suggested fix didn't fix it after all.

Today I came to work, my workstation got new IP. Yesterday it was x.x.x.15 and today it's x.x.x.31.
So my agent was disconnected and could not reconnect to the server.
In /var/ossec/logs/ossec.log I could see: ossec-remoted: WARNING: (1213): Message from 'x.x.x.31' not allowed.

When I re-ran the scrip to re-register the agent it was always re-registring the agent with the old IP of x.x.x.15. I couldn't figure out where is it taking that IP from. But looks like the server was providing it to the script rather than script taking the ip from my workstation.

So, I removed the client from server with the help of: /var/ossec/bin/manage_agents

Now when I ran the powershell script then I still got the good old:
(ps the line numbers don't match because of my own change which I added to replace the last line in the script)
`ConvertFrom-Json : Invalid JSON primitive: The.
At C:\scripts\api-register-agent.ps1:93 char:83

  • ... -resource "/agents/$($agent_id)/key" | Out-String | ConvertFrom-Json
  •                                                      ~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
    • FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand`

and again when I ran the script second time it was all happy :)

@AdriiiPRodri
Copy link
Contributor

Hi @jakko10 ,

I couldn't try the changes because my platform is Linux, I just saw that I can download the Powershell of windows in Linux.
Let me try to find the solution to the problem we currently have.

@AdriiiPRodri
Copy link
Contributor

Hi @jakko10 ,

Sorry for the late, I've been trying options and found one that I think will solve your problem, the script is as follows:

###
#  Powershell script for registering agents automatically with the API
#  Copyright (C) 2017 Wazuh, Inc. All rights reserved.
#  Wazuh.com
#
#  This program is a free software; you can redistribute it
#  and/or modify it under the terms of the GNU General Public
#  License (version 2) as published by the FSF - Free Software
#  Foundation.
###

function Ignore-SelfSignedCerts {
    add-type @"
        using System.Net;
        using System.Security.Cryptography.X509Certificates;
        public class PolicyCert : ICertificatePolicy {
            public PolicyCert() {}
            public bool CheckValidationResult(
                ServicePoint sPoint, X509Certificate cert,
                WebRequest wRequest, int certProb) {
                return true;
            }
        }
"@
    [System.Net.ServicePointManager]::CertificatePolicy = new-object PolicyCert
    [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;
}

function req($method, $resource, $params){
    $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username, $password)))
    $url = $base_url + $resource;

    try{
        return Invoke-WebRequest -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method $method -Uri $url -Body $params
    }catch{
        return $_.Exception
    }

}

# Configuration
$base_url = "http://<Wazuh-Manager-IP>:55000"
$username = "foo"
$password = "bar"
$agent_name = $env:computername
$path = "C:\Program Files (x86)\ossec-agent\"
$config = "C:\Program Files (x86)\ossec-agent\ossec.conf"
$wazuh_manager = "<Wazuh-Manager-IP>"
Ignore-SelfSignedCerts

# Test API integration to make sure IE has run through initial startup dialogue - This can be a problem with new servers.

try{
    $testresponse = req -method "GET" -resource "/manager/info?pretty" | ConvertFrom-Json | select -expand data -ErrorAction Stop -ErrorVariable geterr

    Write-Output "The Wazuh manager is contactable via the API, the response is: `n $($testresponse)"
}catch{
    Write-Host -ForegroundColor Red "IE has not had it's initial startup dialogue dismissed, please complete this step and try again. Script will exit. Error: $($geterr)`n .Please Run OSSEC_AgentConfig Separately once you correct the error."
    Exit
}

# Test for agent already existing in manager

$agentexist = req -method "GET" -resource "/agents?pretty" -params @{search=$agent_name} # searches for the agent based on the env variable name

$agentinfo = $agentexist.Content | ConvertFrom-Json | select -expand data | select totalitems

$agentexistid = $agentexist.Content | ConvertFrom-Json | select -expand data | select -expand items | select id # expands the embedded JSON items to retrieve the agent ID

# If agent does not already exist proceed to create agent and register the agent key

if ($agentinfo.totalitems -lt 1){

    # Adding agent and getting Id from manager
    
    Write-Output "`r`nAdding agent:"
    $response = req -method "POST" -resource "/agents" -params @{name=$agent_name} | ConvertFrom-Json
    If ($response.error -ne '0') {
      Write-Output "ERROR: $($response.message)"
      Exit
    }
    $agent_id = $response.data
    Write-Output "Agent '$($agent_name)' with ID '$($agent_id)' added."
    
    # Getting agent key from manager
    
    Write-Output "`r`nGetting agent key:"
    $response = req -method "GET" -resource "/agents/$($agent_id)/key" | ConvertFrom-Json
    If ($response.error -ne '0') {
      Write-Output "ERROR: $($response.message)"
      Exit
    }
    $agent_key = $response.data
    Write-Output "Key for agent '$($agent_id)' received."
    
    # Importing key
    
    Write-Output "`r`nImporting authentication key:"
    echo "y" | & "$($path)manage_agents.exe" "-i $($agent_key)" "y`r`n"
    
    # Restarting agent
    
    Write-Output "`r`nRestarting:"
    $srvName = "OssecSvc"
    
    Write-Output "Stopping service."
    Stop-Service $srvName
    $srvStat = Get-Service $srvName
    Write-Output "$($srvName) is now $($srvStat.status)"
    
    Start-Sleep -s 10
    
    $regex = '^<ossec_config>   <client>    <server>  <address>.*</address> </server>   </client> </ossec_config>'
    $matches = ([regex]$regex).Matches((Get-Content $config))
    
    Get-Content $config | Where-Object {$_ -notmatch [regex]$regex} | Set-Content $config
    
    Add-Content $config "<ossec_config>   <client>    <server>  <address>$($wazuh_manager)</address> </server>   </client> </ossec_config>"
    
    Start-Sleep -s 10
    
    Write-Output "Starting service."
    Start-Service $srvName
    $srvStat = Get-Service $srvName
    Write-Output "$($srvName) is now $($srvStat.status)"
}
Else {

    # If agent is found in manager by name it will retrieve the key and configure the agent
    
    $response = req -method "GET" -resource "/agents/$($agentexistid.id)/key" | ConvertFrom-Json
    # Key received from manager
    $agent_key = $response.data
    # Importing agent key from manager
    Write-Output "`r`nImporting authentication key:"
    echo "y" | & "$($path)manage_agents.exe" "-i $($agent_key)" "y`r`n"
    
    Write-Output "`r`nRestarting:"
    $srvName = "OssecSvc"
    
    Write-Output "Stopping service."
    Stop-Service $srvName
    $srvStat = Get-Service $srvName
    Write-Output "$($srvName) is now $($srvStat.status)"
    
    Start-Sleep -s 10
    
    $regex = '^<ossec_config>   <client>    <server>  <address>.*</address> </server>   </client> </ossec_config>'
    $matches = ([regex]$regex).Matches((Get-Content $config))
    
    Get-Content $config | Where-Object {$_ -notmatch [regex]$regex} | Set-Content $config
    
    Add-Content $config "<ossec_config>   <client>    <server>  <address>$($wazuh_manager)</address> </server>   </client> </ossec_config>"
    
    Start-Sleep -s 10
    
    Write-Output "Starting service."
    Start-Service $srvName
    $srvStat = Get-Service $srvName
    Write-Output "$($srvName) is now $($srvStat.status)"


}

Tell me if this has solved the problem, any question do not hesitate to ask.

Best regards,
Adri

@jakko10
Copy link
Author

jakko10 commented May 22, 2019

Hi, if I remove the agent and run the new script then I get this:

`C:\scripts\api-register-agent_v2.ps1
add-type : Cannot add type. The type name 'PolicyCert' already exists.
At C:\scripts\api-register-agent_v2.ps1:13 char:5

  • add-type @"
    
  • ~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (PolicyCert:String) [Add-Type], Exception
    • FullyQualifiedErrorId : TYPE_ALREADY_EXISTS,Microsoft.PowerShell.Commands.AddTypeCommand

The Wazuh manager is contactable via the API, the response is:
@{path=/var/ossec; version=v3.9.0; compilation_date=Tue May 21 10:11:41 UTC 2019; type=manager; max_agents=14000; openssl_support=yes; ruleset_version=3914; tz_offset=+0000; t
z_name=UTC}

Adding agent:
Agent 'WIN014' with ID '@{id=003; key=MDAzIFdJTjAxNC1FU1QtVExOIDEwLjU3LjIuMzEgN2M3OTI1MTQxMDU5NGU0MWYwN2RiYjBmOWNiNmUxN2M4OTBjNDMxZjkwMGM2OTM2M445YWI3YmVlMDFjZDFlMQ==}'
added.

Getting agent key:
ConvertFrom-Json : Invalid JSON primitive: System.Net.WebException.
At C:\scripts\api-register-agent_v2.ps1:88 char:74

  • ... -method "GET" -resource "/agents/$($agent_id)/key" | ConvertFrom-Json
  •                                                      ~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
    • FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand

Key for agent '@{id=003; key=MDAzIFdJTjAxNC1FU1QtVExOIDEwLjU3LjIuMzEgN2M3OTI1MTQxMDU5NGU0MWYwN2RiYjBmOWNiNmUxN2M4OTBjNDMxZjkwMGM2OTM2M445YWI3YmVlMDFjZDFlMQ==}' received.

Importing authentication key:

** Invalid authentication key. Starting over again.
** Press ENTER to return to the main menu.

Restarting:
Stopping service.
OssecSvc is now Stopped
Set-Content : The process cannot access the file 'C:\Program Files (x86)\ossec-agent\ossec.conf' because it is being used by another process.
At C:\scripts\api-register-agent_v2.ps1:116 char:71

  • ... fig | Where-Object {$_ -notmatch [regex]$regex} | Set-Content $config
  •                                                   ~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [Set-Content], IOException
    • FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.SetContentCommand

Starting service.
OssecSvc is now Running`

@jakko10
Copy link
Author

jakko10 commented May 22, 2019

Also one more thing which is needed in my case.

# Adding agent and getting Id from manager $IP="any" Write-Output "rnAdding agent:" $response = req -method "POST" -resource "/agents" -params @{name=$agent_name; ip=$IP} | ConvertFrom-Json If ($response.error -ne '0') { Write-Output "ERROR: $($response.message)" Exit }

as you see I added:
$IP="ANY"
and $response = req -method "POST" -resource "/agents" -params @{name=$agent_name; ip=$IP} in the end.
with this change I don't have to worry if my workstation IP changes, my workstation will always show up as connected, just with different IP

@AdriiiPRodri
Copy link
Contributor

Hi @jakko10 ,

Currently if not specifically indicated the IP is set by default 127.0.0.1, one of the values you can assign is "any" which allows the agent to have a dynamic IP. This does not happen with the manager, this one has to have a static address.
The api-register-agent.ps1 script is currently untrusted and we have marked it for future revision, thank you for the warning, we need to correct and add extra checks, I'm going to open an issue.
I show you the steps to register an agent without having to use this script, let's do it using authd, there are other methods which can be consulted in our official documentation.
In this link you can see how to delete an agent

Once we have removed agent we are going to do the following register agent documentation, we will use the registration service with password authorization, this is optional (if we don't want to activate the password we can skip directly to the agent part) but if we want to add a layer more protection against unauthorized records we can add a password to authd for it we go to our file ossec.conf /var/ossec/etc/ossec.conf (in the manager) and changes to yes the option to use password:

<auth>
  ...
  <use_password>yes</use_password>
  ...
</auth>

After changing this we can choose our own password or let one be generated randomly, the latter will occur if we do not specify one in the file /var/ossec/etc/authd.pass and we can consult it in /var/ossec/logs/ossec.log, in our case we will choose one with the following command:

echo "MyCustomPassword" > /var/ossec/etc/authd.pass

We restart the manager for the changes to take effect:

service wazuh-manager restart

Now let's go to our agent, to register we are going to use agent-auth.exe, for it we will open a powershell terminal as administrator user, and we are going to execute the following to add our password (in my case MyCustomPassword) in our authd.pass file and then we will register the agent (MANAGER_IP_ADDRESS has to be changed by the IP of our manager):

echo MyCustomPassword > C:\Program Files (x86)\ossec-agent\authd.pass
C:\Program Files (x86)\ossec-agent\agent-auth.exe -m MANAGER_IP_ADDRESS

*The path may be changed to C:Program Files\...

Finally, we will edit the configuration of our agent to indicate the IP address of our manager, the path of the file is the following C:\Program Files (x86)\ossec-agent\ossec.conf, we open it with our text editor and change the value of MANAGER_IP to the IP of our agent:

<client>
  <server>
    <address>MANAGER_IP</address>
    ...
  </server>
</client>

We restarted our agent and the agent would already be registered and connected to our manager:

Restart-Service -Name wazuh

Best regards,
Adri

@crd1985
Copy link
Contributor

crd1985 commented Jun 3, 2019

Closing due to inactivity. Will reopen if necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants