Skip to content

Instantly share code, notes, and snippets.

@lionaneesh
Created September 23, 2019 15:45
Show Gist options
  • Save lionaneesh/4a88a65fa0cba38eba095c5367cb8f70 to your computer and use it in GitHub Desktop.
Save lionaneesh/4a88a65fa0cba38eba095c5367cb8f70 to your computer and use it in GitHub Desktop.
rms-fixed, source code from Dragon CTF 2019
void *__fastcall fetch(void *url_1)
{
int v1; // eax
char *v2; // rax
__int64 v3; // rdx
int *v4; // rax
void *dest; // ST78_8
uint16_t port_network; // [rsp+1Ah] [rbp-116h]
int portnumber; // [rsp+1Ch] [rbp-114h]
char *hostname; // [rsp+20h] [rbp-110h]
char *portstart; // [rsp+28h] [rbp-108h]
char *v11; // [rsp+30h] [rbp-100h]
char *url_afterhttp; // [rsp+40h] [rbp-F0h]
char *pathbegin; // [rsp+48h] [rbp-E8h]
char *port_str; // [rsp+50h] [rbp-E0h]
struct hostent *hostentpointer; // [rsp+58h] [rbp-D8h]
struct hostent *hostentpointer_1; // [rsp+70h] [rbp-C0h]
int urlptr; // [rsp+80h] [rbp-B0h]
char errorflag; // [rsp+84h] [rbp-ACh]
char *errormsg; // [rsp+88h] [rbp-A8h]
size_t length; // [rsp+90h] [rbp-A0h]
__int64 v21; // [rsp+98h] [rbp-98h]
struct sockaddr *v22; // [rsp+A0h] [rbp-90h]
__int64 v23; // [rsp+A8h] [rbp-88h]
__int64 v24; // [rsp+B0h] [rbp-80h]
unsigned __int64 v25; // [rsp+128h] [rbp-8h]
v25 = __readfsqword(0x28u);
urlptr = *url_1;
errorflag = 1;
errormsg = 0LL;
length = 0LL;
v21 = 0LL;
hostname = 0LL;
v1 = min(*(url_1 + 2), 7LL);
if ( strncmp("http://", *(url_1 + 1), v1) )
{
errormsg = "not http";
LABEL_41:
errorflag = 0;
length = strlen(errormsg);
goto LABEL_42;
}
url_afterhttp = (*(url_1 + 1) + 7LL);
pathbegin = strchrnul(url_afterhttp, '/');
if ( pathbegin - url_afterhttp > 256 )
{
errormsg = "host too long";
goto LABEL_41;
}
portstart = strchr(url_afterhttp, ':');
if ( portstart >= pathbegin )
portstart = 0LL;
if ( portstart )
{
hostname = strndup(url_afterhttp, portstart - url_afterhttp);
port_str = strndup(portstart + 1, pathbegin - (portstart + 1));
if ( !port_str )
__assert_fail("atstr", "task/main.c", 0x7Fu, "fetch");
portnumber = atoi(port_str);
if ( portnumber < 0 || portnumber > 0x10000 )
{
puts("invalid port");
abort();
}
free(port_str);
}
else
{
LOWORD(portnumber) = 80;
hostname = strndup(url_afterhttp, pathbegin - url_afterhttp);
}
if ( !hostname )
__assert_fail("domain", "task/main.c", 0x87u, "fetch");
if ( *pathbegin )
v11 = pathbegin;
else
v11 = "/";
if ( *v11 != 47 )
__assert_fail("path[0] == '/'", "task/main.c", 0x8Du, "fetch");
port_network = htons(portnumber);
hostentpointer = gethostbyname2(hostname, 10);
memset(&v22, 0, 0x80uLL);
if ( hostentpointer )
{
if ( hostentpointer->h_addrtype != 10 )
__assert_fail("hent6->h_addrtype == AF_INET6", "task/main.c", 0x95u, "fetch");
WORD1(v22) = port_network;
LOWORD(v22) = 10;
v2 = *hostentpointer->h_addr_list;
v3 = *(v2 + 1);
v23 = *v2;
v24 = v3;
if ( !memcmp(&v23, &in6addr_loopback, 0x10uLL) || !v23 )
{
errormsg = "localhost not allowed";
goto LABEL_41;
}
}
hostentpointer_1 = gethostbyname2(hostname, 2);
if ( hostentpointer_1 )
{
if ( hostentpointer_1->h_addrtype != 2 )
__assert_fail("hent4->h_addrtype == AF_INET", "task/main.c", 0xA0u, "fetch");
if ( **hostentpointer_1->h_addr_list == 127 || !**hostentpointer_1->h_addr_list )
{
errormsg = "localhost not allowed";
goto LABEL_41;
}
}
if ( !hostentpointer || !make_request(&v22, 0x80u, hostname, v11, &errormsg, &length) )
{
if ( hostentpointer_1 )
{
LOWORD(v22) = 2;
WORD1(v22) = port_network;
HIDWORD(v22) = **hostentpointer_1->h_addr_list;
if ( make_request(&v22, 0x80u, hostname, v11, &errormsg, &length) )
goto LABEL_42;
}
else
{
v4 = __h_errno_location();
errormsg = hstrerror(*v4);
}
goto LABEL_41;
}
LABEL_42:
free(hostname);
dest = calloc(1uLL, 0x20uLL);
memcpy(dest, &urlptr, 0x20uLL);
return dest;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment