wargame

write-up 08

burrri 2023. 7. 3. 14:17

Web Hacking | Dreamhack

1. Command-injection-chatgpt

https://dreamhack.io/wargame/challenges/768/

 

/ping

 

@APP.route('/ping', methods=['GET', 'POST'])
def ping():
    if request.method == 'POST':
        host = request.form.get('host')
        cmd = f'ping -c 3 {host}'
        try:
            output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=5)
            return render_template('ping_result.html', data=output.decode('utf-8'))
        except subprocess.TimeoutExpired:
            return render_template('ping_result.html', data='Timeout !')
        except subprocess.CalledProcessError:
            return render_template('ping_result.html', data=f'an error occurred while executing the command. -> {cmd}')

    return render_template('ping.html')
    
    if __name__ == '__main__':
    APP.run(host='0.0.0.0', port=8000)

코드 중 일부를 가져와보았다. 입력받은 문자열을 ping명령어를 통해서 실행하는 것을 볼 수 있다.

해당 APP은 0.0.0.0 호스에서 실행중이므로 해당 호스트로 ping명령어를 통해 injection 가능하다.

 

 0.0.0.0으로 ping을 보낸 후 ; 구분자를 통해서 작업디렉토리의 파일목록이 출력되도록 하자

 

우리가 찾는 flag.py파일이 존재하는 것을 확인했으니 해당 파일내용을 출력해주자

; 구분자는 앞의 명령어의 성공여부와 무관하게 뒤의 명령어가 실행되는 반면, &&명령어는 앞의 명령어가 성공해야 뒤의 명령어가 실행된다. 

 

 

 

2. simple_sqli_chatgpt

https://dreamhack.io/wargame/challenges/769/

/login에 접속해보자

 

주요한 코드는 다음과 같다.

if os.path.exists(DATABASE) == False:
    db = sqlite3.connect(DATABASE)
    db.execute('create table users(userid char(100), userpassword char(100), userlevel integer);')
    db.execute(f'insert into users(userid, userpassword, userlevel) values ("guest", "guest", 0), ("admin", "{binascii.hexlify(os.urandom(16)).decode("utf8")}", 0);')
    db.commit()
    db.close()

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    else:
        userlevel = request.form.get('userlevel')
        res = query_db(f"select * from users where userlevel='{userlevel}'")
        if res:
            userid = res[0]
            userlevel = res[2]
            print(userid, userlevel)
            if userid == 'admin' and userlevel == 0:
                return f'hello {userid} flag is {FLAG}'
            return f'<script>alert("hello {userid}");history.go(-1);</script>'
        return '<script>alert("wrong");history.go(-1);</script>'

app.run(host='0.0.0.0', port=8000)

db에서  guest계정과 admin계정의 userlevel이 동일하게 0임을 확인할 수 있다. 

 

userlevel이 0인 경우 res[0]과 res[2]는 최상위 레코드인 guest의 userid, userlevel을 도출하므로

sqli injection을 통해서 userlevel을 입력함과 동시에  userid를 설정해주자

자장자장 우리아가~

 

 

 

Reversing

3. rev-basic-1

https://dreamhack.io/wargame/challenges/15/

 

임의의 값을 입력하니 종료된다

 

IDA에서 분석해보자

 

 

input을 하면 다음의 함수가 호출되며 함수는 다음과 같다. 

memset함수를 통해  v4가 참조하는 메모리 영역을 0으로 초기화한 후 입력값을 v4에 저장한다.

이후 sub_140001000함수의 인자로 v4가 전달된다.

_BOOL8 __fastcall sub_140001000(_BYTE *a1)
{
  if ( *a1 != 67 )
    return 0i64;
  if ( a1[1] != 111 )
    return 0i64;
  if ( a1[2] != 109 )
    return 0i64;
  if ( a1[3] != 112 )
    return 0i64;
  if ( a1[4] != 97 )
    return 0i64;
  if ( a1[5] != 114 )
    return 0i64;
  if ( a1[6] != 51 )
    return 0i64;
  if ( a1[7] != 95 )
    return 0i64;
  if ( a1[8] != 116 )
    return 0i64;
  if ( a1[9] != 104 )
    return 0i64;
  if ( a1[10] != 101 )
    return 0i64;
  if ( a1[11] != 95 )
    return 0i64;
  if ( a1[12] != 99 )
    return 0i64;
  if ( a1[13] != 104 )
    return 0i64;
  if ( a1[14] != 52 )
    return 0i64;
  if ( a1[15] != 114 )
    return 0i64;
  if ( a1[16] != 97 )
    return 0i64;
  if ( a1[17] != 99 )
    return 0i64;
  if ( a1[18] != 116 )
    return 0i64;
  if ( a1[19] != 51 )
    return 0i64;
  if ( a1[20] == 114 )
    return a1[21] == 0;
  return 0i64;
}

함수에서 조건문을 통해 배열이 'Compar3_the_ch4ract3r'과 일치하는 지 확인하고 있다. 

a1의 배열에 각각의 int가 저장되어있으며 각 인덱스의 값들이 조건문의 10진수와 같지않으면 0을 반환, 일치하면 1을 반환한다. 

 

위의 함수가 참을 반환시 if 조건문을 만족하여 "correct"를 출력하므로 함수에서 비교하는 문자열이 flag임을 알 수 있다. 

 

 

 

Web hacking

4. command-injection-1

https://dreamhack.io/wargame/challenges/44/

 

웹페이지에 접속하고 코드를 보았을 때, 1번과 동일한 문제인줄 알았다. 그래서 바아로 0.0.0.0;ls 를 입력했는데 

뭘 요청했댄다 개발자도구를 켜서 한번 살펴보았다

정규식 패턴은 대문자,소문자,숫자 그리고 '.' 만 인정되며 5자 이상 20자 이하로 설정되었다. 이 부분을 없애버리자

 

그리고 바로 0.0.0.0;ls를 넣으니

cmd = f'ping -c 3 "{host}"

{host}앞뒤로 큰따옴표" 가 있었다 ㅎ 그래서 다음과 같이 수정해주었다.

 

flag.py를 출력해주자

 

 

 

5. Flying Chars

https://dreamhack.io/wargame/challenges/850/

 

접속하니 문제 이름그대로 문자들이 날라다닌다. 개발자도구에서 코드를 보니 다음과 같이 img파일이 설정되어있었고 

순서대로 읽어주었다. 

    const img_files = ["/static/images/10.png", "/static/images/17.png", "/static/images/13.png",
    "/static/images/7.png","/static/images/16.png", "/static/images/8.png", "/static/images/14.png",
    "/static/images/2.png", "/static/images/9.png", "/static/images/5.png", "/static/images/11.png",
    "/static/images/6.png", "/static/images/12.png", "/static/images/3.png", "/static/images/0.png",
    "/static/images/19.png", "/static/images/4.png", "/static/images/15.png", "/static/images/18.png",
    "/static/images/1.png"];

이 와중에 중간에 한줄건너띄고 읽었다 ㅎㅋ

Too_H4rd_to_sEe_th3_Ch4rs_x.x

 

'wargame' 카테고리의 다른 글

write-up 07  (0) 2023.05.25
write-up 06  (0) 2023.05.18
write-up 05  (0) 2023.05.11
write-up 04  (0) 2023.05.04
write-up 03  (0) 2023.04.05