Mining Ruby Gem vulnerabilities for Fun and No Profit.

Post on 09-Jan-2017

241 views 2 download

Transcript of Mining Ruby Gem vulnerabilities for Fun and No Profit.

Mining Ruby Gem Vulnerabilities for Fun and No Profit

Larry W. Cashdollar

v0.6

Who Am I• Employed at Akamai Technologies• Hobbyist Vulnerability Researcher• 75+ CVEs• Unix Administrator • Penetration Tester Back in Late 90s• Twitter @_larry0• Enjoy Writing and Breaking Code

Agenda• Why Ruby Gems• Gem Pros/Cons• What Vulnerabilities Did I Mine• How Did I Look for Them• Automation• Crowd Sourcing• Other Areas to Mine• Improvements

The Story• Vulnerability Research Like Wading Through

Molasses*• Discover a Vulnerability Once Every Two Months?• I Wanted MOAR FASTER!• I Don’t Write Ruby

* at least for me

Why Gems

• Large Code Base• Lots of New Developers• No One Else Was Really Looking• Popularity

Pros/Cons

• Con– I don’t write Ruby… yet– True PoC Requires a Full Project

• Pro – Lots of Ruby Gem Code to Look At!– Developers New to Secure Coding Practices– Easily Download Gem Code

Ruby Gem Stats

• 3,812,982,562 Downloads• 90,120 Gems Cut Since July 2009

Simple Vulnerabilities and Easy to Find

• Insecure use of /tmp or /var/tmp• Command Injection• Clear Text User/Password Credentials• API Keys• Credentials Exposed to Process Table

The Process

10. Download A Gem20. Unpackage30. Examine40. Log50. GOTO 10

How to Look?

• Lots of Code to Dig Through• Use Tools Readily Available

– find– grep– awk– sed

Searching via Command Line

$ wget http://www.rubygems.org/gems/ftpd-1.0.1.gem$ mv ftpd-1.0.1.gem ftpd-1.0.1.tgz$ tar -zxvf ftpd-1.0.1.tgz$ cd ftpd-1.0.1$ find . -name “*.rb” –exec grep –l system {} \; > list$ for x in `cat list`; do echo “#######[$x]######”; egrep –nC3 system {} \; done > ~/results/cmd.log

Automation

• Download All the Gems!• Search Code for Possible Vulns• Sort and Categorize For Later

The Script

• Shell Script On github• Scrapes rubygems.org• Uses curl/grep/find/awk/sed • It’s an Abomination

#!/bin/sh#ruby gem scraper, grab all the gems to hAck#Larry Cashdollar, @_larry0 2/17/2015

echo "[+] Scraping rubygems.org for all $1 Gems";echo "[+] Cleaning up files";

WPATH=workdirOUTPATH=outdir

rm -rf working.$1echo "[+] Getting number of pages for letter $1";

wget https://rubygems.org/gems?letter=$1 -O $1.max

NUM=`cat $1.max | grep Next | awk -F\= '{print $36}' | awk -F\" '{print $1}'`

#will give us number of pages in Cxecho "[+] Number of pages :"$NUM

echo "[+] Downloading all $1 gems"

for x in `seq 1 $NUM`; do wget -nv https://rubygems.org/gems?letter=$1\&page=$x -O $1.$x.list ; done

echo "[+] Creating package list"

cat $1.*.list |grep "href=\"/gems/" | awk -F= '{print $3}' | sed -e 's/\/gems\///g' | sed -e 's/\"//g' | sed -e 's/>//' > main_pkg_list.$1echo "[+] Downloading all packages pages for parsing"

mkdir working.$1

for x in `cat main_pkg_list.$1`; do wget -nv https://rubygems.org/gems/$x -O working.$1/$x ; done

cd working.$1

LIST=`ls|wc -l`

echo "[+] Creating download script for $LIST gems."echo "#!/bin/sh" > download.sh.tmpfor x in `ls`; do cat $x |grep Download | awk -F\" '{print "wget -nv https://rubygems.org"$4}'; done >> download.sh.tmpcat download.sh.tmp | sort -u > download.shmkdir data.$1mv download.sh data.$1cd data.$1chmod 755 download.shecho "[+] Downloading gems.."./download.shecho "[+] Renaming files from .gem to .tar"

for x in `ls|grep gem`; do echo -n "mv $x "; echo "$x" | sed -e 's/.gem/.tar/'; done > rename

