'분류 전체보기'에 해당되는 글 64건

  1. 2017.05.16 How 2 heap - fastbin_dup.c
  2. 2017.05.15 How 2 heap - first_fit.c
  3. 2017.04.18 Webhacking Study - no more BLIND 6
  4. 2017.02.11 2017 Codegate - 2D Life Write up + 출제후기 11
  5. 2016.12.08 discord.py
  6. 2016.11.02 SQLi.py
  7. 2016.08.24 LLVM -3 2
  8. 2016.08.17 LLVM - 2
  9. 2016.08.12 LLVM - 1
  10. 2016.06.13 Proxy.py

How 2 heap - fastbin_dup.c

System 2017. 5. 16. 13:11

원문 : https://github.com/shellphish/how2heap/blob/master/fastbin_dup.c



#include 
#include 

int main()
{
	printf("이 파일은 fastbins을 통한 double-free 공격을 간단하게 보여줄 겁니다.\n");

	printf("3개의 버퍼를 할당하도록 하죠.\n");
	int *a = malloc(8);
	int *b = malloc(8);
	int *c = malloc(8);

	printf("1st malloc(8): %p\n", a);
	printf("2nd malloc(8): %p\n", b);
	printf("3rd malloc(8): %p\n", c);

	printf("제일 처음것을 할당해제를 하고...\n");
	free(a);

	printf("만약 %p 를 다시 해제한다면 크래쉬가 날텐데, %p가 free list의 제일 위에 있기 때문이죠.\n", a, a);
	// free(a);

	printf("그러므로 대신 %p를 할당해제 합시다..\n", b);
	free(b);

	printf("그럼 이제 %p를 할당해제 할수 있습니다. free list의 처음 노드가 아니기 때문이죠.\n", a);
	free(a);

	printf("free list는 현재 [ %p, %p, %p ] 입니다. 우리가 3회 할당하면, %p를 2번 얻게 될 겁니다.\n", a, b, a, a);
	printf("1st malloc(8): %p\n", malloc(8));
	printf("2nd malloc(8): %p\n", malloc(8));
	printf("3rd malloc(8): %p\n", malloc(8));
}


'System' 카테고리의 다른 글

How 2 heap - first_fit.c  (0) 2017.05.15
LLVM -3  (2) 2016.08.24
LLVM - 2  (0) 2016.08.17
LLVM - 1  (0) 2016.08.12
프로그램에서 일어날수 있는 레이스컨디션의 예제  (8) 2015.04.01
Posted by IzayoiSakuya
,

How 2 heap - first_fit.c

System 2017. 5. 15. 16:47

원문 : https://github.com/shellphish/how2heap/blob/master/first_fit.c 

#include 
#include 
#include 

int main()
{
	printf("이 파일은 POC는 아닙니다. 하지만 glibc's allocator의 본모습을 보여주게 될것입니다.\n");
	printf("glibc 비어있는 청크에서 최초적합 알고리즘을 사용하여 선택후, 가져옵니다.\n");
	printf("만약 청크가 비어있고 충분히 크다면, malloc은 그 청크를 선택하고 가져오겠죠.\n");
	printf("이는 Use-after-free 상황이며 공격 당할 수 있습니다\n");

	printf("2개의 버퍼를 할당합시다. fastbin이 아니도록 충분히 커야만 합니다.\n");
	char* a = malloc(512);
	char* b = malloc(256);
	char* c;

	printf("1st malloc(512): %p\n", a);
	printf("2nd malloc(256): %p\n", b);
	printf("우리는 여기에 더 할당 할 수 있습니다.\n");
	printf("문자열을 할당하여 읽을수 있게 합니다. \"this is A!\"를 버퍼에 넣도록 합시다.\n");
	strcpy(a, "this is A!");
	printf("첫 할당된 메모리 %p, 내용은 %s\n", a, a);

	printf("첫번째 것을 할당 해제 합시다.\n");
	free(a);

	printf("다시 다른것을 할당해제 할 필요는 없습니다. 512 보다 작게 할당하는 한, %p에서 그칠테니까요.\n", a);

	printf("그렇다면, 500 바이트를 할당 해 봅시다\n");
	c = malloc(500);
	printf("3rd malloc(500): %p\n", c);
	printf("여긴 다른 문자열을 넣도록 하죠.\"this is C!\" 이걸로.\n");
	strcpy(c, "this is C!");
	printf("세번째 할당된 메모리는 %p, 내용은 %s\n", c, c);
	printf("최초 할당된 메모리는 %p, 내용은 %s\n", a, a);
	printf("만약 첫번째 할당을 재사용하게 되면 3번째 할당에 사용된 데이터를 가지게 될겁니다.");
}

