'Categories'에 해당되는 글 103건

  1. 2013.09.28 [BOF원정대/FC3] hell_fire -> evil_wizard
  2. 2013.09.26 RTL시 pop pop ret, exit 함수 호출의 원리 2
  3. 2013.09.05 으..
  4. 2013.07.27 codegate junior ctf
  5. 2013.07.18 Binary Search
  6. 2013.07.13 좋은 사이트..
  7. 2013.07.11 [Ollydbg 1.x] OllyMSDN plugin
  8. 2013.07.09 Things to do..
  9. 2013.07.09 c++ 급여 관리 시스템
  10. 2013.05.12 BlackJack in Python


/*

        The Lord of the BOF : The Fellowship of the BOF 

- evil_wizard

- Local BOF on Fedora Core 3 

- hint : GOT overwriting

*/


// magic potion for you

void pop_pop_ret(void)

{

asm("pop %eax");

asm("pop %eax");

asm("ret");

}

 

int main(int argc, char *argv[])

{

char buffer[256];

char saved_sfp[4];

int length; 


if(argc < 2){

printf("argv error\n");

exit(0);

}


// for disturbance RET sleding

length = strlen(argv[1]);

   

        // healing potion for you

        setreuid(geteuid(), geteuid());

        setregid(getegid(), getegid());


// save sfp 

memcpy(saved_sfp, buffer+264, 4);

 

// overflow!!

strcpy(buffer, argv[1]);


// restore sfp 

memcpy(buffer+264, saved_sfp, 4);


        // disturbance RET sleding

        memset(buffer+length, 0, (int)0xff000000 - (int)(buffer+length));


printf("%s\n", buffer);

}

 




위 소스를 봐보면 스택을 0으로 초기화 해줌으로써 RET Sled를 방지해줬고

문제 해결의 실마리로 pop pop ret 코드를 제공해줍니다.

pop pop ret를 이용해 함수를 연쇄적으로 호출 할수가 있는데


[ func1 ][ ret ][ arg1 ][ arg2 ][ func2 ][ ret ][ ...]


위 스택구조에서 ret에다가 pop pop ret을 넣어줌으로써 esp를 8바이트 위로 올려주고 그 다음위치에 있는

값이 ret로 가는 형식으로 함수 연쇄 호출이 가능합니다. 



ASCII Armor 때문에 system함수를 호출할 때 인자구성을 해줄수가 없으므로 ASCII Armor의 영향을 받지않는

PLT를 이용해 주면 됩니다. GOT와 PLT 관련 사이트들은 아래를 참조해주시면 될꺼 같네요


http://lapislazull.tistory.com/54

http://ezbeat.tistory.com/374

http://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html



그럼 GOT Overwrite가 정확히 무엇인지 알아보겠습니다.

GOT Overwrite란 실제 함수의 주소를 저장하고 있는 GOT 테이블을 변조해서 원하는 함수를 호출하는 방법입니다.


예를들어 memcpy함수를 호출할때 GOT Overwrite를 통해 memcpy의 주소가 저장된 GOT 테이블을 system함수의 주소로 변조한 후 memcpy의 plt를 호출하면 system함수가 호출됩니다

그럼 최종적으로 pop pop ret 가젯을 이용해 chaining rtl로 strcpy를 불러와 memory got에 system주소를 넣어주면 될꺼 같네요


[hell_fire@Fedora_1stFloor ~]$ objdump -d evil_wizard | grep pop -A1


--

 804854f: 58                   pop    %eax

 8048550: 58                   pop    %eax

 8048551: c3                   ret    

--


[hell_fire@Fedora_1stFloor ~]$ objdump -h evil_wizard | grep .got.plt

 20 .got.plt      00000038  0804986c  0804986c  0000086c  2**2


[hell_fire@Fedora_1stFloor ~]$ gdb -q wizard_evil


(gdb) b *main+319

Breakpoint 1 at 0x8048693


(gdb) r a

Starting program: /home/hell_fire/wizard_evil a

(no debugging symbols found)...(no debugging symbols found)...a


Breakpoint 1, 0x08048693 in main ()


(gdb) print memcpy

