Guice Shop CTF - Kill Chatbot Challenge

Introduction

Today we will be looking at the Gusto Guice Shop CTF event. This event uses the OWASP Juice Shop vulnerable web application to learn how to identify and exploit common web application vulnerabilities.

What is CTF?

CTF (Capture The Flag) is a kind of information security competition that challenges contestants to solve various tasks ranging from a scavenger hunt on Wikipedia to basic programming exercises to hacking your way into a server to steal data. In these challenges, the contestant is usually asked to find a specific piece of text that may be hidden on the server or behind a webpage. This goal is named the flag!

In organized CTF events, the event is divided into three main categories, these are:

  • Jeopardy
  • Attack-Defense
  • Mixed events

Jeopardy

Competitors participating in Jeopardy-style CTF competitions have to solve complex tasks in a specific order. Each task has its significance. They can either be independent missions or be part of another mission together. Each topic can have a particular difficulty level, or they can be similar in difficulty—the more complex the task, the more points you can earn upon successful completion.

Attack-Defense

Competitors participating in the Offensive-Defense competition try to protect their hosts while attacking other competitors. Before the main part of the competition begins, each participant has enough time to build a defensive wall for their computer. The process of building a defensive wall includes patching and securing. In other words, each participant must find vulnerabilities on their computer before attacking others. Teams score points for fending off opposing teams' attacks and successfully infiltrating other teams. The team with the most points wins.

Mixed Events

In short, it is the category that includes both danger and offensive-defense challenges. For more info: https://ctftime.org/ctf-wtf/

Kill Chatbot Challenge

Guice shop has 100 challenges that are waiting to solve, and one of them is called Kill Chatbot!

Goal

Guice shop has a fast chatbot that helps customers by answering their questions. In that case, we will disable it entirely so that this chatbot can't help customers.

Let’s Start!

Let's review the chatbot first! In the beginning, it wants us to say our name, and then it answers our questions with related answers.

First, I tried to overload it by sending more than one message using brute force, but it caused me to solve another challenge…


Then I decided to look at this page more carefully, and the text 'powered by juicy-chat-bot' caught my attention.

When I googled this text, I found the NodeJS project named juice-chat-bot. Then I looked at the dependencies used by the project, I did not notice any malicious package, but when I started navigating their codes, I caught a strange situation

function process (query, token){
    if (users.get(token)){
        return model.process(trainingSet.lang, query)
    } else {
        return { action: 'uncrecognized', body: 'user does not exists' }
    }
}

We can see that the user messages are stored to use the process function. And then if look at another part, here, a string javascript code is run using this.factory.run(). This specific part is remote code execution.

addUser (token, name){
   this.factory.run(`users.addUser("${token}, "${name}")`)
}

When I looked where 'this.factory' came from, I saw an npm package. The name of the package is vm2.

If you remember, the bot asked us for our name in the first place so it could address us. In this part, the method named addUser() works.

When I type my name as an argument, it uses a value generated as a token and the data I enter as a name. Then add the data I entered as the name into the 'users.addUser' command with string interpolation and run it with the vm2 package.

If we manage to break the process function, the bot will shut down completely. This code looks like an eval() function. So, I decided to use the eval function exploit technique.

addUser (token, name){
   this.factory.run(`users.addUser("${token}, "${name}")`)
}

Then I send data to the chatbot like this after multiple attempts:

oguzhan"); process=null; users.addUser("1234", "ozi

The chatbot will convert this code below.

users.addUser("token", "oguzhan");`
`process = null;`
`users.addUser("1234", "ozi")

In this way, since I set the value of the process function to null, the bot's memory is killed, so it will not know what to reply to the following message. Let's try!

Congratulations! The bot will no longer be able to help users; we have completed the quest!

If you love to solve puzzles, I strongly recommend you have to attend CTF events and try to solve questions like these questions. When you are trying to solve a question, you are gonna gain too much knowledge about security and programming.

Lessons Learned

  • If we need to get a value from the user, we must use the value we receive by passing it through validation. Otherwise, the data received from the user might provide interpretation as code, and in this case, there might be such a security vulnerability.
  • When we decide to use any package for any language, we need to be more careful to select the package/library because your code might be secure but how secure is the package's code? You need to check the package/library’s GitHub/GitLab stars and check to see if it's up to date.

Secure with Gusto!

Special thanks to the entire Gusto Security Team for creating the CTF events and security trainings.

Note from the Security Team

We want to thank Oguzhan for participating and writing this blog post; you're the best! If this seems interesting to you or you're looking for a security role, we're hiring! Please check out our open positions by visiting our career page. We hope to hear from you!