FREE THOUGHT · FREE SOFTWARE · FREE WORLD

Home  »  Hosting  »  Enhanced printenv Script for Server Debugging

by 1 comment

Every Apache server comes pre-shipped with an old cgi script named printenv. It's useful and used for printing out the environment variables from your servers point of view. Basically you save this file where you can then call it from your browser, like site.com/printenv.cgi -- then it will be executing as the user running the web server, nobody, apache, etc.. So this tells you all sorts of interesting things about your server, especially if you want/need to know about the users, groups, and file permissions.


Enabling CGI

You need to do 1 of 2 things to use this:

  1. Make it executable and in your server directory
  2. Use a trick to cause your server to execute it regardless

Htaccess CGI

If you have htaccess then you most likely can get this to work by giving it an execute bit with chmod or from your ftp client, and then use htaccess like this:

Options +ExecCGI Indexes +FollowSymLinks
AddHandler cgi-script .cgi .pl .sh
 
Order Deny,Allow
Deny from All
Allow from 127.0.0.1 ADDYOURIPHERE env=REDIRECT_STATUS
Satisfy All

Search around on this site for php.cgi tricks if you can't seem to get it. Basically you can try stuff like making it an errordocument, using other directives like forcetype, AddType, and even try stuff like mod_security's upload binary setting.

You do not want anyone other than you ever looking at the output of this. It's so full of details about your machine that it would be a huge security problem.

The AskApache Printenv

#!/bin/sh
echo -e "Content-type: text/plainnn"
 
# FUNCTIONS
################################################################################################################
function __A ()
{ local __a __i __z;for __a;do __z=${!${__a}*};for __i in `eval echo "${__z}"`;do echo -e "$__i: ${!__i}";done;done; }
 
function __S ()
{ local L IFS=';';while read -r L;do builtin printf "${#L}@%sn" "$L";done|sort -n|sed -u 's/^[^@]*//'; }
 
function __P ()
{ local l=`builtin printf %${2:-$__WIDTH}s` && echo -e "${l// /${1:-=}}"; }
 
function __T ()
{ echo -e "nn+`__P -`+n| $*n+`__P '='`+"; }
 
function __M ()
{ echo -e " >>> $M" $*; }
 
function __H ()
{ command builtin type $1 &>/dev/null && local a="yes" || return 1; }
 
function LE ()
{
 [[ ! -r /proc/${1:-$$}/limits ]] && return;
 sed -e '1z;s/ *$//;:a;$!N;s/nM.. [a-z]* [a-z]* [a-z]* {1,}([^ ]*) *([^ ]*) *[a-z]* */1:2 /;ta;s/uw+d/u/g;s/ *$//;s/ / | /g;s/([^:]+):1/1:=/g' /proc/${1:-$$}/limits;
}
function LH ()
{
 [[ ! -r /proc/${1:-$$}/limits ]] && return;
 sed -e '1z;s/ *$//;:a;$!N;s/nM.. ([a-z]+ [a-z]* [a-z]*) {1,}([^ ]*) *([^ ]*) *([a-z]*) */:1/;ta;s/ *:/:/g;s/size/sz/g;s/file/f/g;s/ pw+y/ pri/g;s/memory/mem/g;s/pw+s/procs/g;s/^://;s/:/ | /g' /proc/${1:-$$}/limits
}
 
# CUSTOM SETTINGS
################################################################################################################
__WIDTH=170
LC_COLLATE=C LC_CTYPE=C LC_ALL=C
 
# RUNTIME SETUP
#################################################################################################################
shopt -s dotglob nocaseglob extglob
 
# -C If set, disallow existing regular files to be overwritte
# -f Disable file name generation (globbing
# -e Exit immediately if a command exits with a non-zero status
# -B enable brace expansion
# +H disable History
set -C +f +H -B
 
# make sure we dont create any files
umask 0177
 
# redirect everything to output (no logs or stderr is used)
exec 2>/dev/null
 
