SlideShare a Scribd company logo
1 of 20
Download to read offline
DEFCON Prequal 2019
Vitor
#Android #DEX #nativelib #Javascript
STEP 1: p1EncFn
• ooo.vitor.MainActivity
• goal : fc.mValid == true
STEP 1: p1EncFn
• len(OOO{SOMETHING}	)	==	45
• g0(<…SOMETHING…>)
• dp1()
• cf()
STEP 1: p1EncFn
• len(OOO{SOMETHING}	)	==	45
• g0(<…SOMETHING…>)
• 키를 4byte씩 잘라서 XOR
• bArr
• dp1()
• cf()
STEP 1: p1EncFn
• len(OOO{SOMETHING}	)	==	45
• g0(<…SOMETHING…>)
• bArr
• dp1()
• MD5(bArr)해서 key로 사용
• p1EncFn을 AES decrypt
• p1Fn으로 리턴
• cf()
STEP 1: p1EncFn
• len(OOO{SOMETHING}	)	==	45
• g0(<…SOMETHING…>)
• dp1()
• cf()
• dp1()에서 복호화한 클래스 로드
STEP 1: p1EncFn
• Goal
• p1EncFn을 decrypt하는 키의 일부 찾기
• public	static	String p1EncFn	=	
"ckxalskuaewlkszdva";
• PKZIP으로 시작할 것이라는 추측 가능
• 해당 magic number로 시작하도록
뽑아주는 키만 수집
• 그 중 제대로 복호화해주는 것 골라내기
• ’17	01	2F	03’
from Crypto.Cipher import AES
from itertools import product
from multiprocessing	import Pool
import hashlib
num_threads =	8
with open("../vitor_unzip/vitor/assets/ckxalskuaewlkszdva",	"rb")	as f:
file_content =	f.read()[:16]
magic	=	b"PKx03x04" #PKZIP	magic
cnt =	0
iv	=	[19,	55,	19,	55,	19,	55,	19,	55]
magic_iv_xor =	bytes([magic[i]	^	iv[i]	for i in range(4)])
def f(num):
key_list =	[]
for c	in product(range(128),	repeat=3):
r	=	128 //	num_threads
for i in range(r	*	num,	r	*	(num	+	1)):
key_str =	bytes(c)	+	bytes([i])
key	=	hashlib.md5(key_str).digest()
aes =	AES.new(key,	AES.MODE_ECB)
if aes.decrypt(file_content)[:4]	==	magic_iv_xor[:4]:
print(key_str)
key_list.append(key_str)
return key_list
with Pool(processes=8)	as p:
key_list =	p.map(f,	range(8))
STEP 2: 또;;
• ooo.p1.P1
• goal : cf의 return == true
• g1()
• 앗 데자뷰인가
STEP 2: 또;;
• Goal
• def decrypt하는 키의 일부 찾기
• public	static	String def	=	
"mmdffuoscjdamcnssn";
• x7fELF으로 시작할 것이라는 추측 가능
• 해당 magic number로 시작하도록
뽑아주는 키만 수집
• 그 중 제대로 복호화해주는 것 골라내기
• ‘3C	27	43	60’
from Crypto.Cipher import AES
from itertools import product
from multiprocessing	import Pool
import hashlib
num_threads =	8
with open("../vitor_unzip/vitor/assets/mmdffuoscjdamcnssn",	"rb")	as f:
file_content =	f.read()[:16]
magic	=	b"x7fELF" #ELF
cnt =	0
iv	=	[19,	55,	19,	55,	19,	55,	19,	55,	19,	55,	19,	55,	19,	55,	19,	55]
magic_iv_xor =	bytes([magic[i]	^	iv[i]	for i in range(4)])
def f(num):
key_list =	[]
for c	in product(range(128),	repeat=3):
r	=	128 //	num_threads
for i in range(r	*	num,	r	*	(num	+	1)):
key_str =	bytes(c)	+	bytes([i])
key	=	hashlib.md5(key_str).digest()
aes =	AES.new(key,	AES.MODE_ECB)
if aes.decrypt(file_content)[:4]	==	magic_iv_xor[:4]:
print(key_str)
key_list.append(key_str)
return key_list
with Pool(processes=8)	as p:
key_list =	p.map(f,	range(8))
STEP 3: libabc.so
• JNICALL	Java_ooo_p1_P1_xxx()
• g2()
• dp3()
• 쉘코드?!
STEP 3: libabc.so
• JNICALL	Java_ooo_p1_P1_xxx()
• g2()
• 키를 4바이트씩 잘라서 XOR
• bArr
• dp3()
• 파일 xtszs… 를 4바이트씩 XOR
• 결과는 쉘코드일것
• 함수 프롤로그일까???
• 쉘코드?!
STEP 3: libabc.so
• JNICALL	Java_ooo_p1_P1_xxx()
• g2()
• 키를 4바이트씩 잘라서 XOR
• bArr
• dp3()
• 파일 xtszs… 를 4바이트씩 XOR
• 결과는 쉘코드일것
• 함수 프롤로그일까??? 땡
• NOPsled가 있었네욤
• 쉘코드?!
STEP 3: libabc.so
• Goal
• 쉘코드를 만들어주는 키의 일부 찾기
• NOPsled로 시작할 것이라는 추측 가능
• x90x90x90x90으로 시작하도록
• ‘6E	63	27	4E’
from itertools import product
from multiprocessing	import Pool
import struct
def	p32(x):
return struct.pack("<L",	x)
num_threads =	8
with open("../vitor_unzip/vitor/assets/xtszswemcwohpluqmi",	"rb")	as f:
file_content =	f.read()
#magic	=	b"xb8x37x13x03x00"
#magic	=	b"xffxf5"
magic	=	b"x90x90x90x90" #NOPsled
ttlist =	[]
for	j	in	range(100):
ttlist.append(struct.unpack("<L",	file_content[4*j	:	4*j+4])[0])
def decrypt(ct,	key):				
pt =	b""
for i in range(len(ct)	//	4):
pt +=	p32(ttlist[i]	^	key)
key	+=	0x31333337
key	%=	0x100000000
return	pt
def f(num):
key_list =	[]
for i,	j,	k	in product(range(128),	repeat=3):
r	=	128 //	num_threads
for	l	in range(r	*	num,	r	*	(num	+	1)):
key	=	(l	<<	24)	^	(k	<<	16)	^	(j	<<	8)	^	i
if magic	in	decrypt(file_content,	key):
print(key)
key_list.append(key)
return key_list
Step 4: Shellcode
• 아직 끝나지 않았다
• v5 = 2
• v4 = 인자로 받아온 flag index
• flag[0x10:0x14]^flag[0x20:0x24]^flag[0x30:0x34]	
• 쉘코드의 뒤쪽 (offset 0xC8부터) decrypt 한번 더
• offset 0xC8부터 XOR
• flag[0x10:0x14] ^ flag[0x20:0x24]
^ flag[0x30:0x34]	= 42	18	33	13
Step 4: Shellcode
• ROP Chain
Step 4: Shellcode
• ROP Chain
• flag[0x14:0x18] ^ flag[0x28:0x2c]
• 얘가 rol 하면서 4byte씩 xor함
• 뭘 만들어 주려고?
xor ecx,	ecx
xor ecx,	DWORD	PTR	[edi+0x14]
xor ecx,	DWORD	PTR	[edi+0x28]
xor DWORD	PTR	[esi],	ecx
add	esi,0x4
rol ecx,0x8
sub	ebx,0x4
…	<loop>	…
mov	eax,0x31337
ret
Step 4: Shellcode
• ROP Chain
• flag[0x14:0x18] ^ flag[0x28:0x2c]
• 얘가 rol 하면서 4byte씩 xor함
• 뭘 만들어 주려고? HTML
• 이 밑에 memcmp(mmm,	"<html>",	6u)
• cxnvh… 는 <html>로 시작
• 56 2D 52 5D
Step 5: Web ;-(
• ???
Step 5: Web ;-(
• ???
• 합리적 의심 타임
• var	_0x2d96 =
['c2V0RmxhZ0FzVmFsaWQ=','ZmxhZw==','c3Vic3Ry','ID0+IHBIZF8xd19lNHJMMTNyOyl9
','SlNJbnRlcmZhY2U='];
• var	_0x1081d6 =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
• 속는 셈 치고 BASE64 decode
• ['setFlagAsValid', 'flag', 'substr', ' => pHd_1w_e4rL13r;)}', 'JSInterface’]
• 키의 뒤쪽 21글자를 주웠다!
Step 6: Z3
• 조건에 맞게 Z3 돌리기
• 이 때 각 step별로 찾았던 키들을 잘 넣어야 SAT
'OOO{pox&mpuzz,U_solve_it =>	pHd_1w_e4rL13r;)}'
step1key[j]	=	step1key[j]	^	flag[4	+	4*i +	j]
step2key[j]	=	step2key[j]	^	flag[4	+	4*(i+1)	+	j]
step3key[j]	=	step3key[j]	^	flag[4	+	4*(i-1)	+	j]
step4key[j]	=	step4key[j]	^	flag[4*i +	j]
step5key[j]	=	step5key[j]	^	flag[4*i +	j]

More Related Content

What's hot

Realm: 초고속 데이터베이스
Realm: 초고속 데이터베이스Realm: 초고속 데이터베이스
Realm: 초고속 데이터베이스Leonardo YongUk Kim
 
Kth개발자 세미나 1회
Kth개발자 세미나 1회Kth개발자 세미나 1회
Kth개발자 세미나 1회Byeongsu Kang
 
Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706Yong Joon Moon
 
android stuff1
android stuff1android stuff1
android stuff1Jin Jiu
 
[113]how can realm_make_efficient_mobile_database
[113]how can realm_make_efficient_mobile_database[113]how can realm_make_efficient_mobile_database
[113]how can realm_make_efficient_mobile_databaseNAVER D2
 
NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기
NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기
NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기Jong Wook Kim
 
Learning Node Book, Chapter 5
Learning Node Book, Chapter 5Learning Node Book, Chapter 5
Learning Node Book, Chapter 5Ji Hun Kim
 
Sha 2017-teaser-round website attack writeup
Sha 2017-teaser-round website attack writeupSha 2017-teaser-round website attack writeup
Sha 2017-teaser-round website attack writeupSeungyong Lee
 
Windows kernel basic exploit
Windows kernel basic exploitWindows kernel basic exploit
Windows kernel basic exploitKyoungseok Yang
 
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSStartup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSCirculus
 
[2013 CodeEngn Conference 09] wh1ant - various tricks for linux remote exploits
[2013 CodeEngn Conference 09] wh1ant - various tricks for linux remote exploits[2013 CodeEngn Conference 09] wh1ant - various tricks for linux remote exploits
[2013 CodeEngn Conference 09] wh1ant - various tricks for linux remote exploitsGangSeok Lee
 
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013Esun Kim
 
UML distilled 1장 스터디 발표 자료
UML distilled 1장 스터디 발표 자료UML distilled 1장 스터디 발표 자료
UML distilled 1장 스터디 발표 자료beom kyun choi
 
[Algorithm] Shell Sort
[Algorithm] Shell Sort[Algorithm] Shell Sort
[Algorithm] Shell SortBill Kim
 
도커없이컨테이너 만들기 8편 - pid namespace
도커없이컨테이너 만들기 8편 - pid namespace도커없이컨테이너 만들기 8편 - pid namespace
도커없이컨테이너 만들기 8편 - pid namespaceSam Kim
 
[2011 CodeEngn Conference 05] ashine - 안드로이드 리눅스에서의 시스템 해킹
[2011 CodeEngn Conference 05] ashine - 안드로이드 리눅스에서의 시스템 해킹[2011 CodeEngn Conference 05] ashine - 안드로이드 리눅스에서의 시스템 해킹
[2011 CodeEngn Conference 05] ashine - 안드로이드 리눅스에서의 시스템 해킹GangSeok Lee
 
검색엔진이 데이터를 다루는 법 김종민
검색엔진이 데이터를 다루는 법 김종민검색엔진이 데이터를 다루는 법 김종민
검색엔진이 데이터를 다루는 법 김종민종민 김
 

What's hot (20)

Realm: 초고속 데이터베이스
Realm: 초고속 데이터베이스Realm: 초고속 데이터베이스
Realm: 초고속 데이터베이스
 
Kth개발자 세미나 1회
Kth개발자 세미나 1회Kth개발자 세미나 1회
Kth개발자 세미나 1회
 
fengfengfeng
fengfengfengfengfengfeng
fengfengfeng
 
Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706
 
android stuff1
android stuff1android stuff1
android stuff1
 
[113]how can realm_make_efficient_mobile_database
[113]how can realm_make_efficient_mobile_database[113]how can realm_make_efficient_mobile_database
[113]how can realm_make_efficient_mobile_database
 
NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기
NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기
NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기
 
Swift의 함수와 메소드
Swift의 함수와 메소드Swift의 함수와 메소드
Swift의 함수와 메소드
 
Learning Node Book, Chapter 5
Learning Node Book, Chapter 5Learning Node Book, Chapter 5
Learning Node Book, Chapter 5
 
Sha 2017-teaser-round website attack writeup
Sha 2017-teaser-round website attack writeupSha 2017-teaser-round website attack writeup
Sha 2017-teaser-round website attack writeup
 
Windows kernel basic exploit
Windows kernel basic exploitWindows kernel basic exploit
Windows kernel basic exploit
 
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSStartup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JS
 
[2013 CodeEngn Conference 09] wh1ant - various tricks for linux remote exploits
[2013 CodeEngn Conference 09] wh1ant - various tricks for linux remote exploits[2013 CodeEngn Conference 09] wh1ant - various tricks for linux remote exploits
[2013 CodeEngn Conference 09] wh1ant - various tricks for linux remote exploits
 
함수적 사고 2장
함수적 사고 2장함수적 사고 2장
함수적 사고 2장
 
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
 
UML distilled 1장 스터디 발표 자료
UML distilled 1장 스터디 발표 자료UML distilled 1장 스터디 발표 자료
UML distilled 1장 스터디 발표 자료
 
[Algorithm] Shell Sort
[Algorithm] Shell Sort[Algorithm] Shell Sort
[Algorithm] Shell Sort
 
도커없이컨테이너 만들기 8편 - pid namespace
도커없이컨테이너 만들기 8편 - pid namespace도커없이컨테이너 만들기 8편 - pid namespace
도커없이컨테이너 만들기 8편 - pid namespace
 
[2011 CodeEngn Conference 05] ashine - 안드로이드 리눅스에서의 시스템 해킹
[2011 CodeEngn Conference 05] ashine - 안드로이드 리눅스에서의 시스템 해킹[2011 CodeEngn Conference 05] ashine - 안드로이드 리눅스에서의 시스템 해킹
[2011 CodeEngn Conference 05] ashine - 안드로이드 리눅스에서의 시스템 해킹
 
검색엔진이 데이터를 다루는 법 김종민
검색엔진이 데이터를 다루는 법 김종민검색엔진이 데이터를 다루는 법 김종민
검색엔진이 데이터를 다루는 법 김종민
 

Similar to [OpenTRS-001] Vitor

Python programming for Bioinformatics
Python programming for BioinformaticsPython programming for Bioinformatics
Python programming for BioinformaticsHyungyong Kim
 
[0312 조진현] good bye dx9
[0312 조진현] good bye dx9[0312 조진현] good bye dx9
[0312 조진현] good bye dx9진현 조
 
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012Esun Kim
 
Cocos2dx와 c++11를 이용한 게임 개발
Cocos2dx와 c++11를 이용한 게임 개발Cocos2dx와 c++11를 이용한 게임 개발
Cocos2dx와 c++11를 이용한 게임 개발권 태혁
 
Mongo db 시작하기
Mongo db 시작하기Mongo db 시작하기
Mongo db 시작하기OnGameServer
 
Pwnable study basic_1
Pwnable study basic_1Pwnable study basic_1
Pwnable study basic_1Jinkyoung Kim
 
eclipse에서 intelliJ IDEA로
eclipse에서 intelliJ IDEA로eclipse에서 intelliJ IDEA로
eclipse에서 intelliJ IDEA로Juntai Park
 
Dependency hell과 빌드지옥 탈출
Dependency hell과 빌드지옥 탈출Dependency hell과 빌드지옥 탈출
Dependency hell과 빌드지옥 탈출Byeongsu Kang
 
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석GangSeok Lee
 
Profiling - 실시간 대화식 프로파일러
Profiling - 실시간 대화식 프로파일러Profiling - 실시간 대화식 프로파일러
Profiling - 실시간 대화식 프로파일러Heungsub Lee
 
[야생의 땅: 듀랑고]의 식물 생태계를 담당하는 21세기 정원사의 OpenCL 경험담
[야생의 땅: 듀랑고]의 식물 생태계를 담당하는 21세기 정원사의 OpenCL 경험담[야생의 땅: 듀랑고]의 식물 생태계를 담당하는 21세기 정원사의 OpenCL 경험담
[야생의 땅: 듀랑고]의 식물 생태계를 담당하는 21세기 정원사의 OpenCL 경험담Sumin Byeon
 
파이썬 언어 기초
파이썬 언어 기초파이썬 언어 기초
파이썬 언어 기초beom kyun choi
 
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민XpressEngine
 
Visual Studio를 이용한 어셈블리어 학습 part 1
Visual Studio를 이용한 어셈블리어 학습 part 1Visual Studio를 이용한 어셈블리어 학습 part 1
Visual Studio를 이용한 어셈블리어 학습 part 1YEONG-CHEON YOU
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010devCAT Studio, NEXON
 
GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)
GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)
GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)Kyoungchan Lee
 
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버준철 박
 
kgc2014 LINE Rangers/Stage 크래시 및 어뷰징 대응
kgc2014 LINE Rangers/Stage크래시 및 어뷰징 대응kgc2014 LINE Rangers/Stage크래시 및 어뷰징 대응
kgc2014 LINE Rangers/Stage 크래시 및 어뷰징 대응sewoon Nam
 
Load of Buffer Overflow 문제풀이
Load of Buffer Overflow 문제풀이Load of Buffer Overflow 문제풀이
Load of Buffer Overflow 문제풀이fromitive
 

Similar to [OpenTRS-001] Vitor (20)

Python programming for Bioinformatics
Python programming for BioinformaticsPython programming for Bioinformatics
Python programming for Bioinformatics
 
[0312 조진현] good bye dx9
[0312 조진현] good bye dx9[0312 조진현] good bye dx9
[0312 조진현] good bye dx9
 
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
 
Cocos2dx와 c++11를 이용한 게임 개발
Cocos2dx와 c++11를 이용한 게임 개발Cocos2dx와 c++11를 이용한 게임 개발
Cocos2dx와 c++11를 이용한 게임 개발
 
Mongo db 시작하기
Mongo db 시작하기Mongo db 시작하기
Mongo db 시작하기
 
Pwnable study basic_1
Pwnable study basic_1Pwnable study basic_1
Pwnable study basic_1
 
eclipse에서 intelliJ IDEA로
eclipse에서 intelliJ IDEA로eclipse에서 intelliJ IDEA로
eclipse에서 intelliJ IDEA로
 
Dependency hell과 빌드지옥 탈출
Dependency hell과 빌드지옥 탈출Dependency hell과 빌드지옥 탈출
Dependency hell과 빌드지옥 탈출
 
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석
 
Profiling - 실시간 대화식 프로파일러
Profiling - 실시간 대화식 프로파일러Profiling - 실시간 대화식 프로파일러
Profiling - 실시간 대화식 프로파일러
 
[야생의 땅: 듀랑고]의 식물 생태계를 담당하는 21세기 정원사의 OpenCL 경험담
[야생의 땅: 듀랑고]의 식물 생태계를 담당하는 21세기 정원사의 OpenCL 경험담[야생의 땅: 듀랑고]의 식물 생태계를 담당하는 21세기 정원사의 OpenCL 경험담
[야생의 땅: 듀랑고]의 식물 생태계를 담당하는 21세기 정원사의 OpenCL 경험담
 
파이썬 언어 기초
파이썬 언어 기초파이썬 언어 기초
파이썬 언어 기초
 
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민
 
Visual Studio를 이용한 어셈블리어 학습 part 1
Visual Studio를 이용한 어셈블리어 학습 part 1Visual Studio를 이용한 어셈블리어 학습 part 1
Visual Studio를 이용한 어셈블리어 학습 part 1
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010
 
GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)
GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)
GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)
 
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
 
