서비스 보안을 하면서 수많은 툴을 사용해 보았다.

 

특히 모바일과 관련된 여러 가지 툴을 사용하면서 정말 이런 걸 어떻게 만들었을까?

 

이건 조금 별로인데.. 혹은 감탄밖에 안 나오는 툴들이 많이 있었다.

 

따라서 문득 현재까지 모바일 분야를 진단하면서

 

배웠던 기술과 좋은 툴들을 종합해서 나만의 분석툴을 만들기로 하였다.

 

뭐 기간은 얼마나 걸리지는 모르겠지만 차근차근 하나씩 해볼 생각이다.

반응형

'모바일 분석 도구' 카테고리의 다른 글

05. Tab - Package  (2) 2024.01.17
04. Menu-Proxy  (0) 2023.12.23
03. Menu-Connect  (0) 2023.12.22
02. Home, Menu 화면  (0) 2023.12.22
01. Mode Select  (0) 2023.12.22

 

드디어 2021년에 가입했던 청년내일채움공제가 오늘로 끝이 났다.

 

 

타임라인을 보자면 다음과 같다.

 

계약일자 : 2021.02.02.
마지막 공제부금 납부일 : 2023.01.25.
내일채움공제 만기일 : 2023.02.01.
만기일이 속한 달의 급여일 : 2023.02.28.

--------------------------------------------------------------------

운영기관에서 고용노동부로 서류 제출 : 2023.03.13

5회차 기업기여금 적립 : 2023.03.21.
5회차 취업지원금 적립 : 2023.03.28.
만기 신청 : 2023.03.28.

공제금 지급계산서 메일 수령 : 2023. 03. 31.
입금 : 2023. 04. 04.

 

여기서 중요한건 --------------------------------------------------------------------부터이다.

 

설명부터하자면, 만기일2023년 2월 1일이다.

 

즉, 2월 1일까지만 해당 기업에서 근무하면 된다.

 

하지만 여러가지 변수가 있기 때문에 적어도 1주일이나 2주정도 더 다니는것이 좋다.

 

그 후 만기일이 포함된 날의 월급을 받자마자 바로 회사에 서류를 제출해달라고 요청을 한다.

 

여기서부터가 시간이 오래걸린다.

 

물론 알아서 바로 해주는 기업들이 있지만, 대부분 중소기업이라

 

일 처리해주는 사람이 잘 없거나 본인이 챙겨야지만 하는 상황이다.

 

각자의 상황에 맞게 일을 처리해주는분이 계시면 빨리 서류를 준비해달라고 요청을 드리거나,

 

서류를 제출해줄 사람이 없을 경우 그나마 서류를 제출해줄 수 있는 분에게 빠르게 부탁을 하자.

 

일단 내 상황에서는 준비한 서류는 다음과 같다.

 

1. 만기일 시점 (2월)부터 총 6개월간 급여명세서

 

2. 이체확인증(6개월간의 급여에 대한)

 

3. 근로계약서(최초 입사일이 나와있는)

 

4. 중소기업확인증

 

이렇게 총 4개의 서류를 내일채움운영기관에 제출하였다.

 

그렇게 제출한 서류가 1차적으로 운영기관에서 검토한 후 고용노동부로 서류를 제출한다.

 

제출한 후 고용노동부에서 약 1주일에서 2주간 검토를 마친 후 문제가 없을 경우

 

5회차(기업기여금, 정부지원금)이 입금된다.

 

일단 먼저 기업 기여금이 들어오게 되면 카톡으로 알림이 오는데

 

나같은 경우는 기업기여금이 먼저 들어오고 나서 딱 1주일 뒤에 정부지원금이 들어왔다.

 

정부지원금이 들어왔을때는 알림이 안와서 혹시나 싶어 하루에 몇번이나 홈페이지에서 확인했다.

 

홈페이지에서 확인하는게 가장 빠르다.

 

그렇게 5회차까지 모두 납부를 하게 되면 다음과 같이 만기 신청란이 보인다.

 

이렇게 만기금 신청을 눌러 만기를 신청하자.

 

기본적인 내용을 확인한 후 공제만기금 수령계좌에 수령 받을 계좌번호를 입력한다.

 

계좌 입력을 마친 후 내려가다보면 다음과 같은 간단한 설문조사가 나온다.

 

 

여기서 마지막 9번 10번 질문이 더 이어서 공제를 할거냐는 질문이 나오는데 

 

이건 각자 선택해서 진행하면된다.

 

이렇게 하면 만기 신청은 끝이다.

 

그러고 다음과 같은 카톡이 온다.

 

이렇게 왔으면 이제 진짜 마지막으로 기다리면 된다.

 

기다리던중 메일로 공제금 지급 계산서가 왔다.

 

여기서 대충 금액과 이자를 살펴보고 또 기다리면된다.

 

이런 메일을 받아보니 이제야 아 진짜 조금만 기다리면 받을 수 있겠구나라는 생각이 들었다.

 

그리고 내채공 홈페이지를 하루에 몇번씩 들어가서 확인했더니 4월 4일에 지급이 된다고 나와있었다.

 

그래서 4월 4일이 오늘이 오기를 기다리다 오늘 마침내 돈이 입금되었다.

 

 

반응형

iOS에서도 애플리케이션을 모의해킹 또는 분석을 할 때 단말기단이 아닌 패킷 단에서 분석을 하기위해서는

 

Fiddlerburp 인증서를 설치를 해야 프록시에서 잡을 수 있다.

 

따라서 이번에는 iOSBurp 인증서를 설치해보려고한다.

 

먼저 단말기PC가 같은 네트워크에 접속을 해야한다.

 

쉽게 말해 같은 Wi-Fi에 접속하면된다.

 

그 다음은 Burp에서 Proxy 설정을 해주어야한다.

 

PC에 설치된 Burp 메뉴에서 Proxy - Options - Edit - All interfaces를 선택 해준다.

 

 

PC 설정은 이제 끝이 났다.

 

이제 단말기에서 Burp 인증서 설치 및 네트워크 설정만 해주면된다.

 

일단 단말기에서 PC를 거쳐서 통신을 해야 하기 때문에

 

iOS에서 PC의 IP와 proxy port를 설정해주어야한다.

 

iOSWi-Fi 설정에 들어가서 제일 밑에 프록시 구성이라는 탭이있다.

 

기본적으로 ""이라고 설정되어 있지만 클릭해서 수동으로 변경해준다.

 

수동으로 변경하면 밑에 서버와 포트를 입력할 수 있게되는데

 

이때 PCIP와 앞에 burp에서 열어줬던 프록시 포트 번호를 입력해주면된다.

 

설정한 후 단말기에서 https://burp로 접속을 해준다.

 

접속을 하면 다음과 같은 화면이 뜬다면 일단 PC단말기가 연결이 되었다는것이다.

 

 

이제 Burp의 인증서를 단말기에 설치를 해주어야지 단말기에서 발생하는 패킷이 PC에서 볼수가 있다.

 

Burp의 인증서를 설치하기위해서는 "CA Certificate"를 클릭해준다.

 

인증서를 설치하려고하면 다음과 같은 문구가 나오는데 여기서 허용을 클릭해주자.

 

 

허용을 클릭하면 일단 인증서 설치는 끝났다.

 

이제 설치된 인증서에 대한 설정만 해주면된다.

 

설정을 하기위해서는 설정 - 일반 - 프로파일 및 기기 관리에 들어가준다.

 

 

프로파일 및 기기 관리에 들어가면 방금 설치한 인증서가 보인다.

 

인증서를 클릭 한 후 설치를 눌러준다.

 

 

 

이렇게 인증서 설치는 끝이 났다.

 

이제 단말기 시스템에서 해당 인증서를 신뢰만 해주면 설정 및 인증서 설치가 끝이 난다.

 

일반 - 정보 - 인증서 신뢰 설정에 들어간 후 Burp 인증서를 신뢰해주면 된다.

 

 

이제 모든 설치 및 설정은 끝이 났다.

 

마지막으로 Burp에서 제대로 패킷이 잡히는지 확인해보자.

 

 

반응형

'모바일 해킹 > iOS' 카테고리의 다른 글

iOS (Frida 설치)  (0) 2022.04.15
iOS (SSH, SFTP설치)  (0) 2022.04.15
iOS 탈옥 (unc0ver - windows)  (0) 2022.04.15

안드로이드에 Frida를 설치하는 방법과 비슷하다.

트윅으로 설치해도 되고, 원하는 버전을 사용하려면 따로 설치해야한다.

먼저 원하는 버전을 설치하고 싶으면 다음과 같이 진행한다.

먼저 PC에 설치되어있는 Frida 버전은 다음과 같다.

 

(py3) C:\Users\~~~~> frida --version
15.1.14

 

Frida 공식 홈페이지(클릭)에 접속해서

CTRL + F로 server를 입력하여 서버 전용 파일을 찾는다.

설치하기전 안드로이드와 마찬가지로 단말기의 비트 버전을 확인해야 한다.

 

확인하는 방법은 SSH로 접속한 후 uname -a 명령으로 비트를 확인한다.

 


해당 비트와 맞는 frida-server 15.1.14를 설치한 후 

Frida server 파일을 /usr/sbin 경로로 파일을 옮겨준 후

 

해당 경로로 이동하여 아래 명령어로 실행한다. 

# frida-server 파일에 실행권한
chmod 777 ./다운로드 받은 frida 파일 이름

 

# 백그라운드에서 실행
./다운로드 받은 frida 파일 이름 &


두번째 방법은 그냥 트윅으로 설치하는것이다.

Cydia 앱을 실행한 후 소스 > 편집 > 추가 > https://build.frida.re 소스 추가한다.

 


그 후 bulid.frida.re을 클릭 - 개발을 클릭한다.

 

여기서 64bits는 그냥 Frida이고 32bitsFrida for 32bits device이다.

 

이 중 알맞은 환경의 패키지 다운로드한다.

 

 

 

위처럼 간단하게 iOS에 Frida가 설치되었다.


Cydia를 이용하여 frida를 설치하면 default로/usr/sbin/frida-server가 구동된다.

 

이렇게 설치가 끝나면 PC와 Frida로 연결이 되는지 확인해본다.

 

위의 명령어가 잘 실행된다면 iOS에 Frida가 정상적으로 설치가 된것이다.

 

반응형

'모바일 해킹 > iOS' 카테고리의 다른 글

iOS (Burp 인증서 설치)  (0) 2022.04.18
iOS (SSH, SFTP설치)  (0) 2022.04.15
iOS 탈옥 (unc0ver - windows)  (0) 2022.04.15

아이폰을 탈옥한 후 SSHFTP를 사용한다면 모의해킹이나 분석을 할 때

 

조금 편하게 할 수 있다.

 

위 2가지를 한번에 설치 및 사용하기 위해서는 OpenSSH를 설치해주어야 한다.

 

먼저 탈옥된 단말기의 Cydia에서 Openssh를 입력하고 설치해준다.

 

 

Cydia에서 검색 클릭

 

 

검색을 누른 후 openssh를 검색한 후 설치를 눌러준다.

 

 

설치가 완료되면 Cydia로 복귀라는 문구를 클릭하여 openssh 설치를 끝낸다.

 

그 후 PCSSH 통신을 하기 위해서는 같은 네트워크에 접속한 후 단말기의 IP주소를 알아야 한다.

 

따라서 설정 - Wi-Fi에 들어가서 IP 주소를 알아본다.

 

 

단말기의 IP 주소192.168.10.177이다.

 

이제 PCSSH 연결을 위해 MobaXterm이라는 프로그램을 사용한다.

 

MobaXterm을 실행한 후 Session - SSH을 클릭하여 단말기의 IP 주소를 입력해준다.

 

 

IP 주소를 입력하면 다음과 같은 로그인 화면이 뜬다.

 

계정 정보는 root/alpine이다.

 

 

위와 같은 계정 정보를 입력하고 ls 명령을 입력하고 출력이 잘된다면

 

PC와 단말기가 잘 연결되었다는 것이다.

 

 

반응형

'모바일 해킹 > iOS' 카테고리의 다른 글

iOS (Burp 인증서 설치)  (0) 2022.04.18
iOS (Frida 설치)  (0) 2022.04.15
iOS 탈옥 (unc0ver - windows)  (0) 2022.04.15

먼저 iOS에서 모바일 모의해킹을 진행하기 위해서는 탈옥(jailbreak)을 해야 한다.

 

진단 기기의 iOS 버전은 14.2 버전이다.

 

탈옥을 하기 위해서는 여러 가지 방법과 툴이 있지만 이번에는 unc0ver를 사용하여 탈옥을 진행해보자.

 

 

먼저 PC에 altstore를 설치해주어야 한다. 

 

altstore는 여기서 다운로드하면 된다. (여기)

 

위에 접속해서 Windows (beta)를 클릭해서 설치해준다.

 

 

그런 다음 PC에서 설치한 후에 단말기에 altstore를 설치해준다.

 

 

Apple IDPassword를 입력하면 단말기기에서 PIN 코드가 나온다.

 

PIN 코드를 입력하면 altstore가 설치가 된다.

 

그 후 단말기에서 unc0ver 공식 사이트에 접속한다. (여기)

 

공식 사이트에 접속할 때는 사파리로 들어가야 한다.

 

