본문 바로가기

워게임/protostar

net0

(gdb) disas main 

Dump of assembler code for function main:

0x08049844 <main+0>: push   ebp

0x08049845 <main+1>: mov    ebp,esp

0x08049847 <main+3>: and    esp,0xfffffff0

0x0804984a <main+6>: sub    esp,0x20

0x0804984d <main+9>: mov    DWORD PTR [esp+0x8],0x3e7

0x08049855 <main+17>: mov    DWORD PTR [esp+0x4],0x3e7

0x0804985d <main+25>: mov    DWORD PTR [esp],0x8049cdc

0x08049864 <main+32>: call   0x8048eb8 <background_process>


0x08049869 <main+37>: mov    DWORD PTR [esp],0xbb7

0x08049870 <main+44>: call   0x8049355 <serve_forever>


0x08049875 <main+49>: mov    DWORD PTR [esp+0x18],eax

0x08049879 <main+53>: mov    eax,DWORD PTR [esp+0x18]

0x0804987d <main+57>: mov    DWORD PTR [esp],eax

0x08049880 <main+60>: call   0x8049435 <set_io>


0x08049885 <main+65>: mov    DWORD PTR [esp],0x0

0x0804988c <main+72>: call   0x8048c38 <time@plt>

0x08049891 <main+77>: mov    DWORD PTR [esp],eax

0x08049894 <main+80>: call   0x8048bf8 <srandom@plt>


0x08049899 <main+85>: call   0x80497ba <run>


0x0804989e <main+90>: leave  

0x0804989f <main+91>: ret    


음 크게봤을때 main소스 구조는..


int main(){

background_process("net0", 0x3e7, 0x3e7); // 0x3e7 = 999

//각각 name, uid, gid

result = serve_forever(0xbb7); //0xbb7 = 2999

set_io(result);

srandom(time(NULL));

}


이렇게되나보다.


핵심은 background_process랑 serve_forever인데 어차피 나중에 또 나올것 같으니 분석해보자


//argv1 = esp+0x8 "net0"

//argv2 = esp+0x4 0x3e7

//argv3 = esp 0x3e7


(gdb) disas background_process 

Dump of assembler code for function background_process:

0x08048eb8 <background_process+0>: push   ebp

0x08048eb9 <background_process+1>: mov    ebp,esp

0x08048ebb <background_process+3>: push   ebx

0x08048ebc <background_process+4>: sub    esp,0x224

0x08048ec2 <background_process+10>: mov    eax,DWORD PTR [ebp+0x8]

0x08048ec5 <background_process+13>: mov    DWORD PTR [esp],eax

0x08048ec8 <background_process+16>: call   0x8048e0d <validate_name>


//validate_name(argv1)

이 함수를 한번 보장


(gdb) disas validate_name 

Dump of assembler code for function validate_name:

0x08048e0d <validate_name+0>: push   ebp

0x08048e0e <validate_name+1>: mov    ebp,esp

0x08048e10 <validate_name+3>: sub    esp,0x28

0x08048e13 <validate_name+6>: mov    DWORD PTR [ebp-0xc],0x0 //변수 할당 후 초기화

0x08048e1a <validate_name+13>: jmp    0x8048ea5 <validate_name+152>

0x08048e1f <validate_name+18>: mov    eax,DWORD PTR [ebp-0xc] //0

0x08048e22 <validate_name+21>: add    eax,DWORD PTR [ebp+0x8] //argv1

0x08048e25 <validate_name+24>: movzx  eax,BYTE PTR [eax] //첫 바이트 "n"

0x08048e28 <validate_name+27>: cmp    al,0x60

0x08048e2a <validate_name+29>: jle    0x8048e39 <validate_name+44>


// al <= 0x60 조건이면 +44로 점프

(일단 n은 0x6e니까 점프 안함)


0x08048e2c <validate_name+31>: mov    eax,DWORD PTR [ebp-0xc]

0x08048e2f <validate_name+34>: add    eax,DWORD PTR [ebp+0x8]

0x08048e32 <validate_name+37>: movzx  eax,BYTE PTR [eax]

0x08048e35 <validate_name+40>: cmp    al,0x7a

0x08048e37 <validate_name+42>: jle    0x8048ea1 <validate_name+148>


//if(al <= 0x7a){ jmp +148 }

//0x6e니까 여기서 점프될듯