kgc2014 LINE Rangers/Stage 크래시 및 어뷰징 대응
kgc2014 LINE Rangers/Stage크래시 및 어뷰징 대응kgc2014 LINE Rangers/Stage크래시 및 어뷰징 대응
kgc2014 LINE Rangers/Stage 크래시 및 어뷰징 대응
 
Load of Buffer Overflow 문제풀이
Load of Buffer Overflow 문제풀이Load of Buffer Overflow 문제풀이
Load of Buffer Overflow 문제풀이
 
(Lisp)
(Lisp)(Lisp)
(Lisp)
 

More from Theori

[OpenTRS-001] LCARS000
[OpenTRS-001] LCARS000[OpenTRS-001] LCARS000
[OpenTRS-001] LCARS000Theori
 
[OpenTRS-001] RTOoOS
[OpenTRS-001] RTOoOS[OpenTRS-001] RTOoOS
[OpenTRS-001] RTOoOSTheori
 
[OpenTRS-001] Keynote
[OpenTRS-001] Keynote[OpenTRS-001] Keynote
[OpenTRS-001] KeynoteTheori
 
[OpenTRS-001] LCARS022
[OpenTRS-001] LCARS022[OpenTRS-001] LCARS022
[OpenTRS-001] LCARS022Theori
 