$1 = {<text variable, no debug info>} 0x7854c0 <memcpy>


(gdb) print system

$2 = {<text variable, no debug info>} 0x7507c0 <system>


(gdb) print strcpy

$3 = {<text variable, no debug info>} 0x783880 <strcpy>


(gdb) x/10x 0x804986c

0x804986c <_GLOBAL_OFFSET_TABLE_>: 0x080497a0 0x007194f8 0x0070e9e0 0x00783d70

0x804987c <_GLOBAL_OFFSET_TABLE_+16>: 0x007d98f0 0x00730d50 0x0075e660 0x007854c0

0x804988c <_GLOBAL_OFFSET_TABLE_+32>: 0x007d9860 0x0804845a


system함수의 인자로 넣어줄 /bin/sh도 구성해줘야 되는데 

어떤 분의 블로그를 보고 아이디어를 얻었다. bss영역을 이용해 거기다가 /bin/sh 문자열을 

구성해주면 될까 싶어서 시도해봤더니 됬습니다.


[hell_fire@Fedora_1stFloor ~]$ objdump -h evil_wizard | grep bss

 22 .bss          00000004  080498b0  080498b0  000008b0  2**2


[hell_fire@Fedora_1stFloor ~]$ gdb -q wizard_evil

(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) b *main

Breakpoint 1 at 0x8048554

(gdb) r a

Starting program: /home/hell_fire/wizard_evil a

(no debugging symbols found)...(no debugging symbols found)...

Breakpoint 1, 0x08048554 in main ()

(gdb) x/10x 0x080498b0

0x80498b0 <completed.1>: 0x00000000 0x00000000 0x00000000 0x00000000

0x80498c0: 0x00000000 0x00000000 0x00000000 0x00000000

0x80498d0: 0x00000000 0x00000000


저기 공간중에서 적절한 주소값을 찾아서 /bin/sh를 넣어주면 됩니다.

대충 구상도 다 했으니 이제 필요한 문자열들을 찾아내줘야되는데

/, b, i, n, s, h, \xc0, \x07, \x75, \x00 를 찾아주면 되겠습니다.


이제 익스플로잇을 짜주면 되는데 시험 끝나고 마무리 해야될꺼 같네요


'Wargame > LOB[FC]' 카테고리의 다른 글

[BOF원정대/FC3] evil_wizard -> dark_stone  (0) 2013.10.14
Posted by xer0s :

몇일 전에 알아낸 사실인데

RTL을 하거나 ROP등을 하기 위해 exit함수 또는 가젯등을 이용할때 그게 어떤 원리로 돌아가는지 궁금해서 

연구해봤는데

RTL을 예로 들어보면 스택구조가 [ buffer ][ sfp ][ ret ] 대충이런식으로 있다고 가정했을때

ret에 system함수 주소를 넣어주면 정상적으로 (call로 호출) system함수를 호출 했을때 함수 호출 이후 

코드 실행을 위해 saved eip를 스택에 푸쉬하는데 ret로 함수를 호출하면 이 push eip가 안된 상태에서 

함수 내부에서 함수를 빠져나올때 원래 push eip가 되있어야 될위치의 값을 호출하기 때문에 

[ &system ][ &exit ][ /bin/sh ] 와 같은 구성이 가능한 것이다. 함수 인자를 ebp + 8부터 참조하는것도

이 이유 때문이다.

이런 원리를 이용해 chaining rtl을 할때도 pop pop ret과 같은 가젯을 이용해 계속 ret로 함수를 호출하면서

구성을 해줄수가 있다.

'Security' 카테고리의 다른 글

허..  (0) 2013.10.17
php extract vulnerability  (0) 2013.10.13
[Ollydbg 1.x] OllyMSDN plugin  (0) 2013.07.11
유용한 자료들..  (0) 2013.04.22
Duelist crackme #1 풀이  (0) 2013.03.10
Posted by xer0s :

으..

2013. 9. 5. 23:53 from General News/Life story

항상 블로그를 꾸준히 관리하겠다고 다짐하지만 보름을 못가 그 다짐이 무너지네요 ㅠㅠ

이놈의 귀차니즘이 문제지..


