[Ping] 5주차

정다연·2022년 11월 17일

Security

목록 보기
5/12

보안뉴스

“한 번의 침투로 모든 것이 파괴된다” SAP 전송 시스템의 공급망 취약점 발견 - ITWorld Korea

악의적 침입에 취약한 SAP 전송 시스템

내부 SAP 개발 공급망-> 기업 고객이 SAP 표준에 대한 추가 기능과 내부 개발을 요청하는데 사용. 변경 사항은 SAP 전송 요청이 있는 각 SAP 환경의 여러 스테이징 시스템을 통해 제공. 요청 중앙 전송 디렉토리에 보내 릴리즈 후 수정 불가
보내진 요청이 프로덕션 시스템에 임포트되기 전까지 공격자가 시간대를 확보 후, 적절한 권한을 가진 직원이 릴리즈된 요청 상태를 수정 가능으로 변경 가능-> 공격자 변경 관리 및 소프트웨어 배포 프로세스 침투 +공격자 SAP 개발 단계 요청도 악성코드 도입 가능

SAP 전송 시스템 취약점을 해결하는 방법

SAP 소프트웨어 사용 기업: 수정 패치 적용해 파일 시스템 조작 방지
패치 : 공격자가 지능형 지속 위협을 발생시킬 가능성을 낮춤.
SAP: 고객이 전송 로그를 프로덕션 시스템으로 가져오기 전 변조 여부 확인

강의수강 후 강의노트

SQL 인젝션 공격

K-MOOC 계정에 로그인 하세요. | K-MOOC (kmooc.kr)

SQL

관리시스템 데이터 관리하기 위해 설계된 특수 목적의 프로그래밍 언어

sql 명령어

select: 데이터베이스로부터 데이터를 추출
update: 데이터베이스 안에 있는 데이터를 수정
delete: 데이터베이스에서 데이터를 삭제
insert: 데이터베이스 내에서 새로운 데이터 추가
create database: 새로운 데이터베이스 생성
drop table: 테이블 삭제
create table: 새로운 테이블 생성

SQL 삽입 공격

sql 명령어 입력 -> 웹사이트 침투 -> 서버 제어 및 공격
Prack 매거진 54호 -> sql 문 변조 가능성 제기
Rain forest puppy -> sql 인젝션 문서 공객
OWASP Top 10 수차례 올라감

사례

2011: 소니픽처스 프랑스 웹사이트:70여개의 이메일 주소 탈취
2014: 이스라엘 정부 관련 사이트:어나니머스 공격,기밀문서 유출
2014: 42만개 웹사이트:러시아 해킹 그룹 공격으로 12억개 사용자 이름과 비밀번호 유출
2015: 워드프레스용 플러그인 해깅:100만개의 웹사이트 해깅
2015: WTO 웹사이트:대량의 재직자 정보 유출

SQL 삽입 공격의 기본 원리

공격자 -> 조작된 sql 쿼리문 전공-> 웹사이트
웹사이트의 데이터베이스에서 조작된 sql 쿼리문 실행-> DB 정보 유출
DB 삭제 명령 변경 명령-> DB 특정 정보 조작 및 삭제
예제: 로그인 비밀번호 방식 AND ‘password’=“OR ‘1’= ‘1’;
OR 값은 항상 참-> sql 문장 정상 실행-> DB 데이터 추출

SQL 삽입 공격 대응 방안

  1. 안전한 웹사이트 설계와 구현: 입력 값 검증 절차 구현
    입력 값 검사 및 치환
  2. DB 에러 메서지 노출 X : DB 구조 및 이름 파악
  3. 웹 방화벽 활용
  4. 웹 보안 취약점 주기적 점검

제공한 개인정보 서버의 데이터베이스에 저장. 데이터베이스를 사용하는 명령어를 사용해 데이터베이스 속 정보를 삭제, 수정, 가져오는 공격

Webhacking.kr 8번, 18번, 27번, 35번 라이트업 작성

#challenge 35


