比赛没打,赛后补题
首先得知道这是个python打包的elf,先用pyinstxtractor解一下
解完以后平平无奇,反编译chal.pyc也只有导入maze运行run函数
那就只有一个maze.so可以分析
maze.so肯定是python打包成so了
通过手动python导入maze调用help可以看到maze库的很多东西,还可以把密文等参数打印出来
不过导入要满足一些条件
import maze
help(maze)
print('EqdU3uQNCi=',maze.EqdU3uQNCi)
print('UJ9mxXxeoS=',maze.UJ9mxXxeoS)
print('c2VjcmV0=',maze.c2VjcmV0)
print('regexes=',maze.regexes)
help整理的结果如下
NAME
maze
CLASSES
builtins.object
Q2Fy
Q2VsbA
TWF6ZUxhbmc
class Q2Fy(builtins.object) # Car
| Q2Fy(value, x, y)
|
| Methods defined here:
|
| __init__(self, value, x, y)
|
| __repr__(self)
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
class Q2VsbA(builtins.object) # Cell
| Q2VsbA(name, value)
|
| Methods defined here:
|
| __init__(self, name, value)
|
| __repr__(self)
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
class TWF6ZUxhbmc(builtins.object) # MazeLang
| TWF6ZUxhbmc(code)
|
| Methods defined here:
|
| YWRkX2NlbGw(self, code) # add_cell
|
| YWRkX2Z1bmN0aW9u(self, code) # add_function
|
| Z2V0X2NlbGw(self, code) # get_cell
|
| Z2V0X3Bvcw(self, pos, direction) # get_pos
|
| __init__(self, code)
|
| aW5pdA(self) # init
|
| b3Bw(self, direction) # opp
|
| c3RlcA(self) # step
|
| cnVuX3RpbGxfb3V0cHV0(self) # run_till_output
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
FUNCTIONS
aW5pdF9zZWNyZXQ() # init_secret
c29sdmU(SvL6VEBRwx) -> 'int' # solve
exit(status=None, /)
Exit the interpreter by raising SystemExit(status).
If the status is omitted or None, it defaults to zero (i.e., success).
If the status is an integer, it will be used as the system exit status.
If it is another kind of object, it will be printed and the system
exit status will be one (i.e., failure).
run()
DATA
EqdU3uQNCi= [18, 17, 15, 0, 27, 31, 10, 19, 14, 21, 25, 22, 6, 3, 30, 8, 24, 5, 7, 4, 13, 29, 9, 26, 1, 2, 28, 16, 20, 32, 12, 23, 11]
UJ9mxXxeoS= 'IyMgIyMgIyMgIyMgIyMgIyMgIyMKIyMgIyMgIyMgXl4gIyMgXl4gIyMKIyMgIyMgIyMgLi4gIyMgSVogIyMgIyMgIyMgIyMKIyMgJVIgLi4gJUQgIyMgJUQgLi4gLi4gJUwgIyMKIyMgPj4gIyMgLi4gIyMgRUEgKiogUFAgJVUgIyMKIyMgJVUgSUEgVEEgIyMgRUIgKiogUFAgJVUgIyMKIyMgJVUgSUIgVEIgIyMgRUMgKiogUFAgJVUgIyMKIyMgJVUgSUMgVEMgIyMgRUQgKiogUFAgJVUgIyMKIyMgJVUgSUQgVEQgIyMgRUUgKiogUFAgJVUgIyMKIyMgJVUgSUUgVEUgIyMgRUYgKiogUFAgJVUgIyMKIyMgJVUgSUYgVEYgIyMgJVIgKiogSVogJVUgIyMKIyMgJVUgSUcgJUwgIyMgIyMgIyMgIyMgIyMgIyMKIyMgIyMgIyMgIyMgIyMgIyMKClBQIC0+ICs9MQpNTSAtPiAtPTEKSVogLT4gPTAKRUEgLT4gSUYgPT0wIFRIRU4gJVIgRUxTRSAlRApFQiAtPiBJRiA9PTEgVEhFTiAlUiBFTFNFICVECkVDIC0+IElGID09MiBUSEVOICVSIEVMU0UgJUQKRUQgLT4gSUYgPT0zIFRIRU4gJVIgRUxTRSAlRApFRSAtPiBJRiA9PTQgVEhFTiAlUiBFTFNFICVECkVGIC0+IElGID09NSBUSEVOICVSIEVMU0UgJUQKVEEgLT4gSUYgKiogVEhFTiAlTCBFTFNFICVECklBIC0+ID03MgpUQiAtPiBJRiAqKiBUSEVOICVMIEVMU0UgJUQKSUIgLT4gPTczClRDIC0+IElGICoqIFRIRU4gJUwgRUxTRSAlRApJQyAtPiA9ODQKVEQgLT4gSUYgKiogVEhFTiAlTCBFTFNFICVECklEIC0+ID04MApURSAtPiBJRiAqKiBUSEVOICVMIEVMU0UgJUQKSUUgLT4gPTY3ClRGIC0+IElGICoqIFRIRU4gJUwgRUxTRSAlRApJRiAtPiA9ODQKSUcgLT4gPTcwCkxUIC0+IElGID09NiBUSEVOICVEIEVMU0UgJUwK'
# secret
c2VjcmV0= [7, 47, 60, 28, 39, 11, 23, 5, 49, 49, 26, 11, 63, 4, 9, 2, 25, 61, 36, 112, 25, 15, 62, 25, 3, 16, 102, 38, 14, 7, 37, 4, 40]
regexes= {'wall': '##|``', 'path': '\\.\\.', 'splitter': '<>', 'pause': '[0-9]{2}', 'start': '\\^\\^', 'hole': '\\(\\)', 'out': '>>', 'in': '<<', 'one-use': '--', 'direction': '%[LRUDNlrudn]', 'signal': '(?<=\\*)[\\*A-Za-z0-9]', 'function': '[A-Za-z][A-Za-z0-9]'}
FILE
/root/Desktop/maze.so
给定一个没有混淆的api和函数模块的debug功能,盲猜也不是不行【对于我来说无法手撕maze.so把函数逻辑还原,只能胡乱猜着构造】
下面这个是lchild的解题脚本
import maze
maze.aW5pdF9zZWNyZXQ()
flag = []
x0 = maze.TWF6ZUxhbmc(maze.base64.b64decode(maze.UJ9mxXxeoS).decode())
for i in range(33):
flag.append(x0.cnVuX3RpbGxfb3V0cHV0() ^ maze.c2VjcmV0[i])
print(bytes(flag))
# TPCTF{yOu_@re_m@sT3r_OF_mAZElaN6}
题目给了提示py,所以顺理成章的用pyinstxtractor解一下
然后pycdc反编译run.pyc
# Source Generated with Decompyle++
# File: run.pyc (Python 3.8)
Warning: block stack is not empty!
from secret import key, enc
from Crypto.Cipher import AES
from Crypto.Util.number import *
from Crypto.Util.Padding import pad
key = key.encode()
message = input('Enter your message: ').strip()
if not message.startswith('TPCTF{') or message.endswith('}'):
raise AssertionError
def encrypt_message(key = None, message = None):
cipher = AES.new(key, AES.MODE_ECB)
ciphertext = cipher.encrypt(pad(message, AES.block_size))
return ciphertext
encrypted = list(encrypt_message(key, message.encode()))
for x, y in zip(encrypted, enc):
if x != y:
print('Wrong!')
print('Right!')
return None
从表面上看起来也就是输入–>AES加密–>比对
首先from secret import key, enc,从secret把key和enc搞出来
反编译secret.pyc
#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
# Version: Python 3.8
key = '2033-05-18_03:33'
enc = [
213,
231,
201,
213,
9,
197,
233,
81,
111,
223,
34,
166,
103,
225,
175,
180]
拿去解密发现有问题
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from numpy import byte
key = b'2033-05-18_03:33'
enc = [
213,
231,
201,
213,
9,
197,
233,
81,
111,
223,
34,
166,
103,
225,
175,
180]
def decrypt_message(key = None, message = None):
cipher = AES.new(key, AES.MODE_ECB)
ciphertext = cipher.decrypt(bytes(enc))
return ciphertext
print(decrypt_message(key,enc))
# b'flag{test}\x06\x06\x06\x06\x06\x06'
那也只可能是对导入的库做了手脚了,结果就是在下面两个位置有问题
from Crypto.Cipher import AES
key = b'2033-05-18_03:33'
enc = [153, 240, 237, 199, 63, 44, 237, 45, 25, 47, 97, 154, 158, 112, 46, 176, 219, 247, 44, 115, 169, 124, 64, 63, 121, 253, 250, 137, 34, 144, 33, 17, 182, 9, 16, 247, 249, 41, 165, 114, 87, 231, 222, 242, 126, 30, 124, 237]
enc = [i^1 for i in enc]
def decrypt_message(key = None, message = None):
cipher = AES.new(key, AES.MODE_ECB)
ciphertext = cipher.decrypt(bytes(enc))
return ciphertext
print(decrypt_message(key,enc))
# b'TPCTF{83_C4u710U5_0F_PY7hON_k3YW0Rd_sHadOWIN9}\x02\x02'
这个确实是比较抽象,只能是猜到库做了手脚,然后对拍找问题…
其他题的话:apple目前不打算看了,研究gun apl对我来说没啥用,剩余的慢慢复现