Skip to content

Commit 1efb09f

Browse files
authored
Merge pull request #3 from Gh05t-1337/main
Team Blue Omega, libpng
2 parents eacfbcd + a999a3a commit 1efb09f

8 files changed

Lines changed: 144 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Dockerfile
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CVE-2017-12652 in [libpng](https://github.com/pnggroup/libpng) version <=1.6.32beta06.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
FROM ubuntu:24.04
2+
RUN apt-get update && apt-get install -y cmake build-essential python3-pwntools git
3+
ADD --chown=0:0 --chmod=6755 http://github.com/pwncollege/exec-suid/releases/latest/download/exec-suid /usr/bin/exec-suid
4+
COPY challenge.c crash_to_flag.c /challenge/
5+
RUN <<END
6+
set -e
7+
mkdir -p /challenge/bin
8+
cd /challenge
9+
10+
git clone https://github.com/pnggroup/libpng
11+
git config --global user.email "you@example.com"
12+
git config --global user.name "Your Name"
13+
git -C libpng checkout 2b37d46564b48efa0298f57134c6a555c223ee44
14+
git -C libpng revert 2b37d46564b48efa0298f57134c6a555c223ee44
15+
git -C libpng diff 347538e 2b37d465 > /challenge/patch.diff
16+
17+
mkdir /challenge/libpng/build
18+
cd /challenge/libpng/build
19+
cmake -DCMAKE_INSTALL_PREFIX=/challenge -DCMAKE_BUILD_TYPE=Release ../
20+
make
21+
make install
22+
git -C /challenge/libpng clean -fxxd
23+
24+
gcc -I/challenge/include /challenge/*.c /challenge/lib/libpng.a -lz -lm -o /challenge/bin/challenge
25+
chmod 6755 /challenge/bin/challenge
26+
END
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <stdint.h>
4+
#include <dlfcn.h> // <--- needed for dlsym and RTLD_NEXT
5+
#include <png.h>
6+
#include <setjmp.h>
7+
8+
#ifndef RTLD_NEXT
9+
#define RTLD_NEXT ((void *) -1l)
10+
#endif
11+
12+
#define MAX_MALLOC_SIZE 0x7fffffff
13+
#define MAX_PNG_SIZE 0x10000 // Maximum allowed PNG size in bytes
14+
15+
void* malloc(size_t size) {
16+
static void* (*real_malloc)(size_t) = NULL;
17+
if (!real_malloc) {
18+
real_malloc = (void* (*)(size_t))dlsym(RTLD_NEXT, "malloc");
19+
}
20+
21+
if (size > MAX_MALLOC_SIZE) {
22+
printf("Wow! that's a big malloc you've got there! can't handle that.\n");
23+
// Force a segfault
24+
*(volatile int*)0 = 0;
25+
}
26+
27+
return real_malloc(size);
28+
}
29+
30+
// Warning handler: prints the message and stops processing
31+
void png_warning_handler(png_structp png_ptr, png_const_charp msg) {
32+
fprintf(stderr, "libpng warning: %s\n", msg);
33+
longjmp(png_jmpbuf(png_ptr), 1); // jump back to main
34+
}
35+
36+
int main(int argc, char *argv[]) {
37+
if (argc != 2) {
38+
fprintf(stderr, "Usage: %s <input.png>\n", argv[0]);
39+
return EXIT_FAILURE;
40+
}
41+
42+
const char *filename = argv[1];
43+
FILE *fp = fopen(filename, "rb");
44+
if (!fp) {
45+
perror("fopen");
46+
return EXIT_FAILURE;
47+
}
48+
49+
// check if file is small enough
50+
fseek(fp, 0, SEEK_END);
51+
long filesize = ftell(fp);
52+
fseek(fp, 0, SEEK_SET);
53+
54+
if (filesize > MAX_PNG_SIZE) {
55+
fprintf(stderr, "Error: PNG file is too large (%ld bytes). Maximum allowed is %d bytes.\n",
56+
filesize, MAX_PNG_SIZE);
57+
fclose(fp);
58+
return EXIT_FAILURE;
59+
}
60+
61+
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
62+
if (!png_ptr) {
63+
fprintf(stderr, "png_create_read_struct failed\n");
64+
fclose(fp);
65+
return EXIT_FAILURE;
66+
}
67+
68+
png_infop info_ptr = png_create_info_struct(png_ptr);
69+
if (!info_ptr) {
70+
fprintf(stderr, "png_create_info_struct failed\n");
71+
png_destroy_read_struct(&png_ptr, NULL, NULL);
72+
fclose(fp);
73+
return EXIT_FAILURE;
74+
}
75+
76+
// Set custom warning handler; leave error handler NULL to keep default
77+
png_set_error_fn(png_ptr, NULL, NULL, png_warning_handler);
78+
79+
// Setup setjmp to catch warnings and errors
80+
if (setjmp(png_jmpbuf(png_ptr))) {
81+
fprintf(stderr, "Stopped due to a warning/error.\n");
82+
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
83+
fclose(fp);
84+
return EXIT_FAILURE;
85+
}
86+
87+
// Initialize libpng IO and read header
88+
png_init_io(png_ptr, fp);
89+
png_read_info(png_ptr, info_ptr);
90+
91+
// Extract PNG info
92+
png_uint_32 width, height;
93+
int bit_depth, color_type, interlace_type, compression_type, filter_method;
94+
95+
png_get_IHDR(png_ptr, info_ptr,
96+
&width, &height,
97+
&bit_depth, &color_type,
98+
&interlace_type, &compression_type, &filter_method);
99+
100+
printf("Image width: %u\n", width);
101+
printf("Image height: %u\n", height);
102+
printf("Bit depth: %d\n", bit_depth);
103+
printf("Color type: %d\n", color_type);
104+
105+
// Cleanup
106+
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
107+
fclose(fp);
108+
109+
return EXIT_SUCCESS;
110+
}
111+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{% extends "base_templates/crash_to_flag.c" %}
217 Bytes
Loading
1016 Bytes
Binary file not shown.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh -e
2+
3+
/challenge/bin/challenge /challenge/libpng/tests/badadler.png
4+

0 commit comments

Comments
 (0)