Initial commit
This commit is contained in:
18
Makefile
Normal file
18
Makefile
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -ggdb -O0 -Wall -Wextra -Wno-unused-value
|
||||
|
||||
all : client server
|
||||
|
||||
client : client.c
|
||||
|
||||
server : server.c | payload_blob.h
|
||||
|
||||
%_blob.h : %.S | compile-blob.sh
|
||||
./compile-blob.sh $< > $@
|
||||
|
||||
.PHONY = clean
|
||||
clean :
|
||||
rm client server *_blob.h 2>/dev/null || true
|
||||
|
||||
|
||||
61
client.c
Normal file
61
client.c
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "die.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static inline int eval(unsigned char* code)
|
||||
{
|
||||
long size = sysconf(_SC_PAGESIZE);
|
||||
void* start = (void *)((unsigned long)code & ~(size - 1));
|
||||
int ok = mprotect(start, size, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
if (ok == -1) die("mprotect");;
|
||||
|
||||
return ((int(*)())code)();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
struct sockaddr_in serv_addr;
|
||||
unsigned char buffer[BUF_SIZE] = {0};
|
||||
int ok;
|
||||
char *request = "GET / HTTP/1.1" LINEBREAK
|
||||
"Host: localhost" LINEBREAK LINEBREAK;
|
||||
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock == -1) die("socket");
|
||||
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_port = htons(argc == 3 ? atoi(argv[2]) : PORT);
|
||||
|
||||
ok = inet_pton(AF_INET, argc > 1 ? argv[1] : "127.0.0.1", &serv_addr.sin_addr);
|
||||
if (ok == -1) die("inet_pton");
|
||||
|
||||
ok = connect(sock, (struct sockaddr *)&serv_addr, sizeof serv_addr);
|
||||
if (ok == -1) die("connect");
|
||||
|
||||
ok = send(sock, request, strlen(request), 0);
|
||||
if (ok == -1) die("send");
|
||||
|
||||
ssize_t read_cnt = read(sock, buffer, BUF_SIZE);
|
||||
if (read_cnt == -1) die("read");
|
||||
|
||||
ok = close(sock);
|
||||
if (ok == -1) die("close");
|
||||
|
||||
for (ssize_t i=0; i<read_cnt; i++)
|
||||
fprintf(stderr, "%02x ", buffer[i]);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
eval(buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
30
compile-blob.sh
Executable file
30
compile-blob.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
for cmd in ld as clang-format; do
|
||||
command -v $cmd &>/dev/null || (echo command $cmd not found; exit 1 )
|
||||
done
|
||||
|
||||
if [ "$#" -ne "1" ]; then
|
||||
printf "Usage: %s <asm file>" $0 >/dev/stderr
|
||||
exit 1
|
||||
fi
|
||||
|
||||
as_output=$(mktemp)
|
||||
ld_output=$(mktemp)
|
||||
cleanup() {
|
||||
rm $as_output
|
||||
rm $ld_output
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
as $1 -o $as_output
|
||||
ld --oformat binary $as_output -o $ld_output
|
||||
|
||||
(
|
||||
echo '#pragma once'
|
||||
echo 'static const unsigned char binary_data[] = {'
|
||||
tail $ld_output -c +4097 | hexdump -v --format='"" 1/1 "0x%02x,"'
|
||||
echo '};'
|
||||
) | clang-format
|
||||
6
config.h
Normal file
6
config.h
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define PORT 8080
|
||||
#define LINEBREAK "\n"
|
||||
#define BUF_SIZE 1024
|
||||
19
die.h
Normal file
19
die.h
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define die(msg) die_(msg, __func__, __LINE__)
|
||||
static int die_(const char* msg, const char* function, int line)
|
||||
{
|
||||
fprintf(stderr, msg);
|
||||
if (errno) {
|
||||
perror(" ");
|
||||
}
|
||||
fprintf(stderr, "line: %d\n", line);
|
||||
fprintf(stderr, "function: %s\n", function);
|
||||
fprintf(stderr, "errno: %d\n", errno);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
22
payload.S
Normal file
22
payload.S
Normal file
@@ -0,0 +1,22 @@
|
||||
.section .text
|
||||
.globl _start
|
||||
_start:
|
||||
pushq %rbp
|
||||
movq %rsp, %rbp
|
||||
movabsq $8031924123371070824, %rax
|
||||
movq %rax, -45(%rbp)
|
||||
movl $560229490, -37(%rbp)
|
||||
movb $0, -33(%rbp)
|
||||
movl $1, -4(%rbp)
|
||||
leaq -45(%rbp), %rax
|
||||
movq %rax, -16(%rbp)
|
||||
movq $13, -24(%rbp)
|
||||
movl $1, %eax
|
||||
movl -4(%rbp), %edi
|
||||
movq -16(%rbp), %rsi
|
||||
movq -24(%rbp), %rdx
|
||||
syscall
|
||||
movq %rax, -32(%rbp)
|
||||
movl $0, %eax
|
||||
popq %rbp
|
||||
ret
|
||||
18
run.sh
Executable file
18
run.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
make -B
|
||||
|
||||
./server &
|
||||
sleep 0.01
|
||||
server_pid=$!
|
||||
|
||||
if [ "$#" -gt 0 ]; then
|
||||
gdb client
|
||||
else
|
||||
./client
|
||||
fi
|
||||
|
||||
kill $server_pid
|
||||
|
||||
60
server.c
Normal file
60
server.c
Normal file
@@ -0,0 +1,60 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "die.h"
|
||||
#include "payload_blob.h" // defines binary_data[]
|
||||
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int new_socket;
|
||||
struct sockaddr_in address;
|
||||
int addrlen = sizeof(address);
|
||||
char buffer[BUF_SIZE] = {0};
|
||||
|
||||
// Creating socket file descriptor
|
||||
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (server_fd == -1)
|
||||
die("socket failed");;
|
||||
|
||||
// Forcefully attaching socket to the port 8080
|
||||
int opt = 1;
|
||||
int ok = setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
|
||||
&opt, sizeof opt);
|
||||
if (ok == -1) die("setsockopt");;
|
||||
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_addr.s_addr = INADDR_ANY;
|
||||
address.sin_port = htons(PORT);
|
||||
|
||||
bind(server_fd, (struct sockaddr *)&address, sizeof(address));
|
||||
if (ok == -1) die("bind failed");
|
||||
|
||||
ok = listen(server_fd, 3);
|
||||
if (ok == -1) die("listen");
|
||||
|
||||
while (1) {
|
||||
ssize_t n;
|
||||
new_socket = accept(server_fd, (struct sockaddr*)&address,
|
||||
(socklen_t*)&addrlen);
|
||||
if (new_socket == -1) die("accept");
|
||||
|
||||
n = read(new_socket, buffer, BUF_SIZE);
|
||||
if (n == -1) die("read");
|
||||
|
||||
n = write(new_socket, binary_data, sizeof binary_data);
|
||||
if (n == -1) die("write");
|
||||
|
||||
ok = close(new_socket);
|
||||
if (ok == -1) die("close");
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user