들어가면 다음과 같은 화면이 나온다.

 

그림과 같이 Open in AltSotre을 클릭하고 열기를 눌러준다.

 

 

열기를 눌렀는데도 아무런 반응이 없다면 AltStore가 실행이 안된다는 것이다.

 

이때는 단말기에서 설정을 해주어야 한다.

 

설정 방법은 다음과 같다.

 

먼저 설정에 들어간다.

 

 

설정에 들어간 후 위의 그림처럼 일반 -> 기기 관리에 들어가 준다.

 

 

기기 관리를 클릭한 후 위의 그림처럼 신뢰를 눌러준다.

 

그런 후 다시 위의 과정을 진행해주면 다음과 같이 unc0ver가 설치된다.

 

 

여기까지가 unc0ver 설치가 끝이다.

 

다음은 홈 화면으로 가서 앱을 실행한 후 탈옥을 해주면 끝이다.

 

 

조금 기다리면 탈옥이 완료됐다는 문구를 볼 수 있다.

 

 

그럼 재부팅을 하고 나면 Cydia라는 앱이 설치가 되어있으면

 

성공적으로 탈옥이 되었다는 의미이다.

 

반응형

'모바일 해킹 > iOS' 카테고리의 다른 글

iOS (Burp 인증서 설치)  (0) 2022.04.18
iOS (Frida 설치)  (0) 2022.04.15
iOS (SSH, SFTP설치)  (0) 2022.04.15

Level 3 앱을 설치한 후 실행해보자.

 

 

 

이번에는 Level 1~2와는 다르게 문구가 다르게 보인다.

 

빠르게 디컴파일 툴로 해당 문구를 출력해주는 부분을 보자.

 

그림 부분에서는 잘렸지만 이번에도 루팅 체크를 하는 것 같다.

 

다시 if문 조건절에 있는걸 보면 총 5개메소드 루팅체크하는 로직이 존재한다.

 

모두 OR로 되어있기 때문에 하나 하나 분석해봐야 한다.

 

 

먼저 Level 1~2에서 한 것처럼 RootDetection.checkRoot1()을 먼저 살펴보자.

 

아래의 그림은 checkRoot1() 메소드이다.

 

 

해당 메소드를 보면 이름만 바뀐 것을 볼 수 있다.

 

즉, 로직은 Level 1~2와 같다는 말이다.

 

이 부분을 빠르게 후킹 해서 루팅 우회를 진행해보자.

 

 

Frida가 실행된 후 앱은 바로 꺼졌다.

 

따라서 뒤의 IntegrityCheck.isDebuggable(this.getApplicationContext()

 

MainActivity.tampered != 0도 추가적으로 우회를 해보았다.

 

하지만 똑같이 우회가 되지 않았다.

 

그래서 앱이 문제인지 아니면 문제에서 의도한 것인지 파악하기 위해 로그를 분석해보았다.

 

 

위의 그림은 앱이 실행될 때 발생되는 로그를 캡처한 것이다.

 

처음 시작하자마자 Tampering detected! Terminating...라는 문구가 나온다.

 

뭔가 탐지됐다는 말이다.

 

따라서 코드단에서 분석을 진행할 때 놓친 부분이 있나 싶어서 디컴파일 툴에서

 

"Tampering detected! Terminating..." 문구를

 

검색해보았다.

 

 

나오지 않았다.

 

이는 앱단(java)에서 처리하는 것이 아니다고 판단할 수 있다.

 

100%로는 아니다.

 

저 문자열이 동적으로 생성되거나 문자열이 난독화되어있으면

 

원하는 문자인 "Tampering detected! Terminating..."을 검색해도 나오지 않는다.

 

따라서 어딘가에서 루팅 혹은 디버거 탐지 등 어떤 것인지 모르는 탐지 로직이 실행되고 있으며

 

탐지 로직에 걸려 로그가 나왔다는 것만 알 수 있다.

 

따라서 우리가 Secret String을 맞춰 성공하는 alert가 있는 곳으로 가보자.

 

 

if문 앞의 this.check.check_code(v4)가 실행되면서 true을 return 해주면

 

우리는 성공한 메시지를 볼 수 있다.

 

this.check.check_code 메소드를 살펴보자.

 

살펴보면 check_code 메소드에서 this.bar을 호출하고 this.bar에서 return 된 값을 return 한다.

 

this.bar 함수는 위에 정의가 되어있으며 이 역시 native이다.

 

native를 분석하기 전에 컨셉을 잡아보자.

 

아직 루팅 우회가 되지 않았다.

 

앱단에서는 해당 로직을 찾을 수 있었지만 후킹 한 결과 앱이 종료가 되는 현상이 있었다.

 

또한 log에는 Tampering detected! Terminating...라는 문구가 나왔었다.

 

따라서 첫 번째로는 native에서 루팅 우회를 하는 로직을 찾아봐야 한다.

 

두 번째로는 Secret String과 관련된 key를 찾는 것이다.

 

먼저 루팅 우회를 먼저 해야 다음 과정을 진행할 수 있기 때문에 루팅 탐지 로직을 찾아보자.

 

먼저 해당 문구를 IDA에서 찾아보자.

 

 

찾아본 결과 sub_30D0에서 Tampering detected! Terminating... 문구가 사용되고 있다.

 

그렇다면 바로 sub_30D0 함수를 살펴보자.

 

 

살펴보면 우리가 원했던 문구인 Tampering detected! Terminating... 를 찾아볼 수 있다.

 

또한 log에서 볼 수 있었던 TAGUnCrackable3, 내용은 Tampering detected! Terminating...

 

log_print 하는 부분도 찾았다.

 

따라서 여기에서 탐지한다는 의미이다.

 

천천히 코드를 살펴보자.

 

v0 = fopen("/proc/self/maps", "r");

 

먼저 fopen 함수를 사용해서 /proc/self/maps를 읽어온다.

fopen 함수는 원형은 다음과 같고 하는 역할은 파일을 읽어 FILE 구조체 포인터 넘겨주는 함수이다.

 

따라서 v0에는 /proc/self/maps 파일의 포인터가 담겨있다.

 

/proc/self/maps는 무슨 역할을 하는 파일일까?

 

먼저 /proc 디렉터리는 리눅스 계열에서 사용되는 디렉터리이고 실행되는 프로세스 정보를 담고 있다.

 

여기서 의미하는 self는 자신의 pid를 의미한다.

 

maps은 현재 실행되고 있는 프로세스의 주소 맵 또는 프로세스의 메모리 주소 공간을 보여주는 파일이다.

 

종합해보면 현재 실행하고 있는 프로세스(Level 3 앱)의 메모리 주소 맵을 담고 있는

 

파일이라고 생각하면 된다.

 

실제 테스트 단말기에서 maps을 확인해보면 다음과 같은 정보를 볼 수 있다.

 

jackpotlteks:/ # cat /proc/27212/maps
.....
12c00000-13cc0000 rw-p 00000000 00:01 33530                              /dev/ashmem/dalvik-main space (region space)_4735_4735 (deleted)
13cc0000-13ec0000 rw-p 010c0000 00:01 33530                              /dev/ashmem/dalvik-main space (region space)_4735_4735 (deleted)
13ec0000-14140000 ---p 012c0000 00:01 33530                              /dev/ashmem/dalvik-main space (region space)_4735_4735 (deleted)
14140000-2ac00000 rw-p 01540000 00:01 33530                              /dev/ashmem/dalvik-main space (region space)_4735_4735 (deleted)
6f13f000-6f41a000 rw-p 00000000 103:11 228934                            /data/dalvik-cache/arm64/system@framework@boot.art
6f41a000-6f430000 r--p 002db000 103:11 228934                            /data/dalvik-cache/arm64/system@framework@boot.art
6f430000-6f565000 rw-p 00000000 103:11 228943                            /data/dalvik-cache/arm64/system@framework@boot-core-libart.art
6f565000-6f577000 r--p 00135000 103:11 228943                            /data/dalvik-cache/arm64/system@framework@boot-core-libart.art
6f577000-6f5b7000 rw-p 00000000 103:11 228949                            /data/dalvik-cache/arm64/system@framework@boot-conscrypt.art
6f5b7000-6f5ba000 r--p 00040000 103:11 228949                            /data/dalvik-cache/arm64/system@framework@boot-conscrypt.art
......

 

그다음 sub_30D0 함수의 코드를 분석해보자.

 

  v0 = fopen("/proc/self/maps", "r"); // v0에 /proc/self/maps 파일 포인터 저장
  
  if ( v0 )
  {
   	......
  }
  else
  {
LABEL_7:
    v1 = "Error opening /proc/self/maps! Terminating...";
  }

 

만약 if문에서 v0null이면 즉, 파일을 열었을 때 열지 못했다면

 

LABEL 7:로 가면서 "Error opening /proc/self/maps! Terminating..."라는 문구와 종료가 된다.

 

하지만 v0에 파일 포인터가 잘 넘어왔으면 if문 내부로 들어가게 된다.

 

 ...
 
 if ( v0 ) 
  {
    do
    {
      while ( !fgets(&v3, 512LL, v0) ) // /proc/self/maps 512 길이만큼 가져와 v3에 담는다.
      {
        fclose(v0);
        usleep(500LL);
        v0 = fopen("/proc/self/maps", "r");
        if ( !v0 )
          goto LABEL_7;
      }
    }
    while ( !strstr(&v3, "frida") && !strstr(&v3, "xposed") );  
    v1 = "Tampering detected! Terminating...";
  }
  
  ...

 

if문 내부로 들어와서 처음 실행되는 곳이 바로 do while문이다.

 

while문 안에는 fgets라는 함수가 존재한다.

 

fgets 함수의 원형은 다음과 같다.

 

 

쉽게 설명해서 파일 스트림(stream)에서 해당 길이(num)만큼 문자열을 받는다(str).

 

정리하면 /proc/self/maps의 파일 정보를 길이만큼 읽어와서 str에 넣어주는 함수이다.

 

여기까지 정리하면 코드는 다음과 같다.

 

  v0 = fopen("/proc/self/maps", "r"); // v0에 /proc/self/maps 파일 포인터 저장
  
  if ( v0 ) 
  {
    do
    {
      while ( !fgets(&v3, 512LL, v0) ) // /proc/self/maps 512 길이만큼 가져와 v3에 담는다.
      {
        fclose(v0);
        usleep(500LL);
        v0 = fopen("/proc/self/maps", "r");
        if ( !v0 )
          goto LABEL_7;
      }
    }
    while ( !strstr(&v3, "frida") && !strstr(&v3, "xposed") ); 
    v1 = "Tampering detected! Terminating...";
  }
  else
  {
LABEL_7:
    v1 = "Error opening /proc/self/maps! Terminating...";
  }

 

이제 if문안의 2번째 while을 보자.

 

strstr 함수가 2개가 있고 첫 번째 인자에는 v3

 

즉, 위의 fgets 함수에서 /proc/self/maps의 파일 정보를 v3에 담았기 때문에 

 

strstr 함수로 파일 정보을 한 줄 한 줄 읽어 오면서 중 fridaxposed가 들어가 있는지 확인하는 것이다.

 

 

그렇다면 /proc/self/maps에 fridaxposed가 있는지 확인해보자.

 

.........
7d7844e000-7d7844f000 ---p 00000000 00:00 0
7d7844f000-7d78553000 rw-p 00000000 00:00 0
7d78553000-7d78bdc000 r--p 00000000 103:11 972986                        /data/local/tmp/re.frida.server/frida-agent-64.so
7d78bdc000-7d78bdd000 ---p 00000000 00:00 0
7d78bdd000-7d799da000 r-xp 00689000 103:11 972986                        /data/local/tmp/re.frida.server/frida-agent-64.so
7d799da000-7d79a74000 r--p 01485000 103:11 972986                        /data/local/tmp/re.frida.server/frida-agent-64.so
7d79a74000-7d79a8a000 rw-p 0151e000 103:11 972986                        /data/local/tmp/re.frida.server/frida-agent-64.so
7d79a8a000-7d79af5000 rw-p 00000000 00:00 0                              [anon:.bss]
7d79b23000-7d79b24000 ---p 00000000 00:00 0                              [anon:thread stack guard]
......

 

이렇게 maps 파일에 /data/local/tmp/re.frida.server/frida-agent-64.so 가 존재한다.

 

따라서 Tampering detected! Terminating... 문구가 log에 남은 것이다.

 

이제 후킹 포인트를 잡았다.

 

바로 strstr 함수이다.

 

첫 번째 인자를 바꾸거나 두 번째 인자인 frida를 다른 문자열로 바꾸면 되는 것이다.

 

밑의 그림은 strstr 함수를 후킹 하여 첫 번째 인자를 출력해보았다.

 

정상적으로 후킹이 되고 frida가 출력된 것으로 보아 frida가 포함된 문자열을 다른 문자열로 바꿔보자.

 

후킹 한 결과 원래 봤던 로그도 없으며 정상적으로 앱이 실행된다.

 

이렇게 루팅 또는 디버깅 우회가 끝이 났다.

 

 

 

다시 돌아와서 이제 Level 3에서 원하는 Secret String을 찾아야 한다.

 

위의 bar 메소드native 메소드이면 Level 2에서처럼 so 파일을 분석해보아야 한다.

 

so 파일IDA로 열어보자.

 

 

Level 2에서 분석한 것과 마찬가지로 CodeCheck_bar 함수를 클릭해서 분석을 해보자.

 

그 이유는 Level 2에 설명되어있다.

 

 

retrun 하는 result 변수가 처음에는 0으로 설정되어있다.

 

이렇게 0으로 설정되어있으면 Secret String을 맞췄다는 문구를 볼 수가 없다.

 

따라서 result 값이 1이 되도록 만들어줘야 한다.

 

물론 Level 2에서도 bar 함수의 return 값을 1로 설정해주면 되지만 이는 출제의도가 아니다.

 

따라서 코드를 분석해서 Secret String을 알아내야 한다.

 

 

Level 2를 제대로 이해를 했다면 Level 2에서와 마찬가지로 해당 코드를 보고 생각나는 것이 있을 것이다.

 

총길이가 24인 것을 생각할 수 있다.

 

그다음은 while 문을 살펴보자.

 

while 문에서 == 연산이 보인다.

 

== 기준으로 왼쪽 값오른쪽 값이 같냐라는 것이다.

 

같지 않은 경우 while문이 끝이 나며 result는 그대로 0으로 return 되기 때문에 문제를 해결하지 못한다.

 

따라서 while문이 이 문제의 핵심이다.

 

먼저 왼쪽을 보자.

 

 

먼저 v7이 뭐고 v8이 먼지 알아야 한다.

 

v8은 코드에서 그냥 0이다.

 

v7을 알아야 하는데 v7은 IDA에서 다음과 같이 정의되어있다.

 

 

따라서 v5+1472 이가 어떤 함수인지 어떤 역할을 하는지 알아봐야 한다.

 

이를 frida를 활용해서 찍어보면 GetByteArrayElements라는 함수가 나온다.

 

GetByteArrayElements 함수의 정의는 다음과 같다.

 

GetByteArrayElements 함수는 java의 byte 배열을 JNI로 전달하는 함수이다.

 

즉 앱단에서 어떤 값을 so 파일로 전달하는 함수이다.

 

어떤 값을 전달할까??? 

 

GetByteArrayElements가 실행 후 return 값이 담긴 v7를 출력해보자.

 

 

이렇게 앱단에서 입력한 "test123456781264864984" 값이

 

GetByteArrayElements 함수가 실행된 후 v7에 저장이 된다.

 

따라서 while 문의 왼쪽은 사용자가 입력한 Secret String이라는 의미이다.

 

그렇다면 이제 ==을 기준으로 오른쪽의 값이 바로 문제에서 원하는 Secret String이라는 말이다.

 

따라서 우리는 알아야 할 것이 3가지이다.

 

&qword_15038 + v8, &v9, v8이다.

먼저 &qword_15038을 알아보자.

 

먼저 &연산은 주소 값을 가져오는 의미이다.

 

qword_15038에 어떠한 값이 저장되어있는데 그 메모리 주소값을 가져오는 의미이다.

 

그 후 v8을 더해준다.

 

처음에 v80이다.

 

 

하지만 바로 밑에서 ++연산을 통해 v8을 1씩 증가시켜주고 있다.

 

이는 어떠한 문자열이나 값이 배열에 저장되어있는데 index를 한 개씩 증가시킨다는 의미이다.

 

즉, 24자리인 문자열이면 한 문자씩 가져온다는 의미이다.

 

그렇다면 qword_15038에 어떤 값이 들어있는지 살펴보자.

 

 

qword_15038Java_sg_vantagepoint_uncrackable3_MainActivity_init 함수에서 사용되었다.

 

따라서 Java_sg_vantagepoint_uncrackable3_MainActivity_init 함수를 분석해보자.

 

 

Java_sg_vantagepoint_uncrackable3_MainActivity_init에서 strncpy 함수에서

 

qword_15038으로 어떤 값을 copy하는데 무슨 값을? v5에 저장되어있는어떤 값을

 

얼만큼? 24자리 만큼 copy 하는 것이 보인다.

 

이를 frida를 이용해서 strncpy 함수의 두 번째 인자인 v5을 출력해보자.

 

출력해보니 "pizzapizzapizzapizzapizz683"라는 문자열이 나왔다.

 

24자리qword_15038에 copy하니 최종적으로 qword_15038에는

 

"pizzapizzapizzapizzapizz"가 저장된다.

 

이는 어디서 나온 것일까?라고 생각을 해보자.

 

qword_15038Java_sg_vantagepoint_uncrackable3_MainActivity_init 함수에서 초기화되었다.

 

따라서 함수명에서 추측할 수 있듯이 다시 입단으로 돌아가 MainActivity에 선언되어있는

 

native init 메서드가 있는지 확인해보자.

 

 

이렇게 pizzapizzapizzapizzapizzinit 메소드의 인자로 넘겨주었다.

 

따라서 현재까지 다음과 같은 값을 도출할 수 있다.

 

v8은 앞에서도 설명했듯이 0~24까지 증가한다.

 

따라서 pizzapizzapizzapizzapizz라는 문자열에서

 

v8가 0일 때 p,

 

v8가 1일 때 i... v8이 24일 때 z

 

이렇게 한 문자씩 처리하겠다는 의미이다.

 

v80일 때를 보자면 문자 'p'xor연산을 한다.

 

^xor을 의미하는데 p&v9+v8 값을 xor 한다는 의미이다.

 

&v9+v8에서도 앞서 설명한 것처럼 한 문자씩 가져와서 p와 xor 하겠다는 것이다.

 

뒤에서 그림으로 설명되어있다.

 

그렇다면 v9에는 어떤 값이 들어있는지 확인해보자.

 

v9sub_10E0 함수에서 처리된다.

 

sub_10E0 함수에서 v9의 인자 값을 넘겨주고 sub_10E0 함수가 끝나면 v9에는

 

어떤 값이 저장되어있을 것이다.

 

sub_10E0 함수가 끝날 때 v9에는 어떤값이 들어있는지 확인해보자.

 

 

sub_10E0 함수가 끝날때 v9에는 이렇게 값이 들어가 있다.

 

여기까지 정리하자면 다음과 같이 도출할 수 있다.

이렇게 xor을 하는 코드를 작성해서 실행해보면 우리가 원하던 Secret String이 나온다.

 

이를 Level 3에 입력해보자.

 

 

 

정답이다.

 

이번 문제는 조금 설명이 많이길었다.

 

최대한 자세히 step by step으로 설명하려고 노력했다.

 

후킹 코드나 프리다 코드는 일부러 올리지 않았다.

 

적어도 후킹 코드나 프리다 코드는 직접 작성해보길 바란다.

 

검색하면 많이 나온다. 

반응형

'모바일 해킹 > AoS' 카테고리의 다른 글

Magisk 27.0 루팅 탐지 기법  (2) 2024.06.27
[Mobile-CTF] KGB Messenger  (1) 2022.06.01
[UnCrackable AoS] Level 2  (0) 2022.03.23
[UnCrackable AoS] Level 1  (0) 2022.03.23
[Android] NDK란??  (0) 2022.03.09

이번에는 Level 2를 풀어보자.

 

Level 2 앱을 다운로드하여 테스트 단말기에 설치한 후 실행한 모습이다.

 

 

역시나 루팅이 탐지되었다는 문구를 볼 수 있다.

 

이번 Level 2문제도 루팅을 우회해야만 진행할 수 있다.

 

따라서 static 분석을 하기위해  Level 2 apk 파일을 디컴파일 툴로 소스코드를 살펴 보자.

 

Level 2는 처음 시작하는 activitysg.vantagepoint.uncrackable2.MainActivity이다.

 

따라서 가장 먼저 sg.vantagepoint.uncrackable2.MainActivity인 부분을 살펴보자.

 

살펴본 결과 Level 1과 같이 b.a(), b.b(), b.c() 메소드에서 루팅 탐지를 하고 있는 것 같다는 느낌이 든다.

 

Level 1을 제대로 이해했으면 이런 느낌이 와야 한다. 

b.a() 메소드를 살펴보자.

 

 

Level 1과 똑같다.

 

하지만 이번에는 Level 1에서는 다른 방법으로 우회를 해보았다.

 

 

/sbin/su를 -> Level 2나 다른 문자열로 바꾼다면 해당 바이너리가 없기 때문에

 

return 값이 0이 될 것이다.

 

 

Level 1에서는 설명하지 않은

 

Build.TAGS.contains("test-keys")과 "/system/app/Superuser.apk ..."에 대해서는

 

조금만 검색하면 어떤 방식으로 루팅을 체크하는구나 감이 올 것이다.

 

검색하고 찾아보는 것도 실력을 키우는 것 중 하나이다.

 

따라서 Level 1에 대해서 100% 이해하고 넘어왔다면 루팅 우회는 금방 할 것이다.

 

같은 방법으로 우회해도 좋고 위의 방법대로 우회하든 정답은 없다.

 

그다음은 Level 1처럼 Secret String을 맞춰야 한다.

 

해당 메소드를 보자.

this.m.a(v4)이다.

 

v4는 우리가 입력한 string일 것이고 정확하게 비교하는 로직은 this.m.a에 있을 것이다.

 

this.m.a을 살펴보자.

 

this.m.a을 살펴보면 this.bar 메소드사용자가 입력한 String 값

 

byte형식으로 변환해서 bar 메소드로 넘겨준다.

 

bar 함수는 바로 밑에 정의가 되어있으며 내용은 아무것도 없다.

 

bar 메소드modifier을 살펴보면 native라는 것이 보인다.

 

nativejava에서 즉 앱단에서 처리하는 것이 아니라

 

c/c++을 이용해서 so 파일 안에서 처리하겠다는 의미이다.

 

자세한 내용은 여기(클릭)를 참조하자

 

따라서 이번 문제는 자바 앱단이 아닌 native 단 까지 분석을 진행해야 한다는 의미이다.

 

안드로이드에서 NDK를 사용하기 위해서는 so 파일을 load 시켜주는 과정이 꼭 필요하다.

 

 

load 시켜주는 과정이 위에서 빨간 박스 안에 System.loadLibrary("foo")이다.

 

libfoo.so 파일에서 this.bar라는 메소드가 정의되어 있으며

 

해당 메소드에서 이리저리 처리되고 반환 값만 자바단으로 retrun 해주는 형식이다.

 

사실문제의 의도와는 다르게 해당 this.bar 메소드를 후킹 해서 true로 반환해준다면

 

굳이 Secret String을 구하지 않고 밑의 그림처럼 해당 문제를 풀 수 있다.

 

 

하지만 이는 Level 2의 문제 출제 의도랑은 전혀 관련이 없다.

 

따라서 so 파일을 한번 분석을 해보자.

 

so 파일 대부분 lib 파일 안에 존재한다.

 

하지만 폴더가 4개나 있다.

 

이는 사용자가 어떤 OS bit를 가지고 있지 모르니 개발자가 모든 bit에서 실행할 수 있도록 한 것이다.

 

자신의 테스트 단말기의 bit는 다음과 같이 확인할 수 있다.

 

 

따라서 arm64-v8a 폴더로 가보면 libfoo.so 파일이 하나 있다.

 

이걸 분석을 해야 한다.

 

so 파일IDA로 분석을 진행한다.

 

IDA로 보면 Java_sg_vantagepoint_uncrackable2_MainActivity_init

 

Java_sg_vantagepoint_uncrackable2_CodeCheck_bar를 볼 수 있다.

 

이 둘 중 밑의 Java_sg_vantagepoint_uncrackable2_CodeCheck_bar 함수를 자세히 살펴봐야 한다.

 

그 이유는 Java_sg_vantagepoint_uncrackable2_CodeCheck_bar명에서 알 수 있듯이

 

bar가 들어가 있기 때문이다.

 

그렇다면 Java_sg_vantagepoint_uncrackable2_CodeCheck_bar 함수의 로직을 살펴보기 전에

 

컨셉을 잡아야 한다.

 

자세하게도 필요 없다.

 

크게 잡아도 된다.

 

나는 이번 문제를 풀 때 크게 2가지를 생각하고 분석에 들어갔다.

 

어떤 값을 return 하면  Secret String을 우회할 수 있을까?

 

또는 Java_sg_vantagepoint_uncrackable2_CodeCheck_bar에서 사용자가 입력한 Secret String 값과

 

Level 2에서 원하는 Secret String을 비교하는 로직이 있지 않을까?라는 큰 목표나 컨셉을 잡았고

 

이를 토대로 분석을 해보자.

 

 

코드를 보고 return result; 위주로 먼저 분석해보았다.

 

result는 처음에 0이라는 값을 가진다.

 

따라서 return이 0이면 우리가 원하는 Secret String을 찾았다는 메시지를 볼 수가 없다.

 

따라서 if문 안에 있는 result가 1이되게게끔 만들어주어야 한다.

 

물론 여기서 Java_sg_vantagepoint_uncrackable2_CodeCheck_bar 메소드의 return 값을

 

0이 아닌 1로 바꾸어도 문제는 풀 수 있다.

 

하지만 이는 출제자의 의도가 아니다.

 

따라서 if문 안에 있는 result에 (*(_QWORD *)v4 + 1368LL)라는 함수가

 

어떤 함수인지 어떤 역할을 하는지 알아봐야 한다.

 

이는 프리다로 후킹을 해서 확인해볼 수 있다.

 

 

확인해보니 ZN3art3JNI14GetArrayLengthEP7_JNIEnvP7_jarray라고 나온다.

 

여기서 유추해보자. ArrayLegnth이다.

 

(*(_QWORD *)v4 + 1368LL)함수는 뭔가 길이를 반환하는 함수인 거 같다. 

 

그리고 == 23이 붙어있는걸 보아하니

 

총길이가 23이 되어야 한다고 생각할 수 있다.

 

이 생각이 맞는지 검증하기 위해 strncmp의 함수를 살펴보자.

 

strncmp의 함수의 정의는 다음과 같다.

 

 

strncmp인자의 3번째 값으로 길이를 의미하는 23이 들어간 것으로 보아.

 

strncmp로 문제에서 원하는 String Secret 값과 내가 입력한 값이 23자리인지 확인한 다음

 

같다면 result1이 반환할 것이라고 예상할 수 있다.

 

따라서 strncmp를 후킹 하여 첫 번째 인자인 str1 인자를 찍어보면 내가 입력한 String

 

두 번째 인자 str2를 후킹 하면 문제에서 원하는 String이 들어가 있는 문자열이 나올 것이다.

 

이렇게 하면 Java_sg_vantagepoint_uncrackable2_CodeCheck_bar 함수를 분석하기 전에 생각했던

 

2가지의 컨셉을 만족할 수 있다.

 

후킹 코드를 작성해서 앱에서 12345678911234567892123을 입력한다.

 

후킹 코드가 제대로 동작하면

 

strncmp의 첫 번째 인자에 입력한 12345678911234567892123 값을 볼 수 있다.

 

그렇다면 문제에서 원하는 Secret String은 뭘까?

 

strncmp2번째 인자를 확인해보자.

 

이렇게 우리가 원하는 Secret String을 얻을 수 있다.

 

String을 문제에 넣어서 입력해보자.

 

 

이렇게 Level 2도 해결했다.

 

아마 많은 사람들의 풀이 방법을 보고 들어왔겠지만

 

대부분 루팅 우회를 할 때 exit를 후킹을 하는 방법이 많았다.

 

뭐 사실 틀린 말도 아니지만 실제 real world에서는

 

exit 함수로 하나로 루팅을 우회할 수 있는 경우는 거의 없다.

 

활용될 수는 있겠지만 절대 없다.

 

앱을 개발한 회사마다 또는 상황에 따라 보안 설루션들을 우회를 해야 하기 때문에

 

처음 연습할 때 습관을 잘 들이도록 하자.

반응형

'모바일 해킹 > AoS' 카테고리의 다른 글

[Mobile-CTF] KGB Messenger  (1) 2022.06.01
[UnCrackable AoS] Level 3  (0) 2022.03.24
[UnCrackable AoS] Level 1  (0) 2022.03.23
[Android] NDK란??  (0) 2022.03.09
[Android] Frida 설치  (0) 2022.01.23

시작하기 전에 사실 지금 나는 UnCrackable을 풀 이유는 없다.

 

대부분 UnCrackable은 모바일 취약점을 진단하는 입문자용으로 많이 쓰인다.

 

하지만 나도 처음에 모바일 취약점을 진단할 때를 생각해보면 조금 진입장벽이 높았다고 생각했다.

 

나처럼 처음에 어떻게 진단을 해야할까? 라는 사람에게 조금 도움이 되었으면 하는 바람이다.

 

또한 나중에 스스로 해결하고 생각할 수 있도록 풀이과정을 전부 다 포스팅하지 않을 것이다.

 

다만 해당 문제의 출제 원리를 자세히 설명할 것이다.

 

아래의 내용을 제대로 이해했다면 나머지도 금방 혼자서 해결할 수 있을 것이다.

 

그럼 시작!!!

 

UnCrackable에 대해서 짧게 설명하자면

 

OWASP에서 만든 모바일 테스트용 앱으로써, AoSiOS가 있다.

 

인터넷에 조금만 검색해보면 Level 1 apk 파일을 구할 수 있다.

 

Level 1의 apk 파일을 구했다면 테스트 단말기에 설치해준다.

 

 

앱을 단말기에 설치하면 다음과 같은 앱 아이콘이 보이며 실행하면 다음과 같은 문구가 뜬다.

 

 

Root detected!

 

모의해킹 직무를 하다 보면 모바일 진단을 하는 경우가 많다.

 

그리고 위와 같은 루팅이 탐지되었다는 문구를 수도 없이 많이 봤을 것이다.

 

따라서 이 앱을 실행하기 위해서는 Level 1에서 루팅 탐지 로직을 우회하여야 한다.

 

이것이 모바일 진단에서 가장 중요한 작업이다.

 

요즘 대부분 앱에서는 이러한 루팅 탐지디버깅 탐지 등 수많은 탐지 로직이 실행되고 있으며 

 

진단을 하기 위해서는 가장 첫 번째인 루팅 탐지를 우회하여야 한다.

 

(참고로 이 정도 난이도는 상용 앱에서는 거의 없다고 보면 된다.)

 

그럼 해당 문구가 어떻게 어떤 로직으로 인해 루팅이 탐지되었는지 살펴보자.

 

Level 1은 가장 처음 시작하는 부분이 sg.vantagepoint.uncrackable1.MainActivity이다.

 

그렇다면 sg.vantagepoint.uncrackable1.MainActivity을 살펴보기 위해

 

앱을 디컴파일해서 static 분석을 진행해보자.

 

 

앞에서 봤던 문구를 소스코드단에서 볼 수 있다.

 

먼저 onCreate 메소드를 보면 if문 안에

 

 if((c.a()) || (c.b()) || (c.c()))가 존재한다.

 

(c.a()) || (c.b()) || (c.c())) 이 3개의 메소드 중 하나만 true여도 this.a라는 메소드가 실행되어

 

