逆向攻防世界CTF系列61-APK-逆向2

32位,C#写的

image-20241213140611040

dnSpy打开,定位

image-20241213140842597

一眼看到Success和Ctf

仔细看看Main,再运行一下,发现需要连接,后面才能运行,因此我们先连接一下

        private static void Main(string[] args)
        {
            string text = "127.0.0.1";
            int num = 31337;
            TcpClient tcpClient = new TcpClient();
            try
            {
                Console.WriteLine("Connecting...");
                tcpClient.Connect(text, num);
            }
            catch (Exception)
            {
                Console.WriteLine("Cannot connect!\nFail!");
                return;
            }
            Socket client = tcpClient.Client;
            string text2 = "Super Secret Key";
            string text3 = Program.read();
            client.Send(Encoding.ASCII.GetBytes("CTF{"));
            foreach (char c in text2)
            {
                client.Send(Encoding.ASCII.GetBytes(Program.search(c, text3)));
            }
            client.Send(Encoding.ASCII.GetBytes("}"));
            client.Close();
            tcpClient.Close();
            Console.WriteLine("Success!");
        }

代码:

import socket

def start_server():
    # 1️⃣ 服务器地址和端口
    host = '127.0.0.1'
    port = 31337

    # 2️⃣ 创建 TCP 套接字
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((host, port))  # 绑定IP和端口
    server_socket.listen(1)  # 开始监听,最多允许 1 个连接
    print(f"🌐 服务器已启动,正在监听 {host}:{port} ...")

    while True:
        # 3️⃣ 等待客户端连接
        client_socket, client_address = server_socket.accept()
        print(f"🤝 客户端已连接:{client_address}")

        try:
            # 4️⃣ 处理客户端发送的消息
            message = b""
            while True:
                data = client_socket.recv(1024)  # 每次接收 1024 字节
                if not data:  # 如果没有数据,表示连接断开
                    break
                message += data  # 累积消息
                print(f"📩 收到数据: {data.decode('utf-8', errors='ignore')}")

            print(f"📝 最终接收的数据: {message.decode('utf-8', errors='ignore')}")
        except Exception as e:
            print(f"❌ 发生错误:{e}")
        finally:
            # 5️⃣ 关闭客户端连接
            client_socket.close()
            print(f"🔌 客户端 {client_address} 连接已断开\n")

if __name__ == '__main__':
    start_server()

🌐 服务器已启动,正在监听 127.0.0.1:31337 …
🤝 客户端已连接:('127.0.0.1', 65391)
📩 收到数据: CTF{
📩 收到数据: 7e
📩 收到数据: b6
📩 收到数据: 7b
📩 收到数据: 0b
📩 收到数据: b4
📩 收到数据: 42
📩 收到数据: 7e
📩 收到数据: 0b
📩 收到数据: 43
📩 收到数据: b4
📩 收到数据: 0b
📩 收到数据: 60
📩 收到数据: 42
📩 收到数据: 67
📩 收到数据: 0b
📩 收到数据: 55
📩 收到数据: }
📝 最终接收的数据: CTF{7eb67b0bb4427e0b43b40b6042670b55}
🔌 客户端 ('127.0.0.1', 65391) 连接已断开

GPT写的代码怪怪的

直接给了flag提交

应该还有其它方法,我们接着往下看,其实是有输出flag的地方,我们按照逻辑也能逆向

        private static string search(char x, string text)
        {
            int length = text.Length;
            for (int i = 0; i < length; i++)
            {
                if (x == text[i])
                {
                    int num = i * 1337 % 256;
                    return Convert.ToString(num, 16).PadLeft(2, '0');
                }
            }
            return "??";
        }

text3哪来的?read里的

private static string read(){
    string fileName = Process.GetCurrentProcess().MainModule.FileName;
    string[] array = fileName.Split(new char[] { '\\' });
    string text = array[array.Length - 1];
    string text2 = "";
    using (StreamReader streamReader = new StreamReader(text)) {
        text2 = streamReader.ReadToEnd();
    }
    return text2;
}

这段代码的核心目的是读取当前正在执行的可执行文件的内容

Process.GetCurrentProcess().MainModule.FileName 获取可执行文件的路径。

通过 StreamReader 读取整个可执行文件的全部二进制数据,并将其存储在变量 text3 中。

text2已知,我们可以很容易的写出逆向代码

text2 = 'Super Secret Key'

f = open(r'4122e391e1574335907f8e2c4f438d0e.exe','r',encoding='unicode-escape')

text3 = f.read()

f.close()
flag = ''

def search(i ,text):
    l = len(text)
    for j in range(l):
        if (i == text[j]):
            num = j * 1337 % 256;
            return f"{num:02x}"

    return "?"

for i in text2:
    flag += search(i, text3)

print('CTF{'+flag+'}')