From 343e513deb278212f2a86a36107c4134ebfc15fb Mon Sep 17 00:00:00 2001 From: sam Date: Wed, 27 Apr 2005 08:54:33 +0000 Subject: [PATCH] * crack ourcolony captchas (in the scode decoder) * started work on livejournal captchas. git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/pwntcha/trunk@477 92316355-f0b4-4df1-b90c-862c8a59935f --- src/Makefile.am | 1 + src/common.h | 1 + src/livejournal.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 7 +++ src/scode.c | 11 ++++ 5 files changed, 160 insertions(+) create mode 100644 src/livejournal.c diff --git a/src/Makefile.am b/src/Makefile.am index 6596534..16a9dc5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,6 +10,7 @@ pwntcha_SOURCES = \ authimage.c \ clubic.c \ linuxfr.c \ + livejournal.c \ lmt.c \ paypal.c \ phpbb.c \ diff --git a/src/common.h b/src/common.h index f193b2b..c8fe6de 100644 --- a/src/common.h +++ b/src/common.h @@ -41,6 +41,7 @@ void dprintf(const char *fmt, ...); char *decode_authimage(struct image *img); char *decode_clubic(struct image *img); char *decode_linuxfr(struct image *img); +char *decode_livejournal(struct image *img); char *decode_paypal(struct image *img); char *decode_phpbb(struct image *img); char *decode_scode(struct image *img); diff --git a/src/livejournal.c b/src/livejournal.c new file mode 100644 index 0000000..51a6494 --- /dev/null +++ b/src/livejournal.c @@ -0,0 +1,140 @@ +/* + * livejournal.c: decode livejournal captchas + * $Id$ + * + * Copyright: (c) 2005 Sam Hocevar + * This program is free software; you can redistribute it and/or + * modify it under the terms of the Do What The Fuck You Want To + * Public License as published by Banlu Kemiyatorn. See + * http://sam.zoy.org/projects/COPYING.WTFPL for more details. + */ + +#include +#include +#include +#include + +#include "config.h" +#include "common.h" + +static void find_glyphs(struct image *img); + +/* Our macros */ +char *result; + +/* Main function */ +char *decode_livejournal(struct image *img) +{ + struct image *tmp; + + /* livejournal captchas have 7 characters */ + result = malloc(8 * sizeof(char)); + strcpy(result, " "); + + tmp = image_dup(img); + filter_detect_lines(tmp); + filter_fill_holes(tmp); + filter_median(tmp); +// filter_smooth(tmp); +// filter_contrast(tmp); + filter_equalize(tmp, 128); +image_save(tmp, "foo.bmp"); + find_glyphs(tmp); + + image_free(tmp); + + return result; +} + +static void find_glyphs(struct image *img) +{ + static struct font *font = NULL; + struct image *tmp; + int x, y, i = 0; + int r, g, b; + int xmin, xmax, ymin, ymax, startx = 0, cur = 0; + int distmin, distx, disty, distch; + + if(!font) + { + font = font_load_variable("x_font_freesansbold_32_09az.bmp", + "0123456789abcdefghijklmnopqrstuvwxyz"); + if(!font) + exit(1); + } + + tmp = image_new(img->width, img->height); + + for(y = 0; y < img->height; y++) + for(x = 0; x < img->width; x++) + { + getpixel(img, x, y, &r, &g, &b); + setpixel(tmp, x, y, 255, g, 255); + } + + while(cur < 7) + { + /* Try to find 1st letter */ + distmin = INT_MAX; + for(i = 0; i < font->size; i++) + { +int sqr; + int localmin = INT_MAX, localx, localy; + xmin = font->glyphs[i].xmin; + ymin = font->glyphs[i].ymin; + xmax = font->glyphs[i].xmax; + ymax = font->glyphs[i].ymax; +sqr = sqrt(xmax - xmin); + for(y = -16; y < 8; y++) + for(x = 25 * cur; x < 25 * cur + 5; x++) + { + int z, t, dist; + dist = 0; + for(t = 0; t < ymax - ymin; t++) + for(z = 0; z < xmax - xmin; z++) + { + int r2; + getgray(font->img, xmin + z, ymin + t, &r); + getgray(img, x + z, y + t, &r2); + dist += abs(r - r2); + } + //dist = dist * 128 / font->glyphs[i].count; + dist = dist / (xmax - xmin) / sqr; + if(dist < localmin) + { + localmin = dist; + localx = x; + localy = y; + } + } + if(localmin < distmin) + { + distmin = localmin; + distx = localx; + disty = localy; + distch = i; + } + } + + /* Print min glyph */ + xmin = font->glyphs[distch].xmin; + ymin = font->glyphs[distch].ymin; + xmax = font->glyphs[distch].xmax; + ymax = font->glyphs[distch].ymax; + for(y = 0; y < ymax - ymin; y++) + for(x = 0; x < xmax - xmin; x++) + { + getpixel(font->img, xmin + x, ymin + y, &r, &g, &b); + if(r > 128) + continue; + setpixel(tmp, distx + x, disty + y, r, g, b); + } + + startx = distx + 20; + result[cur++] = font->glyphs[distch].c; + } + +image_save(tmp, "foo2.bmp"); + image_free(tmp); +} + diff --git a/src/main.c b/src/main.c index 30035e6..1a902c0 100644 --- a/src/main.c +++ b/src/main.c @@ -138,6 +138,8 @@ int main(int argc, char *argv[]) result = decode_clubic(img); else if(!strcmp(mode, "linuxfr")) result = decode_linuxfr(img); + else if(!strcmp(mode, "livejournal")) + result = decode_livejournal(img); else if(!strcmp(mode, "lmt")) result = decode_lmt(img); else if(!strcmp(mode, "paypal")) @@ -159,6 +161,11 @@ int main(int argc, char *argv[]) dprintf("autodetected authimage captcha\n"); result = decode_authimage(img); } + else if(img->width == 175 && img->height == 35) + { + dprintf("autodetected livejournal captcha\n"); + result = decode_livejournal(img); + } else if(img->width == 100 && img->height == 40 && count < 6) { dprintf("autodetected linuxfr captcha\n"); diff --git a/src/scode.c b/src/scode.c index 27574b2..c1506b7 100644 --- a/src/scode.c +++ b/src/scode.c @@ -202,6 +202,17 @@ static char find_glyph(struct image *img, int xmin, int xmax) case 180: return '8'; case 170: return '9'; #endif + /* ourcolony font */ + case 4020: return '0'; + case 1970: return '1'; + case 4627: return '2'; + case 4410: return '3'; + case 4468: return '4'; + case 4329: return '5'; + case 4910: return '6'; + case 2378: return '7'; + case 5375: return '8'; + case 4710: return '9'; default: dprintf("don't know about checksum %i\n", count); return '?';