"Root detected!"라는 문구를 볼 수 있을 것이다.

 

그럼 (c.a()) || (c.b()) || (c.c()))라는 메소드를 모두 false로 만들어 줘야 한다.

 

c.a() 메소드를 살펴보자.

 

 

먼저 c.a 메소드이다.

 

java.lang.System.getenv 메소드는 현재 시스템의 환경변수 값을 얻어오는 메소드이다.

 

환경변수를 얻어온 값에서 :split 한 값을 for문을 loop 한다.

 

loop 하는 과정에서 File.exists() 메소드를 통해

루트 권한을 얻는 su 명령어(바이너리)가 존재하면 return 1을 하는 로직이다.

frida로 해당 System.getenv 메소드와 c.a()의 return 값을 찍어보자.

먼저 System.getenv 메소드의 return 값은 다음과 같다.

 

 

return 값을 :로 split 했기 때문에 String v0에는 다음과 같이 들어갈 것이다.

 

 

for문 로직을 살펴보자.

 

v0[0]에는 "/sbin"이라는 문자열이 들어가 있다.

 

그렇다면 for문에서 다음과 같이 실행될 것이다.

 

 

테스트용 단말기에 /sbin 디렉토리에 su라는 바이너리가 있는지 확인해보자.

이렇게 su라는 바이너리가 존재한다.

 

따라서 c.a()는 return 1이 되면서 루팅이 탐지되는 것이다.

 

 

이처럼 c.a()와 c.b(), c.c()를 우회해주면 루팅 우회는 끝이 난다.

 

밑의 사진은 c.a()와 c.b(), c.c()를 후킹 하여 루팅 체크 로직을 우회한 모습이다.

 

 

이제 문제에서 원하는 Secret String을 찾아야 한다.

 

사실 위의 루팅 우회Secret String을 우회하는 방법은 한 가지가 있는 것이 아니라

 

여러 가지가 있다.

 

Level 1 문제에서 후킹 포인트가 너무 많다.

 

하지만 Level 1에서 만든 문제의 출제 의도에 맞게 풀어보는 것을 추천한다.

 

다시 돌아와서 핵심은 빨간 박스다.

 

a.a(v4)라는 값이 true이면 된다는 의미이다.

 

a.a 메소드를 살펴보자.

 

마찬가지로 핵심은 빨간색 박스이다.

 

사진이 조금 잘리긴 했지만 우리가 Enter the Secret String에 입력하는 값이 arg5에 저장된다.

 

 

그 후 입력했던 arg5값과 아래의 sg.vantagepoint.a.a.a 메소드에서 return 된 값이 같다면

 

그 값이 Secret key가 된다.

따라서 sg.vantagepoint.a.a.a에서 return 되는 값을 알아내고 입력한다면

 

Level 1을 clear 할 수 있다.

 

sg.vantagepoint.a.a.a 메소드를 살펴보자.

 

sg.vantagepoint.a.a.a 메소드를 보면 AES/ECB/PKCS7Padding라는 문구가 보인다.

 

이것은 AES 암호의 한 종류이다.

 

AES 암호와 관련이 있다는 말이다.

 

그렇다면 AES 암호를 하기 위해서는 key가 있어야 한다. (대칭키 암호이기 때문)

 

또한 암호화 과정이면 평문이 있어야 하고

 

복호화 과정이면 암호화된 암호문이 있어야 할 것이다.

 

이것은 v2.init(2, v0)을 보면 알 수 있다.

 

init에 첫 번째 인자가 1이면 암호화 과정이고

 

2이면 복호화 과정이다.

 

init의 두 번째 인자는 key이다.

 

keyv0의 변수가 들어가 있으며

 

v0SecretKeySpec v0 = new SecretKeySpec(arg2, "AES/ECB/PKCS7Padding")을 나타낸다.

 

v0 SecretKeySpec(arg2, "AES/ECB/PKCS7Padding")리턴 값으로 arg2값이 필요하다.

 

arg2값은 앞의 메소드에서 본 byte값을 의미한다.

 

이렇게 key 셋팅과 AES 셋팅이 끝나면 dofinal 메소드로 복호화를 진행한다.

 

dofinal에는 arg3값이 인자로 들어가 있는데

 

arg3은 앞의 메소드에서 Base64 decode 한 값이 들어간다.

 

이것이 바로 암호문이며 이것을 복호화를 한다면 문제에서 원하는

 

즉 Level 1의 출제의도인 Secret key를 얻을 수 있는 것이다.

 

 

위의 과정을 코드를 작성해도 좋고 후킹을 해도 좋고 방법은 여러 가지이다.

 

밑의 사진은 위의 과정을 코드로 작성하여 Secret key를 구한 모습이다.

 

 

 

반응형

'모바일 해킹 > AoS' 카테고리의 다른 글

[UnCrackable AoS] Level 3  (0) 2022.03.24
[UnCrackable AoS] Level 2  (0) 2022.03.23
[Android] NDK란??  (0) 2022.03.09
[Android] Frida 설치  (0) 2022.01.23
Byte Code & Binary Code  (2) 2021.11.09

NDK란???

 

 

Native Development Kit의 약자로 안드로이드에서 C/C++ 코드를 사용해야 할 때가 있다.

 

안드로이드에서 C나 C++를 사용하기 위해서는 JNI(Jave Native Interface)로 사용 및 개발할 수 있다.

 

즉, NDK는 안드로이드 환경에서 JNI를 사용하기 위해 구성된 키트라고 생각하면 된다.

 

요즘은 C언어를 사용하여 개발하는 일이 많지는 않지만

 

C언어로 만들어진 프로그램과 라이브러리는 여전히 서비스를 제공하는 데 있어서

 

중요한 위치를 차지하고 있다.

 

특히 안드로이드는 리눅스 기반이며 이는 대부분 C로 제작되어있다.

 

C로 제작되어 있기 때문에 C로 작성된 라이브러리를 사용하는 것이 당연한 말이다.

 

또한 가장 큰 장점은 안드로이드의 앱을 개발할 때 Java로 만든 애플리케이션에서

 

일정 부분을 C/C++로 미리 작성된 라이브리를 재 사용이 가능해 개발 시간이 단축되는 장점이 있다.

 

주로 안드로이드에서 가장 많이 사용되는 파일이 libc.so 파일이다.

 

여기서 .so 파일은 shared object 또는 shared library라고 불린다.

 

shared object 또는 shared library는 실행 파일과는 분리되어 있지만

 

Linker라는 것으로 인해 실행 시 실행파일과 함께 메모리에 적재되어

 

프로그램이 정상적으로 실행될 수 있게 해 준다.

 

즉, .so 파일을 쉽게 정의하자면

 

이미 특정한 기능이나 함수들이 미리 정의 및 구현되어 있는 파일을 의미한다.

 

 

쉽게 설명하자면 위의 간단한 C 코드를 보자.

 

그냥 printf 함수로 "Hello World"를 출력하는 C 코드이다.

 

저기서 printf 함수는 위의 코드에서 작성한 적도 없으며 보이지도 않는다.

 

이는 "stdio.h" 헤더 파일에 printf가 미리 정의가 되어 stdio.h 헤더를 선언해주고 그냥 사용한 것이다.

 

이는 안드로이드 앱에서도 마찬가지이다.

반응형

'모바일 해킹 > AoS' 카테고리의 다른 글

[UnCrackable AoS] Level 2  (0) 2022.03.23
[UnCrackable AoS] Level 1  (0) 2022.03.23
[Android] Frida 설치  (0) 2022.01.23
Byte Code & Binary Code  (2) 2021.11.09
Android Penetration Testing - Rooting (Galaxy S6)  (5) 2021.08.27