0x08048e39 <validate_name+44>: mov    eax,DWORD PTR [ebp-0xc]

0x08048e3c <validate_name+47>: add    eax,DWORD PTR [ebp+0x8]

0x08048e3f <validate_name+50>: movzx  eax,BYTE PTR [eax]

0x08048e42 <validate_name+53>: cmp    al,0x40

0x08048e44 <validate_name+55>: jle    0x8048e53 <validate_name+70>


//if(al <= 0x40){ jmp +70 }


0x08048e46 <validate_name+57>: mov    eax,DWORD PTR [ebp-0xc]

0x08048e49 <validate_name+60>: add    eax,DWORD PTR [ebp+0x8]

0x08048e4c <validate_name+63>: movzx  eax,BYTE PTR [eax]

0x08048e4f <validate_name+66>: cmp    al,0x5a

0x08048e51 <validate_name+68>: jle    0x8048ea1 <validate_name+148>


//if(al <= 0x5a){ jmp +148 }


0x08048e53 <validate_name+70>: mov    eax,DWORD PTR [ebp-0xc]

0x08048e56 <validate_name+73>: add    eax,DWORD PTR [ebp+0x8]

0x08048e59 <validate_name+76>: movzx  eax,BYTE PTR [eax]

0x08048e5c <validate_name+79>: cmp    al,0x2f

0x08048e5e <validate_name+81>: jle    0x8048e6d <validate_name+96>


//if(al <= 0x2f){ jmp +96 }


0x08048e60 <validate_name+83>: mov    eax,DWORD PTR [ebp-0xc]

0x08048e63 <validate_name+86>: add    eax,DWORD PTR [ebp+0x8]

0x08048e66 <validate_name+89>: movzx  eax,BYTE PTR [eax]

0x08048e69 <validate_name+92>: cmp    al,0x39

0x08048e6b <validate_name+94>: jle    0x8048ea1 <validate_name+148>


//if(al <= 0x39){ jmp +148 }


0x08048e6d <validate_name+96>: mov    eax,ds:0x804aea0 // stderr

0x08048e72 <validate_name+101>: mov    edx,eax

0x08048e74 <validate_name+103>: mov    eax,0x8049960 // background_process: incorrect name\n

0x08048e79 <validate_name+108>: mov    DWORD PTR [esp+0xc],edx

0x08048e7d <validate_name+112>: mov    DWORD PTR [esp+0x8],0x23

0x08048e85 <validate_name+120>: mov    DWORD PTR [esp+0x4],0x1

0x08048e8d <validate_name+128>: mov    DWORD PTR [esp],eax

0x08048e90 <validate_name+131>: call   0x8048c18 <fwrite@plt>


//fwrite("background_process: incorrect name\n", 0x1, 0x23, stderr)


0x08048e95 <validate_name+136>: mov    DWORD PTR [esp],0x1

0x08048e9c <validate_name+143>: call   0x8048cf8 <exit@plt>


// exit(1)


0x08048ea1 <validate_name+148>: add    DWORD PTR [ebp-0xc],0x1

//"net0"이면 여기로 점프함. 변수를 1로 설정함.


0x08048ea5 <validate_name+152>: mov    eax,DWORD PTR [ebp-0xc]

//초기에 점프하는 곳, 변수 값을 eax에 넣어줌.


0x08048ea8 <validate_name+155>: add    eax,DWORD PTR [ebp+0x8] // argv1

0x08048eab <validate_name+158>: movzx  eax,BYTE PTR [eax]

//eax 초기화하고 argv1 생짜 값을 1바이트 넣음. 여기선 net0의 'n'이 들어가겠지.


0x08048eae <validate_name+161>: test   al,al

0x08048eb0 <validate_name+163>: jne    0x8048e1f <validate_name+18>

0x08048eb6 <validate_name+169>: leave  

0x08048eb7 <validate_name+170>: ret  


분석해봐도 별거없다. 그냥 이름 잘못된건지 체크하는거임.


0x08048ecd <background_process+21>: mov    BYTE PTR [ebp-0xd],0x0 //이것도 변수같은데 무튼 0

0x08048ed1 <background_process+25>: mov    eax,0x8049984 // "/opt/protostar/run/%s.pid"

0x08048ed6 <background_process+30>: mov    edx,DWORD PTR [ebp+0x8] // "net0"

0x08048ed9 <background_process+33>: mov    DWORD PTR [esp+0xc],edx

