LLVM 인스트럭션 타입이랑 같이 출력

씨디팔공/팁 2016.06.10 14:29
크리에이티브 커먼즈 라이선스
Creative Commons License

도저히 인스트럭션이 llvm api상에서 무슨 타입인지 알수가 없어서 만들었습니다, 이 코드를 적용하면서 코드를 작성한 저도 제가 작업하는 LLVM버젼에 적용하면서 아주 약간 수정하면서 썼으니 필요에 따라 수정하면서 쓰시면됩니다

예를들어 LandingPadInst에서 and가 지워지고 LingPadInst 로 돼있습니다

이 글을 작성(6월 10일)하고 코드에 문제가 좀 있어서 공개를 안하고 있었는데 LLVM글 작성을 시작하면서 공개(7월 15일) 했습니다

inst_types = ['AddrSpaceCastInst', 'BitCastInst', 'PtrToIntInst', 'IntToPtrInst', 'FPToSIInst', 'FPToUIInst', 'SIToFPInst', 'UIToFPInst', 'FPExtInst', 'FPTruncInst', 'SExtInst', 'ZExtInst', 'TruncInst', 'UnreachableInst', 'CleanupReturnInst', 'CatchReturnInst', 'CatchPadInst', 'CleanupPadInst', 'CatchSwitchInst', 'ResumeInst', 'InvokeInst', 'IndirectBrInst', 'SwitchInst', 'BranchInst', 'ReturnInst', 'LingPadInst', 'PHINode', 'InsertValueInst', 'ExtractValueInst', 'ShuffleVectorInst', 'InsertElementInst', 'ExtractElementInst', 'VAArgInst', 'SelectInst', 'CallInst', 'FCmpInst', 'ICmpInst', 'FuncletPadInst', 'CmpInst', 'GetElementPtrInst', 'CastInst', 'AtomicRMWInst', 'AtomicCmpXchgInst', 'BinaryOperator', 'FenceInst', 'StoreInst', 'InstrProfValueProfileInst', 'InstrProfIncrementInst', 'VACopyInst', 'VAEndInst', 'GCRelocateInst', 'UnaryInstruction', 'VAStartInst', 'MemMoveInst', 'LoadInst', 'MemCpyInst', 'MemTransferInst', 'MemSetInst', 'MemIntrinsic', 'AllocaInst', 'DbgValueInst', 'DbgDeclareInst', 'TerminatorInst', 'DbgInfoIntrinsic', 'IntrinsicInst']
cpp_code = "void printInstWithType(Instruction inst){\n"
for inst_type in inst_types:
	cpp_code += ("""
	if(isa<%s>(inst)){
		errs() << "[%s] " << inst << "\\n";
	}
"""%(inst_type, inst_type))[1:]
cpp_code += "}"
print cpp_code
void printInstWithType(Instruction inst){
	if(isa<AddrSpaceCastInst>(inst)){
		errs() << "[AddrSpaceCastInst] " << inst << "\n";
	}
	if(isa<BitCastInst>(inst)){
		errs() << "[BitCastInst] " << inst << "\n";
	}
	if(isa<PtrToIntInst>(inst)){
		errs() << "[PtrToIntInst] " << inst << "\n";
	}
	if(isa<IntToPtrInst>(inst)){
		errs() << "[IntToPtrInst] " << inst << "\n";
	}
	if(isa<FPToSIInst>(inst)){
		errs() << "[FPToSIInst] " << inst << "\n";
	}
	if(isa<FPToUIInst>(inst)){
		errs() << "[FPToUIInst] " << inst << "\n";
	}
	if(isa<SIToFPInst>(inst)){
		errs() << "[SIToFPInst] " << inst << "\n";
	}
	if(isa<UIToFPInst>(inst)){
		errs() << "[UIToFPInst] " << inst << "\n";
	}
	if(isa<FPExtInst>(inst)){
		errs() << "[FPExtInst] " << inst << "\n";
	}
	if(isa<FPTruncInst>(inst)){
		errs() << "[FPTruncInst] " << inst << "\n";
	}
	if(isa<SExtInst>(inst)){
		errs() << "[SExtInst] " << inst << "\n";
	}
	if(isa<ZExtInst>(inst)){
		errs() << "[ZExtInst] " << inst << "\n";
	}
	if(isa<TruncInst>(inst)){
		errs() << "[TruncInst] " << inst << "\n";
	}
	if(isa<UnreachableInst>(inst)){
		errs() << "[UnreachableInst] " << inst << "\n";
	}
	if(isa<CleanupReturnInst>(inst)){
		errs() << "[CleanupReturnInst] " << inst << "\n";
	}
	if(isa<CatchReturnInst>(inst)){
		errs() << "[CatchReturnInst] " << inst << "\n";
	}
	if(isa<CatchPadInst>(inst)){
		errs() << "[CatchPadInst] " << inst << "\n";
	}
	if(isa<CleanupPadInst>(inst)){
		errs() << "[CleanupPadInst] " << inst << "\n";
	}
	if(isa<CatchSwitchInst>(inst)){
		errs() << "[CatchSwitchInst] " << inst << "\n";
	}
	if(isa<ResumeInst>(inst)){
		errs() << "[ResumeInst] " << inst << "\n";
	}
	if(isa<InvokeInst>(inst)){
		errs() << "[InvokeInst] " << inst << "\n";
	}
	if(isa<IndirectBrInst>(inst)){
		errs() << "[IndirectBrInst] " << inst << "\n";
	}
	if(isa<SwitchInst>(inst)){
		errs() << "[SwitchInst] " << inst << "\n";
	}
	if(isa<BranchInst>(inst)){
		errs() << "[BranchInst] " << inst << "\n";
	}
	if(isa<ReturnInst>(inst)){
		errs() << "[ReturnInst] " << inst << "\n";
	}
	if(isa<LingPadInst>(inst)){
		errs() << "[LingPadInst] " << inst << "\n";
	}
	if(isa<PHINode>(inst)){
		errs() << "[PHINode] " << inst << "\n";
	}
	if(isa<InsertValueInst>(inst)){
		errs() << "[InsertValueInst] " << inst << "\n";
	}
	if(isa<ExtractValueInst>(inst)){
		errs() << "[ExtractValueInst] " << inst << "\n";
	}
	if(isa<ShuffleVectorInst>(inst)){
		errs() << "[ShuffleVectorInst] " << inst << "\n";
	}
	if(isa<InsertElementInst>(inst)){
		errs() << "[InsertElementInst] " << inst << "\n";
	}
	if(isa<ExtractElementInst>(inst)){
		errs() << "[ExtractElementInst] " << inst << "\n";
	}
	if(isa<VAArgInst>(inst)){
		errs() << "[VAArgInst] " << inst << "\n";
	}
	if(isa<SelectInst>(inst)){
		errs() << "[SelectInst] " << inst << "\n";
	}
	if(isa<CallInst>(inst)){
		errs() << "[CallInst] " << inst << "\n";
	}
	if(isa<FCmpInst>(inst)){
		errs() << "[FCmpInst] " << inst << "\n";
	}
	if(isa<ICmpInst>(inst)){
		errs() << "[ICmpInst] " << inst << "\n";
	}
	if(isa<FuncletPadInst>(inst)){
		errs() << "[FuncletPadInst] " << inst << "\n";
	}
	if(isa<CmpInst>(inst)){
		errs() << "[CmpInst] " << inst << "\n";
	}
	if(isa<GetElementPtrInst>(inst)){
		errs() << "[GetElementPtrInst] " << inst << "\n";
	}
	if(isa<CastInst>(inst)){
		errs() << "[CastInst] " << inst << "\n";
	}
	if(isa<AtomicRMWInst>(inst)){
		errs() << "[AtomicRMWInst] " << inst << "\n";
	}
	if(isa<AtomicCmpXchgInst>(inst)){
		errs() << "[AtomicCmpXchgInst] " << inst << "\n";
	}
	if(isa<BinaryOperator>(inst)){
		errs() << "[BinaryOperator] " << inst << "\n";
	}
	if(isa<FenceInst>(inst)){
		errs() << "[FenceInst] " << inst << "\n";
	}
	if(isa<StoreInst>(inst)){
		errs() << "[StoreInst] " << inst << "\n";
	}
	if(isa<InstrProfValueProfileInst>(inst)){
		errs() << "[InstrProfValueProfileInst] " << inst << "\n";
	}
	if(isa<InstrProfIncrementInst>(inst)){
		errs() << "[InstrProfIncrementInst] " << inst << "\n";
	}
	if(isa<VACopyInst>(inst)){
		errs() << "[VACopyInst] " << inst << "\n";
	}
	if(isa<VAEndInst>(inst)){
		errs() << "[VAEndInst] " << inst << "\n";
	}
	if(isa<GCRelocateInst>(inst)){
		errs() << "[GCRelocateInst] " << inst << "\n";
	}
	if(isa<UnaryInstruction>(inst)){
		errs() << "[UnaryInstruction] " << inst << "\n";
	}
	if(isa<VAStartInst>(inst)){
		errs() << "[VAStartInst] " << inst << "\n";
	}
	if(isa<MemMoveInst>(inst)){
		errs() << "[MemMoveInst] " << inst << "\n";
	}
	if(isa<LoadInst>(inst)){
		errs() << "[LoadInst] " << inst << "\n";
	}
	if(isa<MemCpyInst>(inst)){
		errs() << "[MemCpyInst] " << inst << "\n";
	}
	if(isa<MemTransferInst>(inst)){
		errs() << "[MemTransferInst] " << inst << "\n";
	}
	if(isa<MemSetInst>(inst)){
		errs() << "[MemSetInst] " << inst << "\n";
	}
	if(isa<MemIntrinsic>(inst)){
		errs() << "[MemIntrinsic] " << inst << "\n";
	}
	if(isa<AllocaInst>(inst)){
		errs() << "[AllocaInst] " << inst << "\n";
	}
	if(isa<DbgValueInst>(inst)){
		errs() << "[DbgValueInst] " << inst << "\n";
	}
	if(isa<DbgDeclareInst>(inst)){
		errs() << "[DbgDeclareInst] " << inst << "\n";
	}
	if(isa<TerminatorInst>(inst)){
		errs() << "[TerminatorInst] " << inst << "\n";
	}
	if(isa<DbgInfoIntrinsic>(inst)){
		errs() << "[DbgInfoIntrinsic] " << inst << "\n";
	}
	if(isa<IntrinsicInst>(inst)){
		errs() << "[IntrinsicInst] " << inst << "\n";
	}
}


