Jump to content

Recommended Posts

Tonight, I encountered a bizarre command related to a "flying giant pumpkin." Here's the story:

While playing the game, the server host notified me that there were abnormal requests coming from my client, spamming the server logs. At first, I thought it was a mod issue, so I disabled all local mods—but the problem persisted. I even deleted all mod files and mod log files, yet the issue remained unresolved.

image.jpeg.9674a6852711c167a948cd524071d49c.jpeg

Eventually, I dug into the client log files located in the Klei folder and asked GPT to analyze them. It turned out that after joining another player's world, a specific piece of code was being executed repeatedly: a script that spawns an oversized pumpkin.

I had GPT review the suspicious code. The issue was quite obvious, even when looking at the logs manually—there were huge blocks of repeated and unexplained instructions being executed. The code doesn't do much in other players’ worlds due to the lack of host permissions. However, it keeps spamming your local client logs with garbage entries and, if the server has detection for suspicious client behavior, it floods the server logs too.

According to some friends, this script can indeed spawn flying pumpkins—but only visible with a far zoom-out, because they spawn very high up in the air. I personally haven’t seen one yet, though.

Here's part of the code that was being executed repeatedly(his image is not fully displayed 😞)

for i, v in ipairs(AllPlayers) do
    local pos = v:GetPosition()
    pos.y = 60
    local pmk = SpawnAt('pumpkin_oversized', pos)
    pmk.AnimState:SetMultColour(0, 0, 0, 0)
    pmk:DoTaskInTime(0, function()
        pmk.components.pumpkincarvable.cutdata:set("AQAAAB...")  -- a massive serialized string
    end)
end

Why I'm Sharing This

I'm reposting this issue here in the hope that someone with deeper modding experience or knowledge of how networked components work in Don't Starve Together can help investigate and possibly fix it.

At this point, it's unclear whether this was caused by a malicious mod, a broken update, or just a strange interaction in the code—but the fact that the payload keeps executing even after removing all mods makes it especially concerning.

Thanks for reading.

  • Like 7
  • Shopcat 1
  • Spooky 2
  • Developer

Hi @HelloWig

Thanks for this report!

Are you the person who originally encountered this issue, or are you just sharing the post for more visibility?

Do you happen to still have that log file? I would love to have a look at it, and may have some more questions.