소스코드를 살펴보면 일단 phone 과 id는 get 방식으로 받고, phone에 /,*,select,-,#값 입력 또는 id 길이가 5 이상일 때 no hack 로 빠져나가고, id가 admin일 때 you are not admin 으로 빠져나간다. 그 밑 소스코드를 보면 phone에 어떠한 값을 넣으면 insert into chall35(id,ip,phone)value를 이용해 데이터 베이스에 값을 저장 시 id는 idmin ip는 내 고유 ip번호여야 함을 알 수 있다.
if($_GET['phone'] && $_GET['id']){

if(preg_match("/*|\/|=|select|-|#|;/i",GET[phone]))exit("nohack");if(strlen(_GET['phone'])) exit("no hack"); if(strlen(_GET['id']) > 5) exit("no hack");
if(preg_match("/admin/i",GET[id]))exit("youarenotadmin");mysqliquery(_GET['id'])) exit("you are not admin"); mysqli_query(db,"insert into chall35(id,ip,phone) values('{_GET['id']}','{_SERVER['REMOTE_ADDR']}',{$_GET['phone']})")

preg_match문을 통해 phone 은 필터링이 제대로 안되어 있다는 것을 알 수 있다. 따라서 phone 값 injection을 통해 문제를 푼다.

"select ip from chall35(id,ip,phone) values('guest', 'myip', $_GET['phone'])"
-> "select ip from chall35(id,ip,phone) values('guest', 'myip', 아무 숫자),('admin', 'myip', 아무 숫자)"

mysql 에서는 insert로 여러 개의 입력 값을 전달할 수 있고, insert 사용방식은 INSERT INTO 테이블또는뷰_이름 (컬럼1, [컬럼2, ...]) values (값1, [값2, ...])와 같다고 한다.
따라서 values 값을 추가해주기 위해 아무 숫자),(‘admin’,‘myip’,‘아무번호‘)를 입력하면 문제가 풀린다.

#challenge 18


소스코드를 살펴보면, get방식으로 no를 입력받아야 실행됨을 알 수 있다. 그 후 공백,/,(,),|,&,select,from,0x 등과 같은 값을 입력하면 no hack 로 빠져나간다.
mysql 함수를 통하여 id가 guest, no=$_GET[no]로 q값에 저장함을 알 수 있다. 만약 조건에 부합하면 challenge18_table로부터 id값을 추출한다. 이때 주석 처리를 통해 admin’s no=2 라는 힌트를 줬다.

<?php 
if($_GET['no']){
  $db = dbconnect();
  if(preg_match("/ |\/|\(|\)|\||&|select|from|0x/i",$_GET['no'])) exit("no hack");
  $result = mysqli_fetch_array(mysqli_query($db,"select id from chall18 where id='guest' and no=$_GET[no]")); // admin's no = 2
  if($result['id']=="guest") echo "hi guest";
  if($result['id']=="admin"){
    solve(18);
    echo "hi admin!";
  }
}
?>

id가 admin이어야 문제가 풀리므로
where id='guest' and no=$_GET[no]에서 and 부분을 FALSE인 or로, 뒷 부분을 no가 2인 것으로 바꿔야 한다.

select id form challenge27_table where id=’guest’ and no= or no=2

공백을 우회하는 방법으로는 /를 이용한 주석, \t, \n 이 있다. 위에서 no hack로 빠져나가지 않는 \n를 인코딩한 값인 %0a 이용하여 우회한다.


no=0%0aor%0ano=2를 입력하면 문제가 풀린다.

#challenge 27



소스코드를 살펴보면, get방식으로 no를 입력받아야 실행됨을 알 수 있다. 만약 union,from,challenge,select,\,\t,/,limit,=,0x의 값을 입력하면 no hack 로 빠져나간다. mysql 함수를 통하여 id가 guest, no=$_GET[no]로 r값에 저장함을 알 수 있다. 만약 조건에 부합하면 challenge27_table로부터 id값을 추출한다.

<?php

  if($_GET['no']){

  $db = dbconnect();

  if(preg_match("/#|select|\(| |limit|=|0x/i",$_GET['no'])) exit("no hack");

  $r=mysqli_fetch_array(mysqli_query($db,"select id from chall27 where id='guest' and no=({$_GET['no']})")) or die("query error");

  if($r['id']=="guest") echo("guest");

  if($r['id']=="admin") solve(27); // admin's no = 2

}

?>

id가 admin이어야 문제가 풀리므로
where id='guest' and no=$_GET[no]에서 and 부분을 FALSE인 or로, 뒷 부분을 no가 2인 것으로 바꿔야 한다. 이때는 18번과 달리 no값에 대한 힌트가 없다.

select id form challenge27_table where id=’guest’ and no=(1) or no=(숫자)--

다음에 들어갈 숫자를 0부터 차례대로 guessing 하면 no가 2일 때 no=2)%0aor%0ano%0alike%0a2%0a-- 풀리게 된다.

profile
날 것 그대로의 CS 마인드맵

0개의 댓글