首页
社区
课程
招聘
[原创]第七题 圆圈舞DancingCircle
2019-3-20 22:34 4023

[原创]第七题 圆圈舞DancingCircle

2019-3-20 22:34
4023

(作者:pizZa)
清理花指令

from ida_bytes import get_bytes, patch_bytes

addr = 0x401000
buf = get_bytes(addr, 0x4B9CD0-addr)
def patch_at(p, ln):
    global buf
    buf = buf[:p] + "\x90" * ln + buf[p+ln:]

# jx / jnx
fake_jcc = []
for opcode in xrange(0x70, 0x7F, 2):
    pattern = chr(opcode) + "\x03" + chr(opcode | 1) + "\x01"
    fake_jcc.append(pattern)
    pattern = chr(opcode | 1) + "\x03" + chr(opcode) + "\x01"
    fake_jcc.append(pattern)

for pattern in fake_jcc:
    p = buf.find(pattern)
    while p != -1:
        patch_at(p, 5)
        p = buf.find(pattern, p+1)

# call / pop
pattern = '\xE8'
p = buf.find(pattern)
while p != -1:
    if buf[p + 2:p + 5] == '\x00\x00\x00':
        dst = p + 5 + ord(buf[p + 1])
        if buf[dst:dst + 3] == '\x83\xC4\x04':
            ln = dst - p + 3
            patch_at(p, ln)
        elif buf[dst] == '\x58':
            ln = dst - p + 1
            if buf[p - 1] == '\x50' and buf[dst + 1] == '\x58':
                patch_at(p - 1, ln + 2)
            else:
                patch_at(p, ln)
        elif buf[dst:dst + 5] == '\x83\x04\x24\x06\xc3':
            ln = dst - p + 5
            patch_at(p, ln)
        else:
            print("E80n", hex(p + addr), hex(dst + addr), buf[dst:dst + 3].encode('hex'))
    else:
        pass
    p = buf.find(pattern, p+1)

# stx / jx
fake_jcc = ['\xF8\x73', '\xF9\x72']
for pattern in fake_jcc:
    p = buf.find(pattern)
    while p != -1:
        if ord(buf[p + 2]) < 0x80:
            dst = p + 3 + ord(buf[p + 2])
            ln = dst - p
            patch_at(p, ln)
        else:
            print("CLC", hex(p + addr))
        p = buf.find(pattern, p+1)

fake_jcc = ['\x7C\x03\xEB\x03']
for pattern in fake_jcc:
    p = buf.find(pattern)
    while p != -1:
        if buf[p + 5:p + 5 + 2] == '\x74\xFB':
            ln = 7
            patch_at(p, ln)
        else:
            print("CLC", hex(p + addr))
        p = buf.find(pattern, p+1)

patch_bytes(addr, buf)
print('done')

Dancing Link算法校验数独, 初始数独由两个常量相乘得到, 其中一个与自校验有关. 用输入填写数独, 用反调试填写了其中一个数字.

x = int('BDA39C1046F32C'[::-1], 16) # 0x4BC080
y = int('1ED683F49FA362A30D3473AECDEE'[::-1], 16) # 0x4BC088
z = hex(x*y)[2:].rstrip('L')[::-1] # b79f3d4b9d5a6b8c23b6cb1c35d4b5a1b7b2f8e35b

n = 0
s = ''
for i in xrange(len(z)):
    c = int(z[i], 16)
    if c >= 1 and c <= 9:
        n += 1
        s += str(c)
    else:
        t = c - 9
        n += t
        s += '_' * t
        if i + 1 < len(z) and int(z[i + 1], 16) > 9:
            s += '9'
            n += 1

assert n == 81
for i in xrange(0, 81, 9):
    print(s[i:i+9])

# __79_____
# _3____4__
# 9____5_6_
# _8___23__
# 6___9__1_
# __35____4
# __5_1__7_
# _2______8
# _____35__

由于初始数独存在多解, 之后又直接比较固定答案, 可以在004B9744设置记录断点{dword(ebp-0x2BB4) / 9} | {dword(ebp-0x2BB4) % 9} | {dword(ebp-0x2BC0)}得到标准答案.

s = [
# ((0, 2), 7),
# ((0, 3), 9),
# ((1, 1), 3),
# ((1, 6), 4),
# ((2, 0), 9),
# ((2, 5), 5),
# ((2, 7), 6),
# ((3, 1), 8),
# ((3, 5), 2),
# ((3, 6), 3),
# ((4, 0), 6),
# ((4, 6), 1),
# ((5, 1), 3),
# ((5, 2), 5),
# ((5, 7), 4),
# ((6, 1), 5),
# ((6, 3), 1),
# ((6, 6), 7),
# ((7, 0), 2),
# ((7, 7), 8),
# ((8, 4), 3),
# ((8, 5), 5),
((4, 3), 3),
((7, 3), 5),
((2, 1), 1),
((3, 7), 5),
((4, 1), 5),
((0, 1), 6),
((1, 2), 2),
((4, 8), 2),
((5, 4), 1),
((1, 3), 1),
((0, 5), 8),
((1, 4), 6),
((1, 5), 7),
((4, 5), 8),
((5, 6), 9),
((1, 7), 8),
((1, 0), 5),
((0, 0), 4),
((1, 8), 9),
((2, 2), 8),
((4, 7), 2),
((5, 0), 7),
((3, 0), 1),
((5, 3), 8),
((5, 5), 6),
((3, 8), 7),
((2, 8), 3),
((0, 7), 2),
((0, 4), 3),
((0, 6), 1),
((0, 8), 5),
((2, 6), 7),
((6, 7), 6),
((7, 5), 9),
((6, 5), 2),
((8, 6), 4),
((7, 6), 3),
((6, 8), 7),
((7, 8), 8),
((5, 8), 3),
((8, 0), 9),
((6, 0), 4),
((6, 2), 8),
((6, 4), 9),
((4, 4), 4),
((3, 3), 6),
((3, 4), 9),
((3, 2), 4),
((4, 2), 9),
((7, 2), 4),
((2, 3), 2),
((2, 4), 4),
((7, 4), 6),
((7, 1), 1),
((8, 1), 6),
((8, 2), 7),
((8, 3), 2),
((8, 7), 1)
]

s = list(sorted(s, key=lambda x:x[0][0]*9+x[0][1]))
a = ''.join(map(lambda x:str(x[1]), s))
print(a)
print(hex(int(a[::-1], 10))[2:-1][::-1].upper())

flag:CBC25EF8D9F482BC1F3DA3CA1F154EC89FC3F1414EDD93A3


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

收藏
点赞1
打赏
分享
最新回复 (1)
雪    币: 6051
活跃值: (1441)
能力值: ( LV15,RANK:1473 )
在线值:
发帖
回帖
粉丝
lelfei 23 2019-3-25 17:04
2
0
果然有人找到了程序的后门,赞一个
游客
登录 | 注册 方可回帖
返回