Powerplay

Descrição do Desafio

Categoria: misc

Descrição:

Pump yourself up with power to get an inspirational quote.

Arquivos

Arquivo
Descrição

chall.py

Código sendo executado no servidor.

solve.py

Script em Python que descobre o número correto.

📥 Download: Arquivos

Solução

O desafio disponibliza o seguinte código python.

chall.py
import numpy as np
from secret import flag, quotes

prizes = quotes + ['missingno'] * 4 + [flag] * 24

if __name__ == '__main__':
	print('Welcome to our playground for powerful people where you can pump yourself up and get awesome prizes!\n')
	player_count = int(input('How many players participate?\n'))
	power = np.zeros(player_count, dtype = np.int32)
	for i in range(player_count):
		power[i] = int(input(f'Player {i}, how strong are you right now?\n'))
	ready = False

	while True:
		print('What do you want to do?\n1) pump up\n2) cash in')
		option = int(input())
		if option == 1:
			power = power**2
			ready = True
		elif option == 2:
			if not ready:
				raise Exception('Nope, too weak')
			for i in range(player_count):
				if power[i] < len(quotes):
					print(f'You got an inspiration: {prizes[power[i]]}')
			exit()
		else:
			raise Exception('What?')

Analisando esse código, podemos ver que há um vetor prizes que contém várias strings e a flag 24 vezes no final, então, precisamos acessar alguma dessas posições em que a flag está.

Observando o funcionamento do código, é primeiro pedido do usuário a quantidade de jogadores e a "força" de cada jogador, após isso, o usuário pode escolher duas opções. A primeira opção "pump up" eleva todos as "forças" de todos os jogadores ao quadrado e a segunda opção "cash in" acessa uma posição do vetor prizes, porém, so irá acessar a posição caso a "força" do jogador seja menor que a quantidade de strings no vetor "quotes".

Portanto, precisamos escolher uma "força" que, ao elevar ao quadrado, resulte em uma posição em que a flag está no vetor de prizes, porém, como o vetor prizes contém todas as strings de quotes e o código não deixa o usuário acessar alguma posição que seja maior que o tamanho de quotes, não podemos acessar as posições que a flag está de maneira tradicional.

Para passar por essa verificação, podemos usar uma propriedade da linguagem python que é os índices negativos.

Desse modo, precisamos acessar alguma posição entre -1 e -24, que são as posições em que a flag se encontra. Porém, precisamos de algum número que, elevado ao quadrado, resulta em um número nesse intervalo. Podemos fazer isso utilizando integer overflow.

Como a variável power é definido commo um int de 32 bits, podemos encontrar algum número que, elevado ao quadrado, passa do valor máximo de inteiros de 32 bits e resulta em um número negativo. Para fazer isso, podemos fazer um script simples que testa todos os números de 0 até o maior inteiro possível de 32 bits e verifica se esse número ao quadrado se encaixa no intervalo de -24 a -1.

Ao rodar esse script, obtemos o seguinte output.

Agora, basta apenas conectar ao servidor e usar esse número como "força" de qualquer jogador

Flag: ENO{d0_n0t_be_s0_neg4t1ve_wh3n_y0u_sh0uld_be_pos1t1ve}

Autor da WriteUp

Membro de Exploitation - CaioMendesRRosa

Atualizado