# MAIN EXECUTION
#################################################################################################################
{
 __T "EXPANDING PATH"
 {
  __M "ORIG PATH:$PATH"
  PATH=$PATH:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/libexec:/usr/local/apache/bin
  for t in ${PATH//:/ };
  do
   [[ -d "$t" ]] && sed -n -e "/:${t////\/}:/Q1" <<< ":${p:=}:" && p=$p:$t || continue;
  done
  PATH=${p/:/}:.
  __M "NEW PATH:$PATH"
 }
 
 __T "USER INFO"
 {
  __M "UMASK: `(umask 2>/dev/null)` ( `(umask -S 2>/dev/null)` )"
  __H uname && __M "UNAME: `eval echo $(uname -a 2>/dev/null)`"
  __H whoami && __M "WHOAMI: `(whoami 2>/dev/null)`"
  __H id && __M "ID: `(id 2>/dev/null)`"
  __H logname && __M "LOGNAME: `(logname 2>/dev/null)`"
  __H groups && __M "GROUPS: `(groups 2>/dev/null)`"
  echo -e "nn"
 }
 
 if __H who;
 then
  __T "LOGGED ON USERS"
  {
   (who -a 2>/dev/null)
  }
 fi;
 
 if [[ -r /etc/passwd ]];
 then
  __T "/etc/passwd"
  {
   (cat /etc/passwd)
  }
 fi;
 
 if __H ulimit;
 then
  __T "USER LIMITS"
  {
   ulimit -a
  }
 fi
 
 if [[ -d /dev ]] && __H ls;
 then
  __T "/dev Directory"
  {
   ( ls -vlaph /dev 2>/dev/null )
  }
 fi;
 
 if [[ -d /proc ]];
 then
  __T "CURRENT PROCESS LIMITS"
  {
   for p in `echo /proc/[0-9]*/limits`
   do
    pid=${p:6:$((${#p}-13))}
    [[ $pid == $PPID || $pid == $$ ]] && continue;
    echo -e "n/proc/$pid:"
    sed '1s/x00/ /g;n;s/x00/n/g;/.{2,}/!d' /proc/$pid/cmdline $p 2>/dev/null
   done
  }
 
  __T "CURRENT PROCESS CMDLINE"
  {
   for p in `echo /proc/[0-9]*/cmdline`;
   do
    pid=${p:6:$((${#p}-13))}
    [[ $pid == $PPID || $pid == $$ ]] && continue;
    __M "[ /proc/$pid ]";
    sed 's/x00/ /g;G' $p 2>/dev/null
   done
  }
 fi
 
 __T "IP INFORMATION"
 {
  __H ip && __M "IP:" && (ip -o -f inet addr 2>/dev/null) | sed 's/^.*inet ([0-9.]*).*$/1/g';
  __H nmap && __M "NMAP:" && (nmap --iflist 2>/dev/null) | sed 1,4d | sed -n '/ethernet/s/^.*) ([0-9.]*).*$/1/gp';
  __H ifconfig && __M "IFCONFIG:" && (ifconfig -a 2>/dev/null) | sed -n '/inet a/s/^.*addr:([0-9.]*).*$/1/gp';
  [[ -f "$HOME/.cpanel/datastore/_sbin_ifconfig_-a" ]] && __M "CPANEL CACHE:" && sed -e '/inet/!d; s/.*addr:([0-9.]*).*/1/g' "$HOME/.cpanel/datastore/_sbin_ifconfig_-a" | sort -u
 }
 
 __T "ROUTE / INTERFACE INFO"
 {
  __H route && __M "ROUTE" && (route -nv 2>/dev/null)
  __H ip && ( ip rule && ip route && ip address ) 2>/dev/null
  __H ifconfig && (ifconfig -a 2>/dev/null)
 }
 
 __T "CGI/1.0 test script report:"
 {
  __A SERVER REQUEST GET SERVER PATH REMOTE AUTH CONTENT HTTP TZ GATEWAY QUERY MO
  echo -e "nn"
 }
 
 __T "HIDDEN VARIABLES"
 {
  __A {a..z} {A..Z} _{0..9} _{A..Z} _{a..z} | cat -Tsv 2>/dev/null
  echo -e "nn"
 }
 
 __T "DECLARE INFO"
 {
  for i in "r" "i" "a" "x" "t" "-";
  do
   builtin eval declare -$i && echo;
  done | sed 's/^declare //' | cat -Tsv 2>/dev/null
  echo -e "nn"
 }
 
 __T "SHELL OPTIONS"
 {
  __A SHELLOPTS BASHOPTS
  echo -e "$-: $-"
  __P '-' && builtin shopt -s -p
  __P '-' && builtin shopt -u -p
  echo -e "nn"
 }
 
 __T "ENV AND EXPORT"
 {
  __H env && command env | cat -Tsv 2>/dev/null && __P '-'
  builtin export | cat -Tsv 2>/dev/null
  echo -e "nn"
 }
 
 if __H perl;
 then
  __T "PERL VARIABLES"
  {
   perl -e'foreach $v (sort(keys(%ENV))) {$vv = $ENV{$v};$vv =~ s|n|\n|g;$vv =~ s|"|\"|g;print "${v}="${vv}"n"}' | cat -Tsv 2>/dev/null
   echo -e "nn"
  }
 fi
 
} | fold - -w$(($__WIDTH+3))
exit $?

Tags

April 14th, 2011

Comments Welcome

  • mutant

    This is pretty fantastic. THank you!

Popular Articles
My Online Tools

Related Articles
Newest Posts
Twitter



Hacking and Hackers

The use of "hacker" to mean "security breaker" is a confusion on the part of the mass media. We hackers refuse to recognize that meaning, and continue using the word to mean someone who loves to program, someone who enjoys playful cleverness, or the combination of the two. See my article, On Hacking.
-- Richard M. Stallman






[hide]

It's very simple - you read the protocol and write the code. -Bill Joy

Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution 3.0 License, just credit with a link.
This site is not supported or endorsed by The Apache Software Foundation (ASF). All software and documentation produced by The ASF is licensed. "Apache" is a trademark of The ASF. NCSA HTTPd.
UNIX ® is a registered Trademark of The Open Group. POSIX ® is a registered Trademark of The IEEE.

| Google+ | askapache

Site Map | Contact Webmaster | License and Disclaimer | Terms of Service

↑ TOPMain