Skip to content

Instantly share code, notes, and snippets.

@zhangyoufu
Last active August 29, 2015 14:06
Show Gist options
  • Select an option

  • Save zhangyoufu/e21ad6a802965acbaa0e to your computer and use it in GitHub Desktop.

Select an option

Save zhangyoufu/e21ad6a802965acbaa0e to your computer and use it in GitHub Desktop.
NcN CTF 2014 Qual - eXPLicit - 500 pts
/*******************************************************************************
*
* No cON Name Capture The Flag 2014 Qual
*
* NcN CTF 2014 Qual - eXPLicit - 500 pts
*
* Reverse Engineered by libmaru (libmaru#gmail.com)
*
* Produce identical binary (except Build ID) as the official one
*
* Build Environment:
* Debian jessie
* gcc 4.9.1-12
* libc6-dev 2.19-9
*
* Build Instruction:
* gcc -static -fstack-protector -o explicit explicit.c && strip explicit
*
******************************************************************************/
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define ADDR "0.0.0.0"
#define PORT 7070
int conn_fd;
FILE* conn_fp;
#define msg( s ) fwrite( s, 1, strlen(s), conn_fp )
void serve()
{
char buf[256], *eol;
int number;
msg( "Welcome to Guess The Number Online!\n\n" );
srand( time( NULL ));
number = rand() % 20;
while( 1 )
{
msg( "Pick a number between 0 and 20: " );
fflush( conn_fp );
if( !fgets( buf, 1024, conn_fp )) break; // vuln: buffer overflow
eol = strchr( buf, '\n' );
if( eol ) *eol = '\0';
if( buf[0] == 'q' ) break; // quit
if( atoi( buf ) != number )
{
msg( "Your number is " );
fprintf( conn_fp, buf ); // vuln: format string
fprintf( conn_fp, " which is too %s.\n",
atoi( buf ) > number ? "high" : "low" );
fflush( conn_fp );
}
else
{
msg( "You win! Congratulations!\n\n" );
fflush( conn_fp );
break;
}
}
msg( "Bye\n" );
fflush( conn_fp );
}
#define check( retval, func ) do { \
if( retval == -1 ) \
{ \
perror( func ); \
return 1; \
} \
} while( 0 )
#define call( func, ... ) \
check( func( __VA_ARGS__ ), #func )
int main( int* innocent_argc, char* argv[] ) // strange, yes
{
struct sockaddr_in listen_addr, peer_addr;
socklen_t addr_len;
pid_t pid;
int sock;
memset( &listen_addr, '0', sizeof listen_addr );
listen_addr.sin_family = AF_INET;
listen_addr.sin_port = htons( PORT );
listen_addr.sin_addr.s_addr = inet_addr( ADDR );
sock = socket( AF_INET, SOCK_STREAM, 0 );
check( sock, "socket" );
call( bind, sock, (struct sockaddr*)&listen_addr, sizeof listen_addr );
call( listen, sock, 128 );
while( 1 )
{
conn_fd = accept( sock, (struct sockaddr*)&peer_addr, &addr_len );
pid = fork();
if ( !pid ) // child
{
conn_fp = fdopen( conn_fd, "r+" );
if( !conn_fp )
{
perror("fdopen");
close( conn_fd );
}
else
{
serve();
fclose( conn_fp );
close( conn_fd );
}
break;
}
close( conn_fd );
}
close( sock );
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment