第一次和同学以战队MiRag3参加XCTF联赛,经验不足,技术较弱,以后会加倍努力~!留个爪纪念一下~~
WEB
2099年的flag
直接burpsuit截断,修改消息请求头如下:
直接得到flag
RESTFUL
这里主要考察的是RESTFUL格式
index.php/参数/值
然后根据提示只要put money 大于 12450
即可
兵者多诡
题目说明为上传图片,首先上传一个图片试试。点击上传图片,发现url
http://pics.hctf.io/home.php?fp=upload
在这里猜想为 include($fp+'.php') 典型的文件包含漏洞
现在可以利用 php:filter//当下源码了
源码:
//home.php
<?php
error_reporting(0);
@session_start();
posix_setuid(1000);
$fp = empty($_GET['fp']) ? 'fail' : $_GET['fp'];
if(preg_match('/\.\./',$fp))
{
die('No No No!');
}
if(preg_match('/rm/i',$_SERVER["QUERY_STRING"]))
{
die();
}
?>
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/jumbotron-narrow.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="header clearfix">
<nav>
<ul class="nav nav-pills pull-right">
<li role="presentation" class="active"><a href="home.php?key=hduisa123">Home</a></li>
</ul>
</nav>
<h3 class="text-muted">pictures</h3>
</div>
<div class="jumbotron">
<h1>Pictures Storage</h1>
<p class="lead">在这里上传您的图片,我们将为您保存</p>
<form action="?fp=upload" method="POST" id="form" enctype="multipart/form-data">
<input type="file" id="image" name="image" class="btn btn-lg btn-success" style="margin-left: auto; margin-right: auto;">
<br>
<input type="submit" id="submit" name="submit" class="btn btn-lg btn-success" role="button" value="上传图片">
</form>
</div>
</div>
</body>
</html>
<?php
if($fp !== 'fail')
{
if(!(include($fp.'.php')))
{
?>
<div class="alert alert-danger" role="alert">没有此页面</div>
<?php
exit;
}
}
?>
在home.php
中找到了文件包含源码现在利用它来,上传恶意文件
- 首先想到的是挂图片马:发现菜刀连接不行
- 利用zip上传解压
这里其实考察的还是phar协议,可参考(http://www.hackdig.com/09/hack-26779.htm)
具体可参考此writeup
方法
(1)制作1.php
http://pics.hctf.io/home.php?fp=phar://uploads/4213d630a939bd4fbc7dff432fc0ed4b76c01d1c.png/1
(3)应用菜刀直接连
得到flag
giligili
这道题是通过这道题改的,(https://github.com/sternze/CTF_writeups/blob/master/sCTF/2016_Q1/obfuscat/readme.md#here-we-go-the-second-word-inside-our-flag-is-iz)
深刻理解这个这个大神的题解是解决这道题的先决条件。
这道题就改了几个参数,其他几乎没有变。
这是一道JavaScript代码混淆,打开之后这样的
通过在中间那个框中输入flag,失败就会弹框报错,查看源码,其中有一段JS代码
<script type="text/javascript">
// Come on and get flag:>
var _ = { 0x4c19cff: "random", 0x4728122: "charCodeAt", 0x2138878: "substring", 0x3ca9c7b: "toString", 0x574030a: "eval", 0x270aba9: "indexOf", 0x221201f: function(_9) {
var _8 = []; for (var _a = 0, _b = _9.length; _a < _b; _a++) { _8.push(Number(_9.charCodeAt(_a)).toString(16)); } return "0x" + _8.join(""); }, 0x240cb06: function(_2, _3) {
var _4 = Math.max(_2.length, _3.length); var _7 = _2 + _3; var _6 = ""; for(var _5=0; _5<_4; _5++) { _6 += _7.charAt((_2.charCodeAt(_5%_2.length) ^ _3.charCodeAt(_5%_3.length)) % _4); } return _6; }, 0x5c623d0: function(_c, _d) {
var _e = ""; for(var _f=0; _f<_d; _f++) { _e += _c; } return _e; } };
var $ = [ 0x4c19cff, 0x3cfbd6c, 0xb3f970, 0x4b9257a, 0x1409cc7, 0x46e990e, 0x2138878, 0x1e1049, 0x164a1f9, 0x494c61f, 0x490f545, 0x51ecfcb, 0x4c7911a, 0x29f7b65, 0x4dde0e4, 0x49f889f, 0x5ebd02c, 0x556f342, 0x3f7f3f6, 0x11544aa, 0x53ed47d, 0x697a, 0x623f21c1, 0x5c623d0, 0x32e8f8b, 0x3ca9c7b, 0x367a49b, 0x360179b, 0x5c862d6, 0x30dc1af, 0x7797d1, 0x221201f, 0x5eb4345, 0x5e9baad, 0x39b3b47, 0x32f0b8f, 0x48554de, 0x3e8b5e8, 0x5e4f31f, 0x48a53a6, 0x270aba9, 0x240cb06, 0x574030a, 0x1618f3a, 0x271259f, 0x3a306e5, 0x1d33b46, 0x17c29b5, 0x1cf02f4, 0xeb896b ];
var a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
function check() {
var answer = document.getElementById("message").value;
var correct = (function() {
try {
h = new MersenneTwister(parseInt(btoa(answer[_[$[6]]](0, 4)), 32));
e = h[_[$[""+ +[]]]]()*(""+{})[_[0x4728122]](0xc); for(var _1=0; _1<h.mti; _1++) { e ^= h.mt[_1]; }
l = new MersenneTwister(e), v = true;
l.random(); l.random(); l.random();
o = answer.split("_");
i = l.mt[~~(h.random()*$[0x1f])%0xff];
s = ["0x" + i[_[$[$.length/2]]](0x10), "0x" + e[_[$[$.length/2]]](0o20).split("-")[1]];
e =- (this[_[$[42]]](_[$[31]](o[1])) ^ s[0]); if (-e != $[21]) return false;
e ^= (this[_[$[42]]](_[$[31]](o[2])) ^ s[1]); if (-e != $[22]) return false; e -= 0x352c4a9b;
t = new MersenneTwister(Math.sqrt(-e));
h.random();
a = l.random();
t.random();
y = [ 0xb3f970, 0x4b9257a, 0x46e990e ].map(function(i) {
return $[_[$[40]]](i)+ +1+ -1- +1; });
o[0] = o[0].substring(5); o[3] = o[3].substring(0, o[3].length - 1);
u = ~~~~~~~~~~~~~~~~(a * i); if (o[0].length > 5) return false;
a = parseInt(_[$[23]]("1", Math.max(o[0].length, o[3].length)), 3) ^ eval(_[$[31]](o[0]));
r = (h.random() * l.random() * t.random()) / (h.random() * l.random() * t.random());
e ^= ~r;
r = (h.random() / l.random() / t.random()) / (h.random() * l.random() * t.random());
e ^= ~~r;
a += _[$[31]](o[3].substring(o[3].length - 2)).split("x")[1]; if (parseInt(a.split("84")[1], $.length/2) != 0x4439feb) return false;
d = parseInt(a, 16) == (Math.pow(2, 16)+ -5+ "") + o[3].charCodeAt(o[3].length - 3).toString(16) + "53846" + (new Date().getFullYear() - 1 + "");
i = 0xffff;
n = (p = (f = _[$[23]](o[3].charAt(o[3].length - 4), 3)) == o[3].substring(1, 4));
g = 3;
t = _[$[23]](o[3].charAt(3), 3) == o[3].substring(5, 8) && o[3].charCodeAt(1) * o[0].charCodeAt(0) == 0x2ef3;
h = ((31249*g) & i).toString(16);
i = _[$[31]](o[3].split(f).join("").substring(0, 2)).split("x")[1];
s = i == h;
return (p & t & s & d) === 1 || (p & t & s & d) === true;
} catch (e) {
console.log("gg");
return false;
}
})();
document.getElementById("message").placeholder = correct ? "correct" : "wrong";
if (correct) {
alert("Congratulations! you got it!");
} else {
alert("Sorry, you are wrong...");
}
};
</script>
这个题目的意思就是在主站输入你构造的flag,反馈你的构造的flag是否正确,首先尝试随意提交一个flag,显然报错
这就需要回到那段JavaScript代码了,通过这段代码就可以推测出flag,现在依次分析这段代码
首先从整体分析这个check()
函数,可以看到有四处return false
。这个函数通过分析输入的flag来判断flag对错,这四个return false
就是分别用来判断flag中四个单词对错
所以首先构造hctf{xxxx_xx_xxxx_xxxxx}
,其中x
代表位未知字母,每个单词字母长度时未知的,之所以中间用_
符号连接,是应为有这句代码o = answer.split("_")(在64行)
先看这段代码
l.random(); l.random(); l.random();
o = answer.split("_");
i = l.mt[~~(h.random()*$[0x1f])%0xff];
s = ["0x" + i[_[$[$.length/2]]](0x10), "0x" + e[_[$[$.length/2]]](0o20).split("-")[1]];
e =- (this[_[$[42]]](_[$[31]](o[1])) ^ s[0]); if (-e != $[21]) return false;
把以上代码换成正常代码大概是这样的
e =- (this.eval(_[35725343](o[1])) ^ s[0]);
if (-e != $[21])
return false;
仔细看看这个_[35725343]
,将35725343转为16进制,就是221201f,在代码中找一找
这是个函数,直接看writeup,这个函数可以写成
function toHexString(s) {
var charArray = s.sp lit('');
var result = "0x";
for(i = 0; i < charArray.length; i++) {
result += s.charCodeAt(i).toString(16)
}
return result;
}
这个函数就是将输入的16进制参数转化为ASCLL字符,我们将在后面多次用到这个函数,利用这个函数在此改写刚才那个代码
e = - (this.eval(toHexString(o[1])) ^ 0x381f4862);
if(-e != 941564184)
return false;
所以this.eval(toHexString(o[1])) ^ 0x381f4862==941564184
计算得到
this.eval(toHexString(o[1]))=941564184^0x381f4862=27002
将这个数转为16进制再转为字符串,得flag第二个单词为iz,这里给出从10进制转为16进制再转为ascii字符的python代码
s=raw_input("input:")
s=hex(int(s))[2:]
ch=''
string=''
for i in range(0,len(s),2):
ch=s[i]+s[i+1]
string+=chr(int(ch,16))
print string
接下来接着看这段代码
e ^= (this[_[$[42]]](_[$[31]](o[2])) ^ s[1]); if (-e != $[22]) return false; e -= 0x352c4a9b;
根据writeup换成正常人可以看懂的代码
e