오랜만에 putty로 진입할 수 있는 문제가 나왔다. 컴파일 에러 어쩌구 하는 거 보니까 컴파일에 관한 문제인듯?
#include <stdio.h>
#include <stdlib.h>
void login(){
int passcode1;
int passcode2;
printf("enter passcode1 : ");
scanf("%d", passcode1);
fflush(stdin);
// ha! mommy told me that 32bit is vulnerable to bruteforcing :)
printf("enter passcode2 : ");
scanf("%d", passcode2);
printf("checking...\n");
if(passcode1==338150 && passcode2==13371337){
printf("Login OK!\n");
system("/bin/cat flag");
}
else{
printf("Login Failed!\n");
exit(0);
}
}
void welcome(){
char name[100];
printf("enter you name : ");
scanf("%100s", name);
printf("Welcome %s!\n", name);
}
int main(){
printf("Toddler's Secure Login System 1.0 beta.\n");
welcome();
login();
// something after login...
printf("Now I can safely trust you that you have credential :)\n");
return 0;
}
welcome함수 다음에 login함수가 오고 338150과 13371337이 동시에 일치하면 로그인이 된다.
그래서 다음과 같이 해봤는데 Segmentation fault가 나왔다. 주요 키워드는 아마도
ha! mommy told me that 32bit is vulnerable to bruteforcing :)
이거 인것 같은데.....
우선 모르는것을 한번 정리해 보면.
int fflush (FILE *fp) : 파일 스트림 버퍼를 비우는 함수, 성공시 0, 에러시 EOF ex)fflush(stdin)
scanf로 입력을 받지만 제대로 입력이 되지 않는 경우가 있음. 이 때 버퍼를 지워주기 위해서 사용.
현재는 버퍼 초기화를 표준입력으로 해주기 때문에 이부분이 치명적일 것이라고 예상함.
우선 다양한 시도를 해보았을때 passcode1 값에 숫자가 들어가면 seg flaut가 뜨는 것을 확인 할 수 있었다.
GDB조사를 하기 전에 모르는 것을 정리해보자. GDB 옵션이다.
o : 8진법 표기
x : 16진법 표기
u : 10진법 표기
t : 2진법 표기
b : 1 byte 단위 표기(byte)
h : 2 byte 단위 표기(half word)
w: 4 byte 단위 표기(word) - 난 2byte로 알고 있지만 여기선 4바이트로 쓰이나 보다....
g : 8 byte 단위 표기(giant)
i : 어셈블리 형식으로 출력
s : 문자열로 출력
ex) x/4wx $ebp : ebp를 기준으로 16진법(x)으로 4바이트 단위로(w) 4개 보여준다.
x/s : 문자열로 출력
set {타입} [주소] = [값] : p명령 대신에 set을 통해 메모리의 특정 주소에 저장하는 것이 더 일반적이다.
lea : 좌변에 우변의 주소값을 입력하는 것이다. (좌변은 레지스터만 올수있다)
mov : 좌변에 우변의 값을 입력하는 것이다.
sub : 좌변의 값을 우변의 값과 -(마이너스)연산하여 그 결과를 좌변에 저장. 따라서 좌번에는 reg, mem되어야 함
add : 좌변의 값을 우변의 값과 +(플러스) 연산하여 그 결과를 좌변에 저장. 따라서 좌변에는 reg, mem되어야 함
PTR : 피연산자의 크기를 재설정함 ex) WORD PRT value - value의 크기를 WORD의 크기로 재설정함
또 다시 write-up을 참고한다.
문제1. passcode 부분이 선언만 해주고 초기화를 해주지 않았음.
문제2. scanf()함수로 각 passcode를 받을 때 & 주소 연산자를 붙이지 않았다.
따라서 passcode를 주소로 한 곳에 저장. 주소 자리에 입력이 그대로 들어가고, 초기화를 해주지 않았기 때문에 쓰레기값이 그대로 들어있는 것이다.
해당 부분은 welcome()함수의 char name[100]을 저장하는 부분이다. [ebp-0x70]에 입력값을 저장한다.
그리고 cmp(비교문) 부분(ebp-0x10)에 password1이 저장된 것이다.
ebp-0x70 ~ ebp-0x10 = 0x60 이 차이나므로,
96byte가 차이나게 되는것이다. char name[100]이므로 4byte정도 passcode1에 간섭할 수 있을 것이다.
하지만 fflush()함수로 인해서 버퍼가 표준입력(stdin)으로 초기화 되므로 stdin에 system()를 입력해줘야 한다.
PLT (Procedure Linkage Table) : 외부 프로시저를 연결해주는 테이블. PLT를 통해 다른 라이브러리에 있는 프로시저를 호출해 사용할 수 있다. GOT (Global Offset Table) : PLT가 참조하는 테이블. 프로시저들의 주소가 들어있다. PLT와 GOT에 대해서는 대부분 이렇게 알고 있을 것입니다. ” 함수를 호출하면(PLT를 호출하면) GOT로 점프하는데 GOT에는 함수의 실제 주소가 쓰여있다. 첫 번째 호출이라면 GOT는 함수의 주소를 가지고 있지 않고 ‘어떤 과정’을 거쳐 주소를 알아낸다. 두 번째 호출 부터는 첫 번째 호출 때 알아낸 주소로 바로 점프한다. “ |
fflush()함수가 GOT로 이동할 때 실제 주소가 적혀있다. 따라서 system()의 got를 4byte에 넣어주면 된다.
https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/ 자세한건 여기 나와있다.(햐... 어떻게 이런걸 설계하고 구현하지.... 배울게 많다. 나중에 더 공부해야된다.)
0x08048593 <+47>: call 0x8048430 <fflush@plt>
0x8048430 <fflush@plt>: jmp DWORD PTR ds:0x804a004 (또 뭔가 모르는게 한껏 나오기 시작한....)
0x804a004 <fflush@got.plt>: test BYTE PTR ss: [eax+ecx*1], al
모르는 것을 또 정리하고 가자.
jmp : 특정 지역으로 이동[점프]를 하게 해줌. 가르키는 값을 NULL과 비교한다. 아니면 갯수를 세고 NULL을 만나면 갯수를 리턴한다.
* CS : code segment, 명령어들 있는 곳,
DS : data segment, 변수들 저장하는 곳,
SS : stack segment, 함수들 있는 곳,
ES : extra segment, 프로그래머가 정해서 쓰는 곳,
FS,GS : 80386(32bit) CPU 때 생겨난 용처가 정해지지 않는 영역.
TEST : 좌변과 우변을 AND 시킴. ZF(zero flag)에만 영향을 미치고, 결과값은 저장하지 않음.(나중에 flag정리 필요)
한마디로 fflush 함수로 이동하여 ds(변수들이 저장되는 곳)으로 이동 후, got값을 TEST해본 것으로 추정된다.
Q. 왜 system()함수의 시작부분이 0x080485e3지?
인자 전달 후 , call이 기본 순서인거 같다.
그래서 0x080485e3 부분으로 진행한다. scanf()가 정수형으로 받기 때문에 10진수로 바꿔주면 134514147이다.
표준입력으로 system()함수가 진입하기 때문에 밑에 입력 가능하게 변한다.
Sorry mom.. I got confused about scanf usage :(
지렸다.... 어떻게 이런 생각들을 하고 살 수 있는 걸까. 이번 문제는 2일정도 걸린만큼 많이 배운거 같다.
dddddds ddddddd
'pwnable' 카테고리의 다른 글
[Toddler's Bottle] bof (0) | 2024.05.11 |
---|---|
[Toddler's Bottle] flag (0) | 2024.05.11 |
[Toddler's Bottle] random (0) | 2024.05.11 |
[Toddler's Bottle] mistake (0) | 2024.05.11 |
[Toddler's Bottle] shellshock (0) | 2024.05.11 |