요즘 주식이랑 심리학도 공부하고 있는데 언제한번 그 포스팅이나 할깨요


그나저나 곧있으면 중간고사고 또 금방 디미고 원서 접수기간인데..

포스팅 할수는 있으련지 ㄷㄷ..


'General News > Life story' 카테고리의 다른 글

2014 순천향대 청소년 정보보호 페스티벌 예선  (0) 2014.08.14
2014 코드게이트 주니어 세미나 발표자료 및 후기  (2) 2014.04.03
근황..  (3) 2013.12.31
합격!  (0) 2013.11.27
Things to do..  (0) 2013.07.09
Posted by xer0s :

2013-07-26 오전 10시부터 오후 10시까지 코드게이트에서 주최하는 주니어 ctf가 열렸습니다.                      

아침부터 학원을가서 거의 2시간 다 되서 돌아와서 풀기 시작했는데 벌써 올클 하신분도 계시더군요 -.-


시스템 분야는 아예 자신이 없어서 대회전부터 겁을 먹고 시작했었는데 다행이 처음 3문제는 시스템이 아니더군

요. 시스템공부도 열심히 해서 다음을 기약하며 간단하게 write up 끄적여 봅니다.


#1 

HQGOHVVURERWZDU

위 암호문이 주어지고 문제가 주어졌습니다.

알파벳을 보자마자 떠오른게 시져암호 였는데 key를 1부터 하나하나 해보니 key가 3일때 

ENDLESSROBOTWAR이라는 글자가 나오더군요.

인증했더니 정답이였습니다.


#2

두번째 문제는 리버싱이였습니다. 바이너리를 다운받고 올리로 까본결과 

키가 아니라는 문자열로 가게 해주는 jnz들이 다수 존재했고 jnz바로 위에 입력한글자에서 

특정값과 xor한다음 그걸 비교해주는 연산이 존재했습니다.

각 조건에 맞는 값을 xor해서 구해줘서 이어주면 

hello junior hackers라는 정답이 나왔습니다.


#3

어이없게 삽질을 했던 문제엿습니다.

사이트가 주여졌고 사이트에 들어가보면 id 와 password를 입력하는 창과 두 소스가 주어졌습니다.

계정은 admin_1000 부터 admin_9999까지 사용할 수 있게 코딩이 되어있더군요.

첫번째 소스(login_ok.phps)를 봐보니 @fopen하는 부분에 id_pass_db 디렉토리가 보였습니다.

혹시 되나 하고 그 디렉토리로 접속을 해봣더니 각 계정마다 password가 txt파일로 있더군요.

아이디와 비밀번호를 입력하고 로그인을 하려하자 너무 많은 시도로 block되 있다고 나왓습니다

그래서 두번째 소스인(remove_block_ok.phps)를 봤습니다.

소스를 보면 $authcode를 입력받고 이를 특정값이랑 비교해주는 부분이 있는데 여기서 authcode를 찾아내는

라 조금 삽질을 했었습니다. 그러나 소스 아래부분을 다시 봐줬을때 /block 이라는 디렉토리가 존재하였고 

그 디렉토리를 봐본결과 block이 설정된 계정들 목록이 있더군요.

그래서 거기에 없는 계정으로 다시 패스워드 구해서 로그인 해줬더니 키가 나오고 풀렸습니다.


나름 자극도 받았고 비록 3문제 밖에 못풀었지만 내년에는 꼭 이보다 더 좋은 성적을 위해 노력해야 겠습니다.

대충 끄적인 풀이 읽어 주셔서 감사합니다 ..ㅋㅋ


'General News > Write-Ups' 카테고리의 다른 글

HackIM nullcon 2015 exploitation100  (0) 2015.01.11
ChristmasCTF ALGO200  (0) 2014.12.26
CSAW CTF 2014 Pybabies  (0) 2014.09.26
codegate 2013 vuln200 - exploit only  (0) 2014.02.14
ropasaurusrex  (1) 2013.12.06
Posted by xer0s :

Binary Search

2013. 7. 18. 01:41 from Programming

이진 탐색 알고리즘에 관해 간단하게 포스팅해보려 합니다.


#include <stdio.h>

