Categories: DiscussionDota 2

An analysis of Dota 2 Workshop Bot script “Sirius AI v1.6.3” which has been targeted from a post with lots of false claims

Hi, I would like to share some of my finding about the post https://old.reddit.com/r/DotA2/comments/qt14hf/there_is_a_highly_downloaded_dota_2_ai_bot_script/ that in my opinion, bringing very unfair towards the mentioned bot script, namely "Sirius AI 1.6.3 国际版". The reason is that there are many wrong technical analysis from the original post, not having a concrete backup source, and unable to come to a conclusion. These resulted in spreading Fear, Uncertainty, Doubt and most of all, damaging the work of the author of "Sirius AI 1.6.3 国际版".

Introduction

"Sirius AI 1.6.3 国际版" is a bot script of Dota 2. I will refer it as "SiriusAI".

My goal is ONLY analyze the cloud functions of SiriusAI version 1.6.3 released on 24 Aug 2021 10:38am. This means I don't cover other parts of the bot (like playing and farming, etc.) and also won't guarantee this analysis will be true for any future of this bot.

However, I can say that from skimming through those codes, it seems that the bot only do what other bot scripts do: Play Dota as a Bot. I have not yet discover any remote execution routine in this version (in simple term: the bot cannot extract data from web and change behavior without making an update to SteamWorkshop at this version).

SiriusAI use GNU license, however, I cannot find its repository or any of its source code online. So I subscribed to Steam and copy the source code from SteamLibrary/steamapps/workshop/content/570/1801131815. The bot seems to be a modification of "A Beginner AI", which is also a derived work of "BOT EXPERIMENT" by FURIOUSPUPPY.

The bot technical information

This is about the script that run in the Dota 2 Server (in Coop mode or Lobby) or your local machine (in Solo mode). Skip this section if you are not interested in coding, or how the bot works internally

Overview

The main helper (or library) functions of communication between SiriusAI and 'api.alchedo.top' (I will refer to it "Alcedo") is done within the file AuxiliaryScript/HttpServer.lua. The initiation for communication is done at mode_farm_generic.lua. Other files will only use HttpPost in HttpServer to communicate with the web server, including but not limited to ability_item_usage_generic.lua, bot_generic.lua, GameLive.lua.

The lib only handle formatting and sending the message to the server and not having dedicated set of functions. So I believed that the author is not very experience in designing architecture / RESTFul API, and so the it has to handle everythings from messaging (Chat, Item strategy, ability strategy) and operating (error report, delete user id, heartbeat, ….) from the same endpoint.

Authentication

Authentication is done by reading HttpServer.USERNAME and HttpServer.PASSWORD from the file located at game/天狼星用户配置. The bot do check if this file exist before using it. However, there is no code logic setting this file locally.
These values will be send to the API server on every request.

Communication

