首页
社区
课程
招聘
[原创] KCTF2021 偶遇棋痴出题思路(Android)
发表于: 2021-11-13 22:50 13204

[原创] KCTF2021 偶遇棋痴出题思路(Android)

2021-11-13 22:50
13204

战队名称: Syclover
参赛题目: KCTF2021 神秘的数学(Android)

计算机科学领域,尤其是编程语言,经常倾向于使用一种特定的演算:Lambda演算(Lambda Calculus)。这种演算也广泛地被逻辑学家用于学习计算和离散数学的结构的本质。现在流行的大部分编程语言中都可以找到 Lambda 的影子,例如 Python、Java,它还是函数式编程的理论基础。Lambda 演算具有图灵完备的性质,因此可以用 Lambda 演算实现任何程序。

本题设计思路是将验证逻辑使用 Lambda 演算实现,选手需要学习 Lambda 演算基础知识,例如 Lambda 演算如何实现数值计算、逻辑计算、currying、α-conversion、Beta Reduction、Church Boolean、Church Numberals等知识才能得心应手的解出本题。

在题目设计过程中,提前对 Lambda 表达式进行预编译,并通过 Boost 的序列化组件对预编译表达式序列化,正式题目对表达式反序列化后得到 Lambda 语法树,选手需要通过各种调试技巧从内存中分离 Lambda 语法树。

选手输入验证码后,程序对选手输入的数据进行编译得到对应的 Lambda 表达式,并插入到预编译的语法树上,以便进行数据演算。

最后,根据 Lambda 演算结果,判断选手输入是否正确。

题目 lambda 编译脚本

题目答案(解题脚本):

编译版本flag: pediy{Lambda6}

 
 
 
 
 
import string
from pwn import *
def L_TRUE():
    return "(\\x \\y x)"
 
def L_FALSE():
    return "(\\x \\y y)"
 
def L_ZERO():
    return "(\\f \\x x)"
 
def L_SUCC():
    return "(\\n \\f \\x n f (f x))"
 
def L_NUM(n):
    s = L_ZERO()
    for _ in range(n):
        s = "("+ L_SUCC() + " " + s + ")"
    return s
 
def L_FLAG_NODE(i):
    return ("(\z %d )" % i)
 
def L_SUB():
    return "(\\m\\n n " + L_PRE() + " m)"
 
def L_PRE():
    return "(\\n\\f\\x " + L_CDR() + " (n (" + L_PREFN() + " f) (" + L_CONS() + " x x)))"
 
def L_CDR():
    return "(\\p p " + L_FALSE() + ")"
 
def L_CONS():
    return "(\\x \\y \\f f x y)"
 
def L_PREFN():
    return "(\\f \\p " + L_CONS() +" (f (" + L_CAR() + " p)) (" +  L_CAR() + " p))"
 
def  L_CAR():
    return "(\\p p " + L_TRUE() + ")"
 
def L_ADD():
    return "(\\m \\n \\f \\x m f (n f x))"
 
def L_IF():
    return "(\\p \\x \\y p x y)"
 
def L_NOT():
    return "(\\p \\a \\b p b a)"
 
def L_XOR(): # only works for boolean value
    return "(\\a \\b a (" + L_NOT() + " " + "b" + ") b)"
 
def L_MULT():
    return "(\\m \\n \\f m (n f))"
 
def H_ADD(l, r):
    return "(" + L_ADD() + " " + l + " " + r + ")"
 
def H_MULT(l, r):
    return "(" + " ".join([L_MULT(), l , r]) + ")"
 
def H_SUB(l, r):
    return "(" + " ".join([L_SUB(), l , r]) + ")"
 
def H_XOR(l, r):
    return "(" + " ".join([L_XOR(), l , r]) + ")"
 
def H_ABSDIFF(l, r):
    return H_ADD(H_SUB(l, r), H_SUB(r, l))
 
 