'System' 카테고리의 다른 글

How 2 heap - fastbin_dup.c  (0) 2017.05.16
LLVM -3  (2) 2016.08.24
LLVM - 2  (0) 2016.08.17
LLVM - 1  (0) 2016.08.12
프로그램에서 일어날수 있는 레이스컨디션의 예제  (8) 2015.04.01
Posted by IzayoiSakuya
,


주제 : Webhacking Study - no more BLIND
날짜 : 2017.04.18
작성자 :Sakuya Izayoi


1. 개요 및 목적
Lord Of SQL injection(이하 LOS) 의 문제를 통해 blind SQL injeciton을 알고, 이외의 방법으로 풀수 있는 방안에 대해 연구한다. blind 기법으로 풀어야 할 문제들을 다른 방법으로 접근하는 것으로, CTF 및 모의해킹의 수행시간을 단축함을 그 목적으로 한다.

2. 내용
이번 문서의 시작은 정도원(rubiya)의 페이스북 포스팅에서 시작한다. 포스팅의 내용은, 'LOS의 문제중 간단한 Blind SQL injection 기법을 사용하는 문제가 있었는데, 이 문제를 Blind 기법을 사용하지 않고 풀 수 있다' 라는 내용이다. 






이에 순수한 학문적 호기심이 생겼고, 이 방법을 찾아 mysql의 삽질을 시작하기로 했다.
아래는 이 연구에 사용한 작업환경이다

Mysql : 5.6.30-0ubuntu0.15.10.1
OS      :  Ubuntu 16.04



우선 테스트용 db와 table을 만들어 보자.
해당 테스트에서 사용하는 DB와 구조는 아래와 같다

create database Test_DB;
use Test_DB;
create table users(num int not null, id varchar(30) not null, password varchar(30) not null, primary key(num));
insert into users values(1, 'GUEST', 'GUEST');
insert into users values(2, 'Sakuya', 'admin_Paddword');
insert into users values(3, 'Izayoi', 'noadmin');


목적은 Sakuya의 Password를 가져오는것으로 하도록 하자.  문서의 취지에 맞게 Blind SQL 구문을 사용해서 가져오는 것으로만 한정 하도록 한다.
기본적인 쿼리문의 형태는 


SELECT * FROM users WHERE id='GUEST' and password='{$INPUT}'

를 사용한다.

3. Blind SQL injection
Blind SQL injection은 원하는 정보를 한번에 가져오는 SQL injection과 다르게, 원하는 정보를 1 byte 씩 들고와서 비교하는 기법이다.
1byte씩 비교하기 때문에 분기조건을 가진 구문 혹은 분기로 판단되는 근거를 잡는것이 가장 중요하다. 아래 내용에서는 그러한 분기 구문들, 분기로 판단할수 있는 근거를 체크하는 방법에 대해 설명한다. 해당 구문이 필터링에 걸릴때와 같은 특수한 경우는 제외하고 일반적인 상황에 중점을 둔다. 필터링과 같은 상황에 사용할수 있는 Cheat sheet나 전반적인 SQL injection에 대한 지식은 rubiya의 문서를 참고하면 좋다. 또한 상기의 문서들은 이 문서를 이해하는데 큰 도움을 줄 것이다.

-3.1 IF
if구문은 프로그래밍을 해본 사람이라면 누구나 알고 있을법한 단어이다. if구문의 사용법은 이하와 같다

if(Condition, TRUE, FALSE)

if 의 1번째 인자값인 Condition은 분기조건에 해당한다. 단순한 대소 비교부터 참,거짓 등등 원하는 값을 넣을수 있다.
if 의 2번째 인자값인 TRUE는 Condition의 분기조건이 TRUE(참) 일때 리턴할 값이 들어간다. 이곳엔 단순한 value 부터 Subquery의 결과물까지 여러가지 들어갈 수 있다.
if 의 3번째 인자값인 FALSE는 TRUE와 반대로 분기조건이 FALSE(거짓)일때 리턴할 값이 들어간다. 들어갈수 있는 값은 위에 서술한 TRUE에 들어갈수 있는 종류와 같다.
좀더 자세한 IF 구문의 사용법은 Mysql Reference 측을 참고하도록 하자.

해당 IF와 자주 엮이는 2개의 함수가 있는데, ascii와 substring이다.

-substring
substring 함수는 문자열을 자르는데 사용되는 함수이다. split과 달리 delim 기준이 아닌 순수한 문자열의 index 기준이다. 함수의 모형은 이하와 같다

substring(STRING, start_idx, count_idx)

STRING을 start_idx부터 count_idx만큼의 갯수를 세어 리턴한다.
아래는 substring의 예시이다



