c बफर ओवरफ्लो जीडीबी में काम करता है लेकिन इसके बिना नहीं




security buffer-overflow (6)

मैं CentOS 6.4 32 बिट पर हूं और एक प्रोग्राम में बफर ओवरफ्लो का कारण बन रहा हूं। जीडीबी के भीतर यह काम करता है। आउटपुट यहां है:

[[email protected] bufferoverflow]# gdb stack
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/bufferoverflow/stack...done.
(gdb) r
Starting program: /root/bufferoverflow/stack
process 6003 is executing new program: /bin/bash
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.el6_4.2.i686
sh-4.1#

हालांकि जब मैं प्रोग्राम स्टैक को अपने आप ही चलाता हूं तो यह गलती करता है। यह क्यों हो सकता है?


मैं सेंटोस 6.4 32 बिट पर हूं और एक प्रोग्राम में बफर ओवरफ्लो का कारण बनने की कोशिश कर रहा हूं ... हालांकि जब मैं प्रोग्राम स्टैक को अपने आप ही चलाता हूं तो यह त्रुटियां होती है।

आपको यह भी सुनिश्चित करना चाहिए कि FORTIFY_SOURCE आपके परिणामों को प्रभावित नहीं कर रहा है। SET गलती लगता है जैसे FORTIFY_SOURCE समस्या हो सकती है क्योंकि FORTIFY_SOURCE कुछ प्रकार के बफर ओवरफ़्लो के विरुद्ध सुरक्षा के लिए "सुरक्षित" फ़ंक्शन कॉल डालेगा। यदि संकलक गंतव्य बफर आकार को कम कर सकता है, तो आकार की जांच की जाती है और उल्लंघन ( abort() को उल्लंघन पर कहा जाता है (यानी, आपकी सीईजी गलती)।

परीक्षण के लिए FORTIFY_SOURCE को बंद करने के लिए, आपको -U_FORTIFY_SOURCE या -D_FORTIFY_SOURCE=0 साथ संकलित करना चाहिए।


आपके बफर ओवरफ़्लो जीडीबी और segfaults के तहत काम करता है अन्यथा यह है कि gdb पता स्थान लेआउट यादृच्छिकता अक्षम करता है। मेरा मानना ​​है कि यह डिफ़ॉल्ट रूप से जीडीबी संस्करण 7 में चालू किया गया था।

आप यह आदेश चलाकर इसे देख सकते हैं:

show disable-randomization

और इसे साथ सेट करें

set disable-randomization on

या

set disable-randomization off

अगर आप डीबगिंग प्रक्रिया में गैर-निर्धारणा को पेश करते हैं तो उन कारकों के लिए पर्याप्त रूप से खाता नहीं है, जो विकास के लिए विस्फोट से गंभीर सिरदर्द पैदा कर सकते हैं। विशेष रूप से, डीबगर में स्टैक पते सामान्य निष्पादन के दौरान पते से मेल नहीं खाते हैं। यह आर्टिफैक्ट तब होता है क्योंकि ऑपरेटिंग सिस्टम लोडर स्टैक की शुरुआत से पहले पर्यावरण चर और प्रोग्राम तर्क दोनों रखता है:

चूंकि आपका कमजोर कार्यक्रम कोई तर्क नहीं लेता है, इसलिए पर्यावरण चर संभवतः अपराधी हैं। मारे यकीन है कि वे दोनों invocations, खोल में और डीबगर में समान हैं। इस अंत में, आप env में अपना आमंत्रण लपेट सकते हैं:

env - /path/to/stack

और डीबगर के साथ:

env - gdb /path/to/stack
($) show env
LINES=24
COLUMNS=80

उपर्युक्त उदाहरण में, जीडीबी द्वारा निर्धारित दो पर्यावरण चर हैं, जिन्हें आप आगे अक्षम कर सकते हैं:

unset env LINES
unset env COLUMNS

अब show env एक खाली सूची वापस करनी चाहिए। इस बिंदु पर, आप उस पूर्ण स्टैक पते को खोजने के लिए डिबगिंग प्रक्रिया शुरू कर सकते हैं जिसे आप कूदने के लिए कल्पना करते हैं (उदाहरण के लिए, 0xbffffa8b ), और इसे अपने शोषण में हार्डकोड करें।

एक और सूक्ष्म लेकिन महत्वपूर्ण विस्तार: कॉलिंग ./stack और /path/to/stack बीच एक अंतर है: चूंकि argv[0] प्रोग्राम को बिल्कुल सही तरीके से आयोजित करता है, तो आपको समान आमंत्रण तार सुनिश्चित करने की आवश्यकता होती है। यही कारण है कि मैंने उपर्युक्त उदाहरणों में /path/to/stack किया था, न केवल ./stack और gdb stack

स्मृति सुरक्षा भेद्यता के साथ शोषण करना सीखते समय, मैं नीचे रैपर प्रोग्राम का उपयोग करने की सलाह देता हूं, जो भारी उठाने और बराबर स्टैक ऑफ़सेट सुनिश्चित करता है:

$ invoke stack         # just call the executable
$ invoke -d stack      # run the executable in GDB

यहां लिपि है:

#!/bin/sh

while getopts "dte:h?" opt ; do
  case "$opt" in
    h|\?)
      printf "usage: %s -e KEY=VALUE prog [args...]\n" $(basename $0)
      exit 0
      ;;
    t)
      tty=1
      gdb=1
      ;;
    d)
      gdb=1
      ;;
    e)
      env=$OPTARG
      ;;
  esac
