-
5주차 과제모의해킹스터디_과제 2023. 12. 7. 16:29
[1] 오늘 수업 복습인증 우회
[2] 인증 우회 실습
- 문제 풀기
- 정리 (write-up)
[3] 웹 개발로그인 페이지&회원가입 만들기
[4] login bypass 1에서는 왜 주석이 안먹히는가?
(* 필터링 아님 주의.)
(* 식별/인증 분리 아님)
[+] 추가 과제게시판 쭉! 달려보자!(>직접 만들어보면서 테스트)
[2] 인증 우회 실습
노말틱님께서 플래그를 찾아내는 모의해킹 사이트를 제공해주셨다.
그 문제를 풀고 정리하는 게 이번주 과제인데 일단 풀면서 느낀 것은 너무 재밌다는 것이다.
시간이 걸리더라도 스스로 방법을 계속 생각하면서 하나씩 푸니까 성장하는 재미도 포함해서 너무 좋다.
매번 문제만 나왔으면..
1. segfault challenges 이게 관리자가 문제를 하나씩 내주는 느낌인데, 이번주까지 나온 문제가 14개정도.
시간이 좀 걸렸지만 어찌됐든 나온 문제는 다 풀었고, 그 모든 문제를 다 리뷰할 수는 없기에
그 중에서 가장 내 생각의 틀에서 벗어났던 문제(?)를 하나만 정리하겠다.
- pin code crack
Authentication Bypass(인증우회) 파트에서 나온 문제인데 PIN 번호 4자리의 숫자를 알아내어 입력하는 문제다.
2. pincode 문제 이전의 문제들을 풀었던 것처럼 일단 Burp Suite를 사용해서 페이지를 살펴본 다음 history에 남아있는 기록을 먼저 확인했다.
3. pincode 페이지 기록 확인 별다른 것을 찾을 수가 없었다. 쿠키도 상관없고, request나 response를 수정하여 위변조를 할 부분도 안보이고.
이번주에 배운 sql injection을 사용하려나.. 싶었는데 다른 문제처럼 DB 결과값을 나타내는 부분이 없으니 확인할 수도 없었다.
그러다 수업에서 normaltic님이 알려주신 방법!
4자리 숫자를 0000부터 9999까지 전부 입력하는 프로그램을 짜는 것.
..
...
사실 4자리의 번호만 알아내면 되는 건데, 이번에 배운 것들을 어떻게든 활용해볼 생각에 내 시야가 너무 좁아져 있었다.
이번에 또 하나 배웠다. 넓게 보자. 내가 할 수 있는 것들을 적재적소에 활용할 수 있는 능력이 해커에게 있어서 중요한 것 같다.
아무튼 바로 프로그램을 작성했다.
pincode.py
import requests url = 'http://ctf.segfaulthub.com:1129/6/checkOTP.php?otpNum=' for i in range(0,10000): num = str(i).zfill(4) openUrl = url + num print("["+num+"]") response = requests.get(openUrl) if "Login Fail..." in response.text[0:40]: continue else: url = url + num break print("PIN code : ["+url[-4:]+"]") print("url : ["+url+"]")
pin번호를 GET방식으로 전달하여 확인하기에, 0부터 9999까지 번호를 반복하여 url 뒤에 추가하여 확인하는 코드다.
틀릴 때마다 알림창에 "Login Fail..." 이라는 문구가 나오기 때문에 이것을 기점으로 번호가 맞는지 틀린지를 확인하면 된다.
아래는 프로그램을 돌려 번호를 확인하는 과정인데, 정답을 스포하면 안되니까 모자이크 처리했다.
4. pincode.py 실행결과 며칠간 헤맸던 문제가 1분 안에 풀렸다..
다양한 시각으로 문제에 접근하는 습관을 기르자.
[4] Login Bypass 1 에서는 왜 주석이 안 먹히는가? (필터링x, 식별/인증 분리x)
5. Login Bypass 1 Login Bypass 1, 로그인 페이지에서 로그인 과정을 우회하여 normaltic1 계정으로 로그인하면 되는 문제다.
sql injection은 삽입 가능하다. 그러나 sql 언어에서 주석을 의미하는 '#'을 넣어 뒤의 구문을 주석처리하면 실패한다.
보통 로그인 SQL 구문을 아래처럼 작성하여 DB에 접근하는데
$sql = "SELECT * FROM user WHERE userName = '{$userName}' AND password = '{$password}'";
만약 아이디에 doldol' # 이라 입력하면
$sql = "SELECT * FROM user WHERE userName = 'doldol' #' AND password = '{$password}'";
이렇게 # 뒤에는 주석처리가 되어 ID만 있다면 비밀번호가 없이도 로그인이 가능하게 된다.
그래서 비밀번호를 아무거나 입력해도 로그인이 되어야 하는데 실패한다.
6. Login Bypass 1 주석 근데 #과 함께 맞는 비밀번호를 입력하면 로그인된다.
7. Login Bypass 1 주석2 이 두 케이스를 보고 내가 내린 결론은 '#' 이 주석의 역할을 못한다는 것이다.
어떻게 코드를 작성하면 '#' 주석의 역할을 없앨 수 있을까.
가장 먼저 생각난 것은 문자열 치환이다.
sql 구문의 문자열에서 '#' 을 '' 으로 바꿔주면 되지 않을까 싶었다.
추가적으로 그 앞에 있는 ' 까지 없애줘야 정상적인 구문이 실행되니까 '까지.
where id = 'doldol' #'
where id = 'doldol' #'그러면 확인해보자.
<!doctype html> <html lang="ko"> <main class="form-signin"> <form method="POST" action="sql_test2.php"> <div class="form-floating"> <input type="text" name="userName" class="form-control" id="floatingInput" placeholder="ID"> </div> <div class="form-floating"> <input type="password" name="password" class="form-control" id="floatingPassword" placeholder="비밀번호"> </div> <button class="w-100 btn btn-lg btn-primary" type="submit">Sign in</button> </form> </html>
<!doctype html> <html lang="ko"> <?php $userName = $_POST['userName']; $password = $_POST['password']; $sql_body = "SELECT * FROM user WHERE "; $sql_ID = "userName = '{$userName}'"; $sql_PW = "password = '{$password}'"; $removeSpace_ID = str_replace(' ', '', $sql_ID); $removeSpace_PW = str_replace(' ', '', $sql_PW); $removeAnnot_ID = str_replace('\'#', '', $removeSpace_ID); $removeAnnot_PW = str_replace('\'#', '', $removeSpace_PW); ?> <h2><?php echo "original: ".$sql_body.$sql_ID." AND ".$sql_PW; ?></h2> <h2><?php echo "remove Space: ".$sql_body.$removeSpace_ID." AND ".$removeSpace_PW; ?></h2> <h2><?php echo "remove '# : ".$sql_body.$removeAnnot_ID." AND ".$removeAnnot_PW; ?></h2> </html>
POST 방식으로 ID와 비밀번호를 받아 SQL 구문을 보여주도록 했다.
사용자가 '와 # 사이에 빈 칸을 넣을 수도 있으니 먼저 스페이스를 제거하고
'# 을 한번에 제거했다.
하나 더!
SQL 문은 띄어쓰기가 안되어 있으면 오류가 나니 제거가 필요한 부분의 문자열만 하도록 한다.
SELECT*FROMboardWHEREuserName="doldol" -> ERROR
8. test 주석x 일단 원하는 대로 실행은 잘되는 것 같다.
먼저 스페이스를 제거하고
'와 #를 제거한다.
9. test 주석 원하는 결과가 나왔다.
이 코드를 사용하면 주석이 역할을 못하게 하면서, 주석과 상관없이 ID와 비밀번호가 맞다면 로그인이 가능하다.
이 방법 외에도 주석을 무시하는 방법이 더 있을텐데
지금 생각나는 건 일단 이것밖에..
다음에 더 생각해보겠다.