-Level5
[level5@ftz tmp]$ ls -l /usr/bin/level5
|
-rws--x--- 1 level6 level5 12236 8월 19 2014 /usr/bin/level5 |
|
> level5가 r 권한이 없어서 gdb로 분석할 수 없었다.
> level6 비밀번호를 알아 냈기 때문에 level6로 로그인해 분석해 보자
level6 / what the hell
[level5@ftz tmp]$ su - level6
|
Password: hint - 인포샵 bbs의 텔넷 접속 메뉴에서 많이 사용되던 해킹 방법이다. |
|
> 갑자기 힌트가 출력됬다.
> Ctrl + C 로 그냥 종료해버린다.
[level6@ftz level6]$ gdb /usr/bin/level5
|
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh) Copyright 2003 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux-gnu"... (gdb)disas main Dump of assembler code for function main: 0x0804842c <main+0>: push %ebp 0x0804842d <main+1>: mov %esp,%ebp 0x0804842f <main+3>: sub $0x8,%esp 0x08048432 <main+6>: and $0xfffffff0,%esp 0x08048435 <main+9>: mov $0x0,%eax 0x0804843a <main+14>: sub %eax,%esp 0x0804843c <main+16>: sub $0x8,%esp 0x0804843f <main+19>: push $0x180 0x08048444 <main+24>: push $0x8048580 0x08048449 <main+29>: call 0x804832c <creat> 0x0804844e <main+34>: add $0x10,%esp 0x08048451 <main+37>: mov %eax,0xfffffffc(%ebp) 0x08048454 <main+40>: cmpl $0x0,0xfffffffc(%ebp) 0x08048458 <main+44>: jns 0x8048484 <main+88> 0x0804845a <main+46>: sub $0xc,%esp 0x0804845d <main+49>: push $0x80485a0 0x08048462 <main+54>: call 0x804835c <printf> 0x08048467 <main+59>: add $0x10,%esp 0x0804846a <main+62>: sub $0xc,%esp 0x0804846d <main+65>: push $0x8048580 0x08048472 <main+70>: call 0x804833c <remove> 0x08048477 <main+75>: add $0x10,%esp ---Type <return> to continue, or q <return> to quit--- 0x0804847a <main+78>: sub $0xc,%esp 0x0804847d <main+81>: push $0x0 0x0804847f <main+83>: call 0x804836c <exit> 0x08048484 <main+88>: sub $0x4,%esp 0x08048487 <main+91>: push $0x1f 0x08048489 <main+93>: push $0x80485e0 0x0804848e <main+98>: pushl 0xfffffffc(%ebp) 0x08048491 <main+101>: call 0x804830c <write> 0x08048496 <main+106>: add $0x10,%esp 0x08048499 <main+109>: sub $0xc,%esp 0x0804849c <main+112>: pushl 0xfffffffc(%ebp) 0x0804849f <main+115>: call 0x804831c <close> 0x080484a4 <main+120>: add $0x10,%esp 0x080484a7 <main+123>: sub $0xc,%esp 0x080484aa <main+126>: push $0x8048580 0x080484af <main+131>: call 0x804833c <remove> 0x080484b4 <main+136>: add $0x10,%esp 0x080484b7 <main+139>: leave 0x080484b8 <main+140>: ret 0x080484b9 <main+141>: nop 0x080484ba <main+142>: nop 0x080484bb <main+143>: nop End of assembler dump. |
|
> 간단히 쭉 살펴보면 creat 로 아마 level5.tmp 를 만드는 거 같고 그 다음이 점프이니 파일이 만들어졌는지 아닌지 확인하는 것 같고
> 조건에 따라 출력문 출력하고 파일 삭제 / 파일에 내용 쓰고 파일 닫고 파일 삭제로 이루어 진 것 같다.
|
0x0804843f <main+19>: push $0x180 0x08048444 <main+24>: push $0x8048580 0x08048449 <main+29>: call 0x804832c <creat> |
|
# man creat
|
NAME open, creat - open and possibly create a file or device SYNOPSIS #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); int creat(const char *pathname, mode_t mode); |
|
|
(gdb) x/s 0x8048580 0x8048580 <_IO_stdin_used+28>: "/tmp/level5.tmp" |
|
> pathname은 /tmp/level5.tmp 이고 mode 는 0x180이다.
|
0x08048454 <main+40>: cmpl $0x0,0xfffffffc(%ebp) 0x08048458 <main+44>: jns 0x8048484 <main+88> 0x0804845a <main+46>: sub $0xc,%esp 0x0804845d <main+49>: push $0x80485a0 0x08048462 <main+54>: call 0x804835c <printf> 0x08048467 <main+59>: add $0x10,%esp 0x0804846a <main+62>: sub $0xc,%esp 0x0804846d <main+65>: push $0x8048580 0x08048472 <main+70>: call 0x804833c <remove> 0x08048477 <main+75>: add $0x10,%esp ---Type <return> to continue, or q <return> to quit--- 0x0804847a <main+78>: sub $0xc,%esp 0x0804847d <main+81>: push $0x0 0x0804847f <main+83>: call 0x804836c <exit> |
|
> creat 의 명령어가 잘 수행되면 점프하고 잘 수행되지 않으면 다음으로 넘어간다.
|
(gdb) x/s 0x80485a0 0x80485a0 <_IO_stdin_used+60>: "Can not creat a temporary file.\n" |
|
> 파일 생성 실패 메시지 출력
0x8048580 = /tmp/level5.tmp
remove로 파일을 삭제하고 exit(0)으로 프로그램을 종료한다.
|
0x08048487 <main+91>: push $0x1f 0x08048489 <main+93>: push $0x80485e0 0x0804848e <main+98>: pushl 0xfffffffc(%ebp) 0x08048491 <main+101>: call 0x804830c <write> |
|
# man 2 write
|
NAME write - write to a file descriptor SYNOPSIS #include <unistd.h> ssize_t write(int fd, const void *buf, size_t count); DESCRIPTION write() writes up to count bytes to the file referenced by the file descriptor fd from the buffer starting at buf. POSIX requires that a read() which can be proved to occur after a write() has returned returns the new data. Note that not all file systems are POSIX conforming. |
|
> 3개의 인자가 필요하다. fd 파일 , buf 내용 , count 바이트 수
|
(gdb) x/s 0x80485e0 0x80485e0 <_IO_stdin_used+124>: "next password : what the hell\n" |
|
> buf 의 내용이 level6의 암호가 적혀있다.
> count 는 1f (31)
|
0x0804849c <main+112>: pushl 0xfffffffc(%ebp) 0x0804849f <main+115>: call 0x804831c <close> |
|
> write의 인자 fd 와 같다. -> 적은 파일 (/tmp/level5.tmp)을 닫는다.
> 그리고 삭제한다.
- 의사코드 복원
|
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define PERM 0x180 int main() { int fd; char nextPass[] = "next password : what the hell\n"; char *tempfile = "/tmp/level5.tmp; fd = create(tempFile, PERM); if(fd < 0) { printf("Can not create a temporary file.\n"); remove(tempFile); exit(0); } else { write(fd, nextPass, strlen(nextPass)); close(fd); remove(tempFile); } return 0; } |
|
> 완전히 이 코드로 만들어졌다고 할 수 없지만 같은 동작을 하는 코드를 유추해 볼 수 있다.
'Security > 리버싱' 카테고리의 다른 글
Level6 문제 분석 -의사 코드 (0) | 2017.11.29 |
---|---|
Level6 문제 해결 (0) | 2017.11.29 |
Race Condition(레이스 컨디션) (0) | 2017.11.29 |
Level5 문제해결 (0) | 2017.11.29 |
Level4 문제해결 (0) | 2017.11.29 |