0x08048edd <background_process+37>: mov    DWORD PTR [esp+0x8],eax

0x08048ee1 <background_process+41>: mov    DWORD PTR [esp+0x4],0x1ff

0x08048ee9 <background_process+49>: lea    eax,[ebp-0x20c]

0x08048eef <background_process+55>: mov    DWORD PTR [esp],eax

0x08048ef2 <background_process+58>: call   0x8048cd8 <snprintf@plt>

//snprintf 함수는 가령 snprintf(buffer, 100, "a is %d", 10); 식으로 사용하게되면

//a is 10이라는 문자열이 buffer에 100byte제한으로 박힘과 동시에 출력됨. 정확히는 출력먼저하고 저장할듯

//암튼 여기선 snprintf(0xbffff54c(buffer), 0x1ff, "/opt/protostar/run/%s.pid", "net0")

//0xbffff54c(ebp-0x20c)에는 /opt/protostar/run/net0.pid가 박힘


(gdb) x/10s 0xbffff54c

0xbffff54c: "/opt/protostar/run/net0.pid"


0x08048ef7 <background_process+63>: mov    DWORD PTR [esp+0x8],0x1c0

0x08048eff <background_process+71>: mov    DWORD PTR [esp+0x4],0x242

0x08048f07 <background_process+79>: lea    eax,[ebp-0x20c]

0x08048f0d <background_process+85>: mov    DWORD PTR [esp],eax

0x08048f10 <background_process+88>: call   0x8048a58 <open@plt>


//open(buffer, 0x242, 0x1c0);


0x08048f15 <background_process+93>: mov    DWORD PTR [ebp-0xc],eax

0x08048f18 <background_process+96>: cmp    DWORD PTR [ebp-0xc],0xffffffff

0x08048f1c <background_process+100>: jne    0x8048f5e <background_process+166>

0x08048f1e <background_process+102>: call   0x8048a38 <__errno_location@plt>


//open 함수 실패 시 -1 리턴하니까 실패했나안했나 비교함. 성공했으면 +166으로 ㄱㄱ

//실패했으면 에러번호 리턴하는 함수 호출


0x08048f23 <background_process+107>: mov    eax,DWORD PTR [eax]

0x08048f25 <background_process+109>: mov    DWORD PTR [esp],eax

0x08048f28 <background_process+112>: call   0x8048a88 <strerror@plt>


//에러 번호에 맞는 문자열 가져옴. 문자열포인터 리턴


0x08048f2d <background_process+117>: mov    ecx,0x80499a0

//background_process: Unable to open %s, %s\n


0x08048f32 <background_process+122>: mov    edx,DWORD PTR ds:0x804aea0 //stderr

0x08048f38 <background_process+128>: mov    DWORD PTR [esp+0xc],eax //strerror ptr

0x08048f3c <background_process+132>: lea    eax,[ebp-0x20c] //buffer

0x08048f42 <background_process+138>: mov    DWORD PTR [esp+0x8],eax

0x08048f46 <background_process+142>: mov    DWORD PTR [esp+0x4],ecx

0x08048f4a <background_process+146>: mov    DWORD PTR [esp],edx

0x08048f4d <background_process+149>: call   0x8048c28 <fprintf@plt>


//fprintf(stderr, "background_process: Unable to open %s, %s\n", buffer, strerror ptr);


0x08048f52 <background_process+154>: mov    DWORD PTR [esp],0x1

0x08048f59 <background_process+161>: call   0x8048cf8 <exit@plt>


//exit(1)


그냥 실행하니까 퍼미션없어서 실행안됨 ㅠ

background_process: Unable to open /opt/protostar/run/net0.pid, Permission denied

75 in net0/../common/common.c



//▽여기서부터 정상 호출되었을때 프로세스

0x08048f5e <background_process+166>: mov    eax,DWORD PTR [ebp+0x10]

//ebp-0xc가 uid고 0x10이 gid


0x08048f61 <background_process+169>: mov    DWORD PTR [ebp-0x210],eax

0x08048f67 <background_process+175>: lea    eax,[ebp-0x210] //eax = &gid

0x08048f6d <background_process+181>: mov    DWORD PTR [esp+0x4],eax

0x08048f71 <background_process+185>: mov    DWORD PTR [esp],0x1

0x08048f78 <background_process+192>: call   0x8048a68 <setgroups@plt>


