글
FTZ level18 write up

level18에 hint 에 있는 코드들이다. 코드가 너무 길어서 잘릴 것 같아서 이번에는 이렇게 가지고 왔다.
위에서부터 천천히 해석해보자.
if(count >= 100)
printf("what are you trying to do?\n");
if(check == 0xdeadbeef)
shellout();
else
{
FD_ZERO(&fds);
FD_SET(STDIN_FILENO,&fds);
if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) >= 1)
{
if(FD_ISSET(fileno(stdin),&fds))
{
read(fileno(stdin),&x,1);
count가 100이상이면 "what are you trying to do?를 출력하고
만약 check 가 0xdeadbeef가 맞으면 shellout을 실행시켜라
아니면 입력을 받고 입력값에서 1바이트를 가져와라.
*select() 다중 입출력함수
select() 함수는 fd 가 입출력을 수행할 준비가 되거나 정해진 시간이 결과할 때까지 차단된다.
자신이 생성한 데이터가 수신되었는지 또는 연결해서 주고 받던 소켓이 종료되었는지 체크하기 위해서 사용한다
예를 들어 fd_set이라는 구조체를 사용하여 소켓의 그룹을 구성해야 한다.
select 함수를 이용하려면 FD_로 시작하는 매크로 함수를 공부해야 한다.
FD는 보통 4바이트 크기의 정수로 구성되어있다.
FD_setsize? fd집합의 크기. 즉 이 그룹에 포함 가능한 소켓의 최대 개수
FD_ISSET? fd_set으로 선언된 rfds변수에 특정 fd값이 설정되어있는지 확인할 떄 사용. 예를 들어 fd값이 5인 경우 rfds변쉥 5값에 해당하는 비트가 1이 되어있는지 확인하는 작업을 수행한다.
참고 : https://blog.naver.com/tipsware/220810795410
select() 함수는 fd 가 입출력을 수행할 준비가 되거나 정해진 시간이 결과할 때까지 차단된다.
자신이 생성한 데이터가 수신되었는지 또는 연결해서 주고 받던 소켓이 종료되었는지 체크하기 위해서 사용한다
예를 들어 fd_set이라는 구조체를 사용하여 소켓의 그룹을 구성해야 한다.
select 함수를 이용하려면 FD_로 시작하는 매크로 함수를 공부해야 한다.
FD는 보통 4바이트 크기의 정수로 구성되어있다.
FD_setsize? fd집합의 크기. 즉 이 그룹에 포함 가능한 소켓의 최대 개수
FD_ISSET? fd_set으로 선언된 rfds변수에 특정 fd값이 설정되어있는지 확인할 떄 사용. 예를 들어 fd값이 5인 경우 rfds변쉥 5값에 해당하는 비트가 1이 되어있는지 확인하는 작업을 수행한다.
참고 : https://blog.naver.com/tipsware/220810795410
blog.naver.com
switch(x)
{
case '\r':
case '\n':
printf("\a");
break;
case 0x08:
count--;
printf("\b \b");
break;
default:
string[count] = x;
count++;
break;
}
그1바이트의 값이 0x08이면 count 값을 1씩 빼고
아니라면 string[count]에 값을 넣고 1증가해라
void shellout(void)
{
setreuid(3099,3099);
execl("/bin/sh","sh",NULL);
}
level19의 seturid와 실행하는 쉘
count변수가 0x08입력이 들어오면 1감소하는데
배열의 인덱스가 계속 감소하여 음수가 된다면 string의 시작주소보다 더 낮은주소에 접근하게 되어 앞의 메모리에 접근이 가능하게 된다.

<main+91>에서 deadbeef가 맞는지 검사하고 있다.
ebp-104에서 check라는 것을 알 수 있다.
밑에 더 살펴보면

<main +499 >를 통해 string에서부터 ebp까지의 거리가 100임을 알 수 있다.
그러므로 string변수에서 check 까지의 거리는 -4이다
그러니까 string버퍼에 0x08을 입력해서 count를 음수로 만들고
ebp-104에 deadbeef를 넣으면 level19의 패스워드 값을 얻을 수 있다
0x08을 4번입력해서 count를 -4로 만들어준 후에 deadbeef 넣으면 되겠다!
코드 : (python -c "print '\x08'*4 + '\xef\xbe\xad\xde'";cat) | ./attackme
level19의 패스워드 값을 얻었다!
* inc ? 피연산자에 1을 더한다.
연산 결과에 따라 ZF(Zero Flag)나 OF(Overflow Flag)가 세트될 수 있다.출처: https://p3ace.tistory.com/37 [:: 피스하모니 P3ace...]
+코드 분석하다 어려워서 그냥 다른 사람 블로그 참고했는데
https://leeggoggal.tistory.com/28
이분이랑
https://mandu-mandu.tistory.com/41?category=692689
이분 블로그가 정리가 잘 되어있는 것 같다.
+https://c0wb3ll.tistory.com/
'포너블' 카테고리의 다른 글
| FTZ level19 write up (0) | 2020.03.20 |
|---|---|
| FTZ level17 write up (0) | 2020.03.17 |
| FTZ level16 write up (0) | 2020.03.17 |
| FTZ level15 write up (0) | 2020.03.16 |
| FTZ level14 write up (0) | 2020.03.16 |