모의해킹을 수행할 때 많은 툴을 사용한다.

 

특히 jar 파일 등을 사용할 때 툴들이 java 버전을 타는 경우가 있다.

 

따라서 한 PC에서 여러개의 버전을 돌려야 할 때가 있는데 다음과 같이 설정해주면 2개 이상 편하게 사용할 수 있다.

 

먼저 자바를 설치 한다음 C 드라이브 밑에 C:\java_env에 만들어 주었다.

 

그 후에 아래와 같은 bat 파일을 만들어준다.

 

@echo off
set JAVA_HOME=C:\Program Files\Java\jre1.8.0_201
set PATH=%JAVA_HOME%\bin;%PATH% 
java -version

 

그 후 위의 파일을 java8.bat이라는 파일로 저장해준다.

 

그 후 cmd 창에 java8이라고 입력하면 java 버전이 8되고 java11로 입력하면 11버전으로 실행이 가능하다.

 

 

반응형

갑자기 분석하고 싶은 앱이 있어 앱을 분석하고 리패키징을 하였다.

 

근데 아래와 같은 에러가 났다.

 

.....
생략
.....

[0m java.lang.RuntimeException: Unable to start activity ComponentInfo{../..}: android.content.res.Resources$NotFoundException: Resource ID .... ]


.....
생략
.....

[0m java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "../base.apk"],nativeLibraryDirectories=[/data/app/com./.../lib/arm64, /system/lib64, /vendor/lib64]]] couldn't find "something.so"

 

처음보는 에러였다.

 

그래서 열심히 구글링을 해본결과 앱스토어에서 xapk 형식으로 다운을받았는데

 

이걸 그대로 apktool을 이용해서 pull로 가져오니 위의 에러가 난것이다. 

 

xapk 형식이 아닌 apk로 가져오니 해당 에러가 해결되었다.

 

xapk 형식은 알고는 있었지만 이번 기회에 공부를 해봐야겟다.

반응형

연락은 댓글로!!

반응형

안드로이드 애플리케이션에 대해 취약점 분석 및 모의해킹을 진행 시 Frida는 필수이다.

 

먼저 AndroidFrida를 설치하고 실행 하기 위해서는 PC에서 후킹 스크립트를 작성해야한다.

 

따라서 PC와 모바일 둘 다 Frida를 실행 할 수 있는 환경을 만들어주어야 한다.

 

PC 환경은 이전 포스팅을 보고 환경을 만들어 주자. (클릭)

 

먼저 진단용 단말기는 루팅이 진행되어야한다.

 

루팅과 관련된 내용은 따로 정리할지는 모르겠지만 검색만 하면 다른 포스팅이 많이 있다.

 

참고하자.

 

루팅된 폰에 다음과 같은 명령어를 입력하고 단말기가 32bit인지 64bit인지 확인한다.

 

getprop ro.product.cpu.abi

 

 

arm64-v8a는 64bit이기 때문에 frida 홈페이지에 가서 다운로드 받고 단말기에 넣어주기만 하면 끝이다.

 

Frida 공식 홈페이지는 다음과 같다. (클릭)

 

 

PC에 설치한 frida 버전과 똑같은 버전을 다운로드 받아 준다.

 

다운로드 받은 후 단말기에 해당 frida-server 파일을 넣어주고 실행 할 수 있는 퍼미션을 준다.

 

 

반응형

'모바일 해킹 > AoS' 카테고리의 다른 글

[UnCrackable AoS] Level 1  (0) 2022.03.23
[Android] NDK란??  (0) 2022.03.09
Byte Code & Binary Code  (2) 2021.11.09
Android Penetration Testing - Rooting (Galaxy S6)  (5) 2021.08.27
Android Penetration Testing - Setup  (2) 2021.01.11

모바일 모의해킹 및 취약점 분석 시 frida는 많이 사용된다.

 

따라서 이번에는 Anaconda에서 frida를 설치해보자.

 

먼저 Anaconda 설치는 이전 포스팅을 참고하면 된다. (클릭)

 

 

먼저 Anaconda에서 python을 실행 시켜준다.

 

그 후 다음 명령어를 입력해서 frida를 PC에 설치해주자.

 

pip install frida-tools

 

 

이렇게 설치해주면 PC에 frida가 설치되었다.

 

 

하지만 frida 설치 후 버전 확인 또는 frida를 실행 하였을 때

 

아래의 같이 오류가 난다면 python 버전의 문제이다.

 

***
Failed to load the Frida native extension: DLL load failed: 지정된 모듈을 찾을 수 없습니다.
Please ensure that the extension was compiled for Python 3.x.
***

......

ImportError: DLL load failed: 지정된 모듈을 찾을 수 없습니다.

 

해결 방법은 python 3.7 버전으로 다시 설치하면 된다.

 

 

반응형

 

갑자기 논문을 읽다가 평소와는 다르게 bytecode라는 단어를 보고

 

평소 같았으면 그냥 아 bytecode 하고 넘어갔지만

 

오늘 갑자기 bytecode??, binary code랑 뭐가 다른거지? 하고 어느 순간에 두개의 개념이 헷갈렸다.

 

따라서 이번에는 바이트 코드(Byte Code)바이너리 코드(Binary Code)를 짧게 정리해보고자 한다.

 

모든 언어를 예를 들거나 할때 등장하는 언어가 있다.

 

바로 C언어이다.

 

C언어는 컴파일러에 의해 소스파일(e.g., main.c, test.c)

 

오브젝트 파일(main.obj, test.obj)로 만들어진다. 

 

오브젝트 파일로 변환될때 0과 1로 이루어진 이진 코드

 

바이너리 파일로 변환된다.

 

0과 1로 이루어진 파일이기 때문에 컴퓨터는 해당 파일을 이해는 할 수 있다.

 

다만 실행은 못한다.

 

컴퓨터가 실행을 하기 위해서는 기계어(명령어 집합)가 되어야한다.

 

또한 C언어는 환경에 종속적이다.

 

이러한 문제점을 해결하고자 나온 언어가 자바(Java)이다.

 

자바는 컴파일러에 의해 소스파일(e.g., main.java)오브젝트 파일(e.g., main.class)로 변환되며

 

바이너리 코드가 아닌 바로 바이트 코드로 변환된다.

 

또한 환경에 독립적이며 바로 실행 할수 있다.

 

둘다 똑같이 컴파일러에 의해 소스파일컴파일 되었고

 

컴파일 된 파일 오브젝트 파일되었는데

 

C언어에서는 바이너리 코드, Java에서는 왜 바이트 코드일까?

 

완벽한 정답은 아니지만 두개의 차이점은 바로 실행 할 수 있냐 없냐의 차이이다.

 

차이점을 알아보자.

바이너리 코드

  • 컴퓨터가 인식하고 이해할 수 있는 이진 숫자 체계의 0과 1로 구성된 코드를 의미한다.

기계어

  • 기계어는 CPU가 직접 해독하고 실행할 수 있는 비트 단위로 쓰인 컴퓨터 언어를 통틀어 일컫는다.
  • 기계어는 프로그램을 나타내는 가장 낮은 단계의 개념이다.
  • 기계어는 어셈블리어와 1 : 1로 쓰일 수 있다.

바이트 코드

  • 가상 머신에서 이해하고 실행 할 수 있는 0과 1로 구성된 코드이다.
  • 어떠한 환경에 종속적이지 않고 실행 될  수 있는 가상 머신용 기계어 코드이다.

 

나름 바이너리 코드바이트 코드의 차이를 간단하게 정리를 해보았다.

 

위의 논문에서도 바이너리 코드라고 하지 않고

 

바이트 코드라고 쓰여져있었던것이다. (안드로이드 관련 논문)

 

왜냐? 안드로이드에서 사용하는 애플리케이션(App)은 Java로 만들어졌기 때문이다.

 

 

 

 

반응형

'모바일 해킹 > AoS' 카테고리의 다른 글

[Android] NDK란??  (0) 2022.03.09
[Android] Frida 설치  (0) 2022.01.23
Android Penetration Testing - Rooting (Galaxy S6)  (5) 2021.08.27
Android Penetration Testing - Setup  (2) 2021.01.11
Android Penetration Testing - Introduction  (0) 2021.01.11

1. 문제 설명

 

문제를 클릭해보자.

 

클릭하면 화면에 javascript challenge라는 문구 말고는 아무것도 없다.

 

쿠키값을 봤을때도 아무것도 없어 페이지 소스보기를 눌러보았다.

 

페이지 소스를 봤을때 딱히 다른건 없었지만 <script> 태그에 이상한 이모티콘이 존재했다.

 

따라서 뭔가 이번 문제는 <script> 태그에 난독화 되어 있는 코드를

 

복호화하는것이 우선일 것이라는 생각이 들었다.

 

따라서 구글에 다음과 같이 입력해보았다.

 

 

검색을 해보니 제일 위에 aaencode라는 것이 나온다.

 

클릭해보자.

 

 

클릭해 보니 alert("Hello, JavaScript")이 위의 이모티콘과 같다고 한다.

 

브라우저 콘솔에 넣어보자.

콘솔에 넣고 입력해보니 바로 alert가 떴다.

 

따라서 이번 문제를 풀기 위해 사이트에서 소개하는 Decoder-aaEncode에 접속해보자.

 

Githtml 파일로 decoder가 있다.

 

다운로드 받아 보니 Input the aaencode here난독화된 코드를 넣으면

 

Decoded aaencode String복호화된 코드가 나온다. 

 

복호화 된 코드는 다음과 같다.

 

var enco='';
var enco2=126;
var enco3=33;
var ck=document.URL.substr(document.URL.indexOf('='));
for(i=1;i<122;i++)
{
  enco=enco+String.fromCharCode(i,0);
}
function enco_(x)
{
  return enco.charCodeAt(x);
}
if(ck=="="+String.fromCharCode(enco_(240))+String.fromCharCode(enco_(220))+String.fromCharCode(enco_(232))+String.fromCharCode(enco_(192))+String.fromCharCode(enco_(226))+String.fromCharCode(enco_(200))+String.fromCharCode(enco_(204))+String.fromCharCode(enco_(222-2))+String.fromCharCode(enco_(198))+"~~~~~~"+String.fromCharCode(enco2)+String.fromCharCode(enco3))
{
  location.href="./"+ck.replace("=","")+".php";
}

 

이제 위의 코드를 보면 제일 마지막에

 

location.href로 문제에서 원하는 php 페이지로 가는것이 목적인것같다.

 

2. 문제 풀이

 

먼저 위의 복호화된 코드를 브라우저 콘솔 창에 넣고 어떤 값이 리턴되는지 보자.

 

먼저 문제에서 최종적으로 원하는 것은 원하는 php 사이트로 가는것이다.

 

마지막 if문을 살펴보면 ck라는 변수가

 

=+String.fromCharCode(enco_(240))+String.fromCharCode(enco_(220))...

 

완성된 문자열같아야한다.

 

여기서 + 는 문자나 문자열을 이어주는 역할을 한다.

 

따라서 String.fromCharCode(enco_(240))를 알기 위해서는 enco_라는 함수를 먼저 선언해주어야하며

 

enco_ 함수내에 enco.charCodeAt(x)라는 것을 실행하기 위해서는 enco를 먼저 선언해주어야한다.

 

선언 한 다음 String.fromCharCode(enco_(240))를 실행해보자.

 

y가 나온다.

 

남은것도 다해보면 youaregod~~~~~~~!이라는 문장이 나온다.

 

 

마지막 코드 if문안에 ck라는 변수에 선언해주고 replace로 해주는데

 

콘솔창에서 해보면 다음과 같이 나온다.

하지만 replace가 되려면 =가 ck라는 변수에 존재해야하고,

 

ck라는 변수는 다음과 같이 정의되어 있다.

 

var ck=document.URL.substr(document.URL.indexOf('='));

 

따라서 URL에 12번URL/?=youaregod~~~~~~~!가 들어가야한다.

 

접속해보자.

 

 

 

반응형

'웹 해킹 > Webhacking.kr' 카테고리의 다른 글

11. old-11  (0) 2021.11.09
10. old-10  (0) 2021.11.08
9. old-09  (0) 2021.11.08
8. old-08  (0) 2021.11.05
7. old-07  (0) 2021.11.04

1. 문제 설명

 

먼저 문제를 클릭해보자.

 

문제를 클릭하니 다음과 같은 Wrong이라는 문구와 view-source가 있다.

 

역시 아무런 정보가 없으니 view-source를 클릭해보자.

 

다른 코드들은 볼 필요 없이 위의 PHP 소스코드를 분석해보자.

 

먼저 $pat이라는 변수에 어떤 패턴을 저장하였다.

 

따라서 첫 번째 pat이라는 변수에 저장되어 있는 패턴을 분석해야 한다.

 

그 후 preg_match 함수를 이용해 앞에서 정의한 패턴을 기반으로 regex를 수행한다.

 

perg_match에 대한 설명은 여기에 있다. (클릭)

 

regex를 수행하지만 어떤 문자열이나 값이 있어야 패턴을 적용할 수 있다.

 

그 값이 바로 $_GET['val'] 값이다.

 