//setgroup(0x1, gid)


0x08048f7d <background_process+197>: cmp    eax,0xffffffff

0x08048f80 <background_process+200>: jne    0x8048fb8 <background_process+256>


0x08048f82 <background_process+202>: call   0x8048a38 <__errno_location@plt>

0x08048f87 <background_process+207>: mov    eax,DWORD PTR [eax]

0x08048f89 <background_process+209>: mov    DWORD PTR [esp],eax

0x08048f8c <background_process+212>: call   0x8048a88 <strerror@plt>

0x08048f91 <background_process+217>: mov    ecx,0x80499cc

0x08048f96 <background_process+222>: mov    edx,DWORD PTR ds:0x804aea0

0x08048f9c <background_process+228>: mov    DWORD PTR [esp+0x8],eax

0x08048fa0 <background_process+232>: mov    DWORD PTR [esp+0x4],ecx

0x08048fa4 <background_process+236>: mov    DWORD PTR [esp],edx

0x08048fa7 <background_process+239>: call   0x8048c28 <fprintf@plt>

0x08048fac <background_process+244>: mov    DWORD PTR [esp],0xb

0x08048fb3 <background_process+251>: call   0x8048cf8 <exit@plt>


//아까랑 같은 과정. 실패하면 EPERM을 뱉어낼듯.


0x08048fb8 <background_process+256>: mov    eax,DWORD PTR [ebp+0x10]

0x08048fbb <background_process+259>: mov    DWORD PTR [esp+0x8],eax

0x08048fbf <background_process+263>: mov    eax,DWORD PTR [ebp+0x10]

0x08048fc2 <background_process+266>: mov    DWORD PTR [esp+0x4],eax

0x08048fc6 <background_process+270>: mov    eax,DWORD PTR [ebp+0x10]

0x08048fc9 <background_process+273>: mov    DWORD PTR [esp],eax

0x08048fcc <background_process+276>: call   0x8048b68 <setresgid@plt>


//setresgid는 그룹 권한을 재설정하는 함수임.

//int setresgid(gid_t rgid, gid_t egid, gid_t sgid);

//setresgid(gid, gid, gid);


0x08048fd1 <background_process+281>: cmp    eax,0xffffffff

0x08048fd4 <background_process+284>: jne    0x804900c <background_process+340>


//이 역시 실패시 -1 리턴


0x08048fd6 <background_process+286>: call   0x8048a38 <__errno_location@plt>

0x08048fdb <background_process+291>: mov    eax,DWORD PTR [eax]

0x08048fdd <background_process+293>: mov    DWORD PTR [esp],eax

0x08048fe0 <background_process+296>: call   0x8048a88 <strerror@plt>

0x08048fe5 <background_process+301>: mov    ecx,0x80499fc

0x08048fea <background_process+306>: mov    edx,DWORD PTR ds:0x804aea0

0x08048ff0 <background_process+312>: mov    DWORD PTR [esp+0x8],eax

0x08048ff4 <background_process+316>: mov    DWORD PTR [esp+0x4],ecx

0x08048ff8 <background_process+320>: mov    DWORD PTR [esp],edx

0x08048ffb <background_process+323>: call   0x8048c28 <fprintf@plt>

0x08049000 <background_process+328>: mov    DWORD PTR [esp],0xc

0x08049007 <background_process+335>: call   0x8048cf8 <exit@plt>


0x0804900c <background_process+340>: mov    eax,DWORD PTR [ebp+0xc]

0x0804900f <background_process+343>: mov    DWORD PTR [esp+0x8],eax

0x08049013 <background_process+347>: mov    eax,DWORD PTR [ebp+0xc]

0x08049016 <background_process+350>: mov    DWORD PTR [esp+0x4],eax

0x0804901a <background_process+354>: mov    eax,DWORD PTR [ebp+0xc]

0x0804901d <background_process+357>: mov    DWORD PTR [esp],eax

0x08049020 <background_process+360>: call   0x8048b58 <setresuid@plt>


//setresgid처럼 uid도 set해주는 함수이다.

//int setresuid(uid_t ruid, uid_t euid, uid_t suid);

//setresuid(uid, uid, uid);


0x08049025 <background_process+365>: cmp    eax,0xffffffff

0x08049028 <background_process+368>: jne    0x8049060 <background_process+424>


0x0804902a <background_process+370>: call   0x8048a38 <__errno_location@plt>

