0

I am trying to integrate the use of an external API to perform POST and GET calls with my C# WPF client application. https://developers.virustotal.com/reference.

This is what i have right now:

ScanPage.xaml.cs

private void browseFileButton_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Multiselect = false;
            openFileDialog.Filter = "All files (*.*)|*.*";
            openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            if (openFileDialog.ShowDialog() == true)
            {
                filePath = openFileDialog.FileName;
                fileLocation.Text = filePath;
            }
        }


private async void uploadFileButton_Click(object sender, RoutedEventArgs e)
        {
            if (filePath != null)
            {
                var resultInfo = await InfoProcessor.PostInfo(filePath);
                responseText.Text = "File queued for scanning, please wait a moment...";
                var resultInfo2 = await InfoProcessor.LoadInfo(resultInfo.Resource);
                System.Threading.Thread.Sleep(10000);
                //await Task.Delay(5000).ContinueWith(t => runLoadInfo(resultInfo.Resource));
                responseText.Text = $"Scan Completed, MD5 checksum of file is {resultInfo2.Sha256} \n {resultInfo2.Positives} out of {resultInfo2.Total} {resultInfo2.Permalink} scan engines has detected to be potentially malicious";
            }
            else
            {
                MessageBox.Show("please upload a file");
            }
        }

public static async Task<InfoModel> PostInfo(string fileString)
        {
            string url = "https://www.virustotal.com/vtapi/v2/file/scan";
            string apiKey = "xxxxxx";
            string uploadedFile = fileString;

            var values = new Dictionary<string, string>
            {
                { "apikey", apiKey },
                { "file", uploadedFile}
            };

            var content = new FormUrlEncodedContent(values);

            using (HttpResponseMessage response = await ApiStartup.ApiClient.PostAsync(url, content))
            {
                InfoModel info = await response.Content.ReadAsAsync<InfoModel>();
                return info;
            }


            //var response = await ApiStartup.ApiClient.PostAsync(url, content);
            //var responseString = await response.Content.ReadAsStringAsync();
            //HttpResponseMessage response = await ApiStartup.ApiClient.PostAsJsonAsync("apikey",apiKey );
            //response.EnsureSuccessStatusCode();
        }

public static async Task<InfoModel> LoadInfo(string infoVar)
        {
            string apiKey = "xxxxxxxx";
            //string resourceKey = "efbb7149e39e70c84fe72c6fe8cef5d379fe37e7238d19a8a4536fb2a3146aed"; 
            string resourceKey = infoVar;
            string url = $"https://www.virustotal.com/vtapi/v2/file/report?apikey={apiKey}&resource={resourceKey}";

            using (HttpResponseMessage response = await ApiStartup.ApiClient.GetAsync(url))
            {
                if (response.IsSuccessStatusCode)
                {
                    InfoModel info = await response.Content.ReadAsAsync<InfoModel>();

                    return info;
                }
                else
                {
                    throw new Exception(response.ReasonPhrase);
                }
            }
        }

After posting and getting the result of the scanned report of the uploaded file, it seems like i only upload just the string of the filepath and not the actual file itself. How can i code it so that the selected file would be properly posted instead? Thanks.

Watlah
  • 19
  • 1
  • 4
  • As a note, don't call `Thread.Sleep` in the UI thread. Use `await Task.Delay` (without `ContinueWith`) instead. Besides that, without any information about the API you are using, it's hard to tell what exactly you should do. However, `InfoProcessor.PostInfo(filePath)` will quite obviously only post the file path. You may perhaps read the file's content and post that. – Clemens Nov 03 '19 at 10:21
  • Did you not try a search? This looks to be a set of samples for all api calls in c# https://github.com/Genbox/VirusTotalNet/blob/master/README.md – Andy Nov 03 '19 at 11:05
  • What does InfoProcessor.PostInfo method contain? In that method you should open the file contents, create an object matching the virustotal api and populate the http request. – Sotiris Panopoulos Nov 03 '19 at 11:07
  • Thanks guys, i have included both LoadInfo and PostInfo function in the post, in that case, should i try out the solution in this post? https://stackoverflow.com/questions/16416601/c-sharp-httpclient-4-5-multipart-form-data-upload – Watlah Nov 03 '19 at 11:22

1 Answers1

0

As for your latest comment, yes, you should use multipart form post.

You can implement it yourself, or use an external library to do this for you, like VirusTotalNet, as linked in the comments. If you still want to do it yourself, here is the code from this library:

https://github.com/Genbox/VirusTotalNet/blob/master/src/VirusTotalNet/VirusTotal.cs#L162-L217

Sotiris Panopoulos
  • 1,523
  • 1
  • 13
  • 18
  • So i've tried copy and pasting the required functions that you have highlight in the link you have provided and then adding all the required references and libraries in my **InfoProcessor** class. I know i'm supposed to call **ScanFileAsync** in my **uploadFileButton_Click** function but i cant seem to properly call the function. What i have tried : `var resultInfo = await InfoProcessor.ScanFileAsync(filePath); ` and it returns the intellisense prompt of `An object reference is required for the nonstatic field, method, or property` – Watlah Nov 03 '19 at 15:59
  • I didn't propose to copy and paste the methods. I provided them as a guideline to construct your own implementation. If you want something ready made, there is still the option of using the VirusTotalNet library. Regarding your problem though, is InfoProcessor non-static now? – Sotiris Panopoulos Nov 03 '19 at 16:02
  • Should i just try to implement my own method of posting the multipart form post from the link i have commented earlier? If so, do you have any guides/links/references that i can follow through on this? Thanks – Watlah Nov 03 '19 at 16:03
  • I provided the implementation to use as a guide for you. Yes, the link you posted seems to be enough to do what you want. The specifics to calling the VirusTotal api is in the Github I linked. – Sotiris Panopoulos Nov 03 '19 at 16:06
  • Ok thanks, I've change my InfoProcessor class to static and the intellisense error still prompts just fyi. – Watlah Nov 03 '19 at 16:06
  • Intellisense should point you to which method is not correct. My guess is ScanFileAsync is not static. What are you doing in this method now? Also, if your goal is less code, why not use the library? – Sotiris Panopoulos Nov 03 '19 at 16:13