首页
社区
课程
招聘
[原创]攻防世界PWN新手区:level2
发表于: 2022-4-4 13:51 11814

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

2022-4-4 13:51
11814

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

main函数:

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

vulnerable_function() 函数:

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

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

下面要做的是构建一个新的栈,当跳转到system函数后,我们要构建好system函数视角下的栈情况这里查看system函数的代码:

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

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


cyberpeace{454c892c2a452d51abdbe6b27c85fc5e}

int __cdecl main(int argc, const char **argv, const char **envp)
{
  vulnerable_function();
  system("echo 'Hello World!'");
  return 0;
}
int __cdecl main(int argc, const char **argv, const char **envp)
{
  vulnerable_function();
  system("echo 'Hello World!'");
  return 0;
}
 
ssize_t vulnerable_function()
{
  char buf[136]; // [esp+0h] [ebp-88h] BYREF
 
  system("echo Input:");
  return read(0, buf, 0x100u);
}
ssize_t vulnerable_function()
{
  char buf[136]; // [esp+0h] [ebp-88h] BYREF
 
  system("echo Input:");
  return read(0, buf, 0x100u);
}
-00000088 buf             db 136 dup(?)
+00000000  s              db 4 dup(?)
+00000004  r              db 4 dup(?)
-00000088 buf             db 136 dup(?)
+00000000  s              db 4 dup(?)
+00000004  r              db 4 dup(?)
// attributes: thunk
int system(const char *command)
{
  return system(command);
}
// attributes: thunk
int system(const char *command)
{
  return system(command);
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//