

(출처 : https://llm-examples.streamlit.app)
streamlit은 오픈 소스 애플리케이션 프레임워크로, 몇 줄의 코드만으로 상호 작용이 가능한 데이터 애플리케이션을 만들 수 있게 해준다. 데모용으로 사용하기에 딱 적합하지 않을까 싶다!
이번 프로젝트도 데모를 보여주면 되는 것이기 때문에 streamlit을 선택하게 되었다.
streamlit에서 계정을 만든 다음에
pip install streamlit
streamlit hello
을 하면 ID를 입력하도록 되어있을 것...
파일을 만들어놨으면~
streamlit run 파일명.py
를 통해 실행시키면 결과가 웹페이지로 나타날 것이다 (개편리)
import streamlit as st
def main():
st.set_page_config(page_title="Bug Bounty Program", layout="wide")
st.title("Find the GAP Bug Bounty Program Project 1")
st.markdown("""
프로그램 설명과 가이드에 기반해서 리포트를 작성해야 합니다. 상세정보 보기를 통해 프로그램 상세정보를 확인할 수 있습니다.
""")
st.markdown("")
#리포트 제목
report_title = st.text_input("리포트 제목", placeholder="제목을 입력하세요.")
st.markdown("<div style='margin:20px 0;'></div>", unsafe_allow_html=True)
# Discovery Location
discovery_location = st.text_area("발견 위치", placeholder="URI / URL / Location (or Address)")
st.markdown("")
# Scope
scope = st.selectbox("범위", ["선택", "해당 자원 이상", "해당 자원 한정"])
st.markdown("")
# Attack Point and Payload
col1, col2 = st.columns(2)
with col1:
attack_point = st.text_area("Attack Point", placeholder="취약한 변수명 값이 없을 시 none 입력")
with col2:
payload = st.text_area("Payload", placeholder="payload(공격에 사용된 코드) 값이 없을 시 none 입력")
st.markdown("")
# Attack Type
attack_type = st.selectbox("공격유형", ["선택", "SQL Injection", "XSS", "CSRF", "기타"])
st.markdown("")
# Attack Impact
attack_impact = st.selectbox("공격영향", ["선택", "정보 유출", "시스템 장애", "데이터 손실", "기타"])
st.markdown("")
# Ethical Hacking Self-Assessment
st.subheader("윤리적 해커 자체 평가")
col1, col2, col3 = st.columns(3)
with col1:
access_method = st.multiselect("공격자의 접근 방법", ["네트워크", "제한된 네트워크", "로컬", "물리"])
attack_complexity = st.radio("공격 복잡도", ["특정 정보 조건 필요", "특정 정보/조건 불필요"])
required_privileges = st.radio("필요한 권한", ["없음", "일반 사용자", "상위권한(관리자)"])
with col2:
scope_option = st.radio("범위", ["해당 자원 이상", "해당 자원 한정"])
confidentiality = st.radio("기밀성", ["높음", "낮음", "없음"])
integrity = st.radio("무결성", ["높음", "낮음", "없음"])
with col3:
user_interaction = st.radio("사용자 상호 작용", ["없음", "필요 (메일열람, 페이지접근, 실행 등)"])
availability = st.radio("가용성", ["높음", "낮음", "없음"])
# CSS 스타일 추가 - vulnerability_details에만 적용
st.markdown("""
<style>
/* vulnerability-details 클래스를 가진 요소의 textarea에만 적용 */
.vulnerability-details textarea {
min-height: 500px !important;
}
</style>
""", unsafe_allow_html=True)
vulnerability_overview = st.text_area(
"취약점 개요",
placeholder="취약점 요약, 취약한 SW 버전, 취약점 발생 환경"
)
placeholder_text = """취약점 신고자는 다음 작성 방법을 준수하여 각 항목을 작성해야 하며, 내용이 불충분하다고 판단되는 경우 보완 작성을 요청드릴 수 있습니다.
> 취약점 발견 방법(점검도구 등): 취약점 발견방법에 대한 내용을 기술
> 취약점 발생 원인:
- 취약점 발생 입력 데이터 설명 (문자열, 이미지 등의 파일)
- 취약점 발생 위치 설명 (함수, 어셈블리코드, 프로그램 주소 위치 등)
- 취약점 발생 원인 설명 (소스코드 분석, 리버싱 결과 등으로 취약점 발생 원인을 파악한 내용 기술)
> 취약점 증명 / 검증
1. 취약점에 대한 상세 분석 결과 기술 [단계별로 기술]
- 취약점 분석 결과 스크린 샷 및 설명
- PoC 디버깅 과정 설명
- 보호기법 우회 기술
- 취약점 발생 동영상 첨부 등
> 취약점 악용 시나리오: 취약점이 악용될 수 있는 공격 시나리오와 관련 서비스 (또는 시스템)에 미칠 수 있는 영향
> 기타:
- 참고할 수 있는 자료 (웹사이트 주소 등)
- 발견한 취약점을 악용하고 있는 사례 설명"""
# height 파라미터 직접 사용
vulnerability_details = st.text_area(
"취약점 상세 설명",
placeholder=placeholder_text,
height=500 # 픽셀 단위로 높이 지정
)
mitigation = st.text_area(
"조치방안",
placeholder="취약점을 해결할 수 있는 효과적인 방법을 제시해주세요."
)
# File Attachment
st.subheader("파일첨부")
st.file_uploader("첨부파일은 임시저장되지 않습니다. 최종 제출시에만 첨부파일을 추가해주세요.", type=["png", "jpg", "jpeg", "zip"], accept_multiple_files=True)
st.markdown("")
# Agreement
st.subheader("취약점 정보 활용 및 비밀 유지 동의")
agreement = st.checkbox("취약점 정보 활용 및 비밀유지에 동의합니다.")
# Submission
if st.button("제출하기"):
if agreement:
st.success("리포트가 성공적으로 제출되었습니다.")
else:
st.error("취약점 정보 활용 및 비밀유지에 동의해야 제출이 가능합니다.")
if __name__ == "__main__":
main()
개인적으로 streamlit의 css를 적용시키는게 뭔가 직관적이지도 않고, 구현을 해도 적용이 잘 안되는 것들이 많아 좀 답답한 마음이 들었다...
우선 text-size를 키우려고 markdown을 사용하지 않고 css로만 구현을 해보려고 했으나 다 먹히지 않아 실패. markdown을 사용하면 위아래 공백이 생겨서 원하는 스타일대로 페이지 구현이 되지 않아 css로 적용해보려고 한건데~ 왜! 안되는 것이야! (기필코 해낸다)
아래는 내가 streamlit을 처음 사용해보면서 알게 된 내용을 정리해 보았다.
기본 layout
st.set_page_config(page_title="Page Title", layout="wide")col1, col2 = st.columns(2) with col1: ~ with col2: ~입력 받기
user_input = st.text_input("제목", placeholder = "제목을 입력하세요." long_input = st.text_area("설명", placeholder= "내용을 입력하세요.") option = st.selectbox("옵션 선택", ["옵션1, "옵션2", "옵션3"])agreement = st.checkbox("약관에 동의합니다.")text type
기타
- 파일 업로드 기능
- <code>uploaded_files = st.file_uploader("파일 업로드", type=["png", "jpg", "zip"], accept_multiple_files=True)