0x0804902f <background_process+375>: mov    eax,DWORD PTR [eax]

0x08049031 <background_process+377>: mov    DWORD PTR [esp],eax

0x08049034 <background_process+380>: call   0x8048a88 <strerror@plt>

0x08049039 <background_process+385>: mov    ecx,0x8049a2c

0x0804903e <background_process+390>: mov    edx,DWORD PTR ds:0x804aea0

0x08049044 <background_process+396>: mov    DWORD PTR [esp+0x8],eax

0x08049048 <background_process+400>: mov    DWORD PTR [esp+0x4],ecx

0x0804904c <background_process+404>: mov    DWORD PTR [esp],edx

0x0804904f <background_process+407>: call   0x8048c28 <fprintf@plt>

0x08049054 <background_process+412>: mov    DWORD PTR [esp],0xd

0x0804905b <background_process+419>: call   0x8048cf8 <exit@plt>


0x08049060 <background_process+424>: mov    DWORD PTR [esp+0x4],0x0

0x08049068 <background_process+432>: mov    DWORD PTR [esp],0x0

0x0804906f <background_process+439>: call   0x8048a98 <daemon@plt>


//int daemon(int nochdir,int noclose);

//nochdir이 0인 경우 작업 디렉토리가 루트(/)디렉토리로 변경됩니다.

//noclose가 0인 경우 stdin, stdout, stderr이 모두 dev/null을 가리키게 됩니다.

//http://man7.org/linux/man-pages/man3/daemon.3.html

//daemon(0,0);


0x08049074 <background_process+444>: cmp    eax,0xffffffff

0x08049077 <background_process+447>: jne    0x80490af <background_process+503>


//데몬만들기 성공하면 점프


0x08049079 <background_process+449>: call   0x8048a38 <__errno_location@plt>

0x0804907e <background_process+454>: mov    eax,DWORD PTR [eax]

0x08049080 <background_process+456>: mov    DWORD PTR [esp],eax

0x08049083 <background_process+459>: call   0x8048a88 <strerror@plt>

0x08049088 <background_process+464>: mov    ecx,0x8049a5c

0x0804908d <background_process+469>: mov    edx,DWORD PTR ds:0x804aea0

0x08049093 <background_process+475>: mov    DWORD PTR [esp+0x8],eax

0x08049097 <background_process+479>: mov    DWORD PTR [esp+0x4],ecx

0x0804909b <background_process+483>: mov    DWORD PTR [esp],edx

0x0804909e <background_process+486>: call   0x8048c28 <fprintf@plt>

0x080490a3 <background_process+491>: mov    DWORD PTR [esp],0x2

0x080490aa <background_process+498>: call   0x8048cf8 <exit@plt>


0x080490af <background_process+503>: call   0x8048a78 <getpid@plt>

//현재 프로세스 pid 리턴


0x080490b4 <background_process+508>: mov    edx,0x8049a88 //%d

0x080490b9 <background_process+513>: mov    DWORD PTR [esp+0xc],eax //pid

0x080490bd <background_process+517>: mov    DWORD PTR [esp+0x8],edx //%d

0x080490c1 <background_process+521>: mov    DWORD PTR [esp+0x4],0x1ff //size

0x080490c9 <background_process+529>: lea    eax,[ebp-0x20c] //buffer

0x080490cf <background_process+535>: mov    DWORD PTR [esp],eax

0x080490d2 <background_process+538>: call   0x8048cd8 <snprintf@plt>


//snprintf(buffer, 0x1ff, "%d", pid);


0x080490d7 <background_process+543>: lea    eax,[ebp-0x20c]

0x080490dd <background_process+549>: mov    DWORD PTR [esp],eax

0x080490e0 <background_process+552>: call   0x8048ba8 <strlen@plt>


//strlen(buffer);


0x080490e5 <background_process+557>: mov    DWORD PTR [esp+0x8],eax //buffer length

0x080490e9 <background_process+561>: lea    eax,[ebp-0x20c]

0x080490ef <background_process+567>: mov    DWORD PTR [esp+0x4],eax //buffer

0x080490f3 <background_process+571>: mov    eax,DWORD PTR [ebp-0xc]

0x080490f6 <background_process+574>: mov    DWORD PTR [esp],eax //fd

0x080490f9 <background_process+577>: call   0x8048ae8 <write@plt>