따라서 GET 형식으로 URL 뒤에 ?val=어떤 값을 넣어줘야 한다.

 

그렇게 패턴에 매칭이 되면 solve(11) 함수가 실행되면서 문제가 clear 하게 된다.

 

여기까지 정리해보면 다음과 같다.

 

GET 형식으로 val을 값을 서버로 넘겨주는데

 

이때 값은 perg_match에 매칭이 되어야 한다. (그래야 solve(11) 함수가 실행)

 

perg_match에 매칭 되기 위해서는 pat이라는 변수에 저장되어있는 패턴을 분석해야 한다.

 

따라서 패턴 분석 후 값을 val에 넣어주면 이번 문제는 clear 할 수 있을 것 같다.

 

2. 문제 풀이

 

/[1-3][a-f]{5}_.*$_SERVER[REMOTE_ADDR].*\tp\ta\ts\ts/ 패턴을 하나하나 분석해보자.

 

첫 번째로 나오는 것이 [1-3]이다.

 

1-3은 값인 것 같고 먼저 [ ]가 무엇을 의미하는지 살펴보자.

 

 

[ ]은 지정된 두 문자 사이에 문자 코드가 있는 문자를 찾는다는 의미이다.

 

이것이 뭐냐? 쉽게 말해 범위라고 생각하면 된다.

 

[g-s]지정된 두 문자(g,s) 사이에 있는 모든 문자를 주어진 값에서 찾는다는 의미이다.

 

따라서, abcdefghijklmnopqrstuvwxyz에서

 

g, h, i, j, k, l, m, n, o, p, q, r, s만 패턴에 맞게 적용되는 것이다.

 

다음은 [a-f]이다.

 

똑같이 지정된 두 문자(a,f) 사이에 있는 모든 문자를 주어진 값에서 찾는다는 의미이다.

 

그렇다면 [1-3][a-f] 이 두 개를 사용해서 매칭 되는 문자열을 찾아보자.

 

먼저 위에 처럼 주어진 문자열에 [1-3][a-f]을 만족하기 위해서는 첫 글자가 1~3 사이의 숫자여야 한다.

 

1번을 조사할 때 첫글자가 4니깐 패스, 2번을 조사할때 5라서 패스

 

3번을 조사할때 3이고 바로 뒤에 오는 문자가 [a-f] 사이에 포함되니 3a가 매칭이 된다.

 

 

이제 다음은 {5}

 

5는 값이니깐 { }가 먼지 먼저 알아야 한다.

 

Developer에서 정의한 { } 다음과 같다.

 

{5}는 앞 표현식이 5번 나타나는 부분에만 적용된다는 의미이다.

 

적용된 부분인 aabab는 {5}의 앞 표현식 [a-f]가 총 5번 a, a, b, a, b로 매칭이 되는 것이다. 

 

3은 [a-f]의 앞의 표현식 [1-3]에 의해 매칭 되는것이다.

 

그다음은 _ 이건 말그대로 _ 문자를 의미한다.

 

. 은 새로운 개행이 나오기 전까지의 모든 문자를 의미한다.

 

 

*은 앞의 표현식이 0개 이상 연속으로 반복되는 문자를 의미한다.

 

 

 

 

그 다음은 $_SERVER[REMOTE_ADDR] 변수 값인데

 

REMOTE_ADDR은 내가 접속하는 IP 주소를 의미한다.

 

IP 주소는 구글에 what is my ip라고 검색해도 되고 아래의 URL에 들어가서 확인이 가능하다.

 

https://whatismyipaddress.com/

 

그렇다면 여기까지 매칭이 되게 val을 작성해보자.

 

[1-3][a-f]{5}_.*뒤에 원래 $_SERVER [REMOTE_ADDR] 이것이 들어가야 하지만 들어갔다고 가정하고

 

3 abcde_127.0.0.1가 매칭이 되었다.

 

이제 남은 것은 \tp\ta\ts\ts이다.

 

\t은 우리가 알고 있는 탭이다.

 

____p____a____s____s //____은 탭의 공백을 의미함.

 

pass라는 단어가 나온다.

 

따라서 val3abcde_자신의ip\tp\ta\ts\ts를 넣어주면 된다.

 

하지만 GET 방식이다.

 

GET 방식에서 URL 뒤에 ?val=3abcde_자신의ip\tp\ta\ts\ts를 넣어주면

 

\이 문자가 URL encoding이 되어 %5C가 들어가면서 %5Cp%5Ca%5Cs%5Cs가 된다.

 

따라서 탭의 의미를 주려면 %09를 넣어 줘야 한다.

 

 

반응형

'웹 해킹 > Webhacking.kr' 카테고리의 다른 글

12. old-12  (0) 2021.11.09
10. old-10  (0) 2021.11.08
9. old-09  (0) 2021.11.08
8. old-08  (0) 2021.11.05
7. old-07  (0) 2021.11.04

 


1. 문제 설명


 

문제를 클릭해보자.

 

문제를 클릭하면 다음과 같이 O가 하나 튀어 나온다.

 

그 후 아무런 정보가 없다...

 

쿠키값에도 아무런 정보가 없다...

 

따라서 페이지 소스보기를 눌러 소스를 분석해보았다.

 

문제를 클릭했을때는 보이지 않던 hackme라는 문구와 Goal이라는 문구를 볼 수 있다.

 

뭐지? 하다가 문제 페이지로 다시 돌아가보니 옆으로 스크롤을 할 수 있었다.

 

스크롤을 하다보니 다음과 같은 Goal 점선을 볼 수 있다.

 

 

흠 뭔가 저 OGoal에 위치시켜야 할것 같았다.

 

그럼 다시 페이지 소스를 분석해보자.

 

핵심으로 봐야할 코드는 <a>에 있는 코드들이다.

 

코드는 다음과 같다.

 

<html>
<head>
<title>Challenge 10</title>
</head>

<body>

......

<a id=hackme style="position:relative;left:0;top:0"

onclick="this.style.left=parseInt(this.style.left,10)+1+'px';

if(this.style.left=='1600px')
  this.href='?go='+this.style.left" onmouseover=this.innerHTML='yOu' onmouseout=this.innerHTML='O'>O
  
</a>

......

</body>
</html>

 

먼저 a 태그의 idhackme이다.

 

따라서 문제에서도 힌트를 주었다. 

 

a 태그를 해킹해라라는 의미이다.

 

그다음 onclick 이벤트를 볼 수 있다.

 

말그대로 마우스로 클릭하면 발생하는 이벤트이다.

 

아까 O를 마우스로 클릭해보자.

 

 

O에 마우스를 올리니 yOu라고 바뀌면서 오른쪽으로 이동한다.

 

마우스를 올리니 yOu라고 바뀌고 마우스를 밖으로 빼니 다시 O로 돌아왔다.

 

이런 행동을 하는 코드는 다음과 같다.

 

onmouseover=this.innerHTML='yOu' onmouseout=this.innerHTML='O'>

 

그럼 남은 코드는 다음과 같다.

 

onclick="this.style.left=parseInt(this.style.left,10)+1+'px';

if(this.style.left=='1600px')
  this.href='?go='+this.style.left"

 

클릭하면 +1px 만큼 움직이는것이다.

 

그리고 this.style.left 값이 1600px이 되면 this.href='?go='+this.style.left로

 

뭔지 모르지만 ..?go로 이동한다.

 

따라서 이번 문제의 목표는 this.style.left 값을 1600px로 바꿔주면되는것이다.

 


2. 문제 풀이


개발자도구(F12)로 변경해도되지만 나는 웹 프록시인 피들러(클릭)를 사용해볼것이다.

 

 

먼저 F12를 눌러 Capturing을 시작해준다.

 

그 후 서버에서 응답오는 Response 패킷을 변조 하기위해 Alt+F11을 눌러준다.

 

그 후 문제 사이트를 F5로 새로고침을 하면 다음과 같이 Response 값을 변조 할 수 있다.

 

 

원래 1인 값을 문제에 맞게 1600으로 변조시킨다.

 

변조 시킨후 Alt+C를 눌러 다시 브라우져에게 전달한다.

 

브라우저에게 전달 후 O를 클릭해보면 아래의 그림처럼 Goal안에 들어간다.

 

 

Goal안에 들어간 O에 마우스를 올리면 yOu로 바뀌면서

 

문제에서 정한 링크로 가면서 문제를 Clear할 수 있다.

 

 

반응형

'웹 해킹 > Webhacking.kr' 카테고리의 다른 글

12. old-12  (0) 2021.11.09
11. old-11  (0) 2021.11.09
9. old-09  (0) 2021.11.08
8. old-08  (0) 2021.11.05
7. old-07  (0) 2021.11.04

 


이번 9번 같은 문제는 상당히 이해하기가 어려울 수 있습니다.

개인적으로 의식의 흐름대로 정리한 결과이며 정리한 결과가 정답이 아닐 수 있습니다.

또한 다소 내용이 복잡할 수 있습니다.


 


1. 문제 설명


 

먼저 문제를 클릭해보자.

 

 

이렇게 숫자가 1,2,3이 나와있고 Password를 입력하는 폼이 있다.

 

1번을 눌러보자.

 

 

1번을 눌러보니 Apple이라는 문구를 볼 수 있다

 

역시 Password를 입력하는 폼이 있다.

 

그럼 2번을 눌러보자.

 

 

이번에는 Banana이다.

 

3번을 눌러보자

 

 

3번을 눌러보니 Secret이라는 문구와 함께

 

컬럼 id와 no이 있다고 알려준다.

 

또한 no 3's id is password이라는 문구가 주어진다.

 

해석이 맞는지는 모르겠지만 3번의 id는 패스워드라는 의미이다.

 

즉, 3번의 ID를 찾으면 그것이 Password이고 이게 이번 8번 문제에서의 원하는 값인것 같다.

 

일단 공격 할 수 있는 포인트는 다음과 같이 2곳이라고 생각했다.

  1. 숫자를 의미하는 no
  2. Password를 입력하는 곳

숫자를 의미하는 noURL에서 볼 수 있다.

  1. webhacking.kr/challenge/web-09/?no=1
  2. webhacking.kr/challenge/web-09/?no=2
  3. webhacking.kr/challenge/web-09/?no=3