(and if you happen to have the plantregistry file from your client_save directory, as mentioned above, I'd love to see that as wel)

 

  • Like 8
2 hours ago, bizziboi said:

Hi @HelloWig

Thanks for this report!

Are you the person who originally encountered this issue, or are you just sharing the post for more visibility?

Do you happen to still have that log file? I would love to have a look at it, and may have some more questions.

(and if you happen to have the plantregistry file from your client_save directory, as mentioned above, I'd love to see that as wel)

 

I am the person who encountered this issue. This is a client log from when I tested playing on another server after loading a simple compiled detection mod. Currently, the issue I encountered has been resolved by a modder, who has posted a related thread on the bug tracker.

 

client_log.txt

  • Like 2
  • Thanks 1
2 hours ago, bizziboi said:

Hi @HelloWig

Thanks for this report!

Are you the person who originally encountered this issue, or are you just sharing the post for more visibility?

Do you happen to still have that log file? I would love to have a look at it, and may have some more questions.

(and if you happen to have the plantregistry file from your client_save directory, as mentioned above, I'd love to see that as wel)

 

Sadly, I didn’t realize that I should have kept the plantregistry file when I deleted its contents, but I do have a screenshot of the file’s content from when someone helped me troubleshoot the issue remotely.

屏幕截图 2025-06-26 232805.png

  • Thanks 1
  • Developer

Thanks, and you couldn't possibly know someone would ask for that file of course.

It confirms at least part of what I hoped to find out.

@Dasine while at it - I am curious about the commandhook mod. Is that something you installed?

  • Like 5
  • Thanks 1
23 minutes ago, bizziboi said:

Thanks, and you couldn't possibly know someone would ask for that file of course.

It confirms at least part of what I hoped to find out.

@Dasine while at it - I am curious about the commandhook mod. Is that something you installed?

A modder saw the issue I posted in the community discussion group and compiled a simple mod to help find the source of the large number of unknown commands.(Eventually, he remotely controlled my computer to troubleshoot the problem, found the problem and solved it)

Regarding the question, yes, the client log I sent has only this mod installed.(I didn't save the earlier client log without any mod loaded and it was automatically overwritten. But I did check the content, and it was similar to the log I provided, with a lot of repeated unknown instructions.)

The modder who compiled this mod is the one I posted before,  @mmdx

Edited by Dasine
  • Like 2
15 minutes ago, bizziboi said:

Thanks, and you couldn't possibly know someone would ask for that file of course.

It confirms at least part of what I hoped to find out.

@Dasine while at it - I am curious about the commandhook mod. Is that something you installed?

it"s a simple mod to find where load string , i use it to know the file load some codes . 

the mod hook loadstring and TranceBackstack so i can find where load the pumb code.

and the skin code and pumb code are write in same place , i found the person who get skin problem who will also get pumb problem . 

3 hours ago, bizziboi said:

Hi @HelloWig

Thanks for this report!

Are you the person who originally encountered this issue, or are you just sharing the post for more visibility?

Do you happen to still have that log file? I would love to have a look at it, and may have some more questions.

(and if you happen to have the plantregistry file from your client_save directory, as mentioned above, I'd love to see that as wel)

 

Let's sort out our thoughts. If a server has a module that everyone needs to enable, it can try to write a file on all clients. Then these clients can try to influence the server to enable the original malicious module on their own servers, which will form a chain of transmission. The two previous times, once io was disabled and once skinapi could not be called in the mod, aren't these both superficial measures and not fundamental ones? Why can't we just disable the source. Will the next time the malicious code uses c_reset() to infinitely reset the game, we still write these codes so that they cannot be called in the module? This is ridiculous.

really hope that the io and skin api can work again, after all, the real problem is not these two functions

  • Like 1
  • Thanks 2
5 hours ago, mmdx said:

it"s a simple mod to find where load string , i use it to know the file load some codes . 

the mod hook loadstring and TranceBackstack so i can find where load the pumb code.

and the skin code and pumb code are write in same place , i found the person who get skin problem who will also get pumb problem . 

Let's sort out our thoughts. If a server has a module that everyone needs to enable, it can try to write a file on all clients. Then these clients can try to influence the server to enable the original malicious module on their own servers, which will form a chain of transmission. The two previous times, once io was disabled and once skinapi could not be called in the mod, aren't these both superficial measures and not fundamental ones? Why can't we just disable the source. Will the next time the malicious code uses c_reset() to infinitely reset the game, we still write these codes so that they cannot be called in the module? This is ridiculous.
 

really hope that the io and skin api can work again, after all, the real problem is not these two functions

Thanks for your contribution, it looks like our service here won't be materially affected, which is a relief.

From a personal technical point of view, ensuring security with pure technology while supporting mods is a relatively complex issue, and as a game development team rather than a virtualization tech team it's unrealistic to put a lot of effort into this.

On the other hand, the limitations on the available interfaces do affect the upper limits of the capabilities of some mods with unusual creativity/technical skills.

 

My personal suggestions are as follows:

1. As the old Chinese saying goes, “Blocking is better than removing”.

2. Community issues require community input.

3. Classify the available interfaces of current mods into potentially risky interfaces (external io, serialization, underlying rpc, etc.) and relatively safe ones.

4. Set up a “trusted” category/label for mods, and recruit a small number of reviewers in the player mod community, and mods that have been reviewed by the reviewers can be labeled with this label.

5. Signature verification of game engine executables and libraries at startup. Interact with the steam api at the engine level to make sure that only “trusted” mods can directly call risky interfaces.

 

This isn't a perfect solution, but it's relatively low-complexity to implement and ensures that the development team's efforts aren't diverted from the game itself.

--------------------------------------------------------------------------------------------------------
 

For server operators, I strongly recommend the following hardening solutions. 

 

1. Soft-link `mods/` in the server installation directory to a `security zone' directory, and don't forget `ugc` directory. Severely restrict the security of this directory by applying access permissions/security context/executable permissions on the file system mount. 

2. Mount the server installation directory as “read-only” when running the server on a daily basis. 

3. After each server upgrade, ensure that the server installation directory is additionally verified using steam in a trusted execution environment.

4. Actively monitor the server logs for non-common content and make sure to restart the server regularly.

 

Finally, a small rant. @bizziboi ╮(╯-╰)╭
The server-side `-cloudserver` output is not easy to parse, lacks clear documentation, and lacks additional audit output for critical function calls. This feature, if improved, could be a breakthrough in the security of long-maintained servers.

Edited by WH-2099
  • Like 3
  • Thanks 1
  • Sanity 1

Due to the suggestion to remove the files in question in the initial issue discussion (Chinese player community), many of the affected players we contacted were unable to provide responsive files, but we thank them here for their participation.

This took quite a while, and thanks to @stardust qwq for providing the samples and @liolok for coordinating the communication, we ended up with a relatively pristine collection of simply obfuscated lua functions.

I think the focus may be on the pumpkin carving data, which may express some of the author's views.

Unfortunately, due to lack of time and energy, I won't be able to log into the game anytime soon to do more research.

It's up to you, mod lovers!

https://tmp.starv.ing/plantregistry

This link will expire after a certain period of time, so please save the file yourself if you need to archive it.

Edited by WH-2099
  • Like 1
  • Thanks 2
9 hours ago, bizziboi said:

Hi @HelloWig

Thanks for this report!

Are you the person who originally encountered this issue, or are you just sharing the post for more visibility?

Do you happen to still have that log file? I would love to have a look at it, and may have some more questions.

(and if you happen to have the plantregistry file from your client_save directory, as mentioned above, I'd love to see that as wel)

 

I'm not the one who originally discovered this issue. As you may have seen, the original author has already replied in the comments below. I hope you’ll be able to look into this problem. Thank you very much!

  

@bizziboi

Sorry, we may need your further assistance.

According to feedback from our community, some players have reported that after deleting the plantregistry file, it reappears when entering a specific local save file in single-player mode.

Fortunately, we were able to extract the entire local save file from this player (who had previously provided the plantregistry file), as they had promptly saved a backup after discovering their skin had been maliciously dismantled.

Based on the backup logs, we found that this save file was already infected on June 19 (and thanks to @kipper0k , maybe June 14 or earlier), which differs from the time players reported their skins being maliciously dismantled on June 23.


 

Out of curiosity, despite having almost no experience writing Lua code in a production environment (I am actually a relatively specialized Python engineer), I attempted to investigate the obfuscated code with the help of a language model.

Interestingly, the obfuscation method used in this code was quite “classic” (i.e., it implemented a simple virtual machine internally and serialized the actual code into its own bytecode), so I was able to reuse some of my Python-related processing experience.

 

Based on the relatively easy-to-deobfuscate constant string content, I was able to identify the actual code string that was remotely executed on the player's client.

if not _G.SpawnSecondInstance then return end _G.SpawnSecondInstance = nil StartThread(function() while true do if AllPlayers then for i, v in ipairs(AllPlayers) do local pos = v:GetPosition() pos.y = 60 local pmk = SpawnAt('pumpkin_oversized', pos) pmk.AnimState:SetBuild("pumpkin_oversized") pmk.AnimState:SetBank("pumpkin_oversized") pmk.AnimState:PushAnimation("carved_idle", true) pmk:DoTaskInTime(0, function() pmk.components.pumpkincarvable.cutdata:set('_G.for_other=""') end) pmk:DoTaskInTime(1, pmk.Remove) end end Sleep(1) end end)

In addition, I have pieced together some more certain information:

1. By listening to chat messages, a `/netid` command has been implemented, which likely allows the execution of arbitrary Lua code, posing a high security risk.

2. It attaches its functionality to standard game events such as `OnSay` and `Networking_PartyChat` to ensure its command system remains active at all times.

3. In an infinite loop thread, it continuously generates and removes large pumpkins around all players, causing visual interference or effects.

4. It automatically joins parties and exploits plant state saving.

 

There isn't much information, but it seems clear that this is not an accident. It has self-replication capabilities and has opened a fully exploitable backdoor, making it a standard backdoor worm.

I believe this is likely the vulnerability entry point for the malicious code that later disassembled players' skins.

However, I don't have a good solution to fully deobfuscate it, so there is still a significant amount of logic we are unaware of.

 

---------------------------------------------------------------------------------------------------

 

This raises new questions:

1. Could there be deeper backdoors or other malicious content we haven't discovered in the obfuscated code?

2. Are the parties responsible for creating the backdoor and exploiting it to dissect players' skins the same?

3. During the period when this backdoor infected a significant number of players, were there only malicious actions related to dissecting skins?

4. Before the official patch is released, how should we temporarily address the fact that this backdoor will still exist on some servers and players' local systems?

Edited by WH-2099
  • Like 1
  • Sanity 1
15 hours ago, WH-2099 said:

  

@bizziboi

Sorry, we may need your further assistance.

According to feedback from our community, some players have reported that after deleting the plantregistry file, it reappears when entering a specific local save file in single-player mode.

Fortunately, we were able to extract the entire local save file from this player (who had previously provided the plantregistry file), as they had promptly saved a backup after discovering their skin had been maliciously dismantled.

Based on the backup logs, we found that this save file was already infected on June 19 (and thanks to @kipper0k , maybe June 14 or earlier), which differs from the time players reported their skins being maliciously dismantled on June 23.


 

Out of curiosity, despite having almost no experience writing Lua code in a production environment (I am actually a relatively specialized Python engineer), I attempted to investigate the obfuscated code with the help of a language model.

Interestingly, the obfuscation method used in this code was quite “classic” (i.e., it implemented a simple virtual machine internally and serialized the actual code into its own bytecode), so I was able to reuse some of my Python-related processing experience.

 

Based on the relatively easy-to-deobfuscate constant string content, I was able to identify the actual code string that was remotely executed on the player's client.

if not _G.SpawnSecondInstance then return end _G.SpawnSecondInstance = nil StartThread(function() while true do if AllPlayers then for i, v in ipairs(AllPlayers) do local pos = v:GetPosition() pos.y = 60 local pmk = SpawnAt('pumpkin_oversized', pos) pmk.AnimState:SetBuild("pumpkin_oversized") pmk.AnimState:SetBank("pumpkin_oversized") pmk.AnimState:PushAnimation("carved_idle", true) pmk:DoTaskInTime(0, function() pmk.components.pumpkincarvable.cutdata:set('_G.for_other=""') end) pmk:DoTaskInTime(1, pmk.Remove) end end Sleep(1) end end)

In addition, I have pieced together some more certain information:

1. By listening to chat messages, a `/netid` command has been implemented, which likely allows the execution of arbitrary Lua code, posing a high security risk.

2. It attaches its functionality to standard game events such as `OnSay` and `Networking_PartyChat` to ensure its command system remains active at all times.

3. In an infinite loop thread, it continuously generates and removes large pumpkins around all players, causing visual interference or effects.

4. It automatically joins parties and exploits plant state saving.

 

There isn't much information, but it seems clear that this is not an accident. It has self-replication capabilities and has opened a fully exploitable backdoor, making it a standard backdoor worm.

I believe this is likely the vulnerability entry point for the malicious code that later disassembled players' skins.

However, I don't have a good solution to fully deobfuscate it, so there is still a significant amount of logic we are unaware of.

 

---------------------------------------------------------------------------------------------------

 

This raises new questions:

1. Could there be deeper backdoors or other malicious content we haven't discovered in the obfuscated code?

2. Are the parties responsible for creating the backdoor and exploiting it to dissect players' skins the same?

3. During the period when this backdoor infected a significant number of players, were there only malicious actions related to dissecting skins?

4. Before the official patch is released, how should we temporarily address the fact that this backdoor will still exist on some servers and players' local systems?

you only need to know where save the file code , then it will ez to get the answer , only need to hook Sim:SetPersistentString or loadstring then you can get where the code inject

Yes, I understand the interception you are trying to express here.

However, I'm not so much concerned about the injected code that the virus keeps through the persistent configuration interface(which we've hardened at least 3 years ago), but more about obfuscating the underlying instructions in the code that are not yet clear. In fact, because the persistence it exposes is so conspicuous, I'm worried about whether it uses a "tricky" architecture. Most of the time this is unfounded because it requires specialized knowledge and experience, but in today's LLM-assisted programming environment, I think it's always better to be cautious.

I still strongly recommend that the operator perform the necessary reinforcement on the server.   

Edited by WH-2099

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...