//write(fd, buffer, strlen(buffer));


0x080490fe <background_process+582>: mov    ebx,eax

0x08049100 <background_process+584>: lea    eax,[ebp-0x20c]

0x08049106 <background_process+590>: mov    DWORD PTR [esp],eax

0x08049109 <background_process+593>: call   0x8048ba8 <strlen@plt>


//strlen(buffer);


0x0804910e <background_process+598>: cmp    ebx,eax


//아까 그 strlen값이랑 방금 한 strlen이랑 같은지 체크.


0x08049110 <background_process+600>: je     0x8049148 <background_process+656>

0x08049112 <background_process+602>: call   0x8048a38 <__errno_location@plt>


//문제없으면 656으로


0x08049117 <background_process+607>: mov    eax,DWORD PTR [eax]

0x08049119 <background_process+609>: mov    DWORD PTR [esp],eax

0x0804911c <background_process+612>: call   0x8048a88 <strerror@plt>

0x08049121 <background_process+617>: mov    ecx,0x8049a8c

0x08049126 <background_process+622>: mov    edx,DWORD PTR ds:0x804aea0

0x0804912c <background_process+628>: mov    DWORD PTR [esp+0x8],eax

0x08049130 <background_process+632>: mov    DWORD PTR [esp+0x4],ecx

0x08049134 <background_process+636>: mov    DWORD PTR [esp],edx

0x08049137 <background_process+639>: call   0x8048c28 <fprintf@plt>

0x0804913c <background_process+644>: mov    DWORD PTR [esp],0x3

0x08049143 <background_process+651>: call   0x8048cf8 <exit@plt>


0x08049148 <background_process+656>: mov    eax,DWORD PTR [ebp-0xc]

0x0804914b <background_process+659>: mov    DWORD PTR [esp],eax

0x0804914e <background_process+662>: call   0x8048c08 <close@plt>


//close(fd);


0x08049153 <background_process+667>: cmp    eax,0xffffffff

0x08049156 <background_process+670>: jne    0x804918e <background_process+726>


//문제없으면 점프


0x08049158 <background_process+672>: call   0x8048a38 <__errno_location@plt>

0x0804915d <background_process+677>: mov    eax,DWORD PTR [eax]

0x0804915f <background_process+679>: mov    DWORD PTR [esp],eax

0x08049162 <background_process+682>: call   0x8048a88 <strerror@plt>

0x08049167 <background_process+687>: mov    ecx,0x8049abc

0x0804916c <background_process+692>: mov    edx,DWORD PTR ds:0x804aea0

0x08049172 <background_process+698>: mov    DWORD PTR [esp+0x8],eax

0x08049176 <background_process+702>: mov    DWORD PTR [esp+0x4],ecx

0x0804917a <background_process+706>: mov    DWORD PTR [esp],edx

0x0804917d <background_process+709>: call   0x8048c28 <fprintf@plt>

0x08049182 <background_process+714>: mov    DWORD PTR [esp],0x4

0x08049189 <background_process+721>: call   0x8048cf8 <exit@plt>


0x0804918e <background_process+726>: add    esp,0x224

0x08049194 <background_process+732>: pop    ebx

0x08049195 <background_process+733>: pop    ebp

0x08049196 <background_process+734>: ret    



그냥 /opt/protostar/run/net0.pid 불러와서 데몬 돌리는거임.


이제 serve_forever를 보자.


(gdb) disas serve_forever 

Dump of assembler code for function serve_forever:

0x08049355 <serve_forever+0>: push   ebp

0x08049356 <serve_forever+1>: mov    ebp,esp

0x08049358 <serve_forever+3>: sub    esp,0x38

0x0804935b <serve_forever+6>: mov    eax,DWORD PTR [ebp+0x8]

0x0804935e <serve_forever+9>: mov    DWORD PTR [esp],eax

0x08049361 <serve_forever+12>: call   0x8049197 <get_tcp_server_socket>


//return socket descriptor


0x08049366 <serve_forever+17>: mov    DWORD PTR [ebp-0x10],eax //socket desc.

0x08049369 <serve_forever+20>: mov    DWORD PTR [ebp-0x24],0x10 //변수에 0x10할당인듯

0x08049370 <serve_forever+27>: lea    edx,[ebp-0x24] //edx = &(0x10)

0x08049373 <serve_forever+30>: lea    ecx,[ebp-0x20]

0x08049376 <serve_forever+33>: mov    eax,0x0

0x0804937b <serve_forever+38>: mov    eax,ecx

0x0804937d <serve_forever+40>: mov    DWORD PTR [esp+0x8],edx //addrlen

0x08049381 <serve_forever+44>: mov    DWORD PTR [esp+0x4],eax //addr

0x08049385 <serve_forever+48>: mov    eax,DWORD PTR [ebp-0x10]

0x08049388 <serve_forever+51>: mov    DWORD PTR [esp],eax //s

0x0804938b <serve_forever+54>: call   0x8048b78 <accept@plt>


//int accept(int s, struct sockaddr *addr, socklen_t *addrlen);


0x08049390 <serve_forever+59>: mov    DWORD PTR [ebp-0xc],eax

0x08049393 <serve_forever+62>: cmp    DWORD PTR [ebp-0xc],0xffffffff

0x08049397 <serve_forever+66>: jne    0x80493cf <serve_forever+122>


0x08049399 <serve_forever+68>: call   0x8048a38 <__errno_location@plt>

0x0804939e <serve_forever+73>: mov    eax,DWORD PTR [eax]

0x080493a0 <serve_forever+75>: mov    DWORD PTR [esp],eax

0x080493a3 <serve_forever+78>: call   0x8048a88 <strerror@plt>

0x080493a8 <serve_forever+83>: mov    ecx,0x8049b8c

0x080493ad <serve_forever+88>: mov    edx,DWORD PTR ds:0x804aea0

0x080493b3 <serve_forever+94>: mov    DWORD PTR [esp+0x8],eax

0x080493b7 <serve_forever+98>: mov    DWORD PTR [esp+0x4],ecx

0x080493bb <serve_forever+102>: mov    DWORD PTR [esp],edx

0x080493be <serve_forever+105>: call   0x8048c28 <fprintf@plt>

0x080493c3 <serve_forever+110>: mov    DWORD PTR [esp],0x8

0x080493ca <serve_forever+117>: call   0x8048cf8 <exit@plt>


0x080493cf <serve_forever+122>: call   0x8048c88 <fork@plt>

//새로운 자식 프로세스 생성


0x080493d4 <serve_forever+127>: cmp    eax,0xffffffff

0x080493d7 <serve_forever+130>: je     0x80493df <serve_forever+138>

0x080493d9 <serve_forever+132>: test   eax,eax

0x080493db <serve_forever+134>: je     0x8049415 <serve_forever+192>

0x080493dd <serve_forever+136>: jmp    0x8049425 <serve_forever+208>


0x080493df <serve_forever+138>: call   0x8048a38 <__errno_location@plt>

0x080493e4 <serve_forever+143>: mov    eax,DWORD PTR [eax]

0x080493e6 <serve_forever+145>: mov    DWORD PTR [esp],eax

0x080493e9 <serve_forever+148>: call   0x8048a88 <strerror@plt>

0x080493ee <serve_forever+153>: mov    ecx,0x8049bb4

0x080493f3 <serve_forever+158>: mov    edx,DWORD PTR ds:0x804aea0

0x080493f9 <serve_forever+164>: mov    DWORD PTR [esp+0x8],eax

0x080493fd <serve_forever+168>: mov    DWORD PTR [esp+0x4],ecx

0x08049401 <serve_forever+172>: mov    DWORD PTR [esp],edx

0x08049404 <serve_forever+175>: call   0x8048c28 <fprintf@plt>

0x08049409 <serve_forever+180>: mov    DWORD PTR [esp],0x9

0x08049410 <serve_forever+187>: call   0x8048cf8 <exit@plt>


0x08049415 <serve_forever+192>: mov    eax,DWORD PTR [ebp-0x10]

0x08049418 <serve_forever+195>: mov    DWORD PTR [esp],eax

0x0804941b <serve_forever+198>: call   0x8048c08 <close@plt>


0x08049420 <serve_forever+203>: mov    eax,DWORD PTR [ebp-0xc]

0x08049423 <serve_forever+206>: leave  

0x08049424 <serve_forever+207>: ret    


0x08049425 <serve_forever+208>: mov    eax,DWORD PTR [ebp-0xc]

0x08049428 <serve_forever+211>: mov    DWORD PTR [esp],eax

0x0804942b <serve_forever+214>: call   0x8048c08 <close@plt>