done

shift $(expr $OPTIND - 1)
prog=$(readlink -f $1)
shift
if [ -n "$gdb" ] ; then
  if [ -n "$tty" ]; then
    touch /tmp/gdb-debug-pty
    exec env - $env TERM=screen PWD=$PWD gdb -tty /tmp/gdb-debug-pty --args $prog "[email protected]"
  else
    exec env - $env TERM=screen PWD=$PWD gdb --args $prog "[email protected]"
  fi
else
  exec env - $env TERM=screen PWD=$PWD $prog "[email protected]"
fi

टर्मिनल में और gdb में समान स्टैक के साथ अपने प्रोग्राम को चलाने का एक सीधा तरीका यहां दिया गया है:

सबसे पहले, सुनिश्चित करें कि आपका प्रोग्राम स्टैक सुरक्षा के बिना संकलित किया गया है,

gcc -m32 -fno-stack-protector -z execstack -o shelltest shelltest.c -g

और एएसएलआर अक्षम है:

echo 0 > /proc/sys/kernel/randomize_va_space

नोट: मेरी मशीन पर डिफ़ॉल्ट मान 2 था, इसे बदलने से पहले अपना ध्यान दें।

फिर अपने प्रोग्राम को इस प्रकार चलाएं (क्रमशः टर्मिनल और जीडीबी):

env -i PWD="/root/Documents/MSec" SHELL="/bin/bash" SHLVL=0 /root/Documents/MSec/shelltest
env -i PWD="/root/Documents/MSec" SHELL="/bin/bash" SHLVL=0 gdb /root/Documents/MSec/shelltest

gdb भीतर, LINES और COLUMNS को unset करना सुनिश्चित करें।

नोट: मुझे परीक्षण कार्यक्रम के साथ खेलकर उन पर्यावरण चर मिल गए हैं।

वे दो रन आपको स्टैक के शीर्ष पर समान पॉइंटर्स देंगे, इसलिए यदि आप दूरस्थ रूप से होस्ट किए गए बाइनरी का शोषण करने का प्रयास कर रहे हैं तो रिमोट स्क्रिप्ट शेंगेनियों की आवश्यकता नहीं है।


जीडीबी में कोड चलाते समय स्टैक फ्रेम पॉइंटर का पता सामान्य रूप से इसे चलाने से अलग होता है। तो आप सीधे जीडीबी मोड में रिटर्न पता दूषित कर सकते हैं, लेकिन सामान्य मोड में चलते समय यह सही नहीं हो सकता है। इसके लिए मुख्य कारण दो स्थितियों में पर्यावरण चर भिन्न है।

चूंकि यह सिर्फ एक डेमो है, आप पीड़ित कोड बदल सकते हैं, और बफर के पते को प्रिंट कर सकते हैं। फिर बफर के ऑफसेट + पते पर अपना रिटर्न पता बदलें।

हकीकत में, हालांकि, आपको अपने दुर्भावनापूर्ण कोड से पहले एनओपी स्लड जोड़ने के पते को अनुमान लगाने की आवश्यकता है। और आप सही पता पाने के लिए कई बार अनुमान लगा सकते हैं, क्योंकि आपका अनुमान गलत हो सकता है।

आशा है इससे आपको सहायता मिलेगी।


मैंने यहां स्वीकार किए गए समाधान की कोशिश की है और यह काम नहीं करता है (मेरे लिए)। मुझे पता था कि जीडीबी ने पर्यावरण चर जोड़ा है और इसी कारण से स्टैक पता मेल नहीं खाता है, लेकिन उन चरों को भी हटा रहा है, मैं जीडीबी के बिना अपना शोषण नहीं कर सकता (मैंने स्वीकार किए गए समाधान में लिपि स्क्रिप्ट की भी कोशिश की)।

लेकिन वेब पर खोज करने के लिए मुझे अन्य स्क्रिप्ट मिली जो मेरे लिए काम करती है: https://github.com/hellman/fixenv/blob/master/r.sh

उपयोग मूल रूप से वही है जो स्वीकार किए गए समाधान में लिपि:

  • gdb में प्रोग्राम चलाने के लिए r.sh gdb ./program [args]
  • gdb के बिना प्रोग्राम चलाने के लिए r.sh ./program [args]

और यह स्क्रिप्ट मेरे लिए काम करती है।





memory-safety