int BSearch(int ar[], int len, int target){

int first = 0;

int last = len-1;

int mid;


while(first<=last){

mid = (first + last) / 2;


if(target == ar[mid]){

return mid;

}

else {

if(target < ar[mid])

last = mid - 1;

else

first = mid + 1;

}

}

return -1;

}


int main(void){

int arr[] = {1, 3, 5, 7, 9};

int idx;


idx = BSearch(arr, sizeof(arr)/sizeof(int), 7);

if(idx == -1)

printf("탐색 실패 \n");

else

printf("타겟 저장 인덱스: %d\n", idx);


idx = BSearch(arr, sizeof(arr)/sizeof(int), 4);

if(idx == -1)

printf("탐색 실패 \n");

else

printf("타겟 저장 인덱스: %d\n", idx);


return 0;

}

 


위 소스에서 최악의 경우에 대한 시간 복잡도 함수는

k를 n이 1이 되기까지 2로 나눈 횟수라 할때  T(n) = k + 1 입니다.


n이 1이 되기까지 2로 나눈 횟수가 k이므로 다음과 같은 식도 세울수 있습니다.



저 식을 정리해주면



여기서 이 식에 로그를 취하고 정리해주면



따라서 결국



가 되는데 자료구조를 조금이라도 공부해보신 분이라면 알수 있는 내용이 

저 T(n) 구조를 취한 로그 그래프가 바로 x축을 데이터수라하고 y축을 연산횟수라 하였을때 

가장 바람직한 알고리즘이 된다는 것입니다.


결국 이진탐색알고리즘은 좋은 알고리즘!





'Programming' 카테고리의 다른 글

[dovelet]-crypt  (0) 2014.01.20
os 판별 코드  (0) 2013.10.11
좋은 사이트..  (0) 2013.07.13
c++ 급여 관리 시스템  (0) 2013.07.09
BlackJack in Python  (0) 2013.05.12
Posted by xer0s :

좋은 사이트..

2013. 7. 13. 03:33 from Programming

최근에 ruby on rails도 관심이 생기고 구글링도 하면서 뒤져본 결과

http://www.tutorialspoint.com/index.htm

위 사이트를 발견했습니다. 강의들도 다 깔끔하고 좋고 pdf들도 다 제공되고

assembly부터 해서 여러 프로그래밍 강의들도 있더군요

공유합니다.


// 이 글 쓰면서 하나 ruby on rails 튜토리얼 괜찮은거 하나 더 찾았네요.

// http://ruby.railstutorial.org/ruby-on-rails-tutorial-book


'Programming' 카테고리의 다른 글

[dovelet]-crypt  (0) 2014.01.20
os 판별 코드  (0) 2013.10.11
Binary Search  (0) 2013.07.18
c++ 급여 관리 시스템  (0) 2013.07.09
BlackJack in Python  (0) 2013.05.12
Posted by xer0s :

[Ollydbg 1.x] OllyMSDN plugin

2013. 7. 11. 00:28 from Security

리버싱 공부중 우연히 좋은 플러그인을 하나 발견했습니다.

이때까지 모르는 api는 그때그때 msdn에다 직접 검색하면서 공부하였는데 

이 플러그인은 바로 그런 번거로움을 없애주고 직접 msdn사이트에서 찾고자 하는 api를 찾아줍니다


 

OllyMSDN.zip




dll을 풀어도 안되는 경우가 있는데 win32.hlp도 함께 넣어줘야 합니다.

win32.hlp는 진짜 파일이 아니여도 되고 이름만 win32.hlp면 됩니다


플러그인 사용법은 자신이 검색하고자 하는 api에 오른쪽 마우스 클릭후 

Help on symbolic name(CTRL + F1) 을 클릭해주시면 됩니다.



'Security' 카테고리의 다른 글

허..  (0) 2013.10.17
php extract vulnerability  (0) 2013.10.13
RTL시 pop pop ret, exit 함수 호출의 원리  (2) 2013.09.26
유용한 자료들..  (0) 2013.04.22
Duelist crackme #1 풀이  (0) 2013.03.10
Posted by xer0s :

Things to do..