신고

'씨디팔공 > ' 카테고리의 다른 글

IT인들을 위한 건강챙기기 팁  (2) 2017.03.30
LLVM 인스트럭션 타입이랑 같이 출력  (0) 2016.06.10

설정

트랙백

댓글

HITCON 2015 matrix

크리에이티브 커먼즈 라이선스
Creative Commons License

올해 히트콘에 재밌는 문제가 많았어서 공부할겸 풀이를 작성해봅니다


matrix문제는 제일 배점이 낮은문제였는데

배점이 낮든말든 허접인 저한텐 너무 어려웠습니다


바이너리는 두개의 행렬을 입력받아 곱한다음 출력해주는 컨셉입니다


그런데 행렬을 위한 공간을 할당할 때 힙이 아닌 alloca를 이용해서 할당합니다

힙을 이용하는것과 스택을 이용하는것에서 취약성이 갈리진 않지만

이 프로그램에선 힙을 사용하는 부분이 없고

스택을 사용하기때문에 크리티컬한 데이터를 조작하기가 훨씬 수월합니다

루프를 돌때 abs를 사용하고, 추가 검증이 없어서

-2147483648로 matrix size를 그냥 넣고 행렬 요소들을 계속 입력하다보니 세그폴이 떠서

크래쉬를 일으키는데는 얼마 안걸렸습니다


