CTF/웹해킹

[angstromCTF] Secret Agents - 웹해킹 / SQL Injection

SecurityMan 2022. 3. 12. 15:30


이 문제부터 조금씩 어려워지기 시작했다.

Secret Agents 라는 웹 해킹 문제이다.

 

문제설명을 읽어보면 secret agent portal 에 접속할수 있냐고 물어본다.

그리고 유출된 웹 페이지의 소스코드가 힌트로 제공이 된다.



문제페이지에 접속해보면
Welcome to the Super Secret Agents official site ! 라는 환영문구가 보인다.
비밀요원들만 접속할 수 있는 숨겨진 웹사이트 인가 보다.
아래쪽에
Here's the secret : actual secret agents have their OWN BROWSERS!! 라고 적혀있다.
비밀요원들은 특별한 브라우저를 이용해서 해당 페이지에 접근한다고 한다.

 

브라우저란 우리가 사용하는 크롬, 인터넷 익스플로러, 파이어폭스, 사파리 등을 말한다.
맨 밑에있는 get in 버튼을 누르면 비밀페이지에 접속이 가능한데,

그냥 누르면 너는 여기 접속하는게 허용되지 않았다고 하면서 튕거버린다.

 

반응형

 

웹해킹좀 해봤던 사람이면 여기까지 왔을때 눈치를 챘을것이다.

 

이 문제는 웹 요청 패킷의 User-Agent 헤더값을 수정하면 풀 수 있는 문제이다.

 

User-Agent 헤더 클라이언트가 서버에 자신이 어떤 브라우저를 사용하는지 알려주는 역할을 한다.

 

가령 우리가 컴퓨터로 네이버에 접속할때랑, 폰으로 네이버에 접속할때 UI 가 다른데,

 

그게 바로  User-Agent 헤더에서 폰으로 접속했다는 정보를 담고 있기 때문이다.

 

주어진 소스코드를 보면 어떤 것을 해야하는지 알 수 있다.
python flask를 이용해서 작성된 웹 서버이다.
 
@app.route("/login")
def login():
	u = request.hearders.get("User-Agent")

이부분을 보면 요청 헤더에서 User-Agent 값을 가져와, u 라는 변수에 담는것을 볼 수 있다.

 

for i in cursor.execute("SELECT * FROM Agents WHERE UA='%s'"%(u), multi=True):

여기서는 u라는 변수의 값을 이용하여 데이터베이스에서 정보를 가져오는것을 볼 수 있다.

이렇게 DB와 웹 서버가 상호작용하는 부분에서는 SQL 인젝션 취약점이 발생하게 된다.

 


burp suite라는 프록시 도구를 이용해서 웹 요청 패킷을 잡은 뒤에,
User-Agent 값을 a' or 1=1# 으로 바꿔준다.
그렇게 되면 DB로 날아가는 쿼리가

SELECT * FROM Agents WHERE UA='a' or 1=1#' 이런식으로 변조가 될 것이다.

 

#은 SQL에서 주석을 의미하고 

 

1=1은 참, 참과 or을 하면 앞에있는 WHERE 절도 참이 되기 때문에

 

쿼리는 항상 참이되어서 DB에 있는 모든 결과물이 나오게 될 것이다.

 

위의 응답 패킷에서

 

hey! close, but no bananananaana!! 라는 값이 나오게 된건

 

소스코드의 이 부분 때문이다.

 

if len(res) == 0:
	return render_template("login.html", msg="stop! you're no allowed in here >:)")
if len(res) > 1:
	return render_template("login.html", msg="hey! close, but no bnanananan!!!!")
return render_template("login.html", msg="Welcome, %s"%(res[0][0]))
SQL 명령어의 결과를 res 라는 변수에 담는데, res 의 길이가 1이 넘을경우
hey! close, but no bananananaana!! 라는 값이 나오게 된다. 
res의 길이가 1이 넘는다는건 SQL 인젝션이 성공해서 DB의 모든 값이 나왔다는 것이다.
 
또 res의 값이 0이면 맨 처음봤던 stop! you're no allowed in here이라는 문자가 나오게 되는데
이는 DB에서 매칭된 값이 없어서 결과가 없기때문에 0이 리턴되어서 그런것이다.
결국 우리가 해야할 것은 SQL 인젝셩늘 통해 결과값이 한개만 나오도록(len(res)가 1이 되도록) 하는 것이다.

' a or 1=1 ORDER by UA DESC limit 1#
이라고 입력해본다.
ORDER BY UA DESC로 DB내에 저장된 UA 값을 내림차순으로 정렬하고,
limit 1을 이용해서 맨 위에 하나만 값을 가져와봤다.
그랬더니 Welcome, admin 이라는 값이 나온걸 볼 수 있다.
하지만 admin은 우리가 원하는 플래그가 아니다.
하나씩 천천히 내려가며 찾아야한다.

' a or 1=1 ORDER by UA DESC limit 2,1#
' a or 1=1 ORDER by UA DESC limit 3,1#
' a or 1=1 ORDER by UA DESC limit 4,1#
이런식으로 하나씩 값을 불러와서 찾을수 있다.
 
' a or 1=1 ORDER by UA DESC limit 6,1# 을 했을때
비로소 플래그가 나오게 된다.
반응형