sh renamerm renameecho "[+] Unpacking"for x in `ls *.tar`; do echo $x | sed -e 's/.tar//'| xargs mkdir ; done

for x in `ls |grep -v .tar` ; do echo "- Working on $x";tar -xmf $x.tar -C $x ; done

for x in `ls|grep -v .tar`; do echo "- Unpacking $x"; tar -zxmf $x/data.tar.gz -C $x; done

echo "[+] Generating file lists of potential targets"

cd $WPATH/working.$1/data.$1echo "************************************************************"pwdecho "************************************************************"

find . -name *.rb -exec grep -l "\`#{command}\`" {} \; > cmdfile.$1.log find . -name *.rb -exec egrep -l "api_key|apikey" {} \; > api_key.$1.log find . -name *.rb -exec egrep -l "\`*\`" {} \; > backtick.$1.logfind . -name *.rb -exec egrep -l "system\(|system\s\(" {} \; > system.$1.logfind . -name *.rb -exec egrep -l '%x[\{\(\[]' {} \; > x_percent.$1.log find . -name *.rb -exec grep -l "/tmp" {} \; > tmpfile.$1.log

echo "[+] Looking for (basic) command exec vulnerabilities."#we are only finding a few of them, see http://tech.natemurray.com/2007/03/ruby-shell-commands.htmlfor x in `cat cmdfile.$1.log`; do echo "+--------------------[$x]-------------------+"; grep -nC3 "\`#{command}\`" $x; echo "+---------------------------------------------------------------------+"; done > command.$1.log.txt

for x in `cat x_percent.$1.log`; do echo "+--------------------[$x]-------------------+"; egrep -nC3 '%x[\{\(\[]' $x; echo "+---------------------------------------------------------------------+"; done > x_percent.$1.log.txt

for x in `cat backtick.$1.log`; do echo "+--------------------[$x]-------------------+"; egrep -nC3 "\`*\`" $x; echo "+---------------------------------------------------------------------+"; done > backtick.$1.log.txt

for x in `cat system.$1.log`; do echo "+--------------------[$x]-------------------+"; egrep -nC3 "system\(|system\s\(" $x; echo "+---------------------------------------------------------------------+"; done > system.$1.log.txt

echo "[+] Looking for /tmp file vulnerabilities."

for x in `cat tmpfile.$1.log`; do echo "+--------------------[$x]-------------------+"; grep -nC3 "/tmp" $x; echo "+---------------------------------------------------------------------+"; done > tmpfile.$1.log.txt

echo "[+] Looking for API key exposure vulnerabilities."

for x in `cat api_key.$1.log`; do echo "+--------------------[$x]-------------------+"; egrep -nC3 "api_key|apikey" $x; echo "+---------------------------------------------------------------------+"; done > api_key.$1.log.txt

cp command.$1.log.txt $OUTPATH/$1-command.txtcp tmpfile.$1.log.txt $OUTPATH/$1-tmpfile.txtcp x_percent.$1.log.txt $OUTPATH/$1-xexec.txtcp api_key.$1.log.txt $OUTPATH/$1-apikey.txtcp backtick.$1.log.txt $OUTPATH/$1-backtick.txtcp system.$1.log.txt $OUTPATH/$1-system.txt

cd $WPATH

echo "[+] Done"

Automation

• Pump Everything into MySQL Database• 6000 Entries• At Least 5000 obvious False Positives• FAIL

Crowd Source

• Created User Web Interface • Flag Finds as FP, Confirmed, Needs

Attention, Unknown• Invited a Few Friends

Dependencies

• https://www.ruby-toolbox.com

Going Sour

• Grave Yard of Code• < 1000 downloads• No Response from Gem Author• Pull Requests go un-Pulled• Dreaming about Ruby Code

Other Programming Languages?

• Perl Modules?• PHP Pear Packages?• Joomla! and WordPress

– Themes– Plugins

Improvements

• RFI,LFI,SQLi,XSS,CSRF?• Gem Auditing Project? • Use rubygems.org API?• Reduce FPs

– Better Regular Expressions– Parse .rb scripts, create lookup tables/symbol

tables for variables and code flow

My Github Junk• https://github.com/lcashdol/rci-info• https://github.com/lcashdol/rubygem_miner• https://github.com/lcashdol/wpthemedownloader• https://github.com/lcashdol/wpplugindownloader

WWW• http://www.vapid.dhs.org