July 8th, 2010 by webstersprodigy
This is an update to http://webstersprodigy.net/2010/07/07/pydbg-reverseme-solution/. I change a register now to circumvent the isdebuggerpresent call.
import sys
import ctypes
from pydbg import *
from pydbg.defines import *
print "This is a very stupid keygen that uses a debug method and grabs the key from memory"
print "prints out the valid key, and writes it to memory"
print "Basically, pydbg 'hello, world'"
print "-------------"
if len(sys.argv) != 2:
print "Error. USAGE: keygen.py C:\full\path\ice"
sys.exit(-1)
def handler_breakpoint(mdbg):
if mdbg.get_register("EIP") == 0x004011F5:
valid_str = ""
#the valid serial is at 004030C8
addr = 0x004030C8
while 1:
tmp = mdbg.read(addr, 1)
addr += 1
if tmp != "\x00":
valid_str = valid_str + tmp
else:
break
print "The valid string is: ", valid_str
print "Writing this to memory..."
#write this to memory at 004030b4
#def write (self, address, data, length=0)
#wdata = ctypes.create_string_buffer(valid_str)
mdbg.write(0x00403198, valid_str, len(valid_str))
#checking the write
#print mdbg.read(0x00403198, len(valid_str) + 1)
if mdbg.get_register("EIP") == 0x40106e:
mdbg.set_register("EAX", 0)
return DBG_CONTINUE
dbg = pydbg()
dbg.set_callback(EXCEPTION_BREAKPOINT, handler_breakpoint)
dbg.load(sys.argv[1])
dbg.debug_event_iteration()
#0x40106e is the point where we can circumvent the isdebugger present call
dbg.bp_set(0x40106e)
#at 004011FF in execution,
#breakpoing for reading writing final compare
dbg.bp_set(0x004011F5)
dbg.debug_event_loop()
Tags: pydbg, python, reverseme
Posted in GrayHat, Programming | No Comments »
July 7th, 2010 by webstersprodigy
Last week I wrote a keygen here: http://webstersprodigy.net/2010/06/22/reverseme-windows-keygen/.
This is an almost identical problem, but the binary has been patched to allow debugging (I may do this programmaticly as well, but not yet). I wanted to solve this with programmatic debugging. Here is the exe:
Ice9pch3.
The code simply sets a breakpoint and prints the key to the screen. Also it patches the process memory so that the serial is valid.
import sys
import ctypes
from pydbg import *
from pydbg.defines import *
print "This is a very stupid keygen that uses a debug method and grabs the key from memory"
print "prints out the valid key, and writes it to memory"
print "Basically, pydbg 'hello, world'"
print "-------------"
if len(sys.argv) != 2:
print "Error. USAGE: keygen.py C:\full\path\ice"
sys.exit(-1)
def handler_breakpoint(mdbg):
valid_str = ""
#the valid serial is at 004030C8
addr = 0x004030C8
while 1:
tmp = mdbg.read(addr, 1)
addr += 1
if tmp != "\x00":
valid_str = valid_str + tmp
else:
break
print "The valid string is: ", valid_str
print "Writing this to memory..."
#write this to memory at 004030b4
#def write (self, address, data, length=0)
wdata = ctypes.create_string_buffer(valid_str)
mdbg.write(0x00403198, wdata, len(valid_str))
#checking the write
#print mdbg.read(0x00403198, len(valid_str) + 1)
return DBG_CONTINUE
dbg = pydbg()
dbg.set_callback(EXCEPTION_BREAKPOINT, handler_breakpoint)
dbg.load(sys.argv[1])
dbg.debug_event_iteration()
#at 004011FF in execution,
#def bp_set (self, address, description="", restore=True, handler=None):
dbg.bp_set(0x004011F5)
dbg.debug_event_loop()
Tags: crackme, debugging, pydbg, python
Posted in GrayHat, Programming, windoze | 1 Comment »
June 22nd, 2010 by webstersprodigy
This one was challenging for me, and took me several hours, but was fun. I got caught up on certain parts that may not have been too difficult, but, yeah…
http://crackmes.de/users/tripletordo/ice9/
You can download the executable here Ice9.zip.
The first thing I noticed is probably the ‘trick’ which was simply a call to isdebuggerpresent. I modified the assembly immediately after from JNE to JE so that it only runs if a debugger is present, allowing me to attach my debugger.
00401071 74 0A JE SHORT Ice9.0040107D
This took a lot of trial and error. My strategy was to replicate the logic. Once I got to the point ‘ecx at 0040119c’ I was home free.
#include <iostream>
#include <string>
using namespace std;
void main (int argc, char *argv[]) {
if ( argc != 2) {
cout<<"Bad usage, enter a name > 4 letters"<<endl;
return;
}
string name = argv[1];
string ostring = name;
int i;
//first reverse the string
for (i=0; i<name.length(); i++) {
name[i] = ostring [name.length()-i-1];
}
if (name.length() < 4) {
cout << "name must be more than 4 letters chief"<<endl;
return;
}
int v1 = 0;
int cum = 0;
for (i=1; i<name.length(); i++) {
v1 = name[i];
if (name[i] <= 90) {
if (v1 >= 65)
v1 += 44;
}
cum += v1;
} //ecx at 0040119C
cum = 9 * (12345 * (cum + 666) - 23);
char chr_403119 [122];
unsigned int v;
i=0;
//no bounds checking
do {
v = cum;
cum /= 0xA;
chr_403119[i++] = v % 10 + 48;
} while (v / 10);
chr_403119[i] = '\0';
printf ("%s", chr_403119);
string serial = "";
//reverse the string
for (; i >= 0; --i) {
serial += chr_403119[i];
}
cout<<serial<<endl;
//append all chars except the 'first' three to the end
for (i=3; i< ostring.length(); i++) {
serial += ostring[i];
}
cout<<serial<<endl;
}
My plan on this one, since it was interesting enough and because it’s relatively easy to break at the final value, is to break this a completely different way. I’d like to write a python debugging script that bypasses the isdebuggerpresent and just grabs the final value in the compare at 004011FF. This should be relatively straightforward, and hopefully a good ‘hello, world’ to the world of python debugging. Stay tuned.
Tags: crackmes, IDA, keygen, ollydbg
Posted in Bits and Bytes, GrayHat | No Comments »
June 13th, 2010 by webstersprodigy
This relies on HD’s keys, found http://digitaloffense.net/tools/debian-openssl/
description = [[
Debian OpenSSH/OpenSSL Package Random Number Generator Weakness
]]
---
-- @output
-- 22/ssh open ssh
-- |_ ssh_debian_weak: The following keys are vulnerable: 2048 RSA 1024 RSA
-- SSH Weak Debian Key Script
-- rev 1.0 (2010-02-07)
-- rougly based on ssh_debian_weak.nasl by tennable
-- written by hand
author = "Rich Lundeen <mopey@webstersprodigy.net>"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"websters", "nessus", "act_gather_info"}
dependencies = {"ssh-hostkey"}
require("shortport")
require("ssh1")
require("ssh2")
require("nessus/nessus_conf")
portrule = shortport.port_or_service({22}, {"ssh"})
action = function(host, port)
local keyval = nmap.registry.sshhostkey[host.ip]
if keyval == nil then
return
end
local output = ""
for i,line in ipairs(keyval) do
--TODO eventually binary search is nicer, but due to formats ready from HD
--or if wanted later perhaps add the hex version to registry
local linekey = string.gsub(ssh1.fingerprint_hex(line.fingerprint,
line.algorithm, line.bits), ":", "")
local crimp = pcre.new("^[^\\s]+[\\s]([^\\s]+)[\\s][^\\s]+", 0, "C")
local s, e, t = crimp:exec(linekey, 0, 0)
linekey = string.sub(linekey, t[1], t[2])
local fstring = (nessus_conf.nessus_conf["basedir"] ..
"nselib/nessus/data/debian_weak_ssl/" ..
line.algorithm:lower() .. "_" ..
tostring(line.bits))
local mfile = io.open(fstring, "r")
for vulnkey in mfile:lines() do
--TODO this could be made more efficient
if string.find(vulnkey, linekey, 0) then
output = output .. line.algorithm .. " " .. tostring(line.bits)
end
end
mfile:close()
end
if output ~= "" then
return output
end
end
Tags: lua, nmae, nse
Posted in Computers, Programming | No Comments »