#!/usr/bin/env bash # ══════════════════════════════════════════════════════════════════════════════ # REAPER Learn — Terminal Wrapper Installer # Installs the 'reaper' command on Kali Linux for subscribers. # Run: curl -sSL https://runreaper.com/install | bash # Or: bash install_kali.sh # ══════════════════════════════════════════════════════════════════════════════ set -e REAPER_API="${REAPER_API_URL:-https://runreaper.com}" INSTALL_BIN="/usr/local/bin" KEY_FILE="$HOME/.reaper_learn_key" CONFIG_FILE="$HOME/.reaper_learn.conf" CYAN='\033[0;36m'; BOLD='\033[1m'; DIM='\033[2m' GREEN='\033[0;32m'; ORANGE='\033[0;33m'; RESET='\033[0m' banner() { cat << 'EOF' ██████╗ ███████╗ █████╗ ██████╗ ███████╗██████╗ ██╔══██╗██╔════╝██╔══██╗██╔══██╗██╔════╝██╔══██╗ ██████╔╝█████╗ ███████║██████╔╝█████╗ ██████╔╝ ██╔══██╗██╔══╝ ██╔══██║██╔═══╝ ██╔══╝ ██╔══██╗ ██║ ██║███████╗██║ ██║██║ ███████╗██║ ██║ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═╝ ╚══════╝╚═╝ ╚═╝ Learn Edition — Terminal Installer EOF } echo -e "${CYAN}${BOLD}" banner echo -e "${RESET}" # ── Check dependencies ───────────────────────────────────────────────────── echo -e "${CYAN}[*]${RESET} Checking dependencies..." command -v curl >/dev/null || { echo "Installing curl..."; sudo apt-get install -y curl -qq; } command -v python3 >/dev/null || { echo "python3 required"; exit 1; } command -v bc >/dev/null || sudo apt-get install -y bc -qq 2>/dev/null || true echo -e "${GREEN}[+]${RESET} Dependencies ready" # ── API Key setup ────────────────────────────────────────────────────────── echo "" echo -e "${CYAN}[*]${RESET} Setting up your REAPER Learn API key..." echo -e "${DIM} Get your key at: ${REAPER_API}/dashboard/settings${RESET}" echo "" if [[ -f "$KEY_FILE" ]]; then EXISTING=$(cat "$KEY_FILE" 2>/dev/null) if [[ -n "$EXISTING" && "$EXISTING" == rl_* ]]; then echo -e "${GREEN}[+]${RESET} Existing API key found" read -r -p " Use existing key? [Y/n]: " USE_EXISTING if [[ "$USE_EXISTING" =~ ^[Nn] ]]; then EXISTING="" fi fi fi if [[ -z "$EXISTING" ]]; then while true; do echo -n " Enter your REAPER Learn API key (starts with rl_): " read -r API_KEY < /dev/tty if [[ -n "$API_KEY" && "$API_KEY" == rl_* ]]; then break fi echo -e "${ORANGE}[!]${RESET} Invalid key format. Keys must start with 'rl_'" echo -e " Get your key at: ${REAPER_API}/dashboard/settings" echo "" done echo "$API_KEY" > "$KEY_FILE" chmod 600 "$KEY_FILE" echo -e "${GREEN}[+]${RESET} API key saved (chmod 600)" fi # ── Install main reaper wrapper ──────────────────────────────────────────── echo "" echo -e "${CYAN}[*]${RESET} Installing reaper command..." sudo tee "$INSTALL_BIN/reaper" > /dev/null << 'WRAPPER_EOF' #!/usr/bin/env bash # REAPER Learn — Terminal Wrapper v1.2.0 # Runs any command and sends output to REAPER Learn for guided analysis. REAPER_VERSION="1.2.0" REAPER_API="${REAPER_API_URL:-https://runreaper.com}" REAPER_KEY="$(cat ~/.reaper_learn_key 2>/dev/null)" REAPER_SESSION="${REAPER_SESSION_ID:-}" REAPER_MODE="${REAPER_MODE:-learn}" REAPER_LOG="$HOME/.reaper_learn_history.log" TMP_OUT=$(mktemp /tmp/reaper_XXXXXX) CYAN='\033[0;36m'; BOLD='\033[1m'; DIM='\033[2m'; RESET='\033[0m' GREEN='\033[0;32m'; ORANGE='\033[0;33m' # ── Help ────────────────────────────────────────────────────────────────── if [[ $# -eq 0 ]]; then echo -e "${CYAN}${BOLD}REAPER Learn${RESET} — AI-guided security learning" echo "" echo " Usage: reaper [args...]" echo " Example: reaper nmap -sC -sV 10.10.10.x" echo " Example: reaper gobuster dir -u http://10.10.10.x -w wordlist.txt" echo "" echo " Session: export REAPER_SESSION_ID=" echo " Mode: export REAPER_MODE=learn|pro" echo " Docs: https://runreaper.com/docs" rm -f "$TMP_OUT" exit 0 fi # ── Validate key ────────────────────────────────────────────────────────── if [[ -z "$REAPER_KEY" || "$REAPER_KEY" != rl_* ]]; then echo -e "${ORANGE}[!]${RESET} No valid REAPER Learn API key found." echo -e " Run: curl -sSL https://runreaper.com/install | bash" rm -f "$TMP_OUT" exit 1 fi FULL_CMD="$*" echo -e "\n${CYAN}┌─[ REAPER LEARN ]───────────────────────────────────────${RESET}" echo -e "${CYAN}│${RESET} ${BOLD}$FULL_CMD${RESET}" echo -e "${CYAN}└────────────────────────────────────────────────────────${RESET}\n" # ── Run command ─────────────────────────────────────────────────────────── "$@" 2>&1 | tee "$TMP_OUT" EXIT_CODE=${PIPESTATUS[0]} OUTPUT=$(cat "$TMP_OUT") # Log to history echo "$(date '+%Y-%m-%d %H:%M:%S') CMD: $FULL_CMD" >> "$REAPER_LOG" echo "---" >> "$REAPER_LOG" cat "$TMP_OUT" >> "$REAPER_LOG" echo "" >> "$REAPER_LOG" # Skip analysis for empty output if [[ -z "$OUTPUT" || ${#OUTPUT} -lt 10 ]]; then rm -f "$TMP_OUT" exit $EXIT_CODE fi # Truncate large output if [[ ${#OUTPUT} -gt 80000 ]]; then OUTPUT="${OUTPUT: -80000}" fi # ── Send to REAPER Learn ────────────────────────────────────────────────── echo -e "\n${CYAN}┌─[ REAPER ANALYSIS ]────────────────────────────────────${RESET}" echo -e "${CYAN}│${RESET} ${DIM}Analysing...${RESET}" echo -e "${CYAN}└────────────────────────────────────────────────────────${RESET}" PAYLOAD=$(python3 -c " import json, sys d = { 'output': sys.argv[1], 'command': sys.argv[2], 'mode': sys.argv[3], } if sys.argv[4]: d['session_id'] = sys.argv[4] print(json.dumps(d)) " "$OUTPUT" "$FULL_CMD" "$REAPER_MODE" "$REAPER_SESSION" 2>/dev/null) if [[ -z "$PAYLOAD" ]]; then echo -e "${ORANGE}[!]${RESET} Failed to prepare request" rm -f "$TMP_OUT" exit $EXIT_CODE fi # Stream analysis curl -s -N \ -X POST "${REAPER_API}/api/terminal/analyze" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${REAPER_KEY}" \ -d "$PAYLOAD" | while IFS= read -r line; do if [[ "$line" == data:* ]]; then JSON="${line#data: }" TEXT=$(echo "$JSON" | python3 -c " import json,sys try: d = json.load(sys.stdin) if 'text' in d: print(d['text'], end='') if 'error' in d: print('ERROR: ' + d['error']) except: pass " 2>/dev/null) [[ -n "$TEXT" ]] && printf "%s" "$TEXT" fi done echo -e "\n${CYAN}────────────────────────────────────────────────────────${RESET}" echo -e "${DIM}[ Full analysis at: ${REAPER_API}/dashboard | Exit: ${EXIT_CODE} ]${RESET}\n" rm -f "$TMP_OUT" exit $EXIT_CODE WRAPPER_EOF sudo chmod +x "$INSTALL_BIN/reaper" echo -e "${GREEN}[+]${RESET} Installed: /usr/local/bin/reaper" # ── Shell config ─────────────────────────────────────────────────────────── SHELL_RC="" [[ -f "$HOME/.zshrc" ]] && SHELL_RC="$HOME/.zshrc" [[ -f "$HOME/.zshrc" ]] && SHELL_RC="$HOME/.zshrc" BLOCK=" # ── REAPER Learn ────────────────────────────────────── export REAPER_API_URL=\"${REAPER_API}\" export REAPER_MODE=\"learn\" # Set session: export REAPER_SESSION_ID= # ──────────────────────────────────────────────────────" if [[ -n "$SHELL_RC" ]] && ! grep -q "REAPER Learn" "$SHELL_RC" 2>/dev/null; then echo "$BLOCK" >> "$SHELL_RC" echo -e "${GREEN}[+]${RESET} Added REAPER config to $SHELL_RC" fi # ── Verify API key with server ───────────────────────────────────────────── echo "" echo -e "${CYAN}[*]${RESET} Verifying API key with REAPER Learn..." KEY=$(cat "$KEY_FILE") HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ -H "Authorization: Bearer $KEY" \ "${REAPER_API}/api/users/usage" 2>/dev/null || echo "000") if [[ "$HTTP_CODE" == "200" ]]; then echo -e "${GREEN}[+]${RESET} API key verified successfully" elif [[ "$HTTP_CODE" == "401" ]]; then echo -e "${ORANGE}[!]${RESET} Invalid API key — please check your key at ${REAPER_API}/dashboard" elif [[ "$HTTP_CODE" == "000" ]]; then echo -e "${DIM}[~]${RESET} Could not reach server — key saved, will verify on first use" else echo -e "${DIM}[~]${RESET} HTTP $HTTP_CODE — key saved" fi # ── Done ────────────────────────────────────────────────────────────────── echo "" echo -e "${CYAN}┌─[ INSTALLATION COMPLETE ]──────────────────────────────${RESET}" echo -e "${CYAN}│${RESET}" echo -e "${CYAN}│${RESET} Run any command with ${BOLD}reaper${RESET} prefix:" echo -e "${CYAN}│${RESET} ${GREEN}reaper nmap -sC -sV 10.10.10.x${RESET}" echo -e "${CYAN}│${RESET} ${GREEN}reaper gobuster dir -u http://10.10.10.x -w list.txt${RESET}" echo -e "${CYAN}│${RESET} ${GREEN}reaper hydra -L users.txt -P rockyou.txt ssh://10.10.10.x${RESET}" echo -e "${CYAN}│${RESET}" echo -e "${CYAN}│${RESET} Link a session (from dashboard):" echo -e "${CYAN}│${RESET} ${GREEN}export REAPER_SESSION_ID=${RESET}" echo -e "${CYAN}│${RESET}" echo -e "${CYAN}│${RESET} Dashboard: ${BOLD}${REAPER_API}/dashboard${RESET}" echo -e "${CYAN}│${RESET}" echo -e "${CYAN}│${RESET} Reload shell: ${DIM}source $SHELL_RC${RESET}" echo -e "${CYAN}└────────────────────────────────────────────────────────${RESET}" echo ""