

#app.py
#!/usr/bin/env python3
import subprocess
import ipaddress
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/', methods=['GET'])
def index():
return render_template('index.html')
@app.route('/ping', methods=['GET'])
def ping():
host = request.args.get('host', '')
try:
addr = ipaddress.ip_address(host)
except ValueError:
error_msg = 'Invalid IP address'
print(error_msg)
return render_template('index.html', result=error_msg)
cmd = f'ping -c 3 {addr}'
try:
output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=8)
return render_template('index.html', result=output.decode('utf-8'))
except subprocess.TimeoutExpired:
error_msg = 'Timeout!!!!'
print(error_msg)
return render_template('index.html', result=error_msg)
except subprocess.CalledProcessError:
error_msg = 'An error occurred while executing the command'
print(error_msg)
return render_template('index.html', result=error_msg)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
소스코드를 보면 /ping 페이지에서 shell에서 ping를 하는 것을 볼 수 있다.\
그럼 ;ls를 사용하면 바로 풀리겠다.

@app.route('/ping', methods=['GET'])
def ping():
host = request.args.get('host', '')
try:
addr = ipaddress.ip_address(host)
except ValueError:
error_msg = 'Invalid IP address'
print(error_msg)
return render_template('index.html', result=error_msg)
cmd = f'ping -c 3 {addr}'ipaddress.ip_address를 우회하기
IPv6 주소는 스코프 아이디(scope ID)가 있는데 스코프 아이디는 로컬 네트워크에서 사용되는 식별자이다

여기서 lo, eth0, eth1, loopback0, eth2, eth3가 스코프 아이디이다.
스코프 아이디가 사용되는 이유는
컴퓨터는 여러 개의 서로 다른 스코프의 링크-로컬 주소를 가질 수 있다. 스코프 아이디는 각 주소가 어느 스코프를 위한 것인지를 나타낸다. 예를 들어보자. 컴퓨터가 두 개의 NIC(네트워크 인터페이스 카드)를 갖고 있고 다른 네트워크의 링크-로컬 주소를 가지고 있다. 무언가를 fe80 으로 시작하는 또 다른 주소로 보내려고 한다면, 컴퓨터는 어떤 NIC 를 통해서 보내야 할 지 어떻게 구별할 것인가?
출처:
https://daewonyoon.tistory.com/182
[알락블록:티스토리]
https://github.com/python/cpython/blob/main/Lib/ipaddress.py
def _split_scope_id(ip_str):
"""Helper function to parse IPv6 string address with scope id.
See RFC 4007 for details.
Args:
ip_str: A string, the IPv6 address.
Returns:
(addr, scope_id) tuple.
"""
addr, sep, scope_id = ip_str.partition('%')
if not sep:
scope_id = None
elif not scope_id or '%' in scope_id:
raise AddressValueError('Invalid IPv6 address: "%r"' % ip_str)
return addr, scope_id
이 코드에서 %를 기준으로 나눈다.
scope_id에 %를 제외하고 아무 문자열이 와도 상관이 없다.
적당한 ipv6주소 + % + ; + shell명령어를 host에 넣으면 성공할 것 같다.


성공