ftz.hackerschool.org의 이미지를 사용하여 실습했습니다.
-Level7
level7 / come together
[level7@ftz tmp]$ /bin/level7
|
Insert The Password : aaa 올바르지 않은 패스워드 입니다. 패스워드는 가까운곳에... --_--_- --____- ---_-__ --__-_- |
|
[level7@ftz tmp]$ /bin/level7
|
Insert The Password : mate Congratulation! next password is "break the world". |
|
> 이런 동작을 하는 프로그램을 분석해서 의사코드를 만들어 봅니다.
[level7@ftz tmp]$ ls -l /bin/level7
|
-rws--x--- 1 level8 level7 12312 Aug 19 2014 /bin/level7 |
|
> 하지만 level7에는 r권한이 없기때문에 확인 못한다.
level8의 암호를 알고 있으므로 level8로 로그인하여 확인한다.
level8 / break the world
[level8@ftz level8]$ gdb /bin/level7
|
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: 0x08048454 <main+0>: push %ebp 0x08048455 <main+1>: mov %esp,%ebp 0x08048457 <main+3>: sub $0x8,%esp 0x0804845a <main+6>: and $0xfffffff0,%esp 0x0804845d <main+9>: mov $0x0,%eax 0x08048462 <main+14>: sub %eax,%esp 0x08048464 <main+16>: sub $0xc,%esp 0x08048467 <main+19>: push $0x64 0x08048469 <main+21>: call 0x8048344 <malloc> 0x0804846e <main+26>: add $0x10,%esp 0x08048471 <main+29>: mov %eax,0xfffffffc(%ebp) 0x08048474 <main+32>: sub $0xc,%esp 0x08048477 <main+35>: push $0x80485c0 0x0804847c <main+40>: call 0x8048384 <printf> 0x08048481 <main+45>: add $0x10,%esp 0x08048484 <main+48>: sub $0x4,%esp 0x08048487 <main+51>: pushl 0x8049744 0x0804848d <main+57>: push $0x64 0x0804848f <main+59>: pushl 0xfffffffc(%ebp) 0x08048492 <main+62>: call 0x8048354 <fgets> 0x08048497 <main+67>: add $0x10,%esp 0x0804849a <main+70>: sub $0x4,%esp 0x0804849d <main+73>: push $0x4 0x0804849f <main+75>: push $0x80485d7 0x080484a4 <main+80>: pushl 0xfffffffc(%ebp) 0x080484a7 <main+83>: call 0x8048364 <strncmp> 0x080484ac <main+88>: add $0x10,%esp 0x080484af <main+91>: test %eax,%eax 0x080484b1 <main+93>: jne 0x80484cd <main+121> 0x080484b3 <main+95>: sub $0xc,%esp 0x080484b6 <main+98>: push $0x80485e0 0x080484bb <main+103>: call 0x8048384 <printf> 0x080484c0 <main+108>: add $0x10,%esp 0x080484c3 <main+111>: sub $0xc,%esp 0x080484c6 <main+114>: push $0x0 0x080484c8 <main+116>: call 0x8048394 <exit> 0x080484cd <main+121>: sub $0xc,%esp 0x080484d0 <main+124>: push $0x8048617 0x080484d5 <main+129>: call 0x8048334 <system> 0x080484da <main+134>: add $0x10,%esp 0x080484dd <main+137>: leave 0x080484de <main+138>: ret 0x080484df <main+139>: nop End of assembler dump. |
|
|
0x08048467 <main+19>: push $0x64 0x08048469 <main+21>: call 0x8048344 <malloc> |
|
# man malloc
|
NAME calloc, malloc, free, realloc - Allocate and free dynamic memory SYNOPSIS #include <stdlib.h> void *calloc(size_t nmemb, size_t size); void *malloc(size_t size); void free(void *ptr); void *realloc(void *ptr, size_t size); |
|
> malloc은 메모리를 동적할당 하는 데 쓰입니다. 메모리는 0x64 (100) 입니다.
|
0x08048477 <main+35>: push $0x80485c0 0x0804847c <main+40>: call 0x8048384 <printf> (gdb) x/s 0x80485c0 0x80485c0 <_IO_stdin_used+28>: "Insert The Password : " |
|
> 출력문
|
0x08048487 <main+51>: pushl 0x8049744 0x0804848d <main+57>: push $0x64 0x0804848f <main+59>: pushl 0xfffffffc(%ebp) 0x08048492 <main+62>: call 0x8048354 <fgets> |
|
# man fgets
|
NAME fgetc, fgets, getc, getchar, gets, ungetc - input of characters and strings SYNOPSIS #include <stdio.h> int fgetc(FILE *stream); char *fgets(char *s, int size, FILE *stream); int getc(FILE *stream); int getchar(void); char *gets(char *s); int ungetc(int c, FILE *stream); |
|
> 문자를 읽어 들입니다. size가 100이고 입력은 프로그램을 실행해봤으니 키보드로 입력을 받습니다.( File에서 읽어오지 않음)
> 아마 아까 동적할당 받은 변수에 저장되는 듯 합니다.
|
0x0804849d <main+73>: push $0x4 0x0804849f <main+75>: push $0x80485d7 0x080484a4 <main+80>: pushl 0xfffffffc(%ebp) 0x080484a7 <main+83>: call 0x8048364 <strncmp> (gdb) x/s 0x80485d7 0x80485d7 <_IO_stdin_used+51>: "mate" |
|
> mate라는 단어와 입력받은 단어 4자리를 비교합니다.
# man strncmp
|
NAME strcmp, strncmp - compare two strings SYNOPSIS #include <string.h> int strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t n); |
|
|
0x080484b6 <main+98>: push $0x80485e0 0x080484bb <main+103>: call 0x8048384 <printf> 0x080484c0 <main+108>: add $0x10,%esp 0x080484c3 <main+111>: sub $0xc,%esp 0x080484c6 <main+114>: push $0x0 0x080484c8 <main+116>: call 0x8048394 <exit> (gdb) x/s 0x80485e0 0x80485e0 <_IO_stdin_used+60>: "\nCongratulation! next password is \"break the world\".\n\n" |
|
> 비교에서 맞으면 암호를 알려주고 exit(0)으로 종료됩니다.
|
0x080484d0 <main+124>: push $0x8048617 0x080484d5 <main+129>: call 0x8048334 <system> (gdb) x/s 0x8048617 0x8048617 <_IO_stdin_used+115>: "cat /bin/wrong.txt" |
|
> 틀리면 /bin/worng.txt 파일을 출력하고 종료됩니다.
- 의사코드
|
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #define SIZE 100 int main() { char *input; char password[]="mate"; input = (char *)malloc(SIZE); printf( "Insert The Password : " ); fgets( input, SIZE, stdin ); if(strncmp( str, password, 4) == 0 ){ printf( "\nCongratulation! next password is \"break the world\".\n\n" ); exit(0); } else { system("cat /bin/wrong.txt"); } return 0; } |
|
> 완벽하게 복원할 수 없지만 같은 동작을 수행한다.
'Security > 리버싱' 카테고리의 다른 글
Level9 문제 해결 (0) | 2017.11.30 |
---|---|
Level8 문제 해결 (0) | 2017.11.30 |
Level7 문제 응용 (ASCII) (0) | 2017.11.30 |
Level7 문제 해결 (0) | 2017.11.30 |
Level6 문제 분석 -의사 코드 (0) | 2017.11.29 |