Created
August 23, 2016 09:18
-
-
Save SebHeuze/e84c4451b9c3d19ce3ad450b00253fe4 to your computer and use it in GitHub Desktop.
Correction test rutorrent authentification xmlrpc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| # This code is in the public domain. | |
| # This script will check your ruTorrent installation. I make no guarantee that it | |
| # will detect all problems... | |
| # | |
| # It will test the following: | |
| # - RPC mount points are protected (requires password) | |
| # - user1 can't access user2's RPC mount point | |
| # - user1 can access his own RPC mount point | |
| # - No files in rutorrent/conf or rutorrent/share can be accessed | |
| # - Only an authenticated user can access ruTorrent | |
| # - .svn dirs can't be accessed | |
| # - user1 can't execute code (NOTE: only a few tests!) | |
| # The server to test, eg. 192.168.0.123 | |
| server=$1 | |
| # URL path to ruTorrent dir, usually / or /rutorrent | |
| ruTorrentPath=$2 | |
| # A valid ruTorrent user | |
| user1=$3 | |
| # The ruTorrent user's password | |
| pass1=$4 | |
| # The ruTorrent user's RPC mount point. | |
| user1Rpc=$5 | |
| user2=$6 | |
| pass2=$7 | |
| user2Rpc=$8 | |
| protocol=http | |
| port=80 | |
| # Set to y to only show errors | |
| onlyErrors=y | |
| numFailures=0 | |
| numTests=0 | |
| echo=echo | |
| $echo -n "x" | grep -qE '^-n' && echo=/bin/echo | |
| error() { | |
| $echo "$@" >&2 | |
| } | |
| msg() { | |
| $echo "$@" | |
| } | |
| failed() { | |
| numFailures=$(expr $numFailures + 1) | |
| numTests=$(expr $numTests + 1) | |
| [ $onlyErrors = y ] && _status "$url" | |
| msg | |
| msg " FAILED: $1" | |
| } | |
| passed() { | |
| numTests=$(expr $numTests + 1) | |
| [ $onlyErrors = y ] && return | |
| msg "PASSED" | |
| } | |
| _status() { | |
| $echo -n "Testing $1 ... " | |
| } | |
| status() { | |
| url="$protocol://$1" | |
| [ $onlyErrors = y ] && return | |
| _status "$url" | |
| } | |
| dlFail() { | |
| status $1 | |
| curl -k -f $protocol://$1 >/dev/null 2>&1 && failed "DL: $2" || passed | |
| } | |
| dlOk() { | |
| status $1 | |
| curl -k -f $protocol://$1 >/dev/null 2>&1 && passed || failed "DL: $2" | |
| } | |
| rpcExec() { | |
| local userInput="$1" | |
| shift | |
| local passwordInput="$1" | |
| shift | |
| local url="$1" | |
| shift | |
| xmlrpc -u $userInput -p $passwordInput -curlnoverifypeer true -curlnoverifyhost true -- $protocol://$url "$@" | |
| } | |
| rpcGetString() { | |
| rpcExec "$@" 2>/dev/null | grep -E '^String:' | head -n1 | sed -e "s/^String: '\\(.*\\)'.*/\\1/" | |
| } | |
| rpcGetNumArrayItems() { | |
| rpcExec "$@" 2>/dev/null | grep -E '^Array of' | head -n1 | sed -e "s/^Array of \\([0-9]*\\) items:\$/\\1/" | |
| } | |
| rpcCmdFail() { | |
| local msg="$1" | |
| shift | |
| status $3 | |
| rpcExec "$@" >/dev/null 2>&1 && failed "XMLRPC: $msg" || passed | |
| } | |
| rpcCmdOk() { | |
| local msg="$1" | |
| shift | |
| status $3 | |
| rpcExec "$@" >/dev/null 2>&1 && passed || failed "XMLRPC: $msg" | |
| } | |
| rpcFail() { | |
| status $3 | |
| rpcExec $1 $2 $3 system.methodHelp system.listMethods >/dev/null 2>&1 && failed "XMLRPC: $2" || passed | |
| } | |
| rpcOk() { | |
| status $3 | |
| rpcExec $1 $2 $3 system.methodHelp system.listMethods >/dev/null 2>&1 && passed || failed "XMLRPC: $2" | |
| } | |
| if [ -z "$server" ] || [ -z "$ruTorrentPath" ] || [ -z "$user1" ] || [ -z "$pass1" ] || [ -z "$user1Rpc" ]; then | |
| cat >&2 << EOF | |
| Usage: | |
| $0 server ruTorrentPath user1 pass1 user1Rpc [user2 pass2 user2Rpc] | |
| eg. | |
| $0 192.168.0.123 /rutorrent tom password /RPC2 jerry password /RPC3 | |
| $0 192.168.0.123 /rutorrent tom password /RPC2 | |
| server = The server to test | |
| ruTorrentPath = URL path of ruTorrent, eg. / or /rutorrent | |
| user1 = A valid ruTorrent user | |
| pass1 = The user's ruTorrent password | |
| user1Rpc = The user's RPC mount, eg. /RPC2 | |
| user2 = A valid ruTorrent user | |
| pass2 = The user's ruTorrent password | |
| user2Rpc = The user's RPC mount, eg. /RPC3 | |
| EOF | |
| exit 1 | |
| fi | |
| ruTorrentPath=${ruTorrentPath%*/} | |
| user1Rpc=${user1Rpc#/} | |
| user2Rpc=${user2Rpc#/} | |
| webserver=$(curl -k -D - $protocol://$server:$port/ 2>/dev/null | grep -iE '^Server:' | sed -e 's/^[^:]*:[ ]*\(.*\)$/\1/') | |
| msg "Server: $server" | |
| msg "Web server: $webserver" | |
| if [ -z "$webserver" ]; then | |
| error "Web server seems to be down! Can't continue." | |
| exit 1 | |
| fi | |
| if ! which curl >/dev/null || ! which xmlrpc >/dev/null; then | |
| error "Could not find curl and/or xmlrpc." | |
| exit 1 | |
| fi | |
| rtorrentVer=$(rpcGetString $user1 $pass1 $server:$port/$user1Rpc system.client_version) | |
| libtorrentVer=$(rpcGetString $user1 $pass1 $server:$port/$user1Rpc system.library_version) | |
| if [ -z "$rtorrentVer" ] && [ -z "$libtorrentVer" ]; then | |
| error "Could not detect rtorrent version. Is it running?" | |
| exit 1 | |
| fi | |
| echo "rtorrent: $rtorrentVer/$libtorrentVer" | |
| rpcFail $server:$port/$user1Rpc "Could access user1's RPC mount without a user + password" | |
| [ -n "$user2" ] && rpcFail $server:$port/$user2Rpc "Could access user2's RPC mount without a user + password" | |
| rpcFail $user1 $pass1 $server:$port/$user2Rpc "Could access user2's RPC mount using user1. #1" | |
| rpcFail $user1 $pass1 $server:$port/$user2Rpc/ "Could access user2's RPC mount using user1. #2" | |
| rpcFail $user1 $pass1 $server:$port/$user2Rpc/asdf "Could access user2's RPC mount using user1. #3" | |
| rpcFail $user1 $pass1 $server:$port/${user2Rpc}randomdata "Could access user2's RPC mount using user1. #4" | |
| rpcOk $user1 $pass1 $server:$port/$user1Rpc "user1 could not access his own RPC mount" | |
| [ -n "$user2" ] && rpcOk $user2 $pass2 $server:$port/$user2Rpc "user2 could not access his own RPC mount" | |
| for cmd in execute execute_capture execute_capture_nothrow execute_nothrow execute_raw execute_raw_nothrow; do | |
| rpcCmdFail "Could execute code ($cmd)" $user1 $pass1 $server:$port/$user1Rpc $cmd sh -c whoami | |
| done | |
| status "$user1 $pass1 $server:$port/$user1Rpc" | |
| if rpcExec $user1 $pass1 $server:$port/$user1Rpc execute sh -c echo 'execute=whoami' '>' '~/testfile}' >/dev/null 2>&1 && \ | |
| rpcExec $user1 $pass1 $server:$port/$user1Rpc try_import '~/testfile' >/dev/null 2>&1; then | |
| failed "XMLRPC: Could run commands from file" | |
| else | |
| passed | |
| fi | |
| rpcCmdOk "Could not create a function" $user1 $pass1 $server:$port/$user1Rpc system.method.insert my.func$$ simple 'execute=whoami' | |
| rpcCmdFail "Could execute code using the created func" $user1 $pass1 $server:$port/$user1Rpc my.func$$ "" | |
| for prefix in "" "$user1:$pass1@"; do | |
| dlFail $prefix$server:$port$ruTorrentPath/conf/access.ini "Could access a conf/* file." | |
| dlFail $prefix$server:$port$ruTorrentPath/conf/config.php "Could access a conf/* file." | |
| dlFail $prefix$server:$port$ruTorrentPath/conf/plugins.ini "Could access a conf/* file." | |
| dlFail $prefix$server:$port$ruTorrentPath/conf/users/$user1/config.php "Could access a conf/* file." | |
| dlFail $prefix$server:$port$ruTorrentPath/share/users/$user1/settings/cpu.dat "Could access a conf/* file." | |
| dlFail $prefix$server:$port$ruTorrentPath/conf/.htaccess "Could access conf/.htaccess" | |
| dlFail $prefix$server:$port$ruTorrentPath/share/.htaccess "Could access share/.htaccess" | |
| for u in $user1 $user2; do | |
| dlFail $prefix$server:$port$ruTorrentPath/share/users/$u/settings/cpu.dat "Could access one of $u's share/* files." | |
| dlFail $prefix$server:$port$ruTorrentPath/share/users/$u/settings/extsearch.dat "Could access one of $u's share/* files." | |
| dlFail $prefix$server:$port$ruTorrentPath/share/users/$u/settings/loginmgr.dat "Could access one of $u's share/* files." | |
| dlFail $prefix$server:$port$ruTorrentPath/share/users/$u/settings/rtorrent.dat "Could access one of $u's share/* files." | |
| dlFail $prefix$server:$port$ruTorrentPath/share/users/$u/settings/scheduler.dat "Could access one of $u's share/* files." | |
| dlFail $prefix$server:$port$ruTorrentPath/share/users/$u/settings/uisettings.json "Could access one of $u's share/* files." | |
| dlFail $prefix$server:$port$ruTorrentPath/share/users/$u/settings/rss/cache/info "Could access one of $u's share/* files." | |
| done | |
| dlFail $prefix$server:$port$ruTorrentPath/.svn/entries "Could read .svn subdir" | |
| dlFail $prefix$server:$port$ruTorrentPath/conf/.svn/entries "Could read .svn subdir" | |
| dlFail $prefix$server:$port$ruTorrentPath/css/.svn/entries "Could read .svn subdir" | |
| dlFail $prefix$server:$port$ruTorrentPath/images/.svn/entries "Could read .svn subdir" | |
| dlFail $prefix$server:$port$ruTorrentPath/js/.svn/entries "Could read .svn subdir" | |
| dlFail $prefix$server:$port$ruTorrentPath/lang/.svn/entries "Could read .svn subdir" | |
| dlFail $prefix$server:$port$ruTorrentPath/php/.svn/entries "Could read .svn subdir" | |
| dlFail $prefix$server:$port$ruTorrentPath/plugins/.svn/entries "Could read .svn subdir" | |
| dlFail $prefix$server:$port$ruTorrentPath/share/.svn/entries "Could read .svn subdir" | |
| done | |
| dlFail $server:$port$ruTorrentPath/php/getplugins.php "Could access the site without a password" | |
| dlFail $server:$port$ruTorrentPath/index.html "Could access the site without a password" | |
| dlFail $server:$port$ruTorrentPath/ "Could access the site without a password" | |
| dlFail $server:$port/index.html "Could access the site without a password" | |
| dlFail $server:$port/ "Could access the site without a password" | |
| dlFail baduser:badpassword@$server:$port$ruTorrentPath/index.html "Could access the site with a bad user name + password" | |
| dlOk $user1:$pass1@$server:$port$ruTorrentPath/ "Could not access the ruTorrent site with valid user + password" | |
| dlOk $user1:$pass1@$server:$port$ruTorrentPath/index.html "Could not access the ruTorrent site with valid user + password" | |
| dlOk $user1:$pass1@$server:$port$ruTorrentPath/js/webui.js "Could not access the ruTorrent site with valid user + password" | |
| if [ $numFailures -eq 0 ]; then | |
| msg "All $numTests tests passed!" | |
| msg " Just because all tests passed doesn't mean your server is secure!" | |
| msg " Only a few things were tested." | |
| else | |
| error "$numFailures of $numTests tests failed!" | |
| fi | |
| exit $numFailures |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment