Layer7 동아리 과제 28

포너블 마지막 과제

나는_gosu_다 apk 디컴파일 쳐보니까 jadx로 깔 수 있다고 하길래 jadx로 까봤다. 딱봐도 MainActivity라고 적혀있으니 중요한거 같아서 보면 뭔지는 몰라도, 대충 check_val이 100이면 플래그 출력해주는거라고 충분히 추측할 수 있다. Toast가 뭔지는 몰라도 검색해보면, makeText의 첫번째 이자로 getApplicationContext()를 받고, 그 다음으로 스트링 받고, 마지막으로 길이를 받는다는 것을 알 수 있었다. 그런데 R.string.form1을 보고 들어가봤더니 이상한 주소가 있었다. 잘 찾아보니까 어떻게든 찾을 수 있었다. 그런데, String.valueOf(stringFromJNI())가 있길래, 검색해보니까, C++ native 함수라고 한다. 그래서 ..

포너블 5차시 과제

LIBC base 저기서 libc가 시작하는 주소, 즉 바이너리가 매핑되기 시작하는 부분을 libc base라고 한다. 당연히 다이나믹 링킹에만 해당되는 말이다. 0x00007ffff7dcc00 ~ 0x00007ffff7dee000에 해당한다. 기본적으로 리눅스 커널단에서 ASLR을 지원해서 libc가 매핑된 주소는 계속 바뀐다. 그래서 특정 부분을 가리키기 위해 base를 구한다. 바이너리의 세그먼트들이 그대로 매핑되는 거라서 당연히 libc base를 알면, 특정 부분의 주소도 계산할 수 있다. libc base + offset = address 가 된다. 이를 통해 libc 내부 함수들을 호출할 수 있다. 여기서 offset은 base부터의 떨어진 거리이다. GOT overwrite PLT가 참조하..

포너블 4차시 과제

NX bit : code segment를 제외하고 모두 실행 권한을 빼버리는 보호 기법이다. 원래 스택에 쉘 코드를 삽입하고 instruction pointer를 거기로 옮겨서 쉘을 실행시킬 수 있었는데, Nx 비트가 등장하면서 스택에 실행 권한이 제거되면서 쉘 코드를 사용하기 힘들어졌다. No eXecute라서 NX라고 부른다. plt : procedure linkage table로 execute 권한이 존재한다. 간단한 jmp 문이 존재한다. 여기서 got를 참조해서 libc로 점프한다. Full Relro라서 처음에 dynamic linker가 got도 세팅을 해줘서 여기선 dl autoresolve가 빠져있다. got : global offset table는 심볼에 맞게 libc랑 매칭 해놓은 테..

포너블 3차시 과제

Prob0 Full RELRO, PIE와 Canary가 걸려있고 rwx 권한을 가진 세그먼트가 있다. 버퍼 주소를 제공해준다. 나중에 ret 덮을때 사용하면 될 것 같다. _bss_start는 아마 stdout일 것이다. 0x100만큼 입력을 받는다. 근데 버퍼는 88이니까 bof가 터진다. 입력받은 버퍼 다시 출력하니까 canary leak은 널 바이트 덮어서 하면 될 것 같다. 입력을 gets로 다시 받는데, 그건 ret 덮는데 쓰면 된다. canary는 rbp-0x8에 있으니까 0x60 - 0x8 해서 0x58 + 1 덮어주면 된다. 이렇게 해주면 leak이 잘되는 것을 확인할 수 있다. 약간 바꿔서 출력해보면 잘 출력된다. 이제 ret를 shellcode 주소로 덮으면 된다. 이렇게 덮어주면 된다..

포너블 2차시 과제

change_ret32 vuln가 보인다. setvbuf로 초기 설정해준다. vuln 함수인데 fgets로 입력받는 것을 볼 수 있다. ebp-0x14니까 0x14만큼 채우고 32비트니까 4 바이트 sfp 더 채워서 0x18 채우면 ret 덮을 수 있다. /bin/sh를 부르는 함수 win이 있다. 그래서 ret를 win으로 바꾸면 eip를 마음대로 바꿀 수 있다. 익스플로잇 코드이다. change_ret64 change_ret32의 x64 버전이다. 코드는 완전 똑같다. 단지 오프셋만 조금 달라졌다. 0x20이다. 정렬 때문에 바뀐 거다. 0x20채우고 sfp 8바이트 채워서 0x28 채우고 win으로 덮으면 된다. 익스플로잇 코드이다. overwrite_ret64 스택의 버퍼 주소를 준다. 그리고 사..

리버싱 11차시 과제

prob-3 v4로 32바이트 받고, init_cpu를 호출한다. init_cpu는 입력받은걸 v5로 복사해준다. 그다음 run_cpu가 호출된다. 이런식으로 opcode에 따라서 명령을 수행하는게 들어가있다. 여기를 조금 눈여겨봐야한다. a1[16]과 a1[17]에 cmp 명령처럼 비교된 결과가 들어간다. 그리고 그 a1에 따라서 분기한다. 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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 7..

리버싱 10차시 과제

Prob-begin IDA로 디컴파일한 모습이다. v5에 16글자를 입력받는다. 그리고 16글자 4바이트씩 쪼개서 a1에 집어넣는다. stub에 따라서 다른 명령을 수행한다. stub의 모습이다. stub를 해석하는 프로그램을 작성했다. 위와 같은 결과를 얻을 수 있다. 32비트짜리라서 0xffffffff를 and 해줬다. initcpu 함수에서 아래와 같은 동작을 수행한다. v4[0] = v5[0] v4[1] = v5[1] v4[2] = v5[2] v4[3] = v5[3] v4는 총 8개가 존재하고 32비트이다. 일종의 레지스터 역할이다. 8개의 32비트 레지스터 중 4개가 사용자의 입력을 받아서 설정된다. 그 4개의 레지스터를 미지수로 설정한다. 그다음 v4[7] == 0이라는 조건을 만족시키는 미지..

리버싱 9차시 과제

prob for beginner 열어서 디컴파일 해보면, 이렇게 나온다. 식을 그대로 복사했다. 붙여넣고 &&랑 공백과 개행 문자를 다 없애줬다. 돌려보면 이렇게 나온다. 아까 돌려서 나온 식들을 그대로 복사 붙여넣기 해서 풀었다. print() 기본적으로 개행 문자가 붙어서 나가서, end =''로 개행 문자 없애고 출력했다. prob-1 디컴파일 해보면, 이렇게 나온다. if 문쪽 식을 그대로 복사하고 붙여넣어준다. 그다음 LL을 제거해주고, 보기 좋게 만들어주고 프린트해보면 아래처럼 나온다. 이거 그대로 복사하고 풀어주면 된다. 여기선 8 바이트 v4, v5, v6로 표현되었지만, scanf가 %s로 v4부터 받아서 v5, v4 순서대로 출력해주면 된다. 나온 걸 string으로 만들어주면 리틀엔디..