Communication is done by calling HttpServer.LocalHttpPost (local development) or HttpServer.HttpPost (production). Parameters are:

  • postData: object, the data that need to be posted to the server as the following JSON format
    {

    • operation: string – The operation, discovered values are:
      • "ERROR" – for logging,
      • "message" – receiving player chat message and giving response,
      • "getcloudkits" – for dynamic itemization during live game,
      • "gameEnd" – end game statistics, only transmitted at game end,
      • "getuuid" – get UUID from the server and set it to local
      • "delUUID" – delete the UUID that is being used (from the server ?)
      • "GetPoints" – I don't know what is the purpose, but this is called immediately after Authentication and the result is unused
      • "init" – unused – receiving initial data configuration
      • "heartbeat" – unused – check if server is alive,
      • "kill" – unused – for hero kill statistics, NOTE: this function can adjust bot strategy during live game,
      • "击杀信息" (killing information) – unused – for more detailed hero kill statistics, NOTE: this function can adjust bot strategy during live game,
      • "death" – unused – for death statistics, NOTE: this function can adjust bot strategy during live game,
    • errorContent: string – only if operation is set to ERROR message on error execution,
    • bot: string – name of the bot requesting for getcloudkits operation,
    • message: string – if operation is set to message, message of the player that the bot can see and send to the server
    • gameData: json – if operation is set to gameEnd, information of the game ending statistics with all players in the game. The information is "Team" (rad or dire), "Win" (if the player's team won the game), "Hero" (hero name), "Level", "MaxHealth", "MaxMana", "Gold", "kill", "Death", "Assist", "Bot" (if this player is a bot), "Item0", "Item1" …, "Item5",
    • hero: string – if operation is set to kill, 击杀信息, death – Hero name,
    • kill: string – if operation is set to 击杀信息 – Killed hero name,

    }

  • url: string, URL of the server, here isapi.alcedo.top:3010`

  • call: function, callback function when the server return data. it is called as call(resdata, calldata)

  • calldata: object, the data that needs to be called together with the callback function above

  • notUUID: boolean, if the UUID need to be obtained. false to obtain UUID if HttpServer.UUID is not set, true to ignore missing UUID. If UUID is missing, it will be transmitted with the value local instead (HttpServer.lua:125)

Communication with the server

Before sending the message above, the information need to be wrapped and send as application/json to the server as POST method. Here is the format body:

{

  • data: object postData – from previous section,
  • info: object {

    • uuid: string UUID
    • gameTime: float DotaTime(),
    • script: string constant Sirius AI,
    • user: string username from Authentication section,
    • password: string password from Authentication section

    }

}

New UUID can be get from the request with operation set to getuuid in the previous section. The server seems to always give UUID without any restriction. If UUID is not set (in the first getuuid request), the value will be set as local. The server also accept empty UUID.

Listen for player chat message

I have extracted the snippet here and deleted some of the irrelevant code:

InstallChatCallback(function ( tChat )
    ...
    elseif not closeMessage then
        local postData = {
            operation = 'message',
            message = '"'..tChat.string..'"',
        }
        local allmes = not tChat.team_only
        Http.HttpPost(postData, 'api.alcedo.top:3010',
        function (x, t)
            message = {
                mes = x,
                all = t
            }
            print('来自网络获取的消息:'..x)
        end
        , allmes,true);
    end
end);

We can clearly see that the bot will send any chat message it can see to the backend server on the operation message using InstallChatCallback from Valve Bot API here and here . So the bot only listen to the message that it can see that Valve allow it to. That means it won't read our allies message unless SiriusAI is playing in our team. The chat will be marked if it is allies message and send to the server.

The Web server information

I would like to remind that the information I posted here can be publicly discovered. I will still refrain from linking direct personal or contact information, but censoring or refuse to referring to them are nonsense for me, as these claims need to be verified publicly.

Skip this part if you don't want to know the details of the web server

1. Server location & domain

Through ICANN Whois and CheckHost the server is located in China under Alibaba Cloud service (The domain DNS is hichina.com which is part of https://www.alibabacloud.com/, the server IP address is also inside Alibaba Cloud CIDR).

The service register .top domain through Alibaba Cloud (aliyun.com) .top TLDs offer cheap domain name as low as 1$ compares to .com domain pricing around 9$ minimum.

2. ServerIP & AbuseCheck

If you want to check for history of any hacking activities or abuses, this is the correct direction. Relying on Wikipedia is wrong in many ways

api.alcedo.top seems to be resolved to 39.106.150.173 but alcedo.top resolves to multiple addresses depends on the service so I predict that this is the result of using shared webserver. So I check both their IP and domain based on the table below

AbuseIPDB MXToolbox SiteChecker
api.alcedo.top (39.106.150.173) Clean Clean Clean
alcedo.top (58.215.145.98) Clean 2/82 Clean (and can only check for domain name)
alcedo.top (58.216.118.225) Reported 8 times, 0% confidence of abuse 1/82 N/A
alcedo.top (61.160.228.203) Clean 1/82 N/A

3. HTTPS certificate

alcedo.top and api.alcedo.top:3010 does not use HTTPS
api.alcedo.top is serving through HTTPS with HTTPS certificate from TrustAsia TLS, registered from 05/10/2021 to 05/10/2022 . That means the owner has/renewed the HTTPS certificate since October. The cheapest cert I can find from TrustAsia is 1900 yuan (300$) a year. Please correct me if I'm wrong

If I am this guy I would rather treat myself than wasting 300$ for all of this shit. Actually I lied. I will use Let's encrypt for free.

The claims from old post

1. "… until I looked up the domain used and the specifics of a POST request. The domain used is .top … declared that it was so commonly used for phishing and malware"

  • .top, along with .com, .org, .xyz are TLDs (Top level domain). The domain, however, is the next part before the dot and combining it with .tld to make it a tier 1 domain , example, "aldeco.top", "google.com" are domains. https://en.wikipedia.org/wiki/Domain_name made a very detailed explanation
  • The correct thing to understand is that .top TLD are commonly used for phishing and malware, but the alcedo.top domain is not related

2. "MalwareBytes and Snort … they had to block the entirety of the .top"

  • MalwareBytes and Snort do not represent the entire Internet.
  • I myself blocked the entirety of .xyz in my adblocker because I have never visited any legitimate .xyz domain and it is used for ad spamming. However, when I need to visit a legitimate .xyz website, i will add it to whitelist. The same logic applies to those software companies: it's better and easier to block all of them, rather having to serve their customer with MBs if not GBs of block list and slowing their machine down.

3. "…so commonly used for phishing and malware,"

  • .top domain is commonly used for phishing and malware is a fact, I don't deny it. But accusing someone is shady, they might be doing phishing and distribute malware is like saying "knife is also commonly used to kill people outside US => Anyone using knife is a killer"
  • The reason .top domain is used so commonly is because hacker need a low cost cheap burning domain name. If we make a step back, we will see the same pattern with .tk, .ga, … and also these .xyz 1.111B class domain
  • Use a proper tool to check if someone did any activity in hacking, such as abuseipdb is the better way than just check wiki.
  • If .top TLD is a problem, you can do us a favor and report it to ICANN so they can shut it down.

4. "An "uuid" … I legitimately don't know how this value is generated as resetting my IP does not change the value of it. It could be the real world UUID, which would make sense for this instance, but I'm not sure."

  • If OP has zero idea, I will explain:
    • On startup, Valve Server (Coop Bot) or our machine will has no UUID set
    • If UUID is not set, it will be set to local
    • The script will try to get a valid UUID on its first operation request by calling getuuid operation
    • Set it to HttpServer.UUID and use it in any subsequence requests
  • As mentioned above, this UUID sent to our machine from the server and then be reused for other requests. Think of it like how our Browser or Steam doesn't log us out when we reset our modem / change our IP. Since this script doesn't make a write operation to a file, so this UUID value cannot be used track us at this stage. As when we turn off Dota 2, this UUID value will be cleaned.
  • There is no such thing as "real world UUID". UUID is defined so that if we generate it randomly and use it accordingly, it would be almost impossible for us to have 2 UUID colliding each others. Thus if we are merging 2 systems we won't have a fear of colliding ID. The UUID here is just a representation of how the backend is identifying our session, similar to how cookie are generated. The usage of UUID does not mean it is collecting our ID (Representation <> Purpose) . You need to have proof that a piece of code is retrieving and calculating your Hardware ID if you want to say that someone is collecting it . And also UUID is not the only way to collect our information.
  • My theory here is that the author uses UUID because the SQL software recommended it to him and he thinks it's cool.

5. "Typical header information you can get via a post request, such as your IP address and browser/service used to send the request."

  • Any web service on the internet require your IP Address to send reply. Without it there is no Internet.
  • By the way, this is only the machine that is sending the request. So if we are playing Coop Bot, the IP will be Valve server.

6. "…collecting chat data…"

Yeah…. right….

7. " you can pretty much do the same thing in the above screenshots without having to go to through the shady server" and "instead of giving out their API key for the chatbot service … cheap .top domain that scammers typically use"

  • From the linked image in that post, hello will response {face:14}Hello~
  • Querying api.alcedo.top:3010 for hello, we can see that the response Nice to meet you is completely different. I don't know how they are the same thing.
  • Also having a server instead of giving everybody your API key is the good practice

8. "The creepy responses to anti-CCP terms are a result of the service"

  • You must have fallen into a coma in 2016 so here let me help you, and this
  • ML models are as bias as human because we created it from our dataset. That's why cleaning bias in dataset is important
  • Actually original poster 2nd opinion are very accurate

Conclusion 2: A man made a dota 2 workshop mod and instead of giving out their API key for the chatbot service, they had to buy a very cheap .top domain that scammers typically use (hence the cheapness) to accept POST requests for the chatbot feature to as well as collect data about the performance of their bots, which is actually optional and disabled by default. The creepy responses to anti-CCP terms are a result of the service that he is using and not something he chose to put in the game. None of this is in the description and gives off terrible vibes, resulting in a loser with low MMR typing this up on a Friday Night.

But he seems not buying it "There are a lot of red flags but I don't think there are any mines. I thought it would be an interesting post to make."

9. "main site has a ton of broken links, it looks like a website template was used, and google chrome warns me of an unsecure connection"

  • He did not completed setting his website.
  • Broken links, Google chrome warn us of unsecure connection because we are not supposed to be there. What you are expecting from an unfinished website ?
  • Everyone use framework nowadays, also use multiple frameworks, not just in website development, but software development, mobile development, even CD/CI. What you are talking about ?

Conclusion

Initially I distrust SiriusAI because my bias toward Chinese software development. However, upon careful review, I see that the old post is damaging someone else's hard work. Based on how the project is designed, I predict that the author is a student and a Dota player. I haven't check throughout, but from searching the usage of HTTPRequest (from CreateRemoteHTTPRequest) from all of my subscribed bot scripts, I believe this is the first kind of a bot aside OpenAI that has the ambitious goal of changing the bot behavior in live game. Also, The author invested his money and time into serving better content on the api server than his main personal website. If it was me I would rather not to.

I'm not buying the idea of damaging someone else hardwork, even if they are inexperience. But I have no tolerate in half-ass completed homework with the author saying loudly he has zero idea what is he talking about. This is engineering and not political so we have enough tools and need to use them to verify our works rather than spreading FUD.

TL;DR The old post is damaging a very good bot by only doing incomplete research. This post do coding analysist showing what SiriusAI v1.6.3 is doing, also addressed faulty claims.

Gamer

Recent Posts

Ledx have been so hard for me this wipe

Not being able to craft them sucks. Especially when everyone I talk to about it…

1 year ago

My interesting and unfortunate Gwent life

First I'd like to say I absolutely love this game it's quality. Basically I first…

1 year ago

Teacher Tuesday 12/Dec/2023 – ask your questions here!

Welcome to Teacher Tuesday, a thread where anyone can ask any type of question without…

1 year ago

This games balance is confusing

I’m kind of new/returning to gwent I played beta and obviously it’s a lot lot…

1 year ago

Summary of 10 Days of Draws from Chaffee’s Bundles

Level 1 Bag (Free with Atmosphere Level 2) 6 small consumable (First Aid, Repair, Fire…

1 year ago

Why is my crew at 135%?

Here's my crew - T34-85M - for the life of me I cant figure out…

1 year ago