import random
def challenge(flag, seed):
    random.seed(seed)
    sub_eq = []
    flag_seq = []
    for c in bytes(flag):
        flag_seq.append(c & 0xf)
        flag_seq.append(c >> 0x4)
 
    s = L_NUM(0)
    for i in range(len(flag_seq)):
        l1 = random.randint(1, 10)
        d2 = random.randint(1, 10)
        target = flag_seq[i] * l1 + d2
        print((l1, d2, target), ",")
        sub_eq.append(H_ABSDIFF(H_ADD(H_MULT(L_FLAG_NODE(i), L_NUM(l1)), L_NUM(d2)), L_NUM(target)))
    for exp_i in range(len(sub_eq)):
        s = H_ADD(s, sub_eq[exp_i])
    return s
 
#print()
def compile_data(text):
    p = process(["lambda/lambda", 'xxxx'])
    p.sendline(text)
    return p.recvall().decode('utf-8')
 
def data2array(name, data):
    return "char " + name +"[] = {" + ",".join([hex(c) for c in data.encode("ASCII")]) + ", 0x0};"
 
 
 
def gen_text_arr(t):
    return ("char * arr[] = {" + ",".join(['"%s"' % x for x in t]) + "};").replace("\\","\\\\")
 
ts = [L_NUM(i) for i in range(16)]
ts.append(challenge(b"pediy{Lambda6}", 2))
rr = gen_text_arr(ts)
open("lambda/text_chall.h", "w").write(rr)
input("step2")
l = []
for i in range(16):
    r = open("tests/enc/data_" + str(i) + ".txt", "r").read()
    l.append(data2array("num_%d" % i, r))
open("lambda/nums.h", "w").write("\n".join(l))
open("lambda/chall.h", "w").write(data2array("chall", open("tests/enc/data_16.txt", "r").read()))
import string
from pwn import *
def L_TRUE():
    return "(\\x \\y x)"
 
def L_FALSE():
    return "(\\x \\y y)"
 
def L_ZERO():
    return "(\\f \\x x)"
 
def L_SUCC():
    return "(\\n \\f \\x n f (f x))"
 
def L_NUM(n):
    s = L_ZERO()
    for _ in range(n):
        s = "("+ L_SUCC() + " " + s + ")"
    return s
 
def L_FLAG_NODE(i):
    return ("(\z %d )" % i)
 
def L_SUB():
    return "(\\m\\n n " + L_PRE() + " m)"
 
def L_PRE():
    return "(\\n\\f\\x " + L_CDR() + " (n (" + L_PREFN() + " f) (" + L_CONS() + " x x)))"
 
def L_CDR():
    return "(\\p p " + L_FALSE() + ")"
 
def L_CONS():
    return "(\\x \\y \\f f x y)"
 
def L_PREFN():
    return "(\\f \\p " + L_CONS() +" (f (" + L_CAR() + " p)) (" +  L_CAR() + " p))"
 
def  L_CAR():
    return "(\\p p " + L_TRUE() + ")"
 
def L_ADD():
    return "(\\m \\n \\f \\x m f (n f x))"
 
def L_IF():
    return "(\\p \\x \\y p x y)"
 
def L_NOT():
    return "(\\p \\a \\b p b a)"
 
def L_XOR(): # only works for boolean value
    return "(\\a \\b a (" + L_NOT() + " " + "b" + ") b)"
 
def L_MULT():
    return "(\\m \\n \\f m (n f))"
 
def H_ADD(l, r):
    return "(" + L_ADD() + " " + l + " " + r + ")"
 
def H_MULT(l, r):
    return "(" + " ".join([L_MULT(), l , r]) + ")"
 
def H_SUB(l, r):
    return "(" + " ".join([L_SUB(), l , r]) + ")"
 
def H_XOR(l, r):
    return "(" + " ".join([L_XOR(), l , r]) + ")"
 
def H_ABSDIFF(l, r):
    return H_ADD(H_SUB(l, r), H_SUB(r, l))
 
 
import random

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2021-11-25 16:09 被无名侠编辑 ,原因:
上传的附件:
收藏
免费 10
支持
分享
最新回复 (2)
雪    币: 47147
活跃值: (20445)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
第四题 偶遇棋痴
2021-11-14 19:48
0
游客
登录 | 注册 方可回帖
返回
//