0x08049430 <serve_forever+219>: jmp    0x8049369 <serve_forever+20>



이제 run함수


(gdb) disas run 

Dump of assembler code for function run:

0x080497ba <run+0>: push   ebp

0x080497bb <run+1>: mov    ebp,esp

0x080497bd <run+3>: sub    esp,0x28

0x080497c0 <run+6>: call   0x8048ab8 <random@plt>


0x080497c5 <run+11>: mov    DWORD PTR [ebp-0xc],eax //랜덤값이 ebp-0xc에 박힘

0x080497c8 <run+14>: mov    eax,0x8049c74


(gdb) x/s 0x8049c74

0x8049c74: "Please send '%d' as a little endian 32bit int\n"


0x080497cd <run+19>: mov    edx,DWORD PTR [ebp-0xc]

0x080497d0 <run+22>: mov    DWORD PTR [esp+0x4],edx

0x080497d4 <run+26>: mov    DWORD PTR [esp],eax

0x080497d7 <run+29>: call   0x8048bc8 <printf@plt>


머 저런식으로 랜덤값 출력


0x080497dc <run+34>: mov    eax,ds:0x804aea8

0x080497e1 <run+39>: mov    DWORD PTR [esp+0xc],eax //버퍼인듯

0x080497e5 <run+43>: mov    DWORD PTR [esp+0x8],0x1

0x080497ed <run+51>: mov    DWORD PTR [esp+0x4],0x4

0x080497f5 <run+59>: lea    eax,[ebp-0x10]

0x080497f8 <run+62>: mov    DWORD PTR [esp],eax

0x080497fb <run+65>: call   0x8048cc8 <fread@plt>


//버퍼에서 유저인풋 읽음


0x08049800 <run+70>: test   eax,eax

0x08049802 <run+72>: jne    0x8049818 <run+94>

0x08049804 <run+74>: mov    DWORD PTR [esp+0x4],0x8049ca3

0x0804980c <run+82>: mov    DWORD PTR [esp],0x1

0x08049813 <run+89>: call   0x8048be8 <errx@plt>


(gdb) x/s 0x8049ca3

0x8049ca3: ":(\n"


0x08049818 <run+94>: mov    eax,DWORD PTR [ebp-0x10]

0x0804981b <run+97>: cmp    eax,DWORD PTR [ebp-0xc]

0x0804981e <run+100>: jne    0x804982e <run+116>

0x08049820 <run+102>: mov    DWORD PTR [esp],0x8049ca7

0x08049827 <run+109>: call   0x8048c78 <puts@plt>


걍 그 랜덤값이랑 비교해서 버퍼에씌인값이랑 일치하면 이거띄움

(gdb) x/s 0x8049ca7

0x8049ca7: "Thank you sir/madam"


0x0804982c <run+114>: jmp    0x8049842 <run+136>

0x0804982e <run+116>: mov    edx,DWORD PTR [ebp-0x10]

0x08049831 <run+119>: mov    eax,0x8049cbc

0x08049836 <run+124>: mov    DWORD PTR [esp+0x4],edx

0x0804983a <run+128>: mov    DWORD PTR [esp],eax

0x0804983d <run+131>: call   0x8048bc8 <printf@plt>


(gdb) x/s 0x8049cbc

0x8049cbc: "I'm sorry, you sent %d instead\n"

니가입력한건 이거임 틀렸어 출력


0x08049842 <run+136>: leave  

0x08049843 <run+137>: ret    

End of assembler dump.



그냥 시간나서 서브함수들 전부 분석해봤는데 정말 별거없다


외부에서 2999포트로 접근해보면 숫자를 던져주면서 리틀엔디언 32비트 int를 던져달라고한다.


근데 이 값이 계속 바뀐다.


파이썬으로 간단하게 해치우자


import socket, struct


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect(('192.168.40.141', 2999))

data = s.recv(1024)

fp = data.find("\'")+1

data = data[fp:fp+data[fp:].find("\'")]

s.send(struct.pack("<I",int(data)))

print s.recv(1024)

s.close()


C:\Users\user>E:\pwnable\protostar\net0.py

Thank you sir/madam



'워게임 > protostar' 카테고리의 다른 글

net2  (0) 2015.11.04
net1  (0) 2015.11.04
format4  (0) 2015.11.03
format3  (0) 2015.11.03
format2  (0) 2015.11.03