Blind SQL에서는 보통 3번째 인자값이 1로 고정 되는데, 1byte씩 비교해야 하는 Blind 기법의 특성때문이다.

-ascii
ascii 함수는 C언어의 atoi와 같다. 해당함수의 ascii값을 리턴해 준다. 이 ascii 함수를 통해 substring으로 가져온 문자열을 ascii로 변환하는 것이 일반적인 Blind sql injection의 과정이다.


이제 Condition에 들어갈만한 substring과 ascii 함수를 알아보았다.
이를 조합하여 IF구문을 완성하면 아래와 같은 형태가 될 가능성이 높다

if ( ascii(substring(password,1,1))=0,1,0 )

모의해킹 및 CTF 환경에 따라 IF 구문의 2,3번째 인자값은 바뀔수 있다.
=0 으로 비교하는 부분의 값도 효율성을 위해 Binary Search 를 적용할 수 있다.

해당 구문을 사용하여 Sakuya 계정의 패스워드를 가져와 보도록 하자.



password의 첫 글자를 가져왔을때 해당 문자의 ascii 값이 97일때는 TRUE를, 96일때는 FALSE를 돌려주었다. 이것이 실제 php application에 적용되었을때는 Login 성공/실패 혹은 검색결과 출력/미출력 등의 화면을 보여주는 형태가 될 확률이 높다. 이러한 과정은 많은 시도횟수를 요구하므로 주로 간단한 스크립트를 작성하거나 SQLmap과 같이 알려진 툴을 사용할 때가 많다.

3-2 CASE WHEN
CASE WHEN의 경우에도 if와 같은 동작을 한다.
개략적인 형태는 아래와 같다

CASE WHEN condition1 THEN true ELSE false END
THEN ~ ELSE 사이에 더 많은 THEN 구문을 넣을수 있지만, 여기선 참/거짓만 판단하도록 하나의 THEN~ ELSE만 넣었다.
이 역시 IF와 마찬가지로 condition1 이 TRUE라면 true에 적힌 값을, FALSE라면 false의 값을 리턴하도록 되어있다.
이 역시 자세한 구문은 Mysql Reference를 참고 하도록 하자.

IF와 큰 다른점이 없으므로 사용 예시만 살펴보자.




3-3 row()
row()는 함수라기보다 말 그대로 하나의 row를 표현해준다.
sql 쿼리를 요청했을때 우리에게 보여지는 row의 개념과 동일하다고 생각하면 좋다.
다소의 이해를 돕기위해 아래의 예제를 보자



select 1,2 의 결과와 row(1,2)의 결과는 같다.
하지만 row(1,1)의 결과와 select 1,2의 결과는 다르다.
이것을 통해서도 blind sql injection을 수행할 수 있다.
내가 가져올 계정의 ID가 Sakuya 인것을 알수 있고, password를 모른다고 가정했을때 공격은 아래와 같이 천천히 진행된다



like 구문을 통한 blind sql과 비슷한 양상이라고 생각하면 쉽다.
0x61????????? 값은 Sakuya 계정의 password 형식과 일치하지만
0x62???????? 값은 Sakuya 계정의 password와 일치하지 않고, 이 값은 사전적으로 admin_Paddword보다 뒤에 있으므로 True를 리턴하게 된 결과다.
해당 쿼리를 사용하며 주의할 점은 where 구문 대신 limit를 넣어야 한다는 점이다.
where구문을 통해 결과값을 돌려받기 전 컴파일 단계에서 row와 select의 결과를 미리 비교해 버려서 어떤값을 넣더라도 항상 참이 뜨는 경우를 볼 수 있다.




상기 기술한 내용 이외에도 많은 기법들이 있을수 있다. 하지만 이정도만 따라 올수 있어도 일반적인 Blind SQL injection은 잘 할수 있으리라 생각한다.

4. LOS - orge
해당 문제의 소스코드를 보도록 하자.


<?php 
  
include "./config.php"
  
login_chk(); 
  
dbconnect(); 
  if(
preg_match('/prob|_|\.|\(\)/i'$_GET[pw])) exit("No Hack ~_~"); 
  if(
preg_match('/or|and/i'$_GET[pw])) exit("HeHe"); 
  
$query "select id from prob_orge where id='guest' and pw='{$_GET[pw]}'"
  echo 
"<hr>query : <strong>{$query}</strong><hr><br>"
  
$result = @mysql_fetch_array(mysql_query($query)); 
  if(
$result['id']) echo "<h2>Hello {$result[id]}</h2>"
   
  
$_GET[pw] = addslashes($_GET[pw]); 
  
$query "select pw from prob_orge where id='admin' and pw='{$_GET[pw]}'"
  