2013. 7. 9. 23:50 from General News/Life story

겨울 방학이 2주도 안남았는데

이번 방학은 저번 겨울방학과는 달리 정말 알차게 보내보고 싶네요.

맨날 할일들만 적어놓고 실천을 안하는 경우가 태반인데 

이 포스팅에 쓴 것 만큼은 방학동안 꼭 열심히 해봐야겠습니다.


  • 리버싱 핵심원리 고급 리버싱 파트 + pe 복습
  • 와이어샤크 익숙해지기 + TCP/IP Illustrated 필요한 부분 읽기
  • window via c/c++ 스터딩 
  • c++문법 익숙해지기 + stl공부
  • 자료구조 공부
  • wargame.kr, codeengn, reversing.kr 
  • 리마, 정보처리기능사 자격증 따기 

시간 참 빠른듯..


'General News > Life story' 카테고리의 다른 글

2014 순천향대 청소년 정보보호 페스티벌 예선  (0) 2014.08.14
2014 코드게이트 주니어 세미나 발표자료 및 후기  (2) 2014.04.03
근황..  (3) 2013.12.31
합격!  (0) 2013.11.27
으..  (0) 2013.09.05
Posted by xer0s :

c++ 급여 관리 시스템

2013. 7. 9. 01:45 from Programming

요즘 c++ 배우고 있는데 가상함수 복잡복잡 하네요



#include <iostream>

#include <cstring>

using namespace std;


class Employee

{

private:

char name[100];

public:

Employee(char * name)

{

strcpy(this->name, name);

}

virtual int GetPay() const =0;

virtual void ShowSalaryInfo() const =0;


    void ShowYourName() const

{

cout<<"Name: "<<name<<endl;

}

};


class PermanentWorker : public Employee

{

private:

int salary;

public:

PermanentWorker(char * name, int money) : Employee(name), salary(money)

{ }

int GetPay() const

{

return salary;

}

void ShowSalaryInfo() const

{

ShowYourName();

cout<<"salary: "<<GetPay()<<endl<<endl;

}

};


class EmployeeHandler

{

private:

Employee * empList[50];

int empNum;

public:

EmployeeHandler() : empNum(0)

{ }

void AddEmployee(Employee * emp)

{

empList[empNum++]=emp;

}

void ShowAllSalaryInfo() const

{

}

void ShowTotalSalary() const

{

int sum=0;

cout<<"salary sum: "<<sum<<endl;

}

~EmployeeHandler()

{

for(int i=0; i<empNum; i++)

delete empList[i];

}

};


class TemporaryWorker : public Employee

{

private:

int workTime;

int payPerHour;

public:

TemporaryWorker(char * name, int pay) : Employee(name), workTime(0), payPerHour(pay)

{ }

void AddWorkTime(int time)

{

workTime+=time;

}

int GetPay() const

{

return workTime * payPerHour;

}

void ShowSalaryInfo() const

{

ShowYourName();

cout<<"salary: "<<GetPay()<<endl<<endl;

}

};


class SalesWorker : public PermanentWorker

{

private:

int salesResult;

double bonusRatio;

public:

SalesWorker(char * name, int money, double ratio) : PermanentWorker(name, money), salesResult(0), bonusRatio(ratio)

{ }

void AddSalesResult(int value)

{

salesResult+=value;

}

int GetPay() const

{

return PermanentWorker::GetPay() + (int)(salesResult * bonusRatio);

}

void ShowSalaryInfo() const

{

ShowYourName();

cout<<"salary: "<<GetPay()<<endl<<endl;

}

};


int main(void)