취약점은 전형적인 유형인데

이 문제의 취약점은

메모리를 allocate할때(malloc이나 alloca등)

allocate하는 사이즈를 공격자가 컨트롤 할 수 있고

그 데이터보다 많이 넣을 수 있는데서 발생합니다



>>> v38 = -2147483648

>>> (16 * ((8 * v38 * v38 + 22) / 0x10))&0xffffffffffffffff

16L

>>> 


size of matrix를 -2147483648로 설정하면

alloca안의 식이 0x10으로 계산되고

abs(-2147483648) == 0x80000000이기 때문에

수치상으로만 봐도 오버플로우가 명확히 발생합니다


rip컨트롤은 굉장히 쉽고

pop; ret 을 해주면 bp-68에 있는 첫 어레이에서부터 ROP를 할 수 있습니다


관건은 fflush(stdout)을 어떻게 호출하냐인데


main함수 맨뒤에 fflush(stdout)을 해주고

rbp-28h을 rsp에 넣은 뒤 pop pop popo popo pop p op op op op op popop ret해주는 부분이있습니다

rbp-28h은 우리가 컨트롤 할 수 없는 메모리니

저기로 점프하기전에 rbp를 name(0x6020a0)버퍼에서 적당한 지점으로 설정해주면

fflush를 호출한뒤 name버퍼에서 control flow를 유지시킬수가 있습니다


hitcon2015_matrix.py


cd80.py


신고

'해킹공부 > 캡쳐더플래그' 카테고리의 다른 글

codegate 2017  (0) 2017.02.22
HITCON 2015 matrix  (0) 2015.10.23
WhiteHat Contest 2015 cd80  (6) 2015.10.12
LeaveRet JFF Season3 pwnable vaja  (1) 2015.07.26
Codegate2015 junior writeup  (5) 2015.03.16
pCTF 2013 pork  (3) 2014.08.18

설정

트랙백

댓글

WhiteHat Contest 2015 cd80

크리에이티브 커먼즈 라이선스
Creative Commons License

원래 팀을 구하다가 다들 팀이 이미 구해져있길래

그냥 이번대회가 청소년부로 나갈 수 있는 마지막 대회라

한번쯤 혼자 나가서 내가 어느정도 수준인지 검증해보고 싶었는데

역시 아직 개 뉴비란걸 깨달았다

세상에 고수는 차고 넘치는구나 허허


WHITEHATCONTEST2015_cd80_writeup.pdf



신고

'해킹공부 > 캡쳐더플래그' 카테고리의 다른 글

codegate 2017  (0) 2017.02.22
HITCON 2015 matrix  (0) 2015.10.23
WhiteHat Contest 2015 cd80  (6) 2015.10.12
LeaveRet JFF Season3 pwnable vaja  (1) 2015.07.26
Codegate2015 junior writeup  (5) 2015.03.16
pCTF 2013 pork  (3) 2014.08.18

설정

트랙백

댓글


티스토리 툴바