[OpenTRS-001] election_coin
[OpenTRS-001] election_coin[OpenTRS-001] election_coin
[OpenTRS-001] election_coinTheori
 
[OpenTRS-001] ooops
[OpenTRS-001] ooops[OpenTRS-001] ooops
[OpenTRS-001] ooopsTheori
 
[OpenTRS-001] ASRybaB
[OpenTRS-001] ASRybaB[OpenTRS-001] ASRybaB
[OpenTRS-001] ASRybaBTheori
 

More from Theori (7)

[OpenTRS-001] LCARS000
[OpenTRS-001] LCARS000[OpenTRS-001] LCARS000
[OpenTRS-001] LCARS000
 
[OpenTRS-001] RTOoOS
[OpenTRS-001] RTOoOS[OpenTRS-001] RTOoOS
[OpenTRS-001] RTOoOS
 
[OpenTRS-001] Keynote
[OpenTRS-001] Keynote[OpenTRS-001] Keynote
[OpenTRS-001] Keynote
 
[OpenTRS-001] LCARS022
[OpenTRS-001] LCARS022[OpenTRS-001] LCARS022
[OpenTRS-001] LCARS022
 
[OpenTRS-001] election_coin
[OpenTRS-001] election_coin[OpenTRS-001] election_coin
[OpenTRS-001] election_coin
 
