Thumbnail: jekyll

API Everything - Operation ChatOps Test API Functionality

on under python
5 minute read

API Everything

Operation Chatops

Adding Some Test API Functionality

Setting Up API Functionality
See HERE for Initial Bot Setup instructions.
See HERE for Bot Processes Persistence instructions.
See the above pages for a zero-to-hero setup of a bot, including how to make sure it stays running on your linux host.

Why Send Data?

This page will cover making a bot send data to some endpoint url.
Why send data?
Imagine you have some network device that has API functionality.
Imagine that you’d like to do stuff with that API, you figure out how to do it, and it’s cool and useful.
Now imagine that you just magically have a way to tell some webex bot to do said API stuff with a single message.
We are currently at the “magically” portion of “tell some webex bot to do said API stuff”.
For APIs, you have an endpoint that listens for commands. Let’s say, it’s your Firewall. It has an API address that’s enabled, and API commands it’ll take.
Let’s say this Firewall API has a BLOCK X command, where it will add X domain to a BLOCKLIST.
Let’s say it accepts this API command as https://your-firewall-ip/api/security/policies/blocklist, and let’s say that this simply takes the json input of {“add”: “domain.com”}.
Below is code to give a webexteamsbot everything it needs to perform such an action.
This turns a webex bot into an impromptu Command and Control channel to literally control your firewall, usable only by you.

A New Function to Send Data

First thing’s first, we need a new function in the bot.
It needs to take user input, in the form of “/keyword somedata”.
“Somedata” then needs to be stripped out, so that it alone can be injected into some JSON and later sent to an API.
If there is data within “/send somedata” then we’ll construct a POST request, put somedata into some json, and send it to the endpoint for later processing.
If there’s not any data present then the we’ll make the bot tell the user to supply some data there.
At that point, if the endpoint returns a 200 OK, then we’ll have the bot inform the user, you.
If not, then it will inform the user of whatever status code came about.

Here we go, in code form:

def send_data(incoming_msg):
    # Strip somedata from incoming message "/send somedata"
    data = bot.extract_message("/send", incoming_msg.text).strip()

The above just declares the new function. It accepts the input of your webex user’s msg, and strips the “/send” part from “/send somedata”. Making data = somedata in this example. Below handles what to do with said data, if it exists.

    # If data is present...
    if data:
        print("Data string found: " + data)
        reply = "Can send this: " + data
        headers = {"Content-Type": "application/json"}
        json = {"data": data}  # <--- {"data": "somedata"}
        url = "<REDACTED>"  # <--- Paste in a RequestBins.com endpoint URL here for testing!!!
        # Send the POST to above URL
        response = requests.post(url=url, json=json, headers=headers)
        print(response.status_code)

In the above code, IF data exists, then package up a POST request and send it to some endpoint. This is the entire building block for this bot’s future API Command and Control functionality.
Open up RequestBins.com and paste in the Endpoint URL that it gives you. Below is for handling the POST’s response to said url, and is pretty self explanatory.

        # If successful...
        if response.status_code == 200:
            reply = "200 OK"
            return reply
        # If NOT successful...
        else:
            reply = str(response.status_code)
            return reply
        return reply
    # If data is NOT present...
    else:
        reply = "Please provide some data after /send"
        return reply
    # Return the appropriate reply, from the above options Success, Not Success, or No Data Present.
    return reply

So we’ve got a nice set of nested logic above. If there’s data, send the data. Otherwise skip down and tell the user to give some data. If sending existing data then tell the user what happened, how it went.

Add Command Send Data

The last part needed is to add the command to the bot with the below snippet:
bot.add_command("/send", "Sends command word to an API. \tUsage: '/send <command>'", send_data)
Easy.

Let’s Actually Send Some Data!

So here’s what we’ll do.

  1. Go to this python script, copy/paste what you need into your webex bot code. Be sure to edit all the <REDACTED>’s to match your setup.
  2. Open RequestBin.com and copy your free endpoint url, keep the page open in browser. Paste the url into line 82-ish of the bot’s script, where url = "the url".
  3. Run the bot’s code. Open up webex. Send the bot the msg “/send testing_1_2_3”.
  4. Look at the open RequestBin and view the new POST request that’s in there. If you click the new POST then you will see that your webex bot sent the following: {"data": "yourtext"} Great! Now you can change the requestbin URL to an API Endpoint, and change {“data”: data} to {“whatever’s needed”: data} and start interacting with that API via the bot!

If it didn’t work, or errored out, and you actually WANT it to be working, then direct msg me on Linkedin and I’ll help you troubleshoot. I’m highly invested in this whole “exploit Cisco Webex to make C2 Servers” idea!

Next up is figuring out how to enable my Wazuh API, figuring out how to shut off my kid’s internet with a Wazuh Agent via API, then presenting the findings here!

python, linux, webex, API, requestbin
comments powered by Disqus