nopassword싱글 쿼터(')를 입력해보았다.

 

no' 를 넣으면 다음과 같은 URL이 나온다.

  • webhacking.kr/challenge/web-09/?no=%27

Password에 ' 에 넣으면 다음과 같은 URL이 나온다.

  • webhacking.kr/challenge/web-09/index.php?pw=%27

 

하지만 pw싱글 쿼터를 넣으면 다시 redirect가 되지만 no싱글 쿼터를 입력하면 

 

다음과 같이 Access Denied이라는 문구를 볼 수 있다.

 

 

이로써 공격할 포인트는 password가 아니라 no이라는것을 알 수있다.

 

왜냐? 싱글 쿼터를 입력하였을때 Access Denied이 뜨는것은

 

SQLi를 방지하기 위해 필터링이 되었음을 보여주는것이다.

 

그렇다면 이 문제는 어떻게 풀어야할까?

 

먼저 no필터링이 안되는것을 살펴봐야한다.

 

또한 필터링에 걸리지 않은 SQL문을 가지고 no 3의 ID를 알아내면 이번 문제를 해결 할 수 있을것 같다.

 

하지만 어떤것이 필터링이 된건지 이전의 문제처럼 소스 코드를 볼 수있는곳이 없다.

 

따라서 하나하나 넣어보면서 반응을 봐야한다.

  • 필터링: ', or, ||, and, &&, 공백(%20,%0a), >, <, =, from, select

몇 번 시도하니 위에 처럼 정리가 되었는데 일단 SQLi 문제를 풀때 공백과 from, select가 필터링 되면

 

SQLi를 작성하기 거의 힘들다. 

 

따라서 이문제를 풀기위해서는 경험상 블라인드 SQLi를 이용해야한다.

 

따라서 바이패스 되는 문자는 공백이 당연히 안되니

 

공백을 대신할 수 있는 괄호가 필수적으로 필요할것이다.

 

no에 괄호를 넣어보자.

 

Access Denied는 뜨지 않는다.

 

즉, 괄호를 활용 할 수 있다.


또한 selectfrom을 넣을 수 없다.

 

따라서 ascii 함수와 substr를 활용해서 3에 대한 ID 값 한글자씩 뽑아야한다.

 

따라서 ascii 함수도 필터링 되어있는지 보자.

 

webhacking.kr/challenge/web-09/?no=ascii

 

  • 필터링: ', or, ||, and, 공백(%20,%0a), >, <, =, from, select, ascii

ascii 함수가 필터링 되어 있다면 substr로 뽑아야한다.

 

substr를 넣어보자.

 

Access Denied가 뜨지 않는다.

 

따라서 substr은 사용할 수 있다는 의미이다.

 

substr로 함께 쓰이는 함수는 항상 if문이다. (substr 설명 클릭)

 

if문은 if(조건, , 거짓)이다.

 

if문안에 조건문을 실행하였을때 참이면

 

if문의 두번째 인자인 , 거짓이면 if문의 세번째 인자인 거짓을 반환한다.

 

예를들어, if(1+1=2, 1,0)이면 조건문에 1+1=2이므로 참이되어 1이 반환되는 의미이다. 

 

그렇다면 if문을 활용해서 어떻게 블라인드 SQLi를 수행할까?

 

위에서 설명하였듯이 if문과 substr를 사용할 수 있다고 하였다.

 

if(substr(id,1,1)=id의 첫번째 hex값, 1,2)

 

이렇게 작성해보았다.

 

위에 페이로드를 조금 풀어서 설명하면 substr 함수로 id의 첫번째 글자 1개를 가져온다는 의미이다.

 

그게 id 첫번째의 hex값이 만약 a(0x61)이면 1이 반환이 되고 a가 아니면 2를 의미한다.

 

즉 1이 반환되면 Apple이라는 문구를 볼 수 있을것이고 2가 반환되면 Banana를 볼 수 있다.

 

넣어보자.

 

webhacking.kr/challenge/web-09/?no=if(substr(id,1,1)=0x61,1,2)

 

Access Denied가 뜬다.

 

그렇다면 여기서 =이 필터링 되어있다는것도 알 수 있다.

 

따라서 =를 대신할 수있는 likein을 넣어보자.

 

like를 먼저 넣어보자.

 

webhacking.kr/challenge/web-09/?no=if(substr(id,1,1)like(0x61),1,2

 

 

????

 

Apple이 보인다.

 

그럼 id의 첫번째 값이 a라는 소리인데 혹시 잘못 생각할 수도있으니 

 

webhacking.kr/challenge/web-09/?no=if(substr(id,1,1)like(0x62),1,2)

 

a가 아닌 b를 넣어보자.

 

Apple이라는 문구가 없다.

 

따라서 블라인드 SQLi가 먹혔다.

 

이걸 가지고 이제 문제를 풀어보자!


2. 문제 풀이


위의 문제 설명에서 substr, if, like 또는 in을 사용 할 수 있는것을 확인하였다.

 

substr로 문자를 뽑아 내기 위해서는 3번의 id의 전체 길이를 알아야한다.

 

그래서 코드를 작성해보았다.

webhacking.kr/challenge/web-09/?no=if(length(id)like(5),1,2)일 때는

 

위의 실행 결과 처럼 ID의 길이가 5자리라고 나온다.

 

ID의 자리가 5자리면 'Apple'이다.

 

우리가 원하는 ID값은 no의 값이 3번일때이다.

 

그렇다면 webhacking.kr/challenge/web-09/?no=if(length(id)like(6),2,1) 일때는

 

길이가 6일때는 Banana이니깐 참이다.

 

따라서 if문에서는 참인 결과인 2가 반환되고 no에는 2가 들어가기때문에 Banana 문구가 나와야한다.

 

Apple이 나온다.

 

이게 뭘까?

 

왜 Apple이 나올까???

 

???????????????????????

 

위의 쿼리를 다시 보면 id의 길이가 6이면(banana)이면 참이니깐 2를 반환해서 Banana가 나와야한다.

 

테이블의 정보가 아래 처럼 있다고 가정하자.

 

 

그리고 밑에 쿼리문이 있다고 가정하자.

위의 쿼리문을 다시 해석하자면 id의 길이가 5이면 참인 1이 리턴될것이고

 

id의 길이가 5가 아니면 2리턴될것이다.

 

하지만 여기서 length(id),id의 길이 물었으나 어떤 no의 대한 id인지

 

정보가 없으니 no이 1에서 3까지 전부다 위의 쿼리를 실행하면서

 

조사할것이다라고 생각을 하였다.

 

그 후 다음과 같이 총 3개의 쿼리를 날려 보았다.

 

 

첫번째만 Apple이라는 문구가 나오고 나머지 2개의 쿼리에서는 어떠한 문구를 볼 수 없었다.

 

많은 생각에 걸쳐 다음과 같이 결론을 내렸다.

 

  1. 총 3개의 id에 대해서 조사를 진행한다.
  2. 그 중 첫번째 no이 1일때를 조사한다.
  3. no이 1일때의 id는 apple이다.
  4. 길이가 5자리이다.
  5. 따라서 if문의 최종적인 리턴값은 1이다.
  6. if문의 최종적인 리턴값인 1과 현재 no이 1일때 조사하고있으니 1=1이다.
  7. 1=1이니 최종적으로 true가 Apple이 반환된다.

다시 한번 예를들어 보자.

 

id의 길이가 6일때를 보자.

 

결과부터 보자면 다음과 같은 결과가 나온다.

 

 

아까 위에서 no이 1번에서 3번까지 있기 때문에 총 3번을 조사한다고 하였다.

 

no이 1일때를 살펴보자.

  1. no이 1일때를 보니 id값이 Apple로 총 id의 길이가 5이다.
  2. 따라서 id의 길이가 6인지를 판단했을때 이는 거짓이 되므로 if문의 거짓인 1이 리턴된다.
  3. if문의 최종적인 리턴값은 1, 또한 현재 테이블에서 조사하고 있는 no이 1이다.
  4. if문의 최종적인 리턴값 1과 현재 조사하고있는 no의 1이 같으니 1=1이다.
  5. 따라서 1=1이기 때문에 결과적으로 True니 Apple이 나온다.

no이 2일때를 살펴보자.

  1. no이 2일때를 보니 id값이 Banana로 총 id의 길이가 6이다.
  2. 따라서 id의 길이가 6인지를 판단했을때 이는 참이 되므로 if문의 참인 2가 리턴된다.
  3. if문의 최종적인 리턴값은 2, 따라서 no=2로 들어가기 때문에 no이 2인 Banana가 리턴된다.
  4. if문의 최종적인 리턴값 2과 Banana의 no이 2로 같다.

따라서 2=2이기 때문에 결과적으로 True니 Bananna이 나온다.

no이 3일때를 살펴보자.

  1. no이 3일때를 보니 id값이 ????로 총 id의 길이가 ????이다.
  2. 따라서 id의 길이가 6인지를 판단했을때 이는 거짓이 되므로 if문의 거짓인 1이 리턴된다.
  3. if문의 최종적인 리턴값은 1, 따라서 no=1로 들어가기 때문에 no이 1인 Apple이 리턴된다.
  4. if문의 최종적인 리턴값 1과 3번의 id값인 ?????이 같지 않다.
  5. 따라서 1=3이 아니기 때문에 결과적으로 false이니 무시된다.

 

이렇게 총 3번을 돌면서 판단하는데 제일 먼저 값이 나온 no이 1일때의 Apple이 출력되고

 

뒤의 Banana도 쿼리상 출력은 되었지만 첫번째 Apple만 출력되는것이다.

 

그렇다면 no이 3일때의 id의 길이를 구해보자.

 

앞에서 한 방식 그대로 적용하기 위해 아래처럼 쿼리를 작성하였다.

 

이렇게 no이 3일때의 길이가 1에서부터 증가해서 만약 20까지 범위를 주었다면

 

20까지 증가하면서 no이 3일때의 길이가 맞을때 Secret이라는 문구를 볼 수 있다면

 

그것이 no 3의 길이라고 생각하고 코드를 작성하였다.

 

코드를 작성하고 결과 값을 보니깐 다음과 같았다.

 

 

위의 결과를 보면 id의 길이가 5일때 빼고는 나머지가 다 Apple이 나왔다.

 

왜 이렇게 나온지 살펴보자.

 

길이가 1일때 - if(length(id)like(1),3,1)

  1. 길이가 1인것은 테이블에 존재하지 않는다.
  2. 존재하지 않기 때문에 if문에서는 거짓인 1이 리턴된다.
  3. if문의 최종적인 리턴값은 1
  4. if문의 최종적인 리턴값 1과 no이 1인 경우는 Apple이다.
  5. Apple의 no은 1이다.
  6. if문의 최종적인 리턴값과 5번의 no을 비교했을때 같다.
  7. 따라서 Apple이 나온다.

길이가 5일때 - if(length(id)like(5),3,1)

  1. 길이가 5인것을 no이 1~3까지 순차적으로 조사한다.
  2. no이 1일때의 id의 길이를 보니 Apple로 총 5자리이다.
  3. if문에서 length(5)를 물었기 때문에 참이므로 if문의 참인 3을 반환한다.
  4. if문의 최종적인 리턴값은 3이다.
  5. if문의 최종적인 리턴값은 3이지만 현재 검색하는 no은 1일때이다.
  6. 리턴값과 현재 조사한 no이 다르기 때문에 값이 나오지 않는다.

길이가 6일때 - if(length(id)like(6),3,1)

  1. 길이가 6인것을 no이 1~3까지 순차적으로 조사한다.
  2. no이 1일때의 id의 길이를 보니 Apple로 총 5자리이다.
  3. if문에서 length(6)를 물었기 때문에 거짓이므로 if문의 거짓인 1을 반환한다.
  4. if문의 최종적인 리턴값은 1이다.
  5. if문의 최종적인 리턴값은 1이고 현재 검색하는 no은 1이다.
  6. 리턴값과 현재 조사한 no이 같기 때문에 값이 Apple이 나온다.
  7. no이 1일때가 끝나고 no이 2로 넘어간다.
  8. no이 2일때 id의 길이를 보니 Banana로 총 6자리이다.
  9. if문에서 length(6)를 물었기 때문에 참이므로 if문의 참인 3을 반환한다.
  10. if문의 최종적인 리턴값은 3이다.
  11. if문의 최종적인 리턴값은 3이고 현재 검색하는 no은 2이다.
  12. 리턴값과 현재 조사한 no이 다르기 때문에 값이 나오지 않는다.

여기까지 보고 느낀점은

 

no이 3일때의 id의 길이와 값을 구하기 위해서는 if문의 참일때에는 3이 들어가야하고

 

거짓을때는 1,2가 아닌 다른 숫자를 써야한다는것이다.

 

왜냐하면 이 이유는 위에 과정을 보면 알 수 있다.

 

따라서 0과 또는 4이상의 숫자를 아무 숫자나 입력하면 된다.

 

4를 넣어서 다시 코드를 돌려보자.

 

 

id의 길이가 11일때 no이 3일때 볼 수있었던 Secret이 나온다.

 

이는 위의 과정처럼 혼자서 생각해보자!

 

끝으로 이제 문제를 해결 할 수 있을것 같다.

 

substr을 활용해서 no이 3일때 id의 길이가 11자인 값을 뽑아내보자.

 

나온 결과를 Password 입력에 입력해보자.

 

하지만 안된다.

 

조금만 다시 생각해보니 MYSQL은 소문자 대문자를 구별하지 않는다.

 

따라서 다시 소문자로 바꿔서 입력해보니 Clear 되었다.

 

 

참 설명이 지저분하고 어렵다.

 

하지만 이렇게 하나 하나 풀어서 설명하는 곳이 잘 없어서 혼자 이해하는데 힘들었다.

 

이렇게 이해한것도 틀린거일 수도 있다.

 

지금까지 9문제를 풀었는데 가장 이해하기 어려웠던 문제인것 같다.

반응형

'웹 해킹 > Webhacking.kr' 카테고리의 다른 글

11. old-11  (0) 2021.11.09
10. old-10  (0) 2021.11.08
8. old-08  (0) 2021.11.05
7. old-07  (0) 2021.11.04
6. old-06  (0) 2021.11.03

모의해킹을 하다보면 JEB분석 툴을 사용하기 위해서는 자바가 필수적으로 필요하다.

 

따라서 진단 및 분석을 위해서는 자바를 꼭 설치해줘야한다.

 

또한 JDKJRE 아무꺼나 설치해도 상관없다.

 

하지만 JRE는 꼭있어야하니 JRE를 설치해보자.

 

설치를 해보자.

 

일단 공식 홈페이지에 가서 다운로드를 받아준다. (클릭)

 

그 후 Java SE Runtime Environment 항목에서

 

jre-8u281-windows-x64.exe를 검색해서 다운로드 받아주자.

 

 

다운로드된 파일을 실행하자.

 

실행한 후 대상 폴더 변경을 원하는 폴더에 변경해도되고 그냥 설치를 눌러 설치를 진행해도된다.

 

 

그렇게 쭉 설치를 완료하자.

 

완료 한 후 자바를 사용하기위해서는 환경변수를 등록을 해줘야한다.

 

환경변수를 등록하는 방법은 다음과 같다.

 

시스템 속성-환경변수를 클릭한다.

 

환경변수를 클릭한 후 시스템 변수Path를 찾아 더블클릭을 해준다.

 

 

그 후 새로 만들기를 눌러 자바가 설치된 경로를 적어준다.

 

꼭 bin까지 적어줘야한다.

 

 

그 후 확인을 누르면 환경변수 설정은 끝났다.

 

잘 실행되는지 보자.

 

cmd창에 java라고 입력하면 자바가 실행된다.

반응형

모의해킹을 하다보면 이든 이든 진단을 하기 위해서는 프록시는 필수다.

 

대표적으로 피들러 버프 많이 사용된다.

 

하지만 모바일을 진단할때는 피들러버프+피들러를 많이 사용한다.

 

먼저 피들러를 다운로드 받자. (클릭)

 

 

저기에 정보를 입력하고 Download for Windows 클릭해서 다운로드 받아주자.

 

 

그리고 그냥 설치 해주면된다.

 

설치가 끝나면 피들러를 실행 시키면 다음과 같은 화면을 볼 수 있다.

 

이처럼 밑에 Capturing을 볼 수 있는데 이것은 지금 웹 프록시가 작동중이다는것이다.

 

피들러가 켜진 상태로 네이버에 들어가보자

 

 

이렇게 20번째로 잡힌 패킷에서 URL이 네이버인것을 볼 수 있는데 해당 패킷을 더블 클릭하면

 

오른쪽에 웹 프록시에서 잡은 패킷을 볼 수 있다.

 

하지만 저렇게 노란색 문구로 HTTPS decryption이 불가능하다고 한다.

 

HTTPS 프로토콜은 암호화 프로토콜이기 때문에 제 3자가 볼 수 없다.

 

하지만 웹 프록시에서 나의 패킷을 볼 수가 있는데 이를 보기 위해서 인증서를 설치를 해주어야한다.

 

따라서 저기 노란색 문구를 클릭해서 피들러 인증서를 설치해보자.

 

 

위에서 Decryption HTTPS traffic을 체크하면 옆의 피들러의 인증서를 설치하겠냐고 묻는다.

 

Yes를 눌러주자.

 

또 Yes

 

 

또 또 Yes

또 또 또 Yes

또 또 또 또 Yes

 

이렇게 하다보면 이제 HTTPS 프로콜의 내용도 볼 수있다.

 

다시 네이버에 접속해보자.

 

 

이제 HTTPS 패킷의 내용도 볼 수 있게된다!

 

추가


 

 

그리고 만약에 브라우저에서 서버로 Requset할 때 패킷을 수정하고 싶으면 F11을 누르고 

 

패킷을 수정하면 된다.

 

 

또한 서버로 보내고 응답오는 Response 패킷을 수정하고 싶으면 Alt+F11을 누르고

 

Response 패킷을 수정하면 된다.

 

 

실제 문제에서 사용하는 예시는 여기(클릭)에 있다.

반응형

'기타' 카테고리의 다른 글

[Anaconda] Frida 설치  (0) 2022.01.23
[Java] 자바 JR 설치  (0) 2021.11.06
[Python] 파이참(Pycharm) 설치  (0) 2021.11.06
[Python] 아나콘다(Anaconda) 설치  (0) 2021.01.15
Apache 및 PHP 연동  (0) 2020.12.08

이번에는 파이참을 설치해볼것이다.

 

파이참은 쉽게 말해서 파이썬 통합개발환경이다.

 

사실 파이썬은 별도의 IDE 없이도 사용할 수있다.

 

cmd에 python을 실행하고 코드를 입력해서 실행해도 된다.

 

하지만 IDE에서 코딩하면 편의성 때문에 안 쓸 수가 없다.

 

설치 과정은 다음과 같다.

 

먼저 파이참을 다운로드 받자. (클릭)

 

위의 링크로 들어가면 다음과 같은 화면이 보일 것이다.

 

 

여기서 Community를 눌러 다운로드 받아 주자.

 

받은 파일을 실행하자.

 

실행 한 후 아래 처럼 Next를 눌러준다.

 

 

그 후 다음과 같이 3곳에 체크를 해주고 다시 Next로 설치를 해준다.

 

 

 

반응형

'기타' 카테고리의 다른 글

[Anaconda] Frida 설치  (0) 2022.01.23
[Java] 자바 JR 설치  (0) 2021.11.06
[Web-proxy] 피들러(Fiddler) 설치 및 사용법  (0) 2021.11.06
[Python] 아나콘다(Anaconda) 설치  (0) 2021.01.15
Apache 및 PHP 연동  (0) 2020.12.08

 


1. 문제 설명


 

 

이번 문제도 SQLi 문제이다.

 

문제를 클릭해보자.

 

문제를 클릭하면 다음과 같은 화면을 볼 수 있었다.

 

 

 

이게 뭐지?

 

done! (0/70)??

 

뭔가 시도 횟수를 의미하는것 같았다.

 

역시나 뭐 별 다른 기능이 없어 view-source를 클릭해서 소스코드를 보았다.

 

역시나 소스코드가 길었다.

 

이럴때는 하나하나 분석을 해야한다.

 

$agent=trim(getenv("HTTP_USER_AGENT"));

$ip=$_SERVER['REMOTE_ADDR'];

if(preg_match("/from/i",$agent))
{
  echo("<br>Access Denied!<br><br>");
  echo(htmlspecialchars($agent));
  exit();
}

 

먼저 getenv 함수를 사용해서 HTTP_USER_AGENT 값을 가져온다.

 

가져온 값에서 trim 함수를 이용해서 나온 값을 agent라는 변수에 담는다.

 

그럼 getenv 함수와 trim 함수를 알아보자.

 

 

getenv 함수는 위와과 같이 정의 되어있다.

 

getenv 함수는 환경 변수의 값을 가져오는 함수이다.

 

그리고 인자 값에 가져오고 싶은 환경 변수 값을 적어주는데

 

문제에서는 "HTTP_USER_AGENT"가 인자로 들어가있다.

 

HTTP_USER_AGENT웹 사이트를 접속한 컴퓨터의 웹 브라우저 정보를 의미한다.

 

다음은 trim 함수이다.

 

 

trim 함수는 whitespace공백strip 하는 함수이다.

 

하지만 문장 가운데 존재하는 공백이 아니라 처음 시작과 끝의 공백을 제거하는 함수이다.

 

예를 들어,  __hello__라는 문장이 있다고 가정하자.

 

 

하지만 trim 함수를 사용하면 처음 시작 2개의 공백과 끝의 2개의 공백을 제거하여

 

다음과 같은 문장이 나온다.

 

 

여기까지 정리하자면 접속한 웹 브라우저의 정보를 읽어와 앞 뒤 공백을 제거한다는 의미이다.

 

다음 코드는 $ip=$_SERVER['REMOTE_ADDR'] 인데

 

REMOTE_ADDR는 웹 사이트에 접속한 컴퓨터의 ip 주소를 가져온다.

 

그 다음 preg_match 함수가 또 보인다. (preg_match -> 클릭)

 

regexp 하는 역할을 하는데 agent라는 변수에 들어간 웹 브라우저 정보에서 from을 필터링한다.

 

다음 코드를 보자.

 

$db = dbconnect();

$count_ck = mysqli_fetch_array(mysqli_query($db,"select count(id) from chall8"));

if($count_ck[0] >= 70)
{ 
  mysqli_query($db,"delete from chall8"); 
}

$result = mysqli_query($db,"select id from chall8 where agent='".addslashes($_SERVER['HTTP_USER_AGENT'])."'");

$ck = mysqli_fetch_array($result);

 

웹 브라우저 정보에 "from"이라는 단어가 없으면 dbconnect 함수를 이용해서 db에 접속한다.

 

그 후 다음과 같은 쿼리로 DB에 쿼리를 날린다.

 

말 그대로 chall8이라는 테이블에 id의 갯수가 몇개있는지 묻는 쿼리이다.

 

그 후 countid의 갯수를 count_ck라는 변수에 넣고

 

count_ck70개 이상이면 chall8 테이블을 삭제한다.

 

만약에 70개 미만이면 코드가 밑으로 내려와 DB에 다음과 같은 쿼리로 묻는다.

 

 

위의 쿼리의 의미를 해석 하기 전에 addslashes 함수에 대해서 알아보자.

 

addslashes 함수에 대한 설명은 여기에 자세히 설명이 되어있다. (클릭)

 

$_SERVER['HTTP_USER_AGENT']유저의 브라우저 접속환경을 의미한다.

 

브라우저 접속환경이 왜필요할까?

 

서버의 입장에서는 브라우저별로 스타일을 다르게 보여지게 하거나 필요한 동작이 다를 수 있다.

 

무튼 다시 쿼리문을 정리하자면 다음과 같이 정리할 수 있다.

 

 

그럼 해석 해보자면 chall8이라는 테이블에서 어떤 사용자의 user_agent 값이 있다면

 

user_agent 값을 가지는 id를 보여달라는것이다.

 

만약 나의 idtest이고 user_agent값이 123123이라면

 

chall8이라는 테이블에서 agent의 값이 123123id는 누구냐라는 의미이다.

 

쿼리상 문제가 없으면 id값(test)이 이제 ck라는 변수에 들어가게된다.

 

다음 코드를 보자.

 

if($ck)
{
  echo "hi <b>".htmlentities($ck[0])."</b><p>";
  
  if($ck[0]=="admin")
  {
    mysqli_query($db,"delete from chall8");
    solve(8);
  }
}

if(!$ck)
{
  $q=mysqli_query($db,"insert into chall8(agent,ip,id) values('{$agent}','{$ip}','guest')") or die("query error");
  echo("<br><br>done!  ({$count_ck[0]}/70)");
}

 

ck 변수에 이제 값(id)이 있다면 누구인지 echo 함수를 이용해서 알려주고

 

만약에 admin이라면 chall8이라는 테이블을 삭제 시킨 후

 

solve(8)이라는 함수를 실행 시키면서 문제를 clear 할 수 있다.

 

하지만 ck라는 변수 즉 user_agent로 조회를 했을때 id가 없다면 insert 함수를 이용해서

 

chall8이라는 테이블에 agent, ip, id 값을 각각 넣어준다.

 

여기까지 정리하면 다음과 같다.

 

해당 문제는 idadmin으로 맞춰줘야지만 solve(8) 함수를 실행시킬 수 있다.

 

그렇기 위해서는 adminuser_agent 값을 알아야한다.

 

그 이유는 id를 뽑기 위해서는 밑의 쿼리를 사용해야하기 때문이다.

 

 

하지만 우리는 adminuser_agent 값을 모른다.

 

아니면 chall8이라는 테이블에 admin이라는 id를 가진 값이 없을 수도 있다.

 

따라서 adminuser_agent 값을 알아내던, chall8이라는 테이블에 idadmin을 생성해줘야할것같다.

 


2. 문제 풀이


 

이번 문제를 풀기 위해선 2개의 가정을 생각해보았다.

  1. chall8이라는 테이블에 id가 admin이 있을 경우 -> admin의 user_agent 값을 알아내야함 or 우회
  2. chall8이라는 테이블에 id가 admin이 없을 경우 -> chall8에 id가 admin을 insert 해야함

위의 처럼 정리 해보았다.

 

확률상 1번일 확률은 적다고 생각했다.

 

왜냐하면 php 코를 봤을 때 adminuser_agent를 알아내기 위한 방법이 현재로써는 보이지 않았다.

 

따라서 2번의 가정으로 문제를 풀어봤다.

 

그 이유는 php 코드를 봤을때 아래의 그림처럼 insert문이 존재했기 때문이다.

 

 

그리고 insert에서 사용자의 입력이나 값이 들어가는곳은 2곳이다.

 

agentip이다.

 

ip는 서버에 접속한 클라이언트의 ip를 $ip=$_SERVER['REMOTE_ADDR']로 설정하기 때문에

 

ipSQLi를 하기는 어렵다고 생각하고 agent 변수에 

 

즉, user-agent 값을 수정해서 insert문을 이용해서 id가 'guest'가 아닌 'admin'으로 수정하려고한다.

 

user-agent 값을 수정하기 위해서는 web-proxy를 사용해야한다.

 

이렇게 웹 프록시로 보면 User-Agent에 접속한 브라우저나 환경 값들이 들어가 있다.

 

여기에 SQLi를 수행할것이다.

 

먼저 SQLi가 잘 먹히는지 확인하기 위해

 

프록시를 사용하여 User-Agentguest01이라고 입력하고 서버로 전송해보자.

 

 

 

chall8 테이블에 guest01이라는 user-agent값이 없으니 아래의 SQLiinsert할것이다.

 

그렇다면 다시 guest01를 그대로 user-agent 값에 넣어서 서버로 전송하면 어떻게 될까?

 

chall8guest01이 라는 user-agentinsert 되었기 때문에 "hi guest"라는 문구를 볼 수가 있다.

 

그렇다면 이제 user-agent를 변경해서 insert가 되는것을 확인했으니

 

chall8에 존재하지않는 user-agent 값과 뒤의 'guest' 부분을 'admin'으로 바꿔주고

 

다시 insert 했을때 사용했던 user-agent 값으로 변경하여 서버로 전송하면

 

"hi guest"가 아닌 admin이 될것이다.

 

페이로드는 다음과 같다.

 

이렇게 SQL문을 만들 수 있다.

 

뒤에 #이라고 넣어준 이유는 뒤에 남아 있는 원래의 SQL문을 주석 처리하기 위함이다.

 

 

이렇게 SQL문을 만들었으면 이제 직접 프록시를 이용하여 작성한 페이로드를 넣어보자.

 

 

guest02라는 새로운 user-agent 값과 아이피 주소, 그리고 guest가 아닌 admin을 넣어준다.

 

 

 

그 후 정상적으로 chall8이라는 테이블에 등록되었다는 done!이라는 문구를 볼 수 있다.

 

다시 guest02로 요청을 한다.

 

 

요청을 하게 되면 서버에서 clear 했다는 문구를 볼 수 있다.

 

 

반응형

'웹 해킹 > Webhacking.kr' 카테고리의 다른 글

10. old-10  (0) 2021.11.08
9. old-09  (0) 2021.11.08
7. old-07  (0) 2021.11.04
6. old-06  (0) 2021.11.03
5. old-05  (0) 2021.11.01

+ Recent posts