[OpenTRS-001] ooops
[OpenTRS-001] ooops[OpenTRS-001] ooops
[OpenTRS-001] ooops
 
[OpenTRS-001] ASRybaB
[OpenTRS-001] ASRybaB[OpenTRS-001] ASRybaB
[OpenTRS-001] ASRybaB
 

[OpenTRS-001] Vitor

  • 1. DEFCON Prequal 2019 Vitor #Android #DEX #nativelib #Javascript
  • 2. STEP 1: p1EncFn • ooo.vitor.MainActivity • goal : fc.mValid == true
  • 3. STEP 1: p1EncFn • len(OOO{SOMETHING} ) == 45 • g0(<…SOMETHING…>) • dp1() • cf()
  • 4. STEP 1: p1EncFn • len(OOO{SOMETHING} ) == 45 • g0(<…SOMETHING…>) • 키를 4byte씩 잘라서 XOR • bArr • dp1() • cf()
  • 5. STEP 1: p1EncFn • len(OOO{SOMETHING} ) == 45 • g0(<…SOMETHING…>) • bArr • dp1() • MD5(bArr)해서 key로 사용 • p1EncFn을 AES decrypt • p1Fn으로 리턴 • cf()
  • 6. STEP 1: p1EncFn • len(OOO{SOMETHING} ) == 45 • g0(<…SOMETHING…>) • dp1() • cf() • dp1()에서 복호화한 클래스 로드
  • 7. STEP 1: p1EncFn • Goal • p1EncFn을 decrypt하는 키의 일부 찾기 • public static String p1EncFn = "ckxalskuaewlkszdva"; • PKZIP으로 시작할 것이라는 추측 가능 • 해당 magic number로 시작하도록 뽑아주는 키만 수집 • 그 중 제대로 복호화해주는 것 골라내기 • ’17 01 2F 03’ from Crypto.Cipher import AES from itertools import product from multiprocessing import Pool import hashlib num_threads = 8 with open("../vitor_unzip/vitor/assets/ckxalskuaewlkszdva", "rb") as f: file_content = f.read()[:16] magic = b"PKx03x04" #PKZIP magic cnt = 0 iv = [19, 55, 19, 55, 19, 55, 19, 55] magic_iv_xor = bytes([magic[i] ^ iv[i] for i in range(4)]) def f(num): key_list = [] for c in product(range(128), repeat=3): r = 128 // num_threads for i in range(r * num, r * (num + 1)): key_str = bytes(c) + bytes([i]) key = hashlib.md5(key_str).digest() aes = AES.new(key, AES.MODE_ECB) if aes.decrypt(file_content)[:4] == magic_iv_xor[:4]: print(key_str) key_list.append(key_str) return key_list with Pool(processes=8) as p: key_list = p.map(f, range(8))
  • 8. STEP 2: 또;; • ooo.p1.P1 • goal : cf의 return == true • g1() • 앗 데자뷰인가
  • 9. STEP 2: 또;; • Goal • def decrypt하는 키의 일부 찾기 • public static String def = "mmdffuoscjdamcnssn"; • x7fELF으로 시작할 것이라는 추측 가능 • 해당 magic number로 시작하도록 뽑아주는 키만 수집 • 그 중 제대로 복호화해주는 것 골라내기 • ‘3C 27 43 60’ from Crypto.Cipher import AES from itertools import product from multiprocessing import Pool import hashlib num_threads = 8 with open("../vitor_unzip/vitor/assets/mmdffuoscjdamcnssn", "rb") as f: file_content = f.read()[:16] magic = b"x7fELF" #ELF cnt = 0 iv = [19, 55, 19, 55, 19, 55, 19, 55, 19, 55, 19, 55, 19, 55, 19, 55] magic_iv_xor = bytes([magic[i] ^ iv[i] for i in range(4)]) def f(num): key_list = [] for c in product(range(128), repeat=3): r = 128 // num_threads for i in range(r * num, r * (num + 1)): key_str = bytes(c) + bytes([i]) key = hashlib.md5(key_str).digest() aes = AES.new(key, AES.MODE_ECB) if aes.decrypt(file_content)[:4] == magic_iv_xor[:4]: print(key_str) key_list.append(key_str) return key_list with Pool(processes=8) as p: key_list = p.map(f, range(8))
  • 10. STEP 3: libabc.so • JNICALL Java_ooo_p1_P1_xxx() • g2() • dp3() • 쉘코드?!
  • 11. STEP 3: libabc.so • JNICALL Java_ooo_p1_P1_xxx() • g2() • 키를 4바이트씩 잘라서 XOR • bArr • dp3() • 파일 xtszs… 를 4바이트씩 XOR • 결과는 쉘코드일것 • 함수 프롤로그일까??? • 쉘코드?!
  • 12. STEP 3: libabc.so • JNICALL Java_ooo_p1_P1_xxx() • g2() • 키를 4바이트씩 잘라서 XOR • bArr • dp3() • 파일 xtszs… 를 4바이트씩 XOR • 결과는 쉘코드일것 • 함수 프롤로그일까??? 땡 • NOPsled가 있었네욤 • 쉘코드?!
  • 13. STEP 3: libabc.so • Goal • 쉘코드를 만들어주는 키의 일부 찾기 • NOPsled로 시작할 것이라는 추측 가능 • x90x90x90x90으로 시작하도록 • ‘6E 63 27 4E’ from itertools import product from multiprocessing import Pool import struct def p32(x): return struct.pack("<L", x) num_threads = 8 with open("../vitor_unzip/vitor/assets/xtszswemcwohpluqmi", "rb") as f: file_content = f.read() #magic = b"xb8x37x13x03x00" #magic = b"xffxf5" magic = b"x90x90x90x90" #NOPsled ttlist = [] for j in range(100): ttlist.append(struct.unpack("<L", file_content[4*j : 4*j+4])[0]) def decrypt(ct, key): pt = b"" for i in range(len(ct) // 4): pt += p32(ttlist[i] ^ key) key += 0x31333337 key %= 0x100000000 return pt def f(num): key_list = [] for i, j, k in product(range(128), repeat=3): r = 128 // num_threads for l in range(r * num, r * (num + 1)): key = (l << 24) ^ (k << 16) ^ (j << 8) ^ i if magic in decrypt(file_content, key): print(key) key_list.append(key) return key_list
  • 14. Step 4: Shellcode • 아직 끝나지 않았다 • v5 = 2 • v4 = 인자로 받아온 flag index • flag[0x10:0x14]^flag[0x20:0x24]^flag[0x30:0x34] • 쉘코드의 뒤쪽 (offset 0xC8부터) decrypt 한번 더 • offset 0xC8부터 XOR • flag[0x10:0x14] ^ flag[0x20:0x24] ^ flag[0x30:0x34] = 42 18 33 13
  • 16. Step 4: Shellcode • ROP Chain • flag[0x14:0x18] ^ flag[0x28:0x2c] • 얘가 rol 하면서 4byte씩 xor함 • 뭘 만들어 주려고? xor ecx, ecx xor ecx, DWORD PTR [edi+0x14] xor ecx, DWORD PTR [edi+0x28] xor DWORD PTR [esi], ecx add esi,0x4 rol ecx,0x8 sub ebx,0x4 … <loop> … mov eax,0x31337 ret
  • 17. Step 4: Shellcode • ROP Chain • flag[0x14:0x18] ^ flag[0x28:0x2c] • 얘가 rol 하면서 4byte씩 xor함 • 뭘 만들어 주려고? HTML • 이 밑에 memcmp(mmm, "<html>", 6u) • cxnvh… 는 <html>로 시작 • 56 2D 52 5D
  • 18. Step 5: Web ;-( • ???
  • 19. Step 5: Web ;-( • ??? • 합리적 의심 타임 • var _0x2d96 = ['c2V0RmxhZ0FzVmFsaWQ=','ZmxhZw==','c3Vic3Ry','ID0+IHBIZF8xd19lNHJMMTNyOyl9 ','SlNJbnRlcmZhY2U=']; • var _0x1081d6 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; • 속는 셈 치고 BASE64 decode • ['setFlagAsValid', 'flag', 'substr', ' => pHd_1w_e4rL13r;)}', 'JSInterface’] • 키의 뒤쪽 21글자를 주웠다!
  • 20. Step 6: Z3 • 조건에 맞게 Z3 돌리기 • 이 때 각 step별로 찾았던 키들을 잘 넣어야 SAT 'OOO{pox&mpuzz,U_solve_it => pHd_1w_e4rL13r;)}' step1key[j] = step1key[j] ^ flag[4 + 4*i + j] step2key[j] = step2key[j] ^ flag[4 + 4*(i+1) + j] step3key[j] = step3key[j] ^ flag[4 + 4*(i-1) + j] step4key[j] = step4key[j] ^ flag[4*i + j] step5key[j] = step5key[j] ^ flag[4*i + j]