目录
题目:DASCTF Apr.2023 X SU战队2023开局之战 【简单】easyRE
题目:DASCTF Apr.2023 X SU战队2023开局之战 【中等】gotots
日期:2023.5.3
题目:[GWCTF 2019]pyre
刷题平台:BUUCTF
方向:REVERSE
Write UP:
获取题目附件,根据题目名可知是由python编写,所以直接用uncompyle6进行反编译,dump出py文件。
# uncompyle6 version 3.9.0
# Python bytecode version base 2.7 (62211)
# Decompiled from: Python 3.9.12 (tags/v3.9.12:b28265d, Mar 23 2022, 23:52:46) [MSC v.1929 64 bit (AMD64)]
# Embedded file name: encode.py
# Compiled at: 2019-08-19 21:01:57
print 'Welcome to Re World!'
print 'Your input1 is your flag~'
l = len(input1)
for i in range(l):
num = ((input1[i] + i) % 128 + 128) % 128
code += num
for i in range(l - 1):
code[i] = code[i] ^ code[i + 1]
print code
code = ['\x1f', '\x12', '\x1d', '(', '0', '4', '\x01', '\x06', '\x14', '4', ',',
'\x1b', 'U', '?', 'o', '6', '*', ':', '\x01', 'D', ';', '%', '\x13']
# okay decompiling attachment.pyc
可以看出程序对输入内容进行了两个加密,这两个加密可逆并知道了密文,开始写解密脚本。
code = ['\x1f', '\x12', '\x1d', '(', '0', '4', '\x01', '\x06', '\x14', '4', ',',
'\x1b', 'U', '?', 'o', '6', '*', ':', '\x01', 'D', ';', '%', '\x13']
flag = ""
for i in range(len(code)-2,-1,-1):
code[i] = chr(ord(code[i]) ^ ord(code[i+1]))
for i in range(len(code)):
flag += chr(((ord(code[i]) - i) % 128 + 128) % 128)
print(flag)
# GWHT{Just_Re_1s_Ha66y!}
FLAG:flag{Just_Re_1s_Ha66y!}
日期:2023.5.4
题目:[ACTF新生赛2020]easyre
刷题平台:BUUCTF
方向:REVERSE
Write UP:
获取题目附件后,通过查壳工具发现程序有加UPX壳
对其进行脱壳后将程序放入IDA中进行分析,找到关键的main函数,得知可以发现一个关键数组_data_start__。
由此可以推测,是将输入的字符的对应数值-1作为_data_start__数组的下标与v4进行比较,因此只需要找到v4中的值在_data_start__中的对应下标位置即可。脚本如下:
cipher = "*F'\"N,\"(I?+@"
flag = "ACTF{"
dist = "~}|{zyxwvutsrqponmlkjihgfedcba`_^]\\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$# !\""
for i in range(len(cipher)):
flag += chr(dist.index(cipher[i])+1)
print(flag+'}')
# ACTF{U9X_1S_W6@T?}
FLAG:flag{U9X_1S_W6@T?}
题目:DASCTF Apr.2023 X SU战队2023开局之战 【简单】easyRE
刷题平台:BUUCTF
方向:REVERSE
Write UP:
获取题目附件,根据附件图标可以猜测是python编写的exe文件,利用pyinstxtractor.py将其转成pyc文件,但根据信息发现,该程序所用的python版本为3.11,uncompyle6不支持这个python版本的反编译,当时在此陷入困境,发现自己还是太依赖工具了。
在后来,看到了官方WP后知晓了python的dis库和marshal库可以对pyc文件进行反编译,将其转成字节码。脚本如下:
import dis
import marshal
def main():
file1 = open('easyRE.pyc','rb')
code = marshal.loads(file1.read()[16:])
print(dis.dis(code))
if __name__ == '__main__':
main()
"file1.read()[16:]"是跳过pyc文件的文件头,以防止后续dis解析错误。执行脚本dump出pyc文件的字节码:
0 0 RESUME 0
1 2 LOAD_CONST 0 (0)
4 LOAD_CONST 1 (None)
6 IMPORT_NAME 0 (random)
8 STORE_NAME 0 (random)
3 10 PUSH_NULL
12 LOAD_NAME 0 (random)
14 LOAD_ATTR 1 (Random)
24 LOAD_CONST 2 (322376503)
26 PRECALL 1
30 CALL 1
40 STORE_NAME 2 (r)
6 42 PUSH_NULL
44 LOAD_NAME 3 (input)
46 LOAD_CONST 3 ('Enter your flag: ')
48 PRECALL 1
52 CALL 1
62 LOAD_METHOD 4 (encode)
84 PRECALL 0
88 CALL 0
98 STORE_NAME 5 (pt)
8 100 LOAD_CONST 4 (b'\x8b\xcck\xd3\xed\x96\xffFb\x06r\x085\x82\xbc \xb2\xde)p\x88Q`\x1bf\x18\xb6QUSw\x10\xcd\xd9\x13A$\x86\xe5\xcd\xd9\xff')
102 STORE_NAME 6 (ct)
10 104 BUILD_LIST 0
106 STORE_NAME 7 (buf)
12 108 LOAD_NAME 5 (pt)
110 GET_ITER
>> 112 FOR_ITER 46 (to 206)
114 STORE_NAME 8 (b)
13 116 LOAD_NAME 7 (buf)
118 LOAD_METHOD 9 (append)
140 LOAD_NAME 2 (r)
142 LOAD_METHOD 10 (randint)
164 LOAD_CONST 0 (0)
166 LOAD_CONST 5 (255)
168 PRECALL 2
172 CALL 2
182 LOAD_NAME 8 (b)
184 BINARY_OP 12 (^)
188 PRECALL 1
192 CALL 1
202 POP_TOP
204 JUMP_BACKWARD 47 (to 112)
15 >> 206 PUSH_NULL
208 LOAD_NAME 11 (bytes)
210 LOAD_NAME 7 (buf)
212 PRECALL 1
216 CALL 1
226 LOAD_NAME 6 (ct)
228 COMPARE_OP 2 (==)
234 POP_JUMP_FORWARD_IF_TRUE 2 (to 240)
236 LOAD_ASSERTION_ERROR
238 RAISE_VARARGS 1
17 >> 240 PUSH_NULL
242 LOAD_NAME 12 (print)
244 LOAD_CONST 6 ('Correct!')
246 PRECALL 1
250 CALL 1
260 POP_TOP
262 LOAD_CONST 1 (None)
264 RETURN_VALUE
None
大致能看出脚本流程,保险起见用ChatGPt辅助帮忙分析,得出程序:
import random
r = random.Random(322376503)
pt = input("Enter your flag:").encode()
ct = b'\x8b\xcck\xd3\xed\x96\xffFb\x06r\x085\x82\xbc \xb2\xde)p\x88Q`\x1bf\x18\xb6QUSw\x10\xcd\xd9\x13A$\x86\xe5\xcd\xd9\xff'
buf = []
for b in pt:
buf.append(r.randint(0,255) ^ b)
if bytes(buf) == ct:
print('Correct!')
else:
None
到这里就轻松一些了,进行了异或运算,随机数种子为322376503,解密脚本如下:
import random
r = random.Random(322376503)
ct = b'\x8b\xcck\xd3\xed\x96\xffFb\x06r\x085\x82\xbc \xb2\xde)p\x88Q`\x1bf\x18\xb6QUSw\x10\xcd\xd9\x13A$\x86\xe5\xcd\xd9\xff'
flag = []
for b in ct:
flag.append(r.randint(0,255) ^ b)
for i in range(len(flag)):
print(chr(flag[i]),end="")
# flag{69858b56-4987-438f-a02c-5ab5c09e5138}
FLAG:flag{69858b56-4987-438f-a02c-5ab5c09e5138}
日期:2023.5.5
题目:findit
刷题平台:BUUCTF
方向:REVERSE
Write UP:
获取题目附件,可以看出是一个apk文件,放入JEB中进行反编译,找到MainActivity函数,查看其中函数。
package com.example.findit;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.MenuItem;
import android.view.View.OnClickListener;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity {
@Override // android.support.v7.app.ActionBarActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(0x7F030018); // layout:activity_main
Button btn = (Button)this.findViewById(0x7F05003D); // id:widget3
EditText edit = (EditText)this.findViewById(0x7F05003E); // id:widget2
TextView text = (TextView)this.findViewById(0x7F05003F); // id:widget1
btn.setOnClickListener(new View.OnClickListener() {
@Override // android.view.View$OnClickListener
public void onClick(View v) {
char[] x = new char[17];
char[] y = new char[38];
for(int i = 0; i < 17; ++i) {
if(new char[]{'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'}[i] < 73 && new char[]{'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'}[i] >= 65 || new char[]{'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'}[i] < 105 && new char[]{'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'}[i] >= 97) {
x[i] = (char)(new char[]{'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'}[i] + 18);
}
else if(new char[]{'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'}[i] >= 65 && new char[]{'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'}[i] <= 90 || new char[]{'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'}[i] >= 97 && new char[]{'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'}[i] <= 0x7A) {
x[i] = (char)(new char[]{'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'}[i] - 8);
}
else {
x[i] = new char[]{'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'}[i];
}
}
if(String.valueOf(x).equals(edit.getText().toString())) {
for(int v1 = 0; v1 < 38; ++v1) {
if(new char[]{'p', 'v', 'k', 'q', '{', 'm', '1', '6', '4', '6', '7', '5', '2', '6', '2', '0', '3', '3', 'l', '4', 'm', '4', '9', 'l', 'n', 'p', '7', 'p', '9', 'm', 'n', 'k', '2', '8', 'k', '7', '5', '}'}[v1] >= 65 && new char[]{'p', 'v', 'k', 'q', '{', 'm', '1', '6', '4', '6', '7', '5', '2', '6', '2', '0',