{

EmployeeHandler handler;


handler.AddEmployee(new PermanentWorker("kim", 1000));

handler.AddEmployee(new PermanentWorker("lee", 1500));


TemporaryWorker * alba = new TemporaryWorker("jung", 700);

alba->AddWorkTime(5);

handler.AddEmployee(alba);


SalesWorker * seller = new SalesWorker("hong", 1000, 0.1);

seller->AddSalesResult(7000);

handler.AddEmployee(seller);


handler.ShowAllSalaryInfo();


handler.ShowTotalSalary();

return 0;



'Programming' 카테고리의 다른 글

[dovelet]-crypt  (0) 2014.01.20
os 판별 코드  (0) 2013.10.11
Binary Search  (0) 2013.07.18
좋은 사이트..  (0) 2013.07.13
BlackJack in Python  (0) 2013.05.12
Posted by xer0s :

BlackJack in Python

2013. 5. 12. 19:04 from Programming


#BlackJack rules can be found here http://www.114pda.com/game/card/blackjack_rule.htm

import os import random def game(): os.system("cls") print "WELCOME TO PYTHON BLACKJACK" Cards = [1,2,3,4,5,6,7,8,9,10,11,12,13,14] computerHand = deal() playerHand = deal() print "-------START GAME-------" print "Computer Hand: " + str(computerHand[0]) print "Player Hand: " + str(playerHand) print "\n-------Current Score-----" if(computeScore(playerHand) == 21): print "21! You win!" message() elif(computeScore(computerHand) == 21): print "21! Computer Wins!" message() print computeScore(playerHand) cardHit = raw_input("Do you want to hit (Y/N): ") while(cardHit == "y" or cardHit == "Y" ): hit(playerHand) print "\n------NEW HAND SCORE------" print playerHand print computeScore(playerHand) if(len(playerHand) == 5 and computeScore(playerHand) < 21): print "Less than 5 and Under 21: YOU WIN " message() elif(bust(playerHand) == 1): print "BUST. You lose" message() else: cardHit = raw_input("Do you want to hit (Y/N): ") print "\n-------Computer Turn------" if(computeStrategy(computerHand) == "Hit"): hit(computerHand) print computerHand else: print "I'm done." print computerHand print "\n--------DETERMINE WINNER------" print "COMPUTER: " + str(computeScore(computerHand)) print "PLAYER : " + str(computeScore(playerHand)) if(winner(computerHand,playerHand) == "hand1" and bust(computerHand)==0): print "Computer won" elif(winner(computerHand,playerHand) == "hand2" and bust(playerHand) == 1): print "Computer won" elif(winner(computerHand,playerHand) == "hand1" and bust(computerHand) == 1): print "Player Won" elif(winner(computerHand,playerHand) == "hand2" and bust(playerHand) == 0): print "Player Won" message() def message(): again = raw_input("Do you want to play again? (Y/N) : ") if(again == "Y" or again == "y"): game() else: print "\n\n-------Thank you for playing!--------\n\n" exit() def deal(): random1 = random.randint(1,14) random2 = random.randint(1,14) if (random1 == 11):random1 = "J" if (random1 == 12):random1 = "Q" if (random1 == 13):random1 = "K" if (random1 == 14):random1 = "A" if (random2 == 11):random2 = "J" if (random2 == 12):random2 = "Q" if (random2 == 13):random2 = "K" if (random2 == 14):random2 = "A" hand = [random1,random2] return hand def computeScore(hand): total = 0 for cards in hand: if cards == "J" or cards == "Q" or cards == "K": total+= 10 elif cards == "A": if total == 11: total+= 1 else:total+= 11 else: total += cards return total def hit(hand): newCard = random.randint(1,14) if (newCard == 11):newCard = "J" if (newCard == 12):newCard = "Q" if (newCard == 13):newCard = "K" if (newCard == 14):newCard = "A" hand.append(newCard) return hand def computeStrategy(hand): strategy = "" if (computeScore(hand) > 15): strategy = "Stay" if (computeScore(hand) <=15): strategy = "Hit" return strategy def winner(hand1,hand2): score1 = computeScore(hand1) score2 = computeScore(hand2) if score1 > 21: return "hand2" if score2 > 21: return "hand1" if(score1 > score2): return "hand1" else: return "hand2" def bust(hand): if computeScore(hand) >= 21: return 1 else: return 0 if __name__ == "__main__": game()


'Programming' 카테고리의 다른 글

[dovelet]-crypt  (0) 2014.01.20
os 판별 코드  (0) 2013.10.11
Binary Search  (0) 2013.07.18
좋은 사이트..  (0) 2013.07.13
c++ 급여 관리 시스템  (0) 2013.07.09
Posted by xer0s :