$result = @mysql_fetch_array(mysql_query($query)); 
  if((
$result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orge"); 
  
highlight_file(__FILE__); 
?>

Blind SQL을 막기 위해 열심히 필터링 한 흔적은 보이지 않는다. 단지 이 문제를 blind SQL이라고 짐작하게 하는 부분은

- 출력되는 값은 쿼리 결과에서의 ID 값 뿐인점
- pw 인자를 통해 공격하지만 최종 인증은 pw의 값을 알아야 한다는점
- 쿼리의 결과가 없으면 값이 출력되지 않는점

이 3가지를 들수 있다.

하지만 이 문제들을 blind 기법을 사용하지 않고 공격을 해 보도록 하자.
SQL injection에서 Blind 기법이 아니라면 union과 같이 임의의 출력을 보여줄수 있는 구문을 채용하거나
sleep()과 같은 side channel 을 사용하는것이 큰 부류라고 생각한다. 해당 문제에서 sleep() 을 사용하였을 경우 정확한 값을 측정하기까지 몇번의 시도가 있어야 하고 sleep()도 blind sql 의 갈래로 보는 경우가 많다.
따라서 이 문서에서는 union을 사용해서 공격하는 방법에 대해서 조금 설명하고자 한다.

mysql 또한 프로그래밍에서 말하는 변수라는 개념을 가지고 있다.
mysql에서 변수는 주로 오버헤드를 줄이기 위해서 채용하는 경우가 많다.
이 같은 내용은 기타 프로그래밍에서도 느낄수 있는 예제가 많이 있을것이다.


char* s_name = "Sakuya Izayoi";
for(int i =0; i < 0x99; i++)
  printf("NAME LENGTH : %d",strlen(s_name));

와 같은 코드가 있다면, strlen 함수를 0x99번을 부르게 될것이다. (물론, 컴파일러가 최적화 해줄것이라 생각한다.)
strlen(s_name)의 값을 변수에 넣어두고 그 값을 계속 부르면 오버헤드가 덜 할것이다.

db는 특히나 유저의 요청이 많고 많은 정보를 포함하고 있어서 이러한 최적화를 쿼리단계에서 해주는것도 상당히 중요하다.
여기서 사용하는 변수를 우리는 공격에 사용할 것이다.
우선 원하는 값을 변수에 담고, 그 값을 union을 통해 출력하도록 할 것이다.

우선 변수에 넣는 방법부터 알아보자
변수에 넣을 값을 출력해야 하므로 SELECT 구문에 대한 reference를 참고하면 좋을것 같다. SELECT ~ INTO OUTFILE(DUMPFILE) PATH 를 사용하면 파일로 출력할 수 있지만, var_name을 사용하면 해당 변수에 그 값을 담는것이 가능하다.


하지만 Reference를 보면 into 이후에 union구문을 사용할 수 없다고 되어있다.
실제로 사용하면 에러가 발생한다.

때문에 조금 다른방법으로 변수에 값을 대입하는 방법을 소개한다



해당 방법을 사용하면 변수에 값을 바로 대입하는것이 가능하다.
이를 통해 공격 쿼리문을 다시 구성해보면


공격이 성공한 것을 볼 수 있다.
이것을 응용해서 orge문제에 접근해 보도록 하자.


6c864dec 라는 값을 얻을수 있고, 이것은 admin의 password임을 확인 할 수 있다.
덧붙여서 @a:=pw 이전에 아무런 조건도 주지 않으면, 맨 마지막 row의 값을 들고와서 대입을 하게 되는데 이것은 아마 모든 row를 돌면서 값을 대입하기 때문이라 생각한다.




때문에 원하는 값을 정확히 얻고 싶다면 조건을 붙여주는것으로 쿼리문을 작성할 필요가 있다.

4. 결론
Blind SQL injeciton의 몇가지 기법과 이러한 기법을 우회하여 공격할 수 있는 방법에 대해 알아보았다. 오버헤드를 줄이기 위해서 사용해야 할 변수를 공격에도 사용할수 있음을 알고, DB와 연결되는 보안서비스에 대한 재 점검이 필요한 서버도 있지 않을까?


'Web' 카테고리의 다른 글

[TIP?] sql injection을 위한 깔끔한 코드 작성법  (2) 2018.08.21
Webhacking Study - Query sniff  (2) 2018.04.06
SQLi.py  (0) 2016.11.02
Upload 코드의 흔한 실수  (2) 2016.03.07
Custom Webshell  (0) 2016.02.12
Posted by IzayoiSakuya
,

-출제후기-


문제를 내보는게 어떻겠냐는 처음 제의에 많이 망설였습니다.

코드게이트가 작은 대회도 아니고 제 실력으로 전세계의 짱짱한 해킹팀들을 테스트 하는 문제를 낸다는게 상당히 부담스럽고

코딩실수나 문제 설계 오류로 인해서 많은 팀들의 눈쌀을 찌푸리게 하진 않을까, 제의 해준 회사에 누가 되지는 않을까. 하고 말이죠


"팀당 한두시간 버틸 난이도로 내주세요" 라고 들으니 더더욱 부담이 컸습니다.
하지만 다른 웹문제 출제도 될테니.. 하고 아이디어를 찾기 시작하다가 평소에 생각해둔, 구현해보고 싶은것을 짜보기로 했습니다.

그게 이번 문제의 첫 단계로 지정된 oracle padding attack이었습니다.


이전에 출제됬던 codegate문제의 oracle padding attack과 크고작은 워게임의 oracle padding attack을 보면서 느낀점이

문제 유형이 하나의 블럭에 대해서만 암/복호화를 하는 유형으로 거의 고정되어 있다는걸 느꼈습니다.

이 부분에서 조금의 고민을 했죠. 왜 하나의 블럭만 암/복호화 하는지.


oracle padding attack 을 이해하기 위해서는 하나의 블럭만 암/복호화 해도 상관없다고 생각합니다만,

공격의 기본이 되는 CBC와 같은 원리에 대해서는 다소 도움이 되지 않을것이라 생각했습니다. 그래서 이것을 2개이상의 블럭이 나오도록

암호화 해보는건 어떨까? 라는게 첫 아이디어 였습니다.


하지만 세계급 대회인 만큼 하나의 아이디어로 문제를 내기엔 역부족이라 생각하였습니다. 그래서 복호화 된 평문을 기준으로 새로운

인증과정이 있으면 어떨까? 하는 생각이 났습니다

일반적인 로그인 과정을 보면 ID와 PW를 입력하듯이, 이 평문에는 그러한 정보가 있고 이 정보를 토대로 로그인을 하는 그런 문제를 만드는것이

어떨까? 하는 생각이 났습니다.


처음엔 단순한 sql injection을 넣을까? 하는 생각을 하다가 조금은 특별한 구문을 채용하기로 했습니다.

해당 구문은 특정상황에서 column name을 몰라도 해당 테이블의 정보유출이 가능한 구문으로, real world에선 거의 쓰일 일이 없지만,

여러분의 학문적인 흥미를 유발하기에 충분할 것이라 생각하고, 문제 풀이과정에 있는 도전자 분들에게는 상당히 많은 스트레스를 유발할수 있지만

문제를 풀어냈을때 쾌감과 함께 얻어가는 지식이 있을것이라 생각했습니다.


이 부분은 제가 BoB 과정에 있으면서 들은 조언중  '문제를 만들때는 항상 전달하고자 하는것이 있어야 한다.' 라는 모토와 부합한다고 생각했습니다.

그리하여, 한국시간 19시 50분 경, LC/BC 팀이 처음으로 이 문제를 풀어내고 IRC 닉네임 vos 라는 해커에게서 "정말 좋은 첼린지 였어!" 라는 말을 들었을때

출제하길 정말 잘했다 라는 생각이 들더군요. 


그 이후 몇몇팀이 풀기 시작하고 대학부에서도 한 팀이 풀어냈습니다. 물론, 질문은 대회가 끝나기 10분 전까지도 왔습니다만.. 그만큼 제 문제에 대해

많은 고민을 해 주신게 아닌가 하고 생각하니 그 동안 고생한 것에 대한 보람이 느껴졌습니다.


한편으로는 역시 padbuster와 같은 tool의 사용을 막기 위해서 조금 더 신경썼어야 했다, 문제를 좀더 어렵게 냈어야 했다 등등 마음속에서 다소의 아쉬움도 있었지만 그것들은 단순히 문제로 도전자를 괴롭히기 위한 하나의 심술에 지나지 않는다는 생각을 했습니다. 이 문제로 난 충분히 이야기 하고싶은것을 전달했고, 이에 대해 많은 분들께서 얻어가는게 있다면 이 문제, 코드게이트에서의 2D Life는 성공적인 문제라고 스스로 생각합니다.


대회도중, 대회가 끝나고도 이 문제에 대해 guessing 문제 라고 말씀하시는 분들이 있는걸 보면 아직 제 문제 출제 실력이 역시 미숙하다는것을 느낍니다. 가능한 자연스럽게 유도하는 문제가 되었어야 헀지만 그렇지 못한점, 이 후기를 통해 사과의 말씀 드리고 싶습니다.


첨부한 문서는 출제된 2D life 문제에 해당하는 제가 쓴 Write up 입니다. 어떻게 보면 제작자가 원하는 방향이라고 볼수도 있겠죠.

주변 지인에게서 받은 풀이방법들도 대부분 제가 의도한 구문들이 적혀있어서 다른 Writeup과 큰 차이는 없을수 있지만.. 



2D Life Write up_off the recode.pdf


'Write_UP' 카테고리의 다른 글

2017 Whitehat Contest Final - Neko Online  (1) 2017.11.16
2017 Whitehat Contest - Winner of Life  (0) 2017.11.01
2015 fetival HUST  (0) 2015.05.28
2014 홀리실드 write-up(find out, syntax highlighter)  (0) 2014.11.25
wargame.kr pwcrack  (0) 2014.11.01
Posted by IzayoiSakuya
,

discord.py

2016. 12. 8. 16:18

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

SQLi.py

2016. 11. 2. 14:02

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

LLVM -3

System 2016. 8. 24. 16:48

지난번 설치까지 끝을 냈다. 그럼 사용을 하는걸로 넘어가 보도록 하자.


1. clang? clang!


처음 설치하고 llvm을 실행해보려고 llvm 파일을 찾았더니 아무리 찾아도 없어서 상당히 당황했다.


여기저기 찾아본 결과, 실행파일명은 llvm이 아니라 clang 이라는걸 알기까지 다소 시간이 걸렸다.


우선 테스트 해볼 소스코드는 아래와 같이 간단하다



쓰이지도 않을 c라는 변수와 함께 HIHIHIHIIH를 출력하고 종료하는 단순한 프로그램이다.


이 프로그램을 각각 gcc와 clang(llvm)으로 컴파일 해 볼 예정이다.


우선 clang을 통해서 컴파일 한 것은 test,

gcc를 통해서 컴파일 한것을 test2으로 지정한 후, 두 파일의 opcodes 를 비교하는걸로 시작하자.


먼저 test ( clang )의 결과물이다.



60 라인( 실제로는 라인 수가 아니지만) 이 출력된 것을 볼 수 있다. 


이제 test2 (gcc)를 보도록 하자.


47 라인으로 끝나는 것을 볼 수 있다. 실제로 아래쪽의 코드가 c언어와 매칭하기 더욱 편한것을 느꼈다.


clang을 통해서 쓰는것이 좀더 쓸데없는? 코드를 더 넣는것 같다.



2. 난독화


llvm을 접하게 되면서 가장 관심이 깊었던건 역시 난독화 분야이다. 이 난독화를 테스트 해보기위해 여기저기 뒤진결과 공식 페이지에 사용방법이 나와있는것을 발견했다.



해당 옵션들을 사용해서 두 파일의 난독화 정도를 비교하기 위해 소스코드를 조금만 더 복잡하게 짜서 테스트 해 보기로 하였다.



코드는 55809와 xor 한 결과값을 두고 문구를 출력하는 간단한 프로그램이다. 분기문이 있어야 될것 같아서 몇가지의 분기문을 추가하고 이 것을 컴파일 해 보았다.


우선 일반적으로 clang을 통해 컴파일 한 결과의 그래프는 아래와 같다



마지막 네모 4개를 보아서 저 부근이 switch 문으로 확인할 수 있다. 크게 복잡하지 않은 구조임을 한눈에 확인 할 수 있다.


이제 모든 옵션을 가미한 결과물의 그래프를 보자.



보기만해도 상당히 암이 걸린다. 위에서 적었다 시피 코드가 크게 복잡하지 않음에도 불구하고 이렇게 암걸리는 코드를 생성해 낼 수 있다.


이걸 NDK에 적용하려고 생각하니 벌써부터 신이 난다


3. 일단 마무리


NDK 설정을 해줘야 하기도하고, 이것을 따로 적용시켜주기도 해야하고.. 다음 포스팅까지는 아마 시간이 길게 걸릴것 같다.



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

Reference


NOP


'System' 카테고리의 다른 글

How 2 heap - fastbin_dup.c  (0) 2017.05.16
How 2 heap - first_fit.c  (0) 2017.05.15
LLVM - 2  (0) 2016.08.17
LLVM - 1  (0) 2016.08.12
프로그램에서 일어날수 있는 레이스컨디션의 예제  (8) 2015.04.01
Posted by IzayoiSakuya
,

LLVM - 2

System 2016. 8. 17. 10:35

LLVM 이 무엇인지 알았으니 간략히 설치를 해 보려 한다.


자세한 설치법은.. 역시 공식 사이트를 참조 하는게 가장 좋지만, 그게 귀찮고 힘든 사람들을 위해서 따로 적는것도 나쁘지 않다고 생각한다.


1. LLVM Source Download


16년 8월 17일 현재시간을 기준으로 가장 최근에 올라와 있는 버전은 3.8.1 이다. 하지만 여기서는 Android Obfuscate 를 목적으로 LLVM을 설치하고 있으므로..


3.6.1 버전을 기준으로 설치를 시작한다. 물론, 다른 버전도 설치 방법은 여타 동일하다.


우선은 다운로드 페이지 로 이동해서 3.6.1 버전의 llvm 소스와 clang 소스를 받자.



다른버전을 사용하실 분들께서는 다른버전의 Clang과 LLVM을 받아주시면 된다. 중요한것은, 해당 버전에 맞게 받아 주어야 한다는 것이다.


llvm을 받아서 커스터마이징을 해보고 싶은 분들은 위의 방법과 같이 소스를 받으시면 되고,


난독화를 위해 이미 만들어진 llvm을 사용하시고 싶은 분들은  GIT으로 그 소스가 제공되고 있으며, git clone -b llvm-3.6.1 https://github.com/obfuscator-llvm/obfuscator.git 명령어 입력으로 다운로드 받을 수 있다.


설치방법은 이하 동일하기 때문에 큰 상관이 없다!


2. 설치하기


일단 LLVM의 소스코드를 적절한 디렉토리에 풀고 나면 해당 경로 내부에 tools 라는 폴더가 있다.


이 폴더 안에 Clang의 소스코드를 풀도록 하자.


LLVM

   - Tools

       -Clang

           -Clang의 내용물


의 형태가 되도록 풀어 주어야 한다.

tar 형식으로 되어 있으니 tar -xvf 명령어 등을 사용하여 풀면 된다.


3. 컴파일 시작! 전에


설치 가이드 에서는 cmake를 사용하고 있다. cmake 버전 또한 높은 버전을 요구하므로 cmake의 소스를 받아서 컴파일을 먼저 해 주도록 하자.


여기에서 그 소스들을 다운 받을수 있으며, 간단하게 ./configure 와  make를 실행하는것으로 cmake의 컴파일이 끝난다.


4. 본격적인 컴파일


모든 준비가 되었으면 LLVM 소스코드 폴더 바깥에 임의의 폴더를 하나 만들자. 설치 가이드 에서는 build 라는 폴더로 만들었으니 우리도 친절하게 mkdir build 라고 적어주자.

이제 이 경로에서 cmake -G "Unix Makefiles" ../llvm코드경로 를 입력해 주면 여러 메세지가 나오면서 마지막에 Configure가 완료 되었다고 뜬다.

이후 make 명령어를 입력하여 최종 컴파일에 돌입하자.



컴파일이 쭉쭉 진행되고 있다. 덧붙여서 해당 컴파일은 시간이 상당히 오래 걸리므로 충분히 쉬다가 오셔도 상관 없을것 같다.


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

Referer : http://cd80.tistory.com/97

'System' 카테고리의 다른 글

How 2 heap - first_fit.c  (0) 2017.05.15
LLVM -3  (2) 2016.08.24
LLVM - 1  (0) 2016.08.12
프로그램에서 일어날수 있는 레이스컨디션의 예제  (8) 2015.04.01
사기를 위한 프로그램 분석  (0) 2014.12.26
Posted by IzayoiSakuya
,

LLVM - 1

System 2016. 8. 12. 13:44

0. Intro


주변에서 LLVM에 대한 소문이 무성히 들려온다.


이런저런 사정으로 LLVM을 손대봐야 하는 상황까지 와버려서, 설치부터 실행, 응용까지 차근차근 겪은일들, 해결한 방법 등을 적어 나가려 한다.


우선 LLVM이 무엇인지 알아야 하는데.. 검색으로도 LLVM이 무엇인지 알수 있다.


Low Level Virtual Machine 이라고 하는데.. 뭐 구구절절한건 집어치우고 일단 본론만 들어가자.



1. 왜 LLVM인가?


일단 LLVM이 무슨 프로그램인가 하고 굳이 분류를 나누자면 컴파일러 인 것 같다. 이런저런 글들을 다 살펴보아도 컴파일러에 관한 이야기 밖에 없다.


그럼 평소에 우리가 쓰는 gcc와 같은 컴파일러와 무엇의 차이점이 있는것인가?


이는 어쩔수 없이 흔한 그림으로 대체하여 설명하려 한다.


다소 거부감이 있더라도 최대한 이해한대로 쉽게 풀어 쓸 테니 양해하고 읽으면 좋겠다.


 

출처 : http://kyejusung.com/


글쓴이는 컴파일러에 대한 공부를 한 적이 없다. 그래서 알고있는것은 gcc source.c -o output 정도.


내가 저렇게 명령어를 입력하고 gcc를 실행시키면, 내부적으로는 위의 그림처럼 3단계를 거쳐서 ouput이 나온다고 한다.


모두가 알다시피 우리가 사용하는 프로그래밍 언어는 컴퓨터가 알아듣지 못한다. 이를 기계어로 번역하는 일을 컴파일러가 도맡아 하는데, 이때 몇가지의 과정이 있다.



- Frontend 

 해당 단계에서는 우리가 쓴 프로그래밍 언어를 분석하고 중간코드를 생성한다. LLVM에서는 중간코드를 IR 이라고 부르는 모양이다.


-Optimizer 

 단계 이름 그대로 최적화를 위한 중복계산을 제거하거나 여러가지 변환을 실행한단다.


-BackEnd

 코드를 타겟에 맞는 기계명령어로 매핑하고 실행코드를 생성한다. 



이렇게 3단계를 거쳐서 우리는 output 이라는 컴파일 결과물을 얻을수 있다.


물론, 우리가 자세히 알필요는 없었다. 우리가 필요한건 결과물이지 그 중간과정이 필요한게 아니었으니까. 내가 명령어를 넣으면, 결과물이 나온다. 

이게 글쓴이가 알고있던 컴파일러였다.


LLVM은 쓸데없이 이 3단계를 따로 분리 해 둔 컴파일러이다.


출처 : http://kyejusung.com/



나올 결과물만 보면 이전의 그것들과 다를것이 없다. 우리는 평범하게 소스코드 파일을 입력으로 줄것이고, LLVM은 이것을 컴파일해서 결과물을 가져올 것이다.


이제 겉은 그만 보고 조금만 안으로 들여다보면, LLVM의 잔머리에 감탄할 수도 있다.


LLVM은 중간코드(이하 IR)를 만들고 이를 각 아키텍쳐(타겟)에 맞는 명령어 셋으로 변환 할수 있다.


더이상 크로스컴파일 같은것에 얽매일 필요가 없다는 뜻이다.


사실 이 내용을 처음 접했을때는 여러가지 크로스 컴파일을 덕지덕지 붙여논것이라고 생각했다. 하지만 여기서 LLVM은 한술 더 뜬다


아키텍쳐에 맞는 명령어셋을 IR코드로 변환 가능하다


IR을 명령어로, 명령어를 IR로 바꿀수 있는것은 아마 생각하지 못한 여러가지 이점을 가져올수 있다. 악성코드 분석이든, 개발이나 어느방향이든.



개인적인 사정을 떠나서 LLVM이 어떻게 동작할지, 어떻게 다룰수 있을지에 대해서 흥미가 붙었다.


다음 해야할 일은 LLVM을 설치하고.. 이것을 어떻게 사용할지, IR은 어떻게 보는지, 그리고 정말 결과물을 내가 IR코드로 되돌릴수 있는지에 대해서 테스트 해 볼 생각이다.

'System' 카테고리의 다른 글

How 2 heap - first_fit.c  (0) 2017.05.15
LLVM -3  (2) 2016.08.24
LLVM - 2  (0) 2016.08.17
프로그램에서 일어날수 있는 레이스컨디션의 예제  (8) 2015.04.01
사기를 위한 프로그램 분석  (0) 2014.12.26
Posted by IzayoiSakuya
,

Proxy.py

backup 2016. 6. 13. 14:53
import socket
import os
import sys

class Server():
	def __init__(self,port):
		self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
		self.s.bind(("",port))
		self.s.listen(10)

	def Connect(self):
		self.client, self.addr = self.s.accept()
		print "[*] %s is connected."%(self.addr[0])
		return self.client
			

	def FromUser(self):
		data = self.client.recv(65536)
		return data
		
class Client():
	def __init__(self,Host,Port):
		self.s = socket.socket()
		self.s.connect((Host,int(Port)))

	def FromServer(self):
		data = self.s.recv(65536)
		return data

if len(sys.argv) != 4:
	print "[*] USAGE : %s LocalPort RemoteHost RemotePort"%(sys.argv[0])
	exit(-1)

User = Server(int(sys.argv[1]))
while(1):
	User.Connect()
	pid = os.fork()
	if pid == 0:
		Server = Client(sys.argv[2],sys.argv[3])
		pid = os.fork()
		if pid == 0:
			while (1):
				try:
					data = Server.FromServer()
					User.client.send(data)
				except:
					pass
		else:
			while(1):
				try:
					data = User.FromUser()
					Server.s.send(data+"\r\n")
				except:
					pass
	else:
		continue

'backup' 카테고리의 다른 글

discord.py  (0) 2016.12.08
Pixiv Crawler  (2) 2016.06.02
Zip parser source  (0) 2016.03.15
security tools.php  (0) 2015.12.04
[Gussing]  (0) 2015.10.11
Posted by IzayoiSakuya
,