- 22
- 이니스프리
- 조회 수 513
안녕하세요??
주말 잘 보내고 계시는가요??
http://amina.co.kr/bbs/board.php?bo_table=nariya_qa&wr_id=971
이 글을 보면 그누보드 환경에서 글쓰기 포인트 차감 설정을 했음에도 불구하고
이걸 우회하여 도배하는 스팸이 문제되고 있다고 하던데요 ㅎㄷㄷ
파이썬 requests를 이용한 스팸봇이라면 write_update.php에 formdata를 그대로 대입하는 방식이기 때문에
포인트가 부족하다면 포인트 차감이 설정된 것을 우회하지는 못할 것으로 생각되네요~
(1) 도대체 어떤 방법으로 이러한 스팸이 가능한 것이고, (2) 어떻게 하면 이를 근본적으로 차단할 수 있는지 여쭤봅니다.
그럼 즐거운 주말 되세요 ^-^
감사합니다!
작성자
댓글 22
적어도 현재의 아미나에서는 SQL 인젝션이 가능하지 않도록 취약점 패치가 충분히 되어있다고 알고 있는데요 ㄷㄷ
만약 아미나에서 저런 공격이 가능하다면... 아미나 기반의 수많은 사이트에서 저런 문제가 발생해야 될텐데 저런 유형의 공격을 최근에 본 사례가 없거든요~!
업그레이드를 하지 않아서 발생하는 문제인지, 커스텀의 문제인지, 아니면 새로운 취약점이 발견된 것인지 잘 모르겠네요 ㅠㅠ
취약점이야 어디에나 존재할 수 있으니 최신 패치여도 가능할 지도 모르고요. 네모네모네모님이 네이버 XSS 취약점을 찾아낸 것처럼 어딘가엔 있을 지도 모르는 일이죠 ~!
하지만 구버전을 사용중이라는 이론이 더 그럴듯 해 보이기는 하네요.
아마 새로운 취약점이 발견되었다면 (그누보드던 WP던)난리가 났을 터이니 구버전을 쓰던 중 커스텀된 부분과 뭔가 충돌이 일어나 SQL Injection이 가능하지 않았을까 추측해봅니다.
옙 그렇게 해야겠네요! ^^
감사합니다!!
그런데 아미나는 그누보드 5.3 기반이고 현재 그누보드 최신 버전은 5.4인데
단순히 구 버전이어서 생긴 문제라면 업데이트가 안 되겠죠?? ㅠㅠ
+) 나리야에서 발생한 문제라면 그누보드의 심각한 취약점이 발견된 것이겠네요 ㅎㄷㄷ
DB에 다이렉트로 인젝션이 가능한거면 매우 위함해보이네요.
존재하지 않는 스티커입니다.
포인트가 음수로 되었다는 것을 보았을 때 SQL Injection 공격이라고 보긴 어려울 거 같아요. 만약 SQL Injection 공격으로 시도했다면 포인트 차감은 1번만 이루어지지만 무수히 많은 게시글이 작성되어야 합니다.
그래서 저는 SQL Injection 공격이라고 보기 보다는 서버 성능이 좋지 않아서 생기는 문제와 SQL 쿼리 설계 상의 문제가 합쳐져서 발생하는 문제라고 생각합니다.
DB 취약점이라기보단 서로의 문제가 겹쳐져서 생간일인거군요.
1. 아래의 SQL query를 실행하여 포인트와 게시글 테이블을 만들고 계정을 등록합니다.
CREATE TABLE doc (
`id` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`title` VARCHAR(60),
`description` VARCHAR(255)
);
CREATE TABLE point (
`user_id` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`point` INT(11)
);
INSERT INTO point VALUES(1, 10);
2. 아래와 같이 PHP 코드를 작성합니다.
<?php
$db = array();
$db['hostname'] = 'localhost';
$db['username'] = '*****';
$db['password'] = '*****';
$db['database'] = '*****';
$write_point = 10;
$mysqli = new mysqli($db['hostname'], $db['username'], $db['password'], $db['database']);
$res = $mysqli->query("SELECT `point` from `point` WHERE `user_id` = 1;");
$point = intval(mysqli_fetch_row($res)[0]);
// check if point is larger than write_point
if($point < $write_point) {
echo "Point is not enough!";
} else {
// write post
$query = "INSERT INTO `doc` VALUES(NULL, 'title', 'description')";
$mysqli->query($query);
// assuming write post takes too long...
sleep(5);
// decreasing point
$query = "UPDATE `point` SET `point` = `point` - $write_point WHERE `user_id` = 1;";
$mysqli->query($query);
$res = $mysqli->query("SELECT `point` from `point` WHERE `user_id` = 1;");
$point = intval(mysqli_fetch_row($res)[0]);
echo "Write success! current point: " . $point;
}
3. 아래 python 코드를 실행합니다.
import threading
import requests
url = 'PHP 스크립트의 URL'
class TestThread(threading.Thread):
def __init__(self, url):
super().__init__()
self.url = url
def run(self):
res = requests.get(self.url)
print(res.text)
for i in range(5):
t = TestThread(url)
t.start()
여기서는 성능이 좋지 않아 글쓰기가 오래 걸린다는 가정을 표현하기 위해서 중간에 sleep(5)를 추가했습니다.
오오~ 바쁘신데 상세히 설명해주셔서 정말 감사합니다!!
humit 님께서도 주말 잘 보내고 계시죠??
성능이 좋지 않은 서버를 상대로 멀티스레딩으로 게시글을 작성하는 POST 요청을 하면
미처 포인트를 차감하기 전에 여러 개의 글이 작성될 수 있군요 ㅎㄷㄷ
전혀 생각을 하지 못했던 부분이 심각한 문제를 초래할 수 있네요~!
그렇다면 더 높은 사양의 서버를 구입해서 내부적으로 글 작성에 소요되는 시간을 줄이는 것 이외에는 대책이 없는 것인가요??
아니면 글이 작성되기 전에 미리 포인트를 차감해야 되는 것인가요?? ㅠㅠ
제가 SQL에 대해서는 아주 기초적인 내용밖에 몰라서 올려주신 SQL문 자체에는 딱히 어떤 문제가 있는지 모르겠네요~ ㅜㅜ
그럼 humit 님께서도 남은 주말 즐겁게 보내시고 남은 학기도 홧팅홧팅하세요~
+) 저는 요새 연수를 받고 있는데 공대 분들이 많이 계셔서 반갑더군요 ^-^
존재하지 않는 스티커입니다.
예를 들어 글쓰기 요청이 2개가 이루어지고 포인트는 10이라고 가정을 하겠습니다.
원래 자연스러운 흐름은 (포인트 체크1) => (글쓰기 요청1) => (포인트 감소1) => (포인트 체크2) => (포인트 에러2) 와 같은 흐름이 되어야 합니다.
하지만 저렇게 글쓰기 요청이 오래 걸리면 실행흐름이 아래와 같이 될 수 있습니다.
(포인트 체크1) => (글쓰기 요청1) => (포인트 체크2) => (글쓰기 요청2) => (포인트 감소1) => (포인트 감소2) 와 같은 흐름이 가능해질 수 있습니다. 즉 포인트 체크를 하는 부분이 이전의 포인트 감소가 일어나기 전에 발생할 수 있기 때문에 이런 경우엔 우회가 가능하게 되는 것입니다.
이를 해결하려면 SQL에서 제공하는 기능인 transaction을 사용하는 방법이 있습니다.
역시 코딩의 세계는 어렵게 심오하네요 ㅎㄷㄷ
제가 지금 진행하고 있는 홈페이지 개발에 적용할 수 있도록 transaction 등과 관련하여 공부를 더 해야겠네요 :)
번번이 정말 감사합니다!! ^-^
그럼 굿밤 되세요 :)
존재하지 않는 스티커입니다.
맛스타님 댓글에서는 syntax highlighter를 어떻게 사용해야 하나요??
존재하지 않는 스티커입니다.
(모바일은 본문, 댓글 모두 불가능합니다. 쓸일이 없을 것 같아서요.)
이를 막기 위해선 근본적으로 SQL 인젝션을 방어하는 방향으로 코드를 수정해야 할 테고, 당장은 올라오는 족족 IP 밴을 먹여야 할 것 같습니다.
가장 좋은 것은 커뮤